diff --git a/lookup.py b/lookup.py index 92aee3d..ea650de 100644 --- a/lookup.py +++ b/lookup.py @@ -18,55 +18,16 @@ ACTION_NAME = "Pitch Accent lookup" -def html_page(body_content: str): - head_content = """ - - Pronunciations - - """ - - return f'{head_content}{body_content}' +class ViewPitchAccentsDialog(QDialog): + assert mw, "Anki must be initialized." + _web_relpath = f"/_addons/{mw.addonManager.addonFromModule(__name__)}/web" + _css_relpath = f"{_web_relpath}/pitch_lookup.css" -class ViewPitchAccentsDialog(QDialog): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + mw.addonManager.setWebExports(__name__, r"(img|web)/.*\.(js|css|html|png|svg)") + + def __init__(self, parent: QWidget): + super().__init__(parent) self._webview = AnkiWebView(parent=self, title=ACTION_NAME) self._pronunciations = None self._setup_ui() @@ -83,8 +44,8 @@ def _setup_ui(self): def _make_bottom_buttons(self): buttons = ( - ('Ok', self.accept), - ('Copy HTML to Clipboard', self._copy_pronunciations) + ("Ok", self.accept), + ("Copy HTML to Clipboard", self._copy_pronunciations), ) hbox = QHBoxLayout() for label, action in buttons: @@ -95,32 +56,36 @@ def _make_bottom_buttons(self): return hbox def _copy_pronunciations(self): - return QApplication.clipboard().setText(format_pronunciations( - self._pronunciations, - sep_single='、', - sep_multi='
', - expr_sep=':', - max_results=99, - )) - - def lookup(self, search: str): + return QApplication.clipboard().setText( + format_pronunciations( + self._pronunciations, + sep_single="、", + sep_multi="
", + expr_sep=":", + max_results=99, + ) + ) + + def lookup_pronunciations(self, search: str): self._pronunciations = get_pronunciations(search) return self - def format(self): - """ Format pronunciations as an HTML list. """ + def set_html_result(self): + """Format pronunciations as an HTML list.""" ordered_dict = OrderedDict() for word, entries in self._pronunciations.items(): - ordered_dict[word] = ''.join(dict.fromkeys( - f'
  • {update_html(entry.html_notation)}[{entry.pitch_number}]
  • ' - for entry in entries - )) + ordered_dict[word] = "".join( + dict.fromkeys(f"
  • {update_html(entry.html_notation)}[{entry.pitch_number}]
  • " for entry in entries) + ) entries = [] for word, html in ordered_dict.items(): - entries.append(f'
    {word}
      {html}
    ') + entries.append(f'
    {word}
      {html}
    ') - self._webview.setHtml(html_page(''.join(entries))) + self._webview.stdHtml( + body=f'
    {"".join(entries)}
    ', + css=[self._css_relpath], + ) return self def reject(self) -> None: @@ -137,20 +102,15 @@ def done(self, *args, **kwargs) -> None: def on_lookup_pronunciation(parent: QWidget, text: str): - """ Do a lookup on the selection """ + """Do a lookup on the selection""" if text := clean_furigana(text).strip(): - ( - ViewPitchAccentsDialog(parent) - .lookup(text) - .format() - .exec() - ) + (ViewPitchAccentsDialog(parent).lookup_pronunciations(text).set_html_result().exec()) else: showInfo(_("Empty selection.")) def setup_mw_lookup_action(root_menu: QMenu) -> None: - """ Add a main window entry """ + """Add a main window entry""" action = QAction(ACTION_NAME, root_menu) qconnect(action.triggered, lambda: on_lookup_pronunciation(mw, mw.web.selectedText())) if shortcut := cfg.pitch_accent.lookup_shortcut: @@ -159,12 +119,12 @@ def setup_mw_lookup_action(root_menu: QMenu) -> None: def add_context_menu_item(webview: AnkiWebView, menu: QMenu) -> None: - """ Add a context menu entry """ + """Add a context menu entry""" menu.addAction(ACTION_NAME, lambda: on_lookup_pronunciation(webview, webview.selectedText())) def setup_browser_menu(browser: Browser) -> None: - """ Add a browser entry """ + """Add a browser entry""" action = QAction(ACTION_NAME, browser) qconnect(action.triggered, lambda: on_lookup_pronunciation(browser, browser.editor.web.selectedText())) if shortcut := cfg.pitch_accent.lookup_shortcut: diff --git a/web/pitch_lookup.css b/web/pitch_lookup.css new file mode 100644 index 0000000..080ae1a --- /dev/null +++ b/web/pitch_lookup.css @@ -0,0 +1,51 @@ +*, +*::before, +*::after { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +body { + margin: 0; + font-size: 1.5rem; + font-family: "Noto Serif", "Noto Serif CJK JP", "Yu Mincho", "Liberation Serif", "Times New Roman", Times, Georgia, + Serif; + background-color: #fffaf0; + color: #2a1b0a; + line-height: 1.4; + text-align: left; +} + +.pitch_lookup { + display: grid; + grid-template-columns: max-content 1fr; + row-gap: 0.2rem; + column-gap: 0.2rem; +} + +.keyword { + color: #582020; +} + +.keyword, +.pitch_accents { + margin-top: 0px; + margin-bottom: 0px; + background-color: rgba(87, 43, 43, 0.1); + padding: 0.2rem; +} + +.keyword:nth-of-type(2n), +.pitch_accents:nth-of-type(2n) { + background-color: rgba(144, 148, 113, 0.1); +} + +ol, +ul { + padding-left: 1.5em; +} + +li + li { + margin-top: 0.4rem; +}