Setup: Yomichan
Overview¶
Yomitan is the main program that will create the cards. You can download Yomitan as a Firefox extension or under the Chrome web store.
This section will go over the minimal Yomitan setup to work with this card type.
If you have never used Yomitan before, please see this page first to get it working.
Preliminary Steps¶
If you have used Yomitan before, please make a backup of your settings (just in case).
Additionally, if you downloaded Yomitan from a file, try updating that as well. Most users should have installed it from their browser's extension page, in which case nothing has to be done.
Yomichan Fields¶
To edit the fields that Yomitan will automatically fill out, do the following:
- Navigate to Yomitan Settings.
- Go to the
Anki
section. - Select
Anki card format...
. - Set "Model" as
JP Mining Note
. - Copy and paste the following values into the fields (the custom markers won't be available in the dropdown arrow):
Click here to see the fields to copy and paste.
Anki Fields | Yomichan Format | Notes |
---|---|---|
Key | {expression} |
|
Word | {expression} |
|
WordReading | {furigana-plain} |
|
PAOverride | ||
PAOverrideText | New in version 0.11.0.0 |
|
AJTWordPitch | ||
PrimaryDefinition | {jpmn-primary-definition} |
|
PrimaryDefinitionPicture | New in version 0.11.0.0 |
|
Sentence | {cloze-prefix}<b>{cloze-body}</b>{cloze-suffix} |
|
SentenceReading | ||
AltDisplay | ||
AltDisplayPASentenceCard | ||
AdditionalNotes | ||
*IsSentenceCard | ||
*IsClickCard | ||
*IsHoverCard | ||
*IsTargetedSentenceCard | ||
*PAShowInfo | ||
*PATestOnlyWord | ||
*PADoNotTest | ||
*PASeparateWordCard | ||
*PASeparateSentenceCard | ||
*SeparateClozeDeletionCard | ||
Hint | ||
HintNotHidden | ||
Picture | ||
WordAudio | {audio} |
|
SentenceAudio | ||
PAGraphs | {jpmn-pitch-accent-graphs} |
|
PAPositions | {jpmn-pitch-accent-positions} |
|
PASilence | [sound:_silence.wav] |
|
WordReadingHiragana | {jpmn-word-reading-hiragana} |
New in version 0.11.0.0 |
FrequenciesStylized | {jpmn-frequencies} |
|
FrequencySort | {jpmn-frequency-sort} |
|
SecondaryDefinition | {jpmn-secondary-definition} |
|
ExtraDefinitions | {jpmn-extra-definitions} |
|
UtilityDictionaries | {jpmn-utility-dictionaries} |
|
Comment |
The above fields will create, by default, a basic vocab card in bilingual format, with all other definitions in collapsable fields.
Note
Anything field marked with *
are binary fields, and
should be configured to each user's personal preferences.
To change the default value of any of the fields, simply fill
the field in within the aforementioned Anki card format...
section.
For example, if you want the card to be a sentence card by default,
fill the IsSentenceCard
field here.
The custom markers like {jpmn-primary-definition}
is not provided by Yomitan by default.
See the section below to make these markers usable.
Yomichan Templates¶
Yomitan supports user inserted template code that allows the automatic separation of bilingual and monolingual dictionary definitions, custom stylization, etc. This note type makes heavy use of these custom templates.
To make the new markers usable, do the following:
- Navigate to Yomitan Settings.
- Make sure that advanced settings are turned on (bottom left corner).
- Go to the
Anki
section - Select
Configure Anki card templates...
- If you have existing template code already, I highly recommend resetting the templates (bottom right corner, red button) unless you know exactly what you are doing.
After resetting the templates, without removing any of the existing template code, add the following template code as follows:
-
Copy and paste the code below to the top of the default Yomitan template code:
Click here to show the template code to copy.
{{~! ~}} {{~! ==================== jp-mining-note handlebars ===================== ~}} {{~! v1.0.5 ~}} {{~! ~}} {{~! https://arbyste.github.io/jp-mining-note/ ~}} {{~! ------------------------------------------------------- ~}} {{~! ================ Dictionary Categorization Options ================= ~}} {{~! valid values: "bilingual", "monolingual" ~}} {{~set "opt-first-definition-type" "bilingual" ~}} {{~! A bunch of JP and CN bilingual dictionaries covered by default, including: JMdict, 新和英, CEDICT, etc ~}} {{~#set "bilingual-dict-regex"~}} ^(([Jj][Mm][Dd]ict)(.*)|(.*)新和英(.*)|日本語文法辞典\(全集\)|KireiCake|NEW斎藤和英大辞典|CEDICT|CC-CEDICT(.*)|CantoDict|Canto CEDICT|Words\.hk C-E FS|CE Wiktionary|CC-Canto|Jitendex(.*)|ADD_BILINGUAL_DICTIONARIES_HERE)$ {{~/set~}} {{~#set "utility-dict-regex"~}} ^(NHK日本語発音アクセント新辞典|シン・漢字遣い参考|[Jj][Mm][Dd]ict( Surface)? Forms|JMedict)$ {{~/set~}} {{~#set "ignored-dict-regex"~}} ^(ADD_IGNORED_DICTIONARIES_HERE)$ {{~/set~}} {{~! ====================== Selected Text Options ======================= ~}} {{set "opt-selection-text-enabled" false}} {{set "opt-selection-text-dictionary" true}} {{set "opt-selection-text-glossary" true}} {{set "opt-selection-text-glossary-attempt-bold" true}} {{~! ==================== Frequency Sorting Options ===================== ~}} {{~! See here for the official documentation on how these options work: https://github.com/MarvNC/JP-Resources#freq-settings ~}} {{~#set "opt-ignored-freq-dict-regex"~}} ^(JLPT_Level)$ {{~/set~}} {{~#set "opt-ignored-freq-value-regex"~}} ❌ {{~/set~}} {{~#set "opt-keep-freqs-past-first-regex"~}} ^()$ {{~/set~}} {{~set "opt-no-freq-default-value" 9999999 ~}} {{~set "opt-freq-sorting-method" "harmonic" ~}} {{~! "min", "first", "avg", "harmonic" ~}} {{~set "opt-grammar-override" true ~}} {{~set "opt-grammar-override-value" 0 ~}} {{~#set "opt-grammar-override-dict-regex"~}} ^(日本語文法辞典\(全集\)|毎日のんびり日本語教師|JLPT文法解説まとめ|どんなときどう使う 日本語表現文型辞典|絵でわかる日本語)$ {{~/set~}} {{~! ============== Dictionary First Line Removal Options =============== ~}} {{~set "opt-wrap-first-line-spans" true ~}} {{~! valid values: "except", "only" ~}} {{~set "opt-first-line-regex-mode" "except"~}} {{~! JMdict and jitenon dictionaries from stephenmk are ignored (the latter because the handlebars cannot properly detect the first line.) In particular, removing the first line from jitenon dictionaries with handlebars alone is not trivial, so that feature will not be supported. ~}} {{~#set "opt-first-line-dicts-regex"~}} ^(JMdict.*|Nico/Pixiv|故事・ことわざ・慣用句オンライン|四字熟語辞典オンライン|国語辞典オンライン|大辞林 第四版|新明解国語辞典 第八版)$ {{~/set~}} {{~! ========================== Other Options =========================== ~}} {{~set "opt-primary-def-one-dict-entry-only" false ~}} {{~set "opt-jmdict-list-format" false ~}} {{~! ======================== Plaintext Options ========================= ~}} {{~! WARNING: I recommend not changing these options if you are using the jp-mining-note template. These options will change the general layout of the HTML, which will prevent certain features or stylizations from properly working. (If you aren't using jp-mining-note, please feel free to change these options!) Instead of using these options, see here: https://aquafina-water-bottle.github.io/jp-mining-note/definitions/ These hide specific elements using CSS instead of modifying the raw HTML structure behind it. ~}} {{~set "opt__plaintext__enabled" false ~}} {{~set "opt__plaintext__one-dict-entry-only-no-list" false ~}} {{~set "opt__plaintext__remove-dictionary-tag" false ~}} {{~set "opt__plaintext__remove-first-line-enabled" false ~}} {{~! ============== ORIGINAL YOMICHAN TEMPLATE CODE BELOW ============== ~}}
-
Copy and paste the code below to the bottom of the default Yomitan template code:
Click here to show the template code to copy.
{{~! ============== ORIGINAL YOMICHAN TEMPLATE CODE ABOVE =============== ~}} {{~! v1.0.5 ~}} {{~! ================== helper functions ================== ~}} {{#*inline "s"}}{{/inline}} {{~! categorizes into 4 types: "ignored", "bilingual", "utility", or "monolingual" ~}} {{~#*inline "jpmn-get-dict-type"~}} {{~#scope~}} {{~#set "rx-match-ignored" ~}} {{~#regexMatch (get "ignored-dict-regex") "gu"~}}{{dictionaryName}}{{~/regexMatch~}} {{/set~}} {{~#set "rx-match-bilingual" ~}} {{~#regexMatch (get "bilingual-dict-regex") "gu"~}}{{dictionaryName}}{{~/regexMatch~}} {{/set~}} {{~#set "rx-match-utility" ~}} {{~#regexMatch (get "utility-dict-regex") "gu"~}}{{dictionaryName}}{{~/regexMatch~}} {{/set~}} {{~#if (op "!==" (get "rx-match-ignored") "")~}} ignored {{~else if (op "!==" (get "rx-match-bilingual") "")~}} bilingual {{~else if (op "!==" (get "rx-match-utility") "")~}} utility {{~else~}} {{~! assumed that anything else is a monolingual dictionary ~}} monolingual {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! returns "" if selection text is disabled, or if none existed in the first place ~}} {{~#*inline "_jpmn-selection-text"~}} {{~! text-mode != "" and text-mode > 0 ~}} {{~#if (op "===" (get "opt-selection-text-enabled") true)~}} {{~! removes leading and trailing whitespace ~}} {{~#regexReplace "^\s+|\s+$" "" "g"~}} {{~#getMedia "popupSelectionText"}}{{/getMedia~}} {{~/regexReplace~}} {{~/if~}} {{~/inline~}} {{~! checks that the selection text is indeed a dictionary (returns the text if true, nothing if false) ~}} {{~#*inline "_jpmn-check-dictionary"~}} {{~#scope~}} {{~#set "selection-is-dictionary" false}}{{/set~}} {{~#each definition.definitions~}} {{~#if (op "===" (get "selection") dictionary)~}} {{~#set "selection-is-dictionary" true ~}}{{~/set~}} {{~/if~}} {{~/each~}} {{~#if (op "===" (get "selection-is-dictionary") true)~}} {{~get "selection"~}} {{~else~}} {{~! null ~}} {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! gives the raw glossary as the search string (for searching to see if the selected text is a part of a dictionary) ~}} {{#*inline "_jpmn-glossary-single-search"}} {{~#scope~}} {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}} {{~/scope~}} {{/inline}} {{~! escape a regex string: https://stackoverflow.com/a/6969486~}} {{~! /[.*+?^${}()|[\]\\]/g, '\\$&' ~}} {{~! escapes the `regexString` regex to allow it to be used like a normal search in a string ~}} {{#*inline "_jpmn-escape-regex"}} {{~#regexReplace "[.*+?^${}()|[\]\\]" "\$&" "g"~}}{{~regexString~}}{{~/regexReplace~}} {{/inline}} {{~#*inline "_jpmn-get-dict-if-glossary-selected"~}} {{~#scope~}} {{~#set "result-dictionary" null}}{{/set~}} {{~#set "search-selection"}}{{~#regexReplace "[.*+?^${}()|[\]\\]" "\$&" "g"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}} {{~#each definition.definitions~}} {{~#set "search-def"}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{/set~}} {{~set "search-regex-match" (regexMatch (get "search-selection") "gu" (get "search-def"))}} {{~#if (op "&&" (op "===" (get "result-dictionary") null) (op "!==" (get "search-regex-match") "") )~}} {{~#set "result-dictionary" dictionary}}{{/set~}} {{~/if~}} {{~/each~}} {{~get "result-dictionary" ~}} {{~/scope~}} {{~/inline~}} {{~! searches dictionary, determined by `opt-first-definition-type` - (opt-first-definition-type === bilingual) -> bilingual dictionaries are searched first - (opt-first-definition-type === monolingual) -> monolingual dictionaries are searched first ~}} {{~#*inline "_jpmn-search-primary-definition-dict"~}} {{~#scope~}} {{~#if (op "===" (get "opt-first-definition-type") "bilingual")~}} {{~#set "first-definition-search-type-1" "bilingual"}}{{/set~}} {{~#set "first-definition-search-type-2" "monolingual"}}{{/set~}} {{~else~}} {{~#set "first-definition-search-type-1" "monolingual"}}{{/set~}} {{~#set "first-definition-search-type-2" "bilingual"}}{{/set~}} {{~/if~}} {{~! first-dictionary === null <=> no valid dictionary was found ~}} {{~#set "first-dictionary" null}}{{/set~}} {{~#each definition.definitions~}} {{~#set "test-dict-name"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "test-dict-name") (get "first-definition-search-type-1"))~}} {{~#if (op "===" null (get "first-dictionary"))~}} {{~#set "first-dictionary" dictionary~}}{{~/set~}} {{~/if~}} {{~/if~}} {{~/each~}} {{~! uses other dictionary type, last resort ~}} {{~#if (op "===" (get "first-dictionary") null)~}} {{~#each definition.definitions~}} {{~#set "test-dict-name"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "test-dict-name") (get "first-definition-search-type-2"))~}} {{~#if (op "===" null (get "first-dictionary"))~}} {{~#set "first-dictionary" dictionary~}}{{~/set~}} {{~/if~}} {{~/if~}} {{~/each~}} {{~/if~}} {{~#get "first-dictionary"~}}{{~/get~}} {{~/scope~}} {{~/inline~}} {{~! if (selection-text exists): if (selection-text is exactly a dictionary): return dictionary if (able to detect dictionary of which the selection-text is highlighting): return dictionary return null ~}} {{~#*inline "_jpmn-check-dictionary-and-glossary"~}} {{~#scope~}} {{~#set "result" ""}}{{/set~}} {{~! checks if the selected text matches a dictionary ~}} {{~#if (op "===" (get "opt-selection-text-dictionary") true)~}} {{~#set "result"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}} {{~/if~}} {{~! checks if the selected text matches a definition in a dictionary ~}} {{~#if (op "&&" (op "===" (get "result") "") (op "&&" (op "===" (get "opt-selection-text-glossary") true) (op "===" (get "opt-selection-text-glossary-attempt-bold") true) ) ) ~}} {{~#set "result"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}} {{~/if~}} {{~get "result" ~}} {{~/scope~}} {{~/inline~}} {{~! if (selection-text exists): if (selection-text is exactly a dictionary): return null if (able to detect dictionary of which the selection-text is highlighting): return "uses-glossary" return null ~}} {{~#*inline "_jpmn-selection-uses-glossary"~}} {{~#scope~}} {{~#set "result" ""}}{{/set~}} {{~! checks if the selected text matches a dictionary ~}} {{~#if (op "===" (get "opt-selection-text-dictionary") true)~}} {{~#set "result"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}} {{~/if~}} {{~! checks if the selected text matches a definition in a dictionary ~}} {{~#if (op "!==" (get "result") "") ~}} {{~! selection-text is a dictionary -> null ~}} {{~else if (op "&&" (op "===" (get "opt-selection-text-glossary") true) (op "===" (get "opt-selection-text-glossary-attempt-bold") true) ) ~}} {{~#set "result"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}} {{~#if (op "!==" (get "result") "") ~}} {{~! selection-text dict found -> "uses-glossary" ~}} uses-glossary {{~/if~}} {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! if (selection-text exists): if (selection-text is exactly a dictionary): return dictionary if (able to detect dictionary of which the selection-text is highlighting): return dictionary if (selection-text-glossary is not enabled): return first-dictionary (determined by `opt-first-definition-type`) return null else: return first-dictionary (determined by `opt-first-definition-type`) ~}} {{~#*inline "_jpmn-get-primary-definition-dict"~}} {{~#scope~}} {{~! first checks selection text ~}} {{~#set "selection"}}{{~> _jpmn-selection-text ~}}{{/set~}} {{~#if (op "!==" (get "selection") "")~}} {{~#set "result"}}{{~> _jpmn-check-dictionary-and-glossary . ~}}{{/set~}} {{~! doesn't return a dictionary if opt-selection-text-glossary is false b/c ~}} {{~#if (op "&&" (op "===" (get "result") "") (op "===" (get "opt-selection-text-glossary") false) ) ~}} {{~#set "result"}}{{~> _jpmn-search-primary-definition-dict . ~}}{{/set~}} {{~/if~}} {{~get "result" ~}} {{~! no selection text ~}} {{~else~}} {{~> _jpmn-search-primary-definition-dict . ~}} {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! get number of primary dictionary entries ~}} {{~#*inline "_jpmn-primary-dict-entry-count"~}} {{~#scope~}} {{~#set "primary-dictionary"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}} {{~set "dict-entry-count" 0 ~}} {{~#each definition.definitions~}} {{~#if (op "===" dictionary (get "primary-dictionary")) ~}} {{~! dict-entry-count += 1 ~}} {{~set "dict-entry-count" (op "+" (get "dict-entry-count") 1 ) ~}} {{~/if~}} {{~/each~}} {{~get "dict-entry-count" ~}} {{~/scope~}} {{~/inline~}} {{~! returns "true" if valid dict, "" (null) otherwise ~}} {{~#*inline "_jpmn-non-primary-is-valid-dict"~}} {{~! PARAMETERS: validDictType: "monolingual" or "bilingual" or "utility" dictionaryName: dictionary id entryCount: primary dictionary entry count ~}} {{~#scope~}} {{~set "use-primary-dictionary" (op "&&" (get "opt-primary-def-one-dict-entry-only") (op "&&" (op "!==" (op "+" entryCount) 0) (op "!==" (op "+" entryCount) 1)) ) ~}} {{~set "valid-dict" null ~}} {{~#set "test-dict-type"}}{{~> jpmn-get-dict-type . dictionaryName=dictionaryName ~}}{{/set~}} {{~#if (op "&&" (op "===" (get "test-dict-type") validDictType) (op "||" (op "!==" (get "primary-dictionary") dictionaryName) (op "===" (get "use-primary-dictionary") true) ) ) ~}} {{~set "valid-dict" "true" ~}} {{~/if~}} {{~get "valid-dict" ~}} {{~/scope~}} {{~/inline~}} {{~! returns "true" if valid dict, "" (null) otherwise ~}} {{~#*inline "_jpmn-non-primary-has-valid-dict"~}} {{~! PARAMETERS: validDictType: "monolingual" or "bilingual" or "utility" entryCount: primary dictionary entry count ~}} {{~#scope~}} {{~set "use-primary-dictionary" (op "&&" (get "opt-primary-def-one-dict-entry-only") (op "&&" (op "!==" (op "+" entryCount) 0) (op "!==" (op "+" entryCount) 1)) ) ~}} {{~! without this set statement, the parameters magically disappears within the bottom 'each' loop... ~}} {{~ set "valid-dict-type" validDictType ~}} {{~ set "entry-count" entryCount ~}} {{~set "has-valid-dict" null ~}} {{~#each definition.definitions~}} {{~#set "is-valid-dict"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=(get "valid-dict-type") entryCount=(get "entry-count") dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "is-valid-dict") "true") ~}} {{~set "has-valid-dict" "true" ~}} {{~/if~}} {{~/each~}} {{~get "has-valid-dict" ~}} {{~/scope~}} {{~/inline~}} {{~#*inline "_jpmn-get-primary-definition-value"~}} {{~! ASSUMPTION: "primary-dictionary" and "search-selection" is available to us from previous functions ~}} {{~#scope~}} {{~#if (op "&&" (op "!==" (get "search-selection") "") (get "opt-primary-def-one-dict-entry-only") ) ~}} {{~! text was highlighted -> use primary dictionary entry with highlighted text ~}} {{~set "found-dict-entry" false ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} <ol> {{~/if~}} {{~#each definition.definitions~}} {{~#set "rx-match-dict-entry" ~}} {{~#regexMatch (get "search-selection") "gu"~}}{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/regexMatch~}} {{/set~}} {{~#if (op "&&" (op "===" (get "found-dict-entry") false) (op "&&" (op "!==" (get "rx-match-dict-entry") "") (op "===" dictionary (get "primary-dictionary")) ) ) ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} <li data-details="{{~dictionary~}}"> {{~/if~}} {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} </li> {{~/if~}} {{~set "found-dict-entry" true ~}} {{~/if~}} {{~/each~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} </ol> {{~/if~}} {{~else if (get "opt-primary-def-one-dict-entry-only") ~}} {{~! use first primary dictionary entry ~}} {{~set "found-dict-entry" false ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} <ol> {{~/if~}} {{~#each definition.definitions~}} {{~#if (op "&&" (op "===" (get "found-dict-entry") false) (op "===" dictionary (get "primary-dictionary")) ) ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} <li data-details="{{~dictionary~}}"> {{~/if~}} {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} </li> {{~/if~}} {{~set "found-dict-entry" true ~}} {{~/if~}} {{~/each~}} {{~#if (op "!" (get "opt__plaintext__one-dict-entry-only-no-list")) ~}} </ol> {{~/if~}} {{~else~}} {{~! use all primary dictionary entries ~}} {{~#if (get "opt__plaintext__one-dict-entry-only-no-list") ~}} {{~! must manually calculate number of primary-dictionary entries... ~}} {{~set "t" 0 ~}} {{~#each definition.definitions~}} {{~#if (op "===" dictionary (get "primary-dictionary"))~}} {{~set "t" (op "+" (get "t") 1) ~}} {{~/if~}} {{~/each~}} {{~#if (op ">=" (get "t") 2)~}} <ol> {{~/if~}} {{~#each definition.definitions~}} {{~#if (op "===" dictionary (get "primary-dictionary"))~}} {{~#if (op ">=" (get "t") 2)~}} <li data-details="{{~dictionary~}}"> {{~/if~}} {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} {{~#if (op ">=" (get "t") 2)~}} </li> {{~/if~}} {{~/if~}} {{~/each~}} {{~#if (op ">=" (get "t") 2)~}} </ol> {{~/if~}} {{~else~}} <ol> {{~s~}} {{~#each definition.definitions~}} {{~#if (op "===" dictionary (get "primary-dictionary"))~}} <li data-details="{{~dictionary~}}"> {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} </li> {{~/if~}} {{~/each~}} </ol> {{~s~}} {{~/if~}} {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! if (mode === "except" and (regex doesn't match) or mode === "only" and (regex matches)): return true return null ~}} {{#*inline "_jpmn-check-first-line-dict"}} {{~#scope~}} {{~#set "rx-match-first-line-dict" ~}} {{~#regexMatch (get "opt-first-line-dicts-regex") "u"~}}{{dictionary}}{{~/regexMatch~}} {{/set~}} {{~#if (op "||" (op "&&" (op "===" (get "opt-first-line-regex-mode") "except") (op "===" (get "rx-match-first-line-dict") "") ) (op "&&" (op "===" (get "opt-first-line-regex-mode") "only") (op "!==" (get "rx-match-first-line-dict") "") ) ) ~}} true {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! custom glossary-single function for additional regex parsing per dictionary ~}} {{~! OVERRIDES brief and noDictionaryTag ~}} {{#*inline "_jpmn-glossary-single"}} {{~#scope~}} {{~#if (op "===" dictionary "NHK日本語発音アクセント新辞典")~}} {{~#regexReplace "<br></span> ・" "<br></span>" "g"~}} {{~#regexReplace "<br> ・" "<br>" "g"~}} {{~> _jpmn-glossary-single2 . ~}} {{~/regexReplace~}} {{~/regexReplace~}} {{~else~}} {{~> _jpmn-glossary-single2 . ~}} {{~/if~}} {{~/scope~}} {{/inline}} {{~! custom glossary-single function to add custom html around the dictionary and tags ~}} {{#*inline "_jpmn-glossary-single2"}} {{~#scope~}} {{~#if (op "!" (get "opt__plaintext__enabled")) ~}} <span class="dict-group__tag-list"> {{~s~}} {{~#each definitionTags~}} <span class="dict-group__tag dict-group__tag--name"> {{~s~}} <span class="dict-group__tag-inner"> {{~s~}} {{~name~}} </span> {{~s~}} </span> {{~s~}} {{~/each~}} <span class="dict-group__tag dict-group__tag--dict"> {{~s~}} <span class="dict-group__tag-inner"> {{~s~}} {{~dictionary~}} </span> {{~s~}} </span> {{~s~}} </span> {{~s~}} {{~else~}} {{~#scope~}} {{~#set "any" false}}{{/set~}} {{~#each definitionTags~}} {{~#if (get "any")}}, {{else}}({{/if~}} {{name}} {{~#set "any" true}}{{/set~}} {{~/each~}} {{~#if (op "!" (get "opt__plaintext__remove-dictionary-tag"))~}} {{~#if (get "any")}}, {{else}}({{/if~}} {{dictionary}} {{~#set "any" true}}{{/set~}} {{~/if~}} {{~#if (get "any")}}) {{/if~}} {{~/scope~}} {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} {{~/if~}} {{~#if (op "!" (get "opt__plaintext__enabled")) ~}} <span class="dict-group__glossary"> {{~s~}} {{~/if~}} {{~! option to not wrap with spans because it may break dictionaries (this is the hell that is parsing html with regex) ~}} {{~#if (op "&&" (get "opt-wrap-first-line-spans") (op "!" (get "opt__plaintext__enabled")) ) }} {{~#set "modify-first-line" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}} {{~#if (get "modify-first-line") ~}} {{~#regexReplace "^(<span lang=\"ja\">)?(.*?)<br>" "$1<span class=\"dict-group__glossary--first-line\">$2</span><span class=\"dict-group__glossary--first-line-break\"><br></span>" ~}} {{~> _jpmn-glossary-single3 . ~}} {{~/regexReplace~}} {{~else~}} {{~> _jpmn-glossary-single3 . ~}} {{~/if~}} {{~else if (get "opt__plaintext__remove-first-line-enabled")~}} {{~#set "modify-first-line" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}} {{~#if (get "modify-first-line") ~}} {{~! none match means the dictionary is not an exception, i.e. replace newline ~}} {{~#regexReplace "^(<span lang=\"ja\">)?(.*?)<br>" "$1" ~}} {{~> _jpmn-glossary-single3 . ~}} {{~/regexReplace~}} {{~else~}} {{~> _jpmn-glossary-single3 . ~}} {{~/if~}} {{~else~}} {{~> _jpmn-glossary-single3 . ~}} {{~/if~}} {{~#if (op "!" (get "opt__plaintext__enabled")) ~}} </span> {{~s~}} {{~/if~}} {{~/scope~}} {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} {{/inline}} {{#*inline "_jpmn-glossary-single3"}} {{~#scope~}} {{~#if (op "&&" (op "===" (get "opt-jmdict-list-format") true) (op "||" (op "===" dictionary "JMdict (English)") (op "===" dictionary "JMdict") ) ) ~}} {{~#if (op "<=" glossary.length 1)~}} {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}} {{~else~}} <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul> {{~/if~}} {{~else~}} {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}} {{~/if~}} {{~/scope~}} {{/inline}} {{~! ============= frequencies ============= ~}} {{#*inline "jpmn-frequencies"}} {{~#if (op ">" definition.frequencies.length 0)~}} {{~#each definition.frequencies~}} <div class="frequencies__group" data-details="{{~dictionary~}}"> {{~s~}} <div class="frequencies__number"> {{~s~}} <span class="frequencies__number-inner"> {{~s~}} {{~! removes the "X" in JPDB's frequency and replaces it with a less assuming character (it interferes with the color of the card, since you see red at the top corner which is somewhat distracting) ~}} {{~#regexReplace "❌" "✖" "g"~}} {{~frequency~}} {{~/regexReplace~}} </span> {{~s~}} </div> {{~s~}} <div class="frequencies__dictionary"> {{~s~}} <span class="frequencies__dictionary-inner"> {{~s~}} {{~dictionary~}} </span> {{~s~}} </div> {{~s~}} </div> {{~/each~}} {{~/if~}} {{/inline}} {{~! base code taken from: https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency ~}} {{~! NOTE: THIS IS ONLY KEPT FOR LEGACY PURPOSES, and is now deprecated. Please use {jpmn-frequency-sort} instead. ~}} {{~#*inline "jpmn-min-freq"~}} {{~#scope~}} {{~#set "min-freq" 0~}}{{~/set~}} {{~#each definition.frequencies~}} {{~#set "rx-match-ignored-freq" ~}} {{~#regexMatch (get "ignored-freq-dict-regex") "gu"~}}{{this.dictionary}}{{~/regexMatch~}} {{/set~}} {{~#if (op "&&" (op "||" (op "===" (get "min-freq") 0) (op ">" (op "+" (get "min-freq")) (op "+" (regexMatch "\d" "g" this.frequency))) ) (op "===" (get "rx-match-ignored-freq") "") ) ~}} {{~#set "min-freq" (op "+" (regexMatch "\d" "g" this.frequency))}}{{/set~}} {{~/if~}} {{~/each~}} {{~get "min-freq"~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-frequency-sort"}} {{~! Frequency sort handlebars: v23.03.13.1 ~}} {{~! The latest version can be found at https://github.com/MarvNC/JP-Resources#freq-handlebar ~}} {{~#scope~}} {{~! Do not change the code below unless you know what you are doing. ~}} {{~set "result-freq" -1 ~}} {{~! -1 is chosen because no frequency dictionaries should have an entry as -1 ~}} {{~set "prev-freq-dict" "" ~}} {{~set "t" 1 ~}} {{~set "found-grammar-dict" false ~}} {{~! search for grammar dictionary ~}} {{~#each definition.definitions~}} {{~#set "rx-match-grammar-dicts" ~}} {{~#regexMatch (get "opt-grammar-override-dict-regex") "u"~}}{{this.dictionary}}{{~/regexMatch~}} {{/set~}} {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}} {{~#if (op "!==" (get "rx-match-grammar-dicts") "") ~}} {{~set "found-grammar-dict" true ~}} {{/if~}} {{~/each~}} {{~! Additional case when "Result grouping mode" is set to "No Grouping"~}} {{~#set "rx-match-grammar-dicts" ~}} {{~#regexMatch (get "opt-grammar-override-dict-regex") "u"~}}{{this.definition.dictionary}}{{~/regexMatch~}} {{/set~}} {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}} {{~#if (op "!==" (get "rx-match-grammar-dicts") "") ~}} {{~set "found-grammar-dict" true ~}} {{/if~}} {{~#each definition.frequencies~}} {{~! rx-match-ignored-freq is not empty if ignored <=> rx-match-ignored-freq is empty if not ignored ~}} {{~#set "rx-match-ignored-freq" ~}} {{~#regexMatch (get "opt-ignored-freq-dict-regex") "u"~}}{{this.dictionary}}{{~/regexMatch~}} {{/set~}} {{~#set "rx-match-ignored-value" ~}} {{~#regexMatch (get "opt-ignored-freq-value-regex") "u"~}}{{this.frequency}}{{~/regexMatch~}} {{/set~}} {{~#if (op "&&" (op "===" (get "rx-match-ignored-freq") "") (op "===" (get "rx-match-ignored-value") ""))~}} {{~! only uses the 1st frequency of any dictionary. For example, if JPDB lists 440 and 26189㋕, only the first 440 will be used. ~}} {{~set "read-freq" false ~}} {{~#if (op "!==" (get "prev-freq-dict") this.dictionary ) ~}} {{~set "read-freq" true ~}} {{~set "prev-freq-dict" this.dictionary ~}} {{/if~}} {{~#if (op "!" (get "read-freq") ) ~}} {{~#set "rx-match-keep-freqs" ~}} {{~#regexMatch (get "opt-keep-freqs-past-first-regex") "u"~}}{{this.dictionary}}{{~/regexMatch~}} {{/set~}} {{~! rx-match-keep-freqs is not empty if keep freqs ~}} {{~#if (op "!==" (get "rx-match-keep-freqs") "") ~}} {{~set "read-freq" true ~}} {{/if~}} {{/if~}} {{~#if (get "read-freq") ~}} {{~set "f" (op "+" (regexMatch "\d+" "" this.frequency)) ~}} {{~#if (op "===" (get "opt-freq-sorting-method") "min") ~}} {{~#if (op "||" (op "===" (get "result-freq") -1) (op ">" (get "result-freq") (get "f")) ) ~}} {{~set "result-freq" (op "+" (get "f")) ~}} {{~/if~}} {{~else if (op "===" (get "opt-freq-sorting-method") "first") ~}} {{~#if (op "===" (get "result-freq") -1) ~}} {{~set "result-freq" (get "f") ~}} {{~/if~}} {{~else if (op "===" (get "opt-freq-sorting-method") "avg") ~}} {{~#if (op "===" (get "result-freq") -1) ~}} {{~set "result-freq" (get "f") ~}} {{~else~}} {{~! iterative mean formula (to prevent floating point overflow): $S_{(t+1)} = S_t + \frac{1}{t+1} (x - S_t)$ - example java implementation: https://stackoverflow.com/a/1934266 - proof: https://www.heikohoffmann.de/htmlthesis/node134.html ~}} {{~set "result-freq" (op "+" (get "result-freq") (op "/" (op "-" (get "f") (get "result-freq") ) (get "t") ) ) }} {{~/if~}} {{~set "t" (op "+" (get "t") 1) ~}} {{~else if (op "===" (get "opt-freq-sorting-method") "harmonic") ~}} {{~#if (op ">" (get "f") 0) ~}} {{~! ensures only positive numbers are used ~}} {{~#if (op "===" (get "result-freq") -1) ~}} {{~set "result-freq" (op "/" 1 (get "f")) ~}} {{~else ~}} {{~set "result-freq" (op "+" (get "result-freq") (op "/" 1 (get "f")) ) }} {{~set "t" (op "+" (get "t") 1) ~}} {{~/if~}} {{~/if~}} {{~else if (op "===" (get "opt-freq-sorting-method") "debug") ~}} {{ this.dictionary }}: {{ this.frequency }} -> {{ get "f" }} <br> {{~else~}} (INVALID opt-freq-sorting-method value) {{~/if~}} {{~/if~}} {{~/if~}} {{~/each~}} {{~! (x) >> 0 apparently floors x: https://stackoverflow.com/a/4228528 ~}} {{~#if (op "===" (get "result-freq") -1) ~}} {{~set "result-freq" (get "opt-no-freq-default-value") ~}} {{~ else if (op "===" (get "opt-freq-sorting-method") "avg") ~}} {{~set "result-freq" (op ">>" (get "result-freq") 0 ) ~}} {{~ else if (op "===" (get "opt-freq-sorting-method") "harmonic") ~}} {{~set "result-freq" (op ">>" (op "*" (op "/" 1 (get "result-freq")) (get "t") ) 0 ) ~}} {{~/if~}} {{~! override final result if grammar dictionary ~}} {{~#if ( op "&&" (op "===" (get "found-grammar-dict") true) (op "===" (get "opt-grammar-override") true) ) ~}} {{~set "result-freq" (get "opt-grammar-override-value") ~}} {{/if}} {{~get "result-freq"~}} {{~/scope~}} {{/inline}} {{~! ============== pitch accent ============== ~}} {{#*inline "jpmn-pitch-accent-graphs"}} {{~#if (op ">" pitchCount 0)~}} {{~#each pitches~}} <div class="pa-graphs__group" data-details="{{dictionary}}"> {{~s~}} <div class="pa-graphs__dictionary"> {{~s~}} <div class="pa-graphs__dictionary-inner"> {{~s~}} {{~dictionary~}} </div> {{~s~}} </div> {{~s~}} <ol> {{~s~}} {{~#each pitches~}} <li> {{~> pitch-accent-item-disambiguation~}} {{~#scope~}} {{~#set "any" false}}{{/set~}} {{~#each tags~}} {{~#if (get "any")}}, {{else}}({{/if~}} {{name}} {{~#set "any" true}}{{/set~}} {{~/each~}} {{~#if (get "any")}}) {{/if~}} {{~/scope~}} {{~> pitch-accent-item format="graph"~}} </li> {{~/each~}} </ol> {{~s~}} </div> {{~/each~}} {{~/if~}} {{/inline}} {{#*inline "jpmn-pitch-accent-positions"}} {{~#if (op ">" pitchCount 0)~}} {{~#each pitches~}} <div class="pa-positions__group" data-details="{{dictionary}}"> {{~s~}} <div class="pa-positions__dictionary"> {{~s~}} <div class="pa-positions__dictionary-inner"> {{~s~}} {{~dictionary~}} </div> {{~s~}} </div> {{~s~}} <ol> {{~s~}} {{~#each pitches~}} <li> {{~> pitch-accent-item-disambiguation~}} {{~#scope~}} {{~#set "any" false}}{{/set~}} {{~#each tags~}} {{~#if (get "any")}}, {{else}}({{/if~}} {{name}} {{~#set "any" true}}{{/set~}} {{~/each~}} {{~#if (get "any")}}) {{/if~}} {{~/scope~}} {{~> pitch-accent-item format="position"~}} </li> {{~/each~}} </ol> {{~s~}} </div> {{~/each~}} {{~/if~}} {{/inline}} {{~! ============== dictionaries ============== ~}} {{~! primary def: first monolingual (or first bilingual if no monolingual dicts found) ~}} {{~! does the reverse if opt-first-definition-type is "bilingual" ~}} {{~#*inline "jpmn-primary-definition"~}} {{~#scope~}} {{~#set "primary-dictionary"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}} {{~#if (op "===" (get "primary-dictionary") "")~}} {{~> _jpmn-selection-text ~}} {{~else~}} {{~#set "selection"}}{{~> _jpmn-selection-text ~}}{{/set~}} {{~#set "selection-uses-glossary"~}} {{~> _jpmn-selection-uses-glossary . ~}} {{~/set~}} {{~! not "" <=> is a filled string ~}} {{~#if (op "!==" (get "selection-uses-glossary") "")~}} {{~! escape regex ~}} {{~#set "search-selection"}}{{~#regexReplace "[.*+?^${}()|[\]\\]" "\$&" "g"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}} {{~#set "search-selection-bold"}}<b>{{~> _jpmn-selection-text ~}}</b>{{/set~}} {{~#regexReplace (get "search-selection") (get "search-selection-bold") "g"~}} {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}} {{~/regexReplace~}} {{~else~}} {{~#set "search-selection"}}{{/set~}} {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}} {{~/if~}} {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! extra def: bilingual defs (excluding primary def) ~}} {{~#*inline "jpmn-secondary-definition"~}} {{~#scope~}} {{~#set "primary-dictionary"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}} {{~! looks to see if another dictionary exists ~}} {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}} {{~#set "entry-count"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}} {{~#set "has-valid-dict"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType="bilingual" entryCount=(get "entry-count")~}}{{/set~}} {{~#if (op "===" (get "has-valid-dict") "true") ~}} <ol> {{~#each definition.definitions~}} {{~#set "is-valid-dict"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType="bilingual" entryCount=(get "entry-count") dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "is-valid-dict") "true") ~}} <li data-details="{{~dictionary~}}"> {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} </li> {{~/if~}} {{~/each~}} </ol> {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! extra def: monolingual defs (excluding primary def) ~}} {{~#*inline "jpmn-extra-definitions"~}} {{~#scope~}} {{~#set "primary-dictionary"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}} {{~! looks to see if another dictionary exists ~}} {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}} {{~#set "entry-count"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}} {{~#set "has-valid-dict"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType="monolingual" entryCount=(get "entry-count")~}}{{/set~}} {{~#if (op "===" (get "has-valid-dict") "true") ~}} <ol> {{~#each definition.definitions~}} {{~#set "is-valid-dict"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType="monolingual" entryCount=(get "entry-count") dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "is-valid-dict") "true") ~}} <li data-details="{{~dictionary~}}"> {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} </li> {{~/if~}} {{~/each~}} </ol> {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! pitch accent info: all pitch accent info dictionaries ~}} {{~#*inline "jpmn-utility-dictionaries"~}} {{~#scope~}} {{~! looks to see if another dictionary exists ~}} {{~! this if-statement is much more simple than the ones above, since utility dictionaries usually aren't the primary definition (if it is, then it'll just be repeated again here) ~}} {{~#set "has-valid-dict"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType="utility"~}}{{/set~}} {{~#if (op "===" (get "has-valid-dict") "true") ~}} <ol> {{~#each definition.definitions~}} {{~#set "test-dict-name"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}} {{~#if (op "===" (get "test-dict-name") "utility")~}} <li data-details="{{~dictionary~}}"> {{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}} </li> {{~/if~}} {{~/each~}} </ol> {{~/if~}} {{~/scope~}} {{~/inline~}} {{~! ======= other ======= ~}} {{~#*inline "jpmn-word-reading-hiragana"~}} {{~#set "word-reading" ~}}{{> reading}}{{/set~}} {{~#if (op "" (get "word-reading")) ~}} {{~#set "word-reading" ~}}{{> expression}}{{/set~}} {{~/if~}} {{#hiragana (get "word-reading") keepProlongedSoundMarks=false}}{{/hiragana}} {{~/inline~}} {{~! thanks to: - https://github.com/FooSoft/yomichan/issues/1952#issuecomment-922671489 for the base code - DaNautics#8833 for finding the above + removing the span classes ~}} {{#*inline "jpmn-sentence-bolded-furigana-plain"}} {{~#if definition.cloze~}} {{~#regexReplace "(<span class=\"term\">)|(</span>)" "" "g"~}} {{~#regexReplace "<ruby>(.+?)<rt>(.+?)</rt></ruby>" " $1[$2]" "g"~}} {{~#if (hasMedia "textFurigana" definition.cloze.prefix)~}} {{~#getMedia "textFurigana" definition.cloze.prefix escape=false}}{{/getMedia~}} {{~else~}} {{~definition.cloze.prefix~}} {{~/if~}} <b> {{~#if (hasMedia "textFurigana" definition.cloze.body)~}} {{~#getMedia "textFurigana" definition.cloze.body escape=false}}{{/getMedia~}} {{~else~}} {{~definition.cloze.body~}} {{~/if~}} </b> {{~#if (hasMedia "textFurigana" definition.cloze.suffix)~}} {{~#getMedia "textFurigana" definition.cloze.suffix escape=false}}{{/getMedia~}} {{~else~}} {{~definition.cloze.suffix~}} {{~/if~}} {{~/regexReplace~}} {{~/regexReplace~}} {{~/if~}} {{/inline}} {{#*inline "jpmn-filled-if-word-is-hiragana"}} {{~#scope~}} {{~#set "expression" ~}}{{> expression}}{{/set~}} {{~#set "reading" ~}}{{> reading}}{{/set~}} {{~#set "expression-hiragana" ~}}{{> jpmn-word-reading-hiragana}}{{/set~}} {{~#if (op "&&" (op "===" (get "expression") (get "reading")) (op "===" (get "expression") (get "expression-hiragana")))~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-filled-if-word-is-not-hiragana"}} {{~#scope~}} {{~#set "filled" ~}}{{> jpmn-filled-if-word-is-hiragana}}{{/set~}} {{~#if (op "===" (get "filled") "")~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-filled-if-grammar-point"}} {{~#scope~}} {{~set "found-grammar-dict" false ~}} {{~! search for grammar dictionary ~}} {{~#each definition.definitions~}} {{~#set "rx-match-grammar-dicts" ~}} {{~#regexMatch (get "opt-grammar-override-dict-regex") "gu"~}}{{this.dictionary}}{{~/regexMatch~}} {{/set~}} {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}} {{~#if (op "!==" (get "rx-match-grammar-dicts") "") ~}} {{~set "found-grammar-dict" true ~}} {{/if~}} {{~/each~}} {{~! Additional case when "Result grouping mode" is set to "No Grouping"~}} {{~#set "rx-match-grammar-dicts" ~}} {{~#regexMatch (get "opt-grammar-override-dict-regex") "gu"~}}{{this.definition.dictionary}}{{~/regexMatch~}} {{/set~}} {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}} {{~#if (op "!==" (get "rx-match-grammar-dicts") "") ~}} {{~set "found-grammar-dict" true ~}} {{/if~}} {{~#if (get "found-grammar-dict") ~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-filled-if-not-grammar-point"}} {{~#scope~}} {{~#set "filled" ~}}{{> jpmn-filled-if-grammar-point}}{{/set~}} {{~#if (op "===" (get "filled") "")~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-filled-if-on-mim"}} {{~#scope~}} {{~#set "rx-match-on-mim" ~}} {{~#regexMatch "(, |^)on-mim(, |$)" "gu"~}}{{> tags }}{{~/regexMatch~}} {{/set~}} {{~#if (op "!==" (get "rx-match-on-mim") "") ~}} 1 {{/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-filled-if-not-on-mim"}} {{~#scope~}} {{~#set "filled" ~}}{{> jpmn-filled-if-not-on-mim}}{{/set~}} {{~#if (op "===" (get "filled") "")~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{~! my personal settings: - sentence card if grammar point - otherwise, if it's on-mim, then hint card - otherwise, default ~}} {{#*inline "jpmn-is-sentence-card"}} {{~> jpmn-filled-if-grammar-point ~}} {{/inline}} {{#*inline "jpmn-is-hint-card"}} {{~#scope~}} {{~#set "filled" ~}}{{> jpmn-is-sentence-card}}{{/set~}} {{~#if (op "===" (get "filled") "")~}} {{~> jpmn-filled-if-on-mim ~}} {{~/if~}} {{~/scope~}} {{/inline}} {{#*inline "jpmn-is-click-card"}} {{~#scope~}} {{~#set "filled1" ~}}{{> jpmn-is-hint-card}}{{/set~}} {{~#set "filled2" ~}}{{> jpmn-is-sentence-card}}{{/set~}} {{~#if (op "&&" (op "===" (get "filled1") "") (op "===" (get "filled2") "") )~}} 1 {{~/if~}} {{~/scope~}} {{/inline}} {{~! a test to check if your dictionaries are correctly classified. ~}} {{~! Only meant to be used for debugging purposes, not Anki. ~}} {{~#*inline "jpmn-test-dict-type"~}} {{~#scope~}} {{~#each definition.definitions~}} 「{{dictionary}}」: {{> jpmn-get-dict-type . dictionaryName=dictionary}} {{/each~}} {{~/scope~}} {{~/inline~}}
Make an example card!¶
At this point, you should be able to make cards with Yomitan!
Click here to show some example Japanese sentences.
「や、いらっしゃい。ま、毒を食らわば皿までって言うしね。あ、違うか。乗り掛かった船?」
「なによぅ…甲斐甲斐しく会いに来た女に対して、最初に言うセリフがそれ?」
「あの時逃げ出した私の罰…あの時の汚辱は今ここで、全部そそいでやるんだ…」
「貴方なんなんです?なにか、妙に銃口慣れしていますね…若者特有の空威張りという訳でもなさそうですし…」
Obviously, just Yomitan alone doesn't fill every field. Notably, the picture and sentence audio is missing.
Outside of that, there are some final settings you can adjust within the Yomitan templates if the card doesn't look quite right.
Yomichan Templates Options Summary¶
Monolingual Definition¶
If you want the first definition you see (the PrimaryDefinition
field) to be monolingual,
change the following line at the top of the templates code:
Additionally, a common thing that people want to do with monolingual dictionaries is to remove the first line of the definition, because it may contain extra info that the user does not want. See here to do exactly that.
Note
If you are using monolingual dictionaries, on your first few cards,
please check that your dictionaries are in the expected places.
Extra bilingual definitions should be under Secondary Definition
,
and extra monolingual definitions should be under Extra Definitions
.
If your dictionaries are ending up in the wrong sections, then it is likely a problem with how the template code categorizes the dictionaries. See here for more info.
Selected Text as the Definition¶
If you want to select the text to use instead of the definition,
simply set opt-selection-text-enabled
to true
.
By default, this enable the following behavior:
- If nothing is selected, then the first dictionary is chosen just like normal.
- If a dictionary is selected, then that dictionary will replace the first definition.
- If a section of text is selected, then that dictionary will replace the first definition. Additionally, that section of text will be highlighted (bolded).
Note
Selecting parts of a definition to bold the text does not always work, especially when used across text with formatting or newlines. See this for more details.
With this being said, selecting the dictionary should always work.
Additional Instructions for Other Platforms¶
Outside of creating cards on the PC, there are some other platforms that one can create cards from.
Android Setup¶
Warning
Actually using JPMN on mobile devices (e.g. for reviewing), is currently not stable. This simply shows how to make the cards on Android.
If you wish to add cards on Android, use AnkiconnectAndroid and follow the instructions on the AnkiconnectAndroid's README page. It might help to export a copy of Yomitan settings from your PC and import said settings on Android, instead of re-doing all of the steps on Android.
Note
Occasionally, importing your Yomitan settings from the PC may lead to AnkiconnectAndroid not working. If AnkiconnectAndroid doesn't work after going through the entire README, try resetting your Yomitan settings on Android and starting from scratch.
Note
There is currently no way to automatically add an image (e.g. a screenshot) automatically. Images must be added manually within AnkiDroid.
Although screenshots cannot be added automatically, the runtime options supports automatically adding images based off of tags. See here for more info.
Kindle Setup¶
One can use something like ann2html to export a Yomitan-able HTML file based on the Kindle's vocabulary builder. This allows you to add the cards through Yomitan on the PC.
Enjoy your new one-click cards!¶
If you've made it this far, then congratulations! Most fields of the cards have been automatically filled out, just from Yomitan alone!
This concludes the setup process for creating cards with Yomitan.
From here, you likely fall under one of the two categories below:
-
I'm new to sentence mining.
If you're new to sentence mining, there are likely some things things that you would like to set up. These include:
- Getting the actual text to use Yomitan on.
- Getting the pictures and/or sentence audio from the media into the card.
Head over to the Setup: Everything Else page to see exactly that.
-
I already have a sentence mining workflow.
If you have a workflow already setup, you may have to do some minor tweaks to your current workflow to match the new field names. For example, the exporting sentence audio and picture fields may be different compared to your previous card.
Other than that, you are completely finished with the setup process!
Note
See Setup: Everything Else (Notes on Various Programs) for specific tips on a select few programs.