diff --git a/autopa/index.html b/autopa/index.html index 7305aae8..6f7306cc 100644 --- a/autopa/index.html +++ b/autopa/index.html @@ -2253,7 +2253,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
There are many runtime options that change exactly what is colored. By default, everything except words found in tooltips (kanji hover and word indicators) are highlighted.
@@ -2292,7 +2292,7 @@New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
A word is automatically colored as 起伏 if the WordTags
field contains a verb tag,
and its pitch accent group is not 平板.
This WordTags
field can only be filled out if you have a modern version of the
@@ -2341,7 +2341,7 @@
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
If the PAOverrideText
field is filled, then this field is displayed exactly as is,
without any changes or parsing.
This provides the most flexibility, but the least ease of usage.
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Multiple numbers can be used, as long as they are separated by commas. This is useful on certain words with devoiced mora, where the pitch accent can be multiple positions with little real distinction.
@@ -2433,7 +2433,7 @@New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
This section requires you to type certain special characters. @@ -2547,7 +2547,7 @@
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO: update pictures with correct config + add new config value for all dictionaries
Sometimes, pitch accent dictionaries show multiple pitch accents for a word. However, only the first pitch accent is shown by default.
diff --git a/cardtypes/index.html b/cardtypes/index.html index b046b1c0..1df6b20d 100644 --- a/cardtypes/index.html +++ b/cardtypes/index.html @@ -2223,7 +2223,7 @@New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO new image)
Audio cards allows you to create cards that tests word or sentence audio.
@@ -2243,7 +2243,7 @@New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
This is simply a regular audio card, but the entire sentence is tested.
Indicator: The displayed text is exactly 「?」
@@ -2357,7 +2357,7 @@New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
A hint vocab card is simply a vocab card that shows the sentence below the word. The tested content is the word itself, so you would test yourself as if it were a @@ -2388,7 +2388,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
This is exactly the same as the Hint Vocab Card, except the word within the sentence is automatically highlighted. @@ -2400,7 +2400,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
A hint sentence card is very similar to a Hint Vocab card, except the tested content is the entire sentence. @@ -2424,7 +2424,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
Sentence-first cards are a group of cards that show the sentence first, and then show the tested word below. @@ -2434,7 +2434,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
Just like a TSC, if you only want to read one specific portion of the sentence, you can highlight that specific portion.
@@ -2444,7 +2444,7 @@New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
@@ -2015,7 +2015,7 @@Helpers:
{jpmn-filled-if-word-is-hiragana}
・{jpmn-filled-if-word-is-not-hiragana}
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
@@ -2024,7 +2024,7 @@Helpers:
{jpmn-filled-if-grammar-point}
・{jpmn-filled-if-not-grammar-point}
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
diff --git a/definitions/index.html b/definitions/index.html index 2d715f0a..a4d543ee 100644 --- a/definitions/index.html +++ b/definitions/index.html @@ -2508,7 +2508,7 @@Helpers:
{jpmn-filled-if-on-mim}
・{jpmn-filled-if-on-mim}
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
As mentioned in the algorithms discussion, the method used by this note can lead to invalid HTML. This is because the resulting HTML is parsed with regex in order to match that first line. In computer science, it is recommended that @@ -2727,7 +2727,7 @@
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The following two options are useful if you want to ignore certain problematic dictionaries, that do not play well with the regex above.
{{~set "opt-first-line-regex-mode" "except"~}}
diff --git a/externallinks/index.html b/externallinks/index.html
index c0894b10..b92b02cf 100644
--- a/externallinks/index.html
+++ b/externallinks/index.html
@@ -1889,7 +1889,7 @@ External Links (TODO)
Naturally, these can be customized to your liking.
Customize external links¶
-New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
Custom external links can be specified under the externalLinks
section
in the compile options.
Creating external links is is explained in the config file,
@@ -1937,7 +1937,7 @@
Icons with multiple text characters
External links in primary definition¶
-
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
External links usually appear in the "Extra Info" section.
If you wish to have the external links to be on the primary definition section,
set externalLinksPosition
to "Primary Definition"
diff --git a/images/index.html b/images/index.html
index 012e7245..17b847ca 100644
--- a/images/index.html
+++ b/images/index.html
@@ -1210,8 +1210,15 @@
-
-
- How to Disable Collapsed Images
+
+ How to Collapse Yomitan Images
+
+
+
+
+ -
+
+ How to Disable Collapsed User Images
@@ -1905,8 +1912,15 @@
-
-
- How to Disable Collapsed Images
+
+ How to Collapse Yomitan Images
+
+
+
+
+ -
+
+ How to Disable Collapsed User Images
@@ -2030,7 +2044,7 @@ Main ImageAutomatically Add Images Using Tags¶
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
One can automatically add a specific image if a card contains
a specific tag.
This is particularily useful for cards made from written media, such as books.
@@ -2051,39 +2065,47 @@
Automatically Add Images Using Tags
TODO example gif
Collapsed Images¶
-Any customly inserted images, including images inserted directly by Yomichan,
+
Any images that are added to a definition by Yomitan are shown by default. If you
+add a custom image to a definiton however, it
will be converted to text which you have to hover over to reveal.
Of course, this image can also be clicked on to zoom.
See the video demo below to see exactly what happens.
-How to Disable Collapsed Images¶
-There are several ways of disabling collapsed images.
+How to Collapse Yomitan Images¶
+If you want images from Yomitan to be collapsed by default, add the following
+to your runtime options:
+```json
+"imgStylizer.glossary.primaryDef.mode.yomichan": "collapse",
+```
+
+How to Disable Collapsed User Images¶
+There are several ways of disabling collapsed user images.
-
Place your images in the PrimaryDefinitionPicture
field, as shown in the section below.
-
Disable it globally in the runtime options:
-// alternatively, try "none" instead of "float".
-"imgStylizer.glossary.primaryDef.mode.yomichan": "float",
+// alternatively, try "none" instead of "float".
+"imgStylizer.glossary.primaryDef.mode.user": "float",
-
-
Disable it per card, by adding the following tag: img-yomichan-float
.
- Alternatively, try adding img-yomichan-no-styling
.
+Disable it per card, by adding the following tag: img-user-float
.
+ Alternatively, try adding img-user-no-styling
.
-
To disable this for only specific images,
edit the HTML
of the desired field, and add data-do-not-convert="true"
.
For example:
-
<img src="your_image.png" data-do-not-convert="true">
+
The PrimaryDefinitionPicture
Field¶
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
This field can be used to place images in the Primary Definition section without collapsing the image.
Large images are automatically resized to fit the area.
This is useful if one wants to put images in place of, or to suppliment definitions.
@@ -2141,10 +2163,10 @@
The PrimaryDefinitionPicture
For example, one can add text, tables, or links to the field.
Changing Automatic Positioning Behavior¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The following runtime option can be used to change how the primary definition picture is positioned:
-// Valid options (case sensitive): "auto", "bottom", "right", "top"
-"imgStylizer.glossary.floatImg.position": "auto",
+// Valid options (case sensitive): "auto", "bottom", "right", "top"
+"imgStylizer.glossary.floatImg.position": "auto",
The options bottom
, right
, and top
force the image to always be placed
below, to the right, and above the definition, respectively.
@@ -2161,7 +2183,7 @@ Force PositioningImage Blur¶
-
New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
Images on cards can be automatically blurred by marking it with a NSFW tag.
To mark a card as NSFW, add any of the following tags to the card:
@@ -2170,12 +2192,12 @@ Image Blurruntime options:
-"imgStylizer.mainImage.blur.enabled": true, // (1)!
+
- The
imgStylizer
module must be enabled to use the image blur feature.
For example:
- "imgStylizer.enabled": true,
+
This is enabled by default, so you likely don't need to manually enable this module.
@@ -2291,7 +2313,7 @@ Additional DetailsJuly 9, 2023
+ February 16, 2024
diff --git a/importing/index.html b/importing/index.html
index 7137a346..087a439c 100644
--- a/importing/index.html
+++ b/importing/index.html
@@ -2427,7 +2427,7 @@ 1. Correctly Formatting Sente
2. Cleanup Other Fields¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Run the following batch command:
diff --git a/index.html b/index.html
index 6af8c1f0..c743d405 100644
--- a/index.html
+++ b/index.html
@@ -1804,7 +1804,7 @@ Home
designed to be visually appealing and simple to use without sacrificing functionality.
Easily paired with most automatic card creation workflows,
this aims to make your experience with Anki as smooth as possible.
-Current version: 0.12.0.0-prerelease-15
+Current version: 0.12.0.0-prerelease-16
diff --git a/infocircle/index.html b/infocircle/index.html
index 866c03cb..178c2443 100644
--- a/infocircle/index.html
+++ b/infocircle/index.html
@@ -1914,7 +1914,7 @@ InterfaceLocking the Info Circle¶
-New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
You can toggle (click on) the info circle to lock the tooltip in place.
This may be useful for copying/pasting errors and other debugging purposes.
diff --git a/kanjihover/index.html b/kanjihover/index.html
index f4f8f5a7..039be317 100644
--- a/kanjihover/index.html
+++ b/kanjihover/index.html
@@ -2048,7 +2048,7 @@ Interface: Open CardRefresh Button¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO
- If editing
WordReading
field or some other card shown as the results,
diff --git a/other/index.html b/other/index.html
index e0444abb..d198168a 100644
--- a/other/index.html
+++ b/other/index.html
@@ -2020,7 +2020,7 @@ Comment
fieldComment
fieldRemove the "(N/A)" on cards with no pitch accents¶
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
If the word has no pitch accent, the pitch accent is usually displayed as (N/A)
.
This indicator can be removed with the following CSS:
.dh-left__word-pitch-text:empty:before {
@@ -2115,7 +2115,7 @@ Changing colorsRemoving the word / sentence at the top of the back side¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
diff --git a/quickstart/index.html b/quickstart/index.html
index c4c177e3..618ab7d7 100644
--- a/quickstart/index.html
+++ b/quickstart/index.html
@@ -2302,7 +2302,7 @@ Selecting DefinitionsSimplify Definitions¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
If you want to remove the list numbers, as well as the first line
of most definitions, set the following runtime option:
"blockquotes.simplifyDefinitions.enabled": true,
@@ -2331,7 +2331,7 @@ Kanji Hover
Word Indicators¶
Main Page: Word Indicators
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words
in your deck are found.
@@ -2432,7 +2432,7 @@ Adjusting Font SizeChanging the display Language¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, the display language is in English.
Currently, Japanese and English are supported as display languages.
To change the display language (say, to Japanese), use the following compile option:
diff --git a/runtimeoptions/index.html b/runtimeoptions/index.html
index e6eb0004..8b3112ed 100644
--- a/runtimeoptions/index.html
+++ b/runtimeoptions/index.html
@@ -2148,7 +2148,7 @@
Override OptionsOption Branch Values¶
-
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
All runtime options are formatted as a key/value pair.
A simple example is the following:
"kanjiHover.enabled": true,
@@ -2177,7 +2177,7 @@ Option Branch Valuessrc/ts/options.ts.
(TODO not dev branch)
isMobile
and isPC
¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The isMobile
and isPC
type allows you to specify different values depending if
you are using Anki on a mobile device, or PC (non-mobile).
"key": {
@@ -2196,7 +2196,7 @@ isMobile
and isPC
isiPhoneiPad
¶
TODO
viewportWidth
¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The viewportWidth
type allows you to specify different values depending
on the screen width.
Note that the viewport width is read for each card flip.
@@ -2215,7 +2215,7 @@
viewportWidth
viewportWidthBreakpoint
¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
"key": {
"type": "viewportWidthBreakpoint",
"args": {
diff --git a/search/search_index.json b/search/search_index.json
index 1f174678..5d24baa9 100644
--- a/search/search_index.json
+++ b/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"Foreword
This project is a fork of the outstanding JP Mining Note project created by Aquafina-Water-Bottle. Aquafina went silent a couple of months ago, and in the meantime, bugs have started to creep into this project as other supporting software has received updates.
The purpose of this fork is to provide bugfixes for JPMN until Aquafina returns to take over maintenance again. I don't have the time or expertise to continue adding features to the note, but hopefully I can keep it functional.
Version 0.12.0.0-prerelease-13
has been released alongside this fork. It resolves a bug that was introduced by a recent AJTJapanese update, which resulted in an Unexpected flattened.childNode
error and prevented pitch accent information from being displayed correctly. Note that some user actions are required after this update. Click here for instructions on updating.
When Aquafina returns and resumes maintenance of the main project, I will close down this fork. The documentation for the original project can be found here.
jp-mining-note (JPMN) is a highly customizable Anki card template for studying Japanese, designed to be visually appealing and simple to use without sacrificing functionality. Easily paired with most automatic card creation workflows, this aims to make your experience with Anki as smooth as possible.
Current version: 0.12.0.0-prerelease-15
GUIFieldsCard CreationFront | DarkBack | DarkFront | LightBack | Light Click here to get started!
"},{"location":"alternatives/","title":"Alternatives","text":"This page is dedicated to gathering various note types and decks that isn't jp-mining-note. These are added in order of when I first come across the note type, so it's roughly ordered from the oldest to newest note types.
I personally try to add as many templates as I can find here, but it's likely I will miss some. Feel free to let me know of any note types you find interesting (including your own note type, or modified versions of this note), and I will very likely add it here! (Brownie points if you make a pull request for it too!)
"},{"location":"alternatives/#note-types","title":"Note Types","text":""},{"location":"alternatives/#anime-cards","title":"Anime Cards","text":" Website\u30fbDownload\u30fbContact
Example images
Image 1Image 2 "},{"location":"alternatives/#lazy-guide-xelieus-modified-anime-card","title":"(Lazy Guide) Xelieu's Modified Anime Card","text":" Website & Download\u30fbContact: Xelieu#8158
(TMW server)
Example images (bilingual examples not shown)
Modern | DarkModern | LightSimple | DarkSimple | Dark (alternative)Simple | Light "},{"location":"alternatives/#stegatxins0s-modified-anime-card","title":"stegatxins0's Modified Anime Card","text":" Website & Download\u30fbContact: Private1
Example image
"},{"location":"alternatives/#tatsumotos-tsc","title":"Tatsumoto's TSC","text":" Website\u30fbDownload\u30fbMirror\u30fbContact
- TSC is short for \"Targeted sentence cards\"
- jp-mining-note is a heavily modified version of this (to the point of it being completely rewritten)
Example image
"},{"location":"alternatives/#ajatt-tools-ankinotetypes","title":"AJATT-Tool's AnkiNoteTypes","text":" Website\u30fbContact
- A collection of user-created notes. Most are based off of the above TSC template.
- The examples below do not showcase every note. Visit the
templates
folder on the website to see all the available notes.
Examples
JP1K TSC (dark)JP1K TSC (light)FallbackWordSentence (cyphar) /templates/Japanese JP1K TSC
/templates/Japanese JP1K TSC
/templates/Japanese fallback
/templates/Japanese words
/templates/Japanese Mined Sentences (cyphar)
"},{"location":"alternatives/#mooniebiloneys-note-types","title":"MoonieBiloney's Note Types","text":" Website\u30fbDownload\u30fbContact
- Some require a Patreon subscription to access
"},{"location":"alternatives/#eminent-note-type","title":"Eminent Note Type","text":" Website & Download\u30fbContact: eminent#8189
(Perdition's server)
Example images
FrontBack "},{"location":"alternatives/#elaxs-note-type","title":"Elax's Note Type","text":" Download\u30fbContact: \u3069\u3093\u5e95#6628
(TMW server)
Example images
Front | DarkBack | DarkFront | LightBack | Light Description from the author This is my anki card format it is based in the Gruvbox color scheme (https://github.com/morhetz/gruvbox) and changes dynamically with your Anki theme, you will need this handlebars in yomichan for it to work: https://pastebin.com/KSjbwrHk (It is a modified version of the one in animecards, the only thing it changes is the color of the pitch pattern so it changes dynamically with the Anki theme) although if you're going to use the dark theme and you already have the animecards handlebars is not neccessary to download it although I still recommend it.
You can change between vocab card, sentence card, vocab audio card, and sentence audio card.
(Original discord message, on TMW server)
"},{"location":"alternatives/#timms-anki-template","title":"Timm's Anki Template","text":" Download\u30fbDownload (alternative theme)\u30fbContact: Timm#3250
(TMW server)
Examples
ImageVideo Description from the author UPDATE1: tango wasn't being colored in the sentence so i fixed it, check yomichan screen shot and add the css UPDATE2: added css
Here is my anki template, which is the result of bits I liked from other templates which I tried to glue together with my limited knowledge of programming.
https://streamable.com/j3etpw
Includes a card mined from the VN Steins;Gate 0 and a card from the LN \u5fd8\u5374\u63a2\u5075
Yomichan: https://i.imgur.com/vuHoVlM.png
Add this to the styling page of the template in anki
- Handlebars: https://pastebin.com/TeSJc6ij
Features:
- Automatic pitch coloring from https://ankiweb.net/shared/info/1557722832 iirc
- Semi-automatic title generation, so you know from which anime/VN etc. a word is from
- drop down page for multiple definitions, that are automatically added
- The same features as look below (you can reverse a word to be a sentence card, audio card etc, with one click)
- has full coverage with the intergration of embedded websites (more on this in the next section)
- NSFW filter to blur pictures from here https://rentry.co/mining
- stroke order for vocab that can be activated if you do so (most of the time the stroke order is clear, but what i implemented it for, is for that \u4e07\u304c\u4e00 case where a word has a weird stroke order, making it easier to remember)
- horrible and clusstered code made by me
Note: This template is has following imperfections:
- Idk how to insert a line break when a word has multiple readings, picture of the problem https://i.imgur.com/YQpRgOj.png
- Websites for more coverage are not displayed correct on mobile, also idk how to fix it
- I think images are not responsively sized on mobile
DM me if you have problems recreating the template (\u7de8\u96c6\u6e08)
CSS update:
Add this to the styling of the template in anki and check the yomichan screenshot above
.jpsentence {\nmargin: 20px 0 0 0;\nfont-size: 35px;\ntext-align:center;\n}\n.pcolor {\ndisplay: inline-block;\n}\n
add this to .img2 and .img:
display:flex;\njustify-content: center;\nalign-items:center;\nmargin: 0 auto;\n
add this exclusively to .img2:
margin-bottom: 25px;\n
Remove on the front template the div with jpsentence for the tango
(Original discord message, on TMW server)
"},{"location":"alternatives/#tigy01s-note-type","title":"Tigy01's Note Type","text":" Website\u30fbDownload\u30fbContact: Tigy01#1231
(Refold (JP) Server)
Example images
FrontBack "},{"location":"alternatives/#stazors-note-type","title":"Stazor's Note Type","text":" Download\u30fbOriginal discord message\u30fbContact: Stazor#6633
(TMW server)
- The download link contains a
readme.txt
that has instructions on how to setup the fields & basic info on the card
Example images
FrontFront (on hover)BackBack (light) "},{"location":"alternatives/#rudnams-note-type","title":"rudnam's Note Type","text":" Website & Download\u30fbContact: rudnam#8661
(Refold (JP) Server)
Example images
Full demoVocabSentence "},{"location":"alternatives/#jidoujishos-note-type","title":"jidoujisho's Note Type","text":"The app jidoujisho comes with its own Anki template, that should be automatically generated on the first card add when using the app.
"},{"location":"alternatives/#jo-mako-audio","title":"Jo-Mako - Audio","text":" Website & Download & Contact
- Audio and picture at the front, everything else at the back
Example images
FrontBackKanji Popup "},{"location":"alternatives/#jo-mako-reading","title":"Jo-Mako - Reading","text":" Website & Download & Contact
- Sentence at the front (with revealable picture and reading). Meaning at the back.
Example images
Example 1Example 2 "},{"location":"alternatives/#mallys-note-type","title":"Mally's Note Type","text":" Website & Download
Example images
FrontBack "},{"location":"alternatives/#nocompos-note-type","title":"Nocompo's Note Type","text":" Website & Download
Example images
FrontBack "},{"location":"alternatives/#klierets-templates","title":"Klieret's Templates","text":" Website & Download
"},{"location":"alternatives/#anacreons-template","title":"Anacreon's Template","text":" Website & Download
Example image
"},{"location":"alternatives/#decks","title":"Decks","text":""},{"location":"alternatives/#kanken-deck","title":"Kanken deck","text":" Website & Download\u30fbContact
- The definitive deck to use for learning how to write kanji
- Not a note type used for mining
- Also see: Xelieu's alternative theme
Example image
"},{"location":"alternatives/#nihongokyoshi-anki-deck","title":"NihongoKyoshi Anki Deck","text":" Download\u30fbOriginal discord message\u30fbContact: medamayaki#0328
(TMW server)
- Monolingual grammar deck
Example images
Front | DarkBack | DarkFront | LightBack | Light "},{"location":"alternatives/#other-decks","title":"Other Decks","text":" - Decks from AJATT
- Decks from TMW
"},{"location":"alternatives/#everything-else-not-made-specifically-to-learn-japanese","title":"Everything Else (Not made specifically to learn Japanese)","text":" - Prettify
- Modern Card Themes
- Anki Cards Templates SuperList
- Raagaception's 12STD CBSE Deck (Science stream, PCM)
- Anki Minimal Language Learning Template
- Awesome Anki
-
He seems to have left TMW Discord server, and his demo video on Youtube was privated. I assume he no longer wants to be contacted. If you have any questions about this setup, you should be able to ask in TMW server instead.\u00a0\u21a9
"},{"location":"autopa/","title":"Pitch Accent","text":"This page is dedicated to showcasing how pitch accent is displayed, and various ways to edit said display.
"},{"location":"autopa/#what-is-pitch-accent","title":"What Is Pitch Accent?","text":"Here is a (slightly modified) excerpt taken from the AJT Japanese Github page that explains the notation well:
Quote
For more information on the Japanese pitch accent, I would like to refer you to this wikipedia article. In short, the following notations can be found:
- Overline: Indicates \"High\" pitch (see \"Binary pitch\" in Wikipedia article).
- Overline downstep: usually means stressing the mora/syllable before.
-
Red circle mark: Nasal pronunciation.
For example, \u3052 would be a nasal \u3051, and would represented as \u3051\u00b0.
-
Blue color: Devoiced mora (barely pronounced at all).
For example, \u30d2 would be closer to h than hi. Likewise, \u30af would be more like a k than ku.
"},{"location":"autopa/#specifying-pitch-accent","title":"Specifying Pitch Accent","text":"The displayed pitch accent is usually the first position found in PAPositions
. However, you can override this automatically chosen position using the PAOverride
field.
The demo above covers the most basic usage of PAOverride
, which should suffice for most people.
The rest of the page covers the details on exactly how PAOverride
works, and all the ways to customize how the pitch accent is displayed.
"},{"location":"autopa/#colored-pitch-accent","title":"Colored Pitch Accent","text":"The reading, word and pitch overline can be automatically colored in Migaku style colors, according to the pitch accent.
This automatic coloring behavior is disabled by default, and must be enabled in the runtime options:
\"autoPitchAccent.coloredPitchAccent.enabled\": true, // (1)!\n
- The
autoPitchAccent
module must be enabled to use colored pitch accent. For example: \"autoPitchAccent.enabled\": true,\n
This is enabled by default, so you likely don't need to manually enable this module.
"},{"location":"autopa/#pitch-accent-groups","title":"Pitch Accent Groups","text":"Anki Tag \u65e5\u672c\u8a9e Example Reading heiban \u5e73\u677f \u81ea\u7136 \u3057\u305c\u3093\uffe3 atamadaka \u982d\u9ad8 \u4eba\u751f \u3058\uff3c\u3093\u305b\u3044 nakadaka \u4e2d\u9ad8 \u5f31\u70b9 \u3058\u3083\u304f\u3066\uff3c\u3093 odaka \u5c3e\u9ad8 \u9053\u5177 \u3069\u3046\u3050\uff3c kifuku \u8d77\u4f0f \u9a5a\u304f \u304a\u3069\u308d\uff3c\u304f"},{"location":"autopa/#controlling-what-gets-colored","title":"Controlling What Gets Colored","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
There are many runtime options that change exactly what is colored. By default, everything except words found in tooltips (kanji hover and word indicators) are highlighted.
\"autoPitchAccent.coloredPitchAccent.color.wordReadingPitchOverline\": true,\n\"autoPitchAccent.coloredPitchAccent.color.wordReadingKanji\": true,\n\"autoPitchAccent.coloredPitchAccent.color.testedContent\": true,\n\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": true,\n\"autoPitchAccent.coloredPitchAccent.color.definitions\": true,\n\"tooltips.overrideOptions.autoPitchAccent\": {\n// highlights bolded kanji\n\"autoPitchAccent.coloredPitchAccent.color.wordReadingKanji\": false,\n// highlights bolded sentence below word\n\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": false, // (1)!\n},\n
- If you want enable word coloring within the sentence, the word within the sentence must be able to be highlighted in the first place. To enable this, use the following runtime option:
\"tooltips.highlightWordInSentence\": true,\n
"},{"location":"autopa/#when-pitch-is-not-automatically-colored","title":"When Pitch Is Not Automatically Colored","text":"Pitch accent coloring requires a numeric position value somewhere within the card. This is usually found in one of these places:
PAPositions
PAOverride
AJTWordPitch
(the numeric position is automatically calculated through the HTML)
Usually, PAPositions
is automatically filled.
In the cases where pitch accent coloring does not work as expected, your two main options are:
- Using
PAOverride
with a number (recommended). - Force the pitch accent group with tags (see below).
"},{"location":"autopa/#kifuku-coloring","title":"Kifuku Coloring","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
) A word is automatically colored as \u8d77\u4f0f if the WordTags
field contains a verb tag, and its pitch accent group is not \u5e73\u677f.
This WordTags
field can only be filled out if you have a modern version of the JMdict dictionary for Yomichan For old cards that do not have this field filled, you will have to manually mark the word with -1
(in PAOverride
).
"},{"location":"autopa/#override-pitch-accent-group","title":"Override Pitch Accent Group","text":"In some extremely rare cases, you must set manually set the pitch accent group, if the available options do not work. To do this, add the appropriate tag to the card.
The exact tags that can be used are shown in the summary table above, under the Anki Tag
and \u65e5\u672c\u8a9e sections. For example, the tag can be heiban
, \u5e73\u677f
, etc.
Note
The tag only overrides the pitch accent color, and does not affect the pitch accent representation itself.
This fact can be useful for certain exceptions, such as how \u901a\u308b is [1] instead of [2]. If you want to use the \u8d77\u4f0f pattern on \u901a\u308b, you will have to set the PAOverride
value to 1
, and then add the \u8d77\u4f0f
tag.
TODO image of above (without tag, with tag)
"},{"location":"autopa/#how-pitch-accent-is-selected","title":"How Pitch Accent is Selected","text":"Pitch accent is selected based on the following priority:
- PAOverrideText
- PAOverride
- PAPositions
- AJTWordPitch
The first field that is non-empty will be the field that is used to display the pitch accent.
Note
When the auto-pitch-accent
module is disabled, the priority changes to the following:
PAOverrideText
PAOverride
AJTWordPitch
Of course, as the module is disabled, PAOverride
will not be parsed in any way. More info on this can be found in the PAOverride field section below.
"},{"location":"autopa/#1-paoverridetext","title":"(1) PAOverrideText","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
If the PAOverrideText
field is filled, then this field is displayed exactly as is, without any changes or parsing. This provides the most flexibility, but the least ease of usage.
PAOverrideText with: \"Hello world!\""},{"location":"autopa/#2-paoverride","title":"(2) PAOverride","text":"The PAOverride
allows for two primary formats: positions and text format. If the field contents cannot be parsed in either of these formats, then the field is displayed without any special formatting. This will act just like PAOverrideText
.
"},{"location":"autopa/#21-paoverride-positions-format","title":"(2.1) PAOverride: Positions Format","text":"When the PAOverride
field contains any number, that number will be considered as the downstep position, and be rendered as such. The number -1
represents the \u8d77\u4f0f pattern, and can be used to set the downstep to be after the second last mora.
Examples (on the \u507d\u8005 card):
PAOverride Result Notes 0
\u30cb\u30bb\u30e2\u30ce 1
\u30cb\ua71c\u30bb\u30e2\u30ce -1
\u30cb\u30bb\u30e2\ua71c\u30ce \u8d77\u4f0f"},{"location":"autopa/#multiple-numbers","title":"Multiple Numbers","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
Multiple numbers can be used, as long as they are separated by commas. This is useful on certain words with devoiced mora, where the pitch accent can be multiple positions with little real distinction.
Additionally, individual numbers can be bolded to grey out the other positions. This is useful to highlight the correct pitch accent among all possiblities.
Examples (on the \u507d\u8005 card):
PAOverride Result Notes 0,2,4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c 0 ,2, 4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c The parser ignores all whitespace. <b>0</b>,2,4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c Restrictions on bolded numbers
Multiple numbers cannot be bolded together. If you want to bold multiple numbers, they have to be bolded individually. Additionally, commas cannot be bolded.
For example, 0,<b>1</b>,<b>2</b>,3
is valid, but 0,<b>1,2</b>,3
and 0,<b>1,</b>2,3
are invalid.
"},{"location":"autopa/#22-paoverride-text-format","title":"(2.2) PAOverride: Text Format","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
How To Type Special Characters (click here) This section requires you to type certain special characters. You can type these characters on any standard IME.
Characters Result \\
\uff3c \u3046\u3048
(ue
) \uffe3 ,
\u3001 /
\u30fb If no number is found within the PAOverride
field, the contents will be parsed using this format.
To define any pitch accent in text format, use \u300c\uff3c\u300d to specify downstep. For example, \u4eba\u751f should be written as \u300c\u3058\uff3c\u3093\u305b\u3044\u300d.
For words with no downstep (\u5e73\u677f\u578b), the \u300c\uffe3\u300d character must be placed at the end of the word. For example, \u8eab\u9577 should be written as \u300c\u3057\u3093\u3061\u3087\u3046\uffe3\u300d.
Removing the required \uffe3 symbol (click here) The restriction that \u5e73\u677f words require the \uffe3 symbol at the end can be removed using the following runtime option:
\"autoPitchAccent.paOverride.heibanMarkerRequired\": false,\n
This would allow any words without any downstep marker to be rendered as \u5e73\u677f. Using the above example, one can instead type \u8eab\u9577 as \u300c\u3057\u3093\u3061\u3087\u3046\u300d.
Examples:
PAOverride Result \u3058\uff3c\u3093\u305b\u3044 \u30b8\ua71c\u30f3\u30bb\u30a4 \u3044\u304d\u304a\uff3c\u3044 \u30a4\u30ad\u30aa\ua71c\u30a4 \u3069\u3046\u3050\uff3c \u30c9\u30a6\u30b0\ua71c \u3057\u3093\u3061\u3087\u3046\uffe3 \u30b7\u30f3\u30c1\u30e7\u30a6"},{"location":"autopa/#multiple-words","title":"Multiple Words","text":"Multiple words can be defined, as long as they are separated with either the \u300c\u30fb\u300d or \u300c\u3001\u300d characters.
This is particularly useful on expressions with multiple words, such as \u300c\u6bd2\u3092\u98df\u3089\u308f\u3070\u76bf\u307e\u3067\u300d.
Examples:
PAOverride Result \u3069\u304f\uff3c\u3001\u304f\u3089\u3046\uffe3\u3001\u3055\u3089\uffe3 \u30c9\u30af\ua71c\u3001\u30af\u30e9\u30a6\u3001\u30b5\u30e9 \u3061\uff3c\u304b\u30fb\u3061\u304b\uff3c \u30c1\ua71c\u30ab\u30fb\u30c1\u30ab\ua71c Note
This renderer will not accept any field with formatting. This means that bold, italics, overlines, etc. cannot be present in the field. For example, the input <b>\u306b\u305b\u3082\u306e</b>
will be rejected.
"},{"location":"autopa/#23-paoverride-raw-text","title":"(2.3) PAOverride: Raw Text","text":"As a last case resort, if the input of this field cannot be parsed as either of the two, the exact contents of PAOverride
will be displayed. This will behave exactly the same as PAOverrideText
.
"},{"location":"autopa/#3-papositions","title":"(3) PAPositions","text":"This field is automatically filled out as long as Yomichan has pitch accent dictionaries, and the tested word is covered in said dictionary.
By default, the first pitch of the first dictionary is shown.
"},{"location":"autopa/#show-all-possibilities-in-dictionary","title":"Show All Possibilities in Dictionary","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
TODO: update pictures with correct config + add new config value for all dictionaries
Sometimes, pitch accent dictionaries show multiple pitch accents for a word. However, only the first pitch accent is shown by default.
One entry (default)All entriesOne entry + boldAll entries + bold If you want to show all of the pitch accent entries (in the first dictionary), use the following runtime option:
\"autoPitchAccent.paPositions.displayMode\": \"selected-dictionary\",\n
If you want to select the correct pitch accent, bold that position in PAPositions
(or simply use PAOverride
as described above)
Note
This option only works on cards formatted with JPMN's {jpmn-pitch-accent-positions}
helper. This means this option will not work on old cards that were imported to the JPMN
format.
"},{"location":"autopa/#4-ajtwordpitch","title":"(4) AJTWordPitch","text":"If you have the optional AJT Japanese add-on installed and correctly configured, then this field is automatically generated on all cards.
This is used as a fallback option, in case your installed pitch accent dictionaries does not cover the tested content, but this add-on does.
"},{"location":"autopa/#how-the-reading-is-selected","title":"How the Reading is Selected","text":"The reading consists of the actual kana that is shown on the card. By default, the word reading is selected based on the following priority:
AJTWordPitch
WordReading
"},{"location":"autopa/#reading-ajtwordpitch","title":"Reading: AJTWordPitch","text":"Usually, the reading is selected from AJTWordPitch
. This has a few features over the raw word reading:
AJTWordPitch
usually includes devoiced and nasal info, whereas WordReading
does not. - Readings are katakana, and cannot be changed to hiragana.
Note
If you do not want the reading in AJTWordPitch
to be used, change the following runtime option to false
:
\"autoPitchAccent.searchForAJTWord\": false,\n
"},{"location":"autopa/#reading-wordreading","title":"Reading: WordReading","text":"If the word cannot be found under AJTWordPitch
, then the default reading in WordReading
is used, and displayed in katakana.
Unlike AJTWordPitch
, this reading can be changed to the word reading kana (usually hiragana), katakana, or katakana with long vowel marks in the runtime options:
// The reading display to show if nothing is generated by AJT Japanese.\n// Valid options:\n// \"word-reading\"\n// \"katakana\"\n// \"katakana-with-long-vowel-marks\"\n\"autoPitchAccent.readingDisplayMode\": \"katakana\",\n
"},{"location":"autopa/#pitch-accent-styling-details","title":"Pitch Accent Styling Details","text":"This covers some details if you are directly using PAOverrideText
, and want to have a similar format to the generated pitch accent. You very likely won't be doing this.
Styling Details (click here) -
The generated style is very similar to the generated style of the AJTWordPitch field. To display the style properly, you can simply copy and edit the HTML tags directly. If you want to see the true generated output, use the AnkiWebView Inspector and inspect the element.
-
If you want to grey out other words, you will have to use the bold <b>
tag. However, you must wrap the greyed out words with the <b>
tag.
This is the opposite of what would expect from everything in this page, but the behavior is this way due to restrictions in the current CSS specification.
-
Note that AJT Japanese also outputs the following span classes, however these are simply ignored by JPMN. You can include them if you want, but they will have no effect on the styling:
<span class=\"low\"></span>
<span class=\"low_rise\"></span>
-
Example with all possible styles:
\u30c1\u30e5<span class=\"high_drop\">\u30fc\u30ab<span class=\"nasal\">\u00b0</span></span><span class=\"devoiced\">\u30af</span>\u30bb\u30a4<b>\u30fb\u30cb<span class=\"high\">\u30bb\u30e2\u30ce</span></b>\n
"},{"location":"backfilling/","title":"Backfilling (TODO)","text":"TODO introduction
"},{"location":"backfilling/#backfill-pitch-accents-and-sentence-furigana","title":"Backfill Pitch Accents & Sentence Furigana","text":"TODO outdated! rerecord!
This requires the AJT Japanese
addon to be correctly setup.
-
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select the desired notes. The following Anki query selects all notes without sentence furigana or without generated pitch accents:
\"note:JP Mining Note\" (AJTWordPitch: OR SentenceReading:)\n
Don't forget to Ctrl+A to select all of the resulting cards! -
Head over to:
Edit
(top left corner) \u2192 AJT: Bulk-generate
.
"},{"location":"backfilling/#backfill-wordaudio","title":"Backfill WordAudio
","text":"To backfill word audio, I recommend using the Local Audio Server for Yomichan add-on, combined with DillonWall's Generate Batch Audio add-on.
To use the Generate Batch Audio add-on, simply select the desired notes in Anki's card browser, and then navigate to:
Edit
\u2192 Generate Bulk Audio
Tip
You can use the following query within Anki's card browser to find all cards without word audio:
\"note:JP Mining Note\" WordAudio:\n
Don't forget to Ctrl+A to select all of the resulting cards! The Generate Batch Audio add-on requires a few changes to its fields in order to work with JPMN:
- All URLs should have
{wordreading}
instead of {reading}
. Audio field
should be WordAudio
. Filter kana
should be WordReading
.
An example is shown below:
"},{"location":"backfilling/#backfill-frequencysort","title":"Backfill FrequencySort
","text":"FrequencySort
behaves exactly the same as Marv's Frequency
field as documented in Marv's JP Resources page page.
That page also contains instructions on how to backfill the field if it is empty.
If you are following the command line instructions, use the following command:
python backfill.py \"Word\" --freq-field \"FrequencySort\" --query \"FrequencySort: \\\"note:JP Mining Note\\\"\"\n
"},{"location":"batch/","title":"Batch Commands (TODO)","text":"Batch commands are actions that affect multiple notes all at once. Usually, these commands affect all JP Mining Note
notes. Please use these commands with caution, and always backup your collection before doing large changes to your Anki collection!
"},{"location":"batch/#running-batch-commands","title":"Running batch commands","text":"Before running any batch command, ensure Anki is open, and Anki-Connect is installed.
There are two ways of running batch commands.
-
If you are using JPMN Manager, you can run it by navigating to the following:
Tools
\u2192 JPMN Manager
\u2192 Run batch command
-
Alternatively, you can run batch commands directly through command line:
WindowsmacOS & Linux :: Ensure you have Anki open, and with Anki-Connect running\n:: Also ensure that you have python 3.9+ installed.\npython tools\\batch.py YOUR_BATCH_COMMAND\n
# Ensure you have Anki open, and with Anki-Connect running\n# Also ensure that you have python 3.9+ installed.\n# You may have to use `python3` instead of `python`.\npython3 tools/batch.py YOUR_BATCH_COMMAND\n
"},{"location":"batch/#available-batch-commands","title":"Available batch commands","text":"Below contains an incomplete list of available batch commands.
Most batch commands are ad-hoc commands written for one-time usage, usually for importing notes or updating notes. If you want the full list, run the following command:
python3 tools/batch.py --help\n
"},{"location":"batch/#fill_field","title":"fill_field","text":"usage: fill_field [-h] [--value VALUE] [--query QUERY] field_name
Sets the given field to 1
.
Some examples:
# set all cards to sentence cards\nfill_field IsSentenceCard\n\n# does the above, but fills the field with `x` instead of `1`:\nfill_field IsSentenceCard --value \"x\"\n
"},{"location":"batch/#empty_field","title":"empty_field","text":"usage: empty_field [-h] [--query QUERY] field_name
Empties the given field.
"},{"location":"batch/#copy_field","title":"copy_field","text":"usage: copy_field [-h] [--query QUERY] src dest
Copies the contents of the source (src) field to the destination (dest) field.
"},{"location":"batch/#verify_fields","title":"verify_fields","text":"usage: verify_fields [-h] [--version VERSION]
Checks that the fields and its order is correct with the current version.
"},{"location":"batch/#reposition_fields","title":"reposition_fields","text":"usage: reposition_fields [-h] [--version VERSION]
Automatically reorders the field list to be the expected order
"},{"location":"blockquotes/","title":"Blockquotes (TODO)","text":"For the purposes of this note type, a blockquote is simply a name given to group together the following sections of text:
- Primary Definition
- Secondary Definition
- Additional Notes
- Extra Definitions
- Extra Info
These are called \"blockquotes\" because they are stylized as a blockquote, and are internally contained inside a blockquote
HTML tag.
Topics such as how dictionaries are selected are not covered here. For those topics, see the Definitions page instead.
"},{"location":"blockquotes/#desktop-interface","title":"Desktop Interface","text":"TODO image
On desktop, only the Primary definition is revealed by default. All other blockquotes are shown by un-collapsing the individual sections.
"},{"location":"blockquotes/#automatically-reveal-collapsed-blockquotes","title":"Automatically reveal collapsed blockquotes","text":"Collapsed sections can be set to be automatically opened under the following runtime option:
\"blockquotes.open.enabled\": true,\n
Example Config (click here) \"blockquotes.open.enabled\": true,\n\"blockquotes.open.secondaryDefinition\": true,\n\"blockquotes.openOnNew.enabled\": true, // (1)!\n\"blockquotes.openOnNew.extraInfo\": true,\n
- This allows a blockquote to be open on new cards only. The
blockquotes.open.enabled
option always opens a blockquote. regardless of whether the card is new or not.
DefaultUsing example config (new card)Using example config (non-new card) "},{"location":"blockquotes/#grey-out-empty-collapsed-blockquotes","title":"Grey out empty collapsed blockquotes","text":"Collapsable fields that are empty are completely hidden by default. These can be greyed out instead, using the following runtime option:
\"blockquotes.hideEmpty\": false,\n
Empty fields greyed outEmpty fields not shown (default) "},{"location":"blockquotes/#grey-out-collapsed-blockquotes-until-hover","title":"Grey out collapsed blockquotes until hover","text":"Even when collapsed blockquotes are hidden, it may take up more eye space than desired. One solution to this is to grey out the collapsed blockquotes until hover, with the following CSS:
/* greys out the summary text until hover */\n.glossary-details > summary {\ncolor: var(--text-color--3);\n}\n.glossary-details:hover > summary {\ncolor: var(--text-color--1);\n}\n/* non-grey when open */\n.glossary-details[open] > summary {\ncolor: var(--text-color);\n}\n
Greyed out until hoverDefault behavior TODO
TODO
Note
This is NOT recommended if you set blockquotes.hideEmpty
to false
, because it makes differentiating between empty blockquotes and non-empty blockquotes much more difficult.
"},{"location":"blockquotes/#mobile-interface","title":"Mobile Interface","text":"On mobile, the collapsible sections are replaced with tabs. Clicking on these tabs reveal the relevant section.
TODO table of icon to section
"},{"location":"blockquotes/#folder-tab-mode","title":"Folder Tab Mode","text":"As folder tabs are inheriently a bit different than collapsible sections, a few different modes exist to control how they behave:
Unique (default)MultipleLinked \"blockquotes.folderTab.mode\": \"unique\",\n
Only one unique tab can show up at once. This is the default behavior.
TODO image
\"blockquotes.folderTab.mode\": \"multiple\",\n
Anywhere from 0 to all tabs can be shown at once. This best mimics the behavior on PC.
TODO image
\"blockquotes.folderTab.mode\": \"linked\",\n
This behaves like the unique
mode, except specified tabs can be \"linked\" together, such that those specific tabs will always show together. These linked tabs can be specified with blockquotes.folderTab.linkedTabs
.
TODO image
"},{"location":"blockquotes/#show-multiple-tabs-at-once","title":"Show multiple tabs at once","text":"By default, multiple tabs cannot be shown at the same time. If you have any blockquotes.open.*
runtime options set, then you may see a warning saying:
TODO\n
In order to see multiple blockquotes at the same time, you will need to set the folder tab mode to either multiple
or linked
.
Warning
None of the blockquotes.openOnNew
options will work on mobile:
- Unfortunately, there is currently no way to determine whether a card is new on mobile or not, as it requires an Anki-Connect call not supported by AnkiConnectAndroid.
- Additionally, the AnkiDroid JS API
ankiGetCardType()
doesn't seem to behave correctly either.
Likewise, there is no way to change the folder tab mode or linked tabs depending on whether the card is new,
"},{"location":"blockquotes/#do-not-hide-tabs-when-empty","title":"Do not hide tabs when empty","text":"On mobile, the tabs will be hidden when empty. This runtime option allows them to be shown (but replaced with a small dot) when empty.
\"blockquotes.folderTab.showDotWhenEmpty\": true,\n
Dot replacing empty tabs (true
)Hidden tabs (false
, default) TODO
TODO
"},{"location":"building/","title":"Building","text":""},{"location":"building/#technical-summary","title":"Technical Summary","text":"The Anki card template is generated through jinja
templates, which is a popular templating engine for Python
. All of these templates are located under the (root)/src
folder.
The Anki templates are generated through a combination of sass
(for CSS), jinja
(for HTML generation), and npm
(Webpack + TypeScript) for JavaScript generation. All of this is managed through the tools/make.py
script.
You must build the note to use any compile options.
Additionally, if you want to use bleeding edge features (the absolute latest features, which maybe riddled with bugs), you must build and install the note from the dev
branch. More info about this is shown later.
Note
The instructions listed below will be primarily Linux based. Notes for other operating systems may be shown, but are not guaranteed.
It is also assumed that you have knowledge of basic command line.
"},{"location":"building/#building","title":"Building","text":""},{"location":"building/#prerequisites","title":"Prerequisites","text":" - Python 3.10.6 or higher
- I recommend pyenv to upgrade your python version if you're running Linux.
- git
- npm
- Anki-Connect
- Anki 2.1.54+ or higher
"},{"location":"building/#initialization-git","title":"Initialization (git)","text":"First, you must clone the repository onto your drive.
# on fresh installs\ngit clone https://github.com/arbyste/jp-mining-note.git\ncd jp-mining-note\n\n# alternatively, if you already have the repository on your system:\ngit pull origin master\n
The master
branch is the stable version of the note.
If you want to build the pre-release version of the note, use the dev
branch. For example, do the following:
git fetch\ngit checkout dev\n
"},{"location":"building/#initialization-venv","title":"Initialization (venv)","text":"The following creates a custom python environment with venv
, so that packages aren't installed into your global python environment.
# assuming you are under the root folder, usu. jp-mining-note\n# You may have to use `python` instead of `python3`, and `pip` instead of `pip3`.\npython3 -m venv .venv\n\n# The following is for POSIX (bash/zsh) only.\n# See how to activate venv on your system in the official documentation:\n# https://docs.python.org/3/library/venv.html\nsource ./.venv/bin/activate\n\npip3 install -r tools/requirements.txt\n
Some additional options with venv
are shown below.
Disabling the venv deactivate\n
Resetting the venv # run this only if you're already in a venv\ndeactivate\n\nrm -r ./venv\npython3 -m venv .venv\nsource ./.venv/bin/activate\npip3 install -r tools/requirements.txt\n
Don't want to use venv? It is highly recommended that you use venv, or something else that isolates the python environment.
However, in case you don't want to use venv
, you can manually install the dependencies (including dependencies for building documentation):
pip3 install \\\npyjson5 jinja2 black pytest \\\nmkdocs mkdocs-video mkdocs-material mkdocs-macros-plugin mkdocs-redirects \\\nmkdocs-git-revision-date-localized-plugin\n
"},{"location":"building/#initialization-npm","title":"Initialization (npm)","text":"The following installs all the required dependencies for generating the note's JavaScript.
# installs a clean state of the dependencies\nnpm ci\n
"},{"location":"building/#building-and-installing","title":"Building and Installing","text":"After setting up venv
and npm
, you are ready to build and install the note.
# Builds the note into the (root)/build folder, and installs.\n# WARNING: completely overrides current note that is installed!\n# Please make a backup of your collection before doing this!\npython3 tools/main.py\n
Note
If you are attempting to (build and) install the bleeding edge version of the note on an Anki profile that does NOT already have the note installed, you have to run the installation script twice. For example:
python3 tools/main.py\npython3 tools/main.py\n
Additional things you can do with the project are shown below.
"},{"location":"building/#running-tests","title":"Running Tests","text":"cd tools\npython3 -m pytest ./tests\n
"},{"location":"building/#building-the-documentation","title":"Building the Documentation","text":"To \"build\" the documentation, all you have to do is the following:
cd docs\n\n# you should now be in (root)/docs, where the mkdocs.yml is.\nmkdocs serve\n
This will allow you to preview the website (usually at http://127.0.0.1:8000/jp-mining-note/
).
If you are looking to edit the documentation, all related files should be found under this docs
folder. The important markdown files are found under:
(root)\n L docs\n L docs\n L index.md # the home page\n L preface.md\n L setup.md\n L ...\n L mkdocs.yml\n
"},{"location":"building/#common-errors","title":"Common Errors","text":"(TODO) Fill this out as people start working with this note
"},{"location":"cardtypes/","title":"Card Types","text":""},{"location":"cardtypes/#preface","title":"Preface","text":"Previously, this note type only had vocab and sentence cards. Although I was originally fine with this, I started to realize some issues with only having these two card types:
- Vocab cards that require context have to be turned into sentence cards, and
- Sentence cards take a very long time to review, and can create context-based memories.
I found that many vocab cards had to be turned into sentence cards, since either the context was fundamental to understanding the definition, or there were other parts of the sentence that I wanted to test. This lead to many sentence cards, which naturally meant that Anki sessions lasted longer.
I attempted to tackle these exact issues by introducing new card types outside of the fundamental vocab and sentence cards.
"},{"location":"cardtypes/#changing-card-type","title":"Changing Card Type","text":"The rest of this page will document all card types that this note can create, and will use certain terminology such as \"filling a field\". If you do not know what this means, see the quickstart page on just that.
"},{"location":"cardtypes/#vocab-card","title":"Vocab Card","text":"A vocab card simply shows the target word at the front. You test yourself on the reading and definition of the word.
How to create: This is the default card type. Nothing has to be done for the card to be a vocab card.
"},{"location":"cardtypes/#sentence-card","title":"Sentence Card","text":"A sentence card simply shows the entire sentence at the front. You test yourself on the reading and meaning of the entire sentence.
How to create: Fill the IsSentenceCard
field.
"},{"location":"cardtypes/#targeted-sentence-card","title":"Targeted Sentence Card (TSC)","text":"A targeted sentence card is a special case of the sentence card. The sentence is shown at the front, but only the highlighted content (only the word by default) is tested. This allows you to have all the information and context of the sentence, but you don't have to waste your time testing other parts of the sentence.
This card type was originally defined here.
How to create: Fill the IsTargetedSentenceCard
field.
"},{"location":"cardtypes/#audio-cards","title":"Audio Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
(TODO new image)
Audio cards allows you to create cards that tests word or sentence audio.
Indicator: The sentence contains [...]
How to test:
- The audio should be automatically played on the front side of the card. With this audio, test yourself on the meaning and reading of the unknown section.
How to create: Fill the IsAudioCard
field. The word(s) that are hidden are exactly the words that are bolded in the Sentence
(or the AltDisplaySentence
) field.
Note
Before version 0.12.0.0
, these were misnamed as \"Cloze Deletion Cards, and the field was misnamed as IsClozeDeletionCard
\".
"},{"location":"cardtypes/#sentence-audio-cards","title":"Sentence Audio Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
(TODO image)
This is simply a regular audio card, but the entire sentence is tested.
Indicator: The displayed text is exactly \u300c\uff1f\u300d
How to test:
- The audio should be automatically played on the front side of the card. With this audio, test yourself on the meaning and reading of the entire sentence.
How to create: Fill the IsAudioCard
and IsSentenceCard
field.
"},{"location":"cardtypes/#reveal-cards","title":"Reveal Cards","text":"Reveal cards (previously known as hybrid cards) are a group of card types that have the distinct feature that the word is shown at the front, while the sentence is hidden but can be shown through some natural means. Additionally, all reveal cards have some form of underline beneath the tested word, to differentiate it between a vocab card.
The primary reason why this exists is to prevent context-based memories. For example, in a TSC or sentence card, you may only remember the tested word due to its surrounding context.
Notes
-
For all forms of reveal cards, you can press n
to toggle whether the sentence is shown or not.
-
The \"How to test\" sections are simply recommended ways of testing, and are by no means the required way of testing yourself. Feel free to test yourself differently depending on whatever you think works the best.
"},{"location":"cardtypes/#hover-vocab-card","title":"Hover Vocab Card","text":"A hover vocab word shows the tested word at the front. When you hover over the word, you can see the full sentence, with the tested word highlighted.
This acts similarly to a vocab card. However, you are given the option to see the full sentence without failing the card.
This is also known as the fallback card.
Indicator: Grey & dotted underline under the word.
How to test:
- Attempt to guess the reading and definition of the word without hovering over the word.
- If you are able to guess both the reading and definition of the word, flip the card.
- Otherwise, hover over the word and guess the reading and definition of the word with the entire sentence.
How to create: Fill the IsHoverCard
field.
"},{"location":"cardtypes/#click-vocab-card","title":"Click Vocab Card","text":"A click vocab word shows the tested word at the front. When you click on the word, you can see the full sentence, with the tested word highlighted.
This card acts as an intermediary between the hover vocab card and the vocab card itself. You must guess the reading BEFORE revealing the sentence, but you can use the sentence to guess the definition.
Indicator: Grey & dashed underline under the word.
How to test:
- Attempt to guess the reading of the word without hovering over the word. If you are unable to guess the reading of the word before revealing the entire sentence, then the card must be marked as a fail.
- After guessing the reading of the word, you can optionally click on the word to reveal the entire sentence to guess the definition.
- In other words, if you can only guess the definition by reading the sentence, then the card should still be passed.
How to create: Fill the IsClickCard
field.
"},{"location":"cardtypes/#hover-sentence-card","title":"Hover Sentence Card","text":"This acts similarly to the hover vocab card. However, the tested content is the entire sentence, so you must hover over the word to test the entire sentence.
Indicator: Colored word & dotted underline under the word.
How to test:
- Attempt to guess the reading and definition of the word without hovering over the word.
- Regardless of whether you are able to guess the reading and definition of the word, hover over the word and test yourself on the sentence (as if it was a sentence card).
How to create: Fill the IsHoverCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#click-sentence-card","title":"Click Sentence Card","text":"This acts similar to the click vocab card. However, similarly to the hover sentence card, the tested content is the entire display, so you must click the word to test the entire display
Indicator: Colored word & dashed underline under the word.
How to test:
- Attempt to guess the reading of the word without hovering over the word. If you are unable to guess the reading of the word before revealing the entire sentence, then the card must be marked as a fail.
- After guessing the reading of the word, click on the word to reveal the entire sentence, and test yourself on the sentence (as if it was a sentence card).
How to create: Fill the IsClickCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#reveal-tsc","title":"Reveal TSC","text":"Similarly to the normal TSC, if you want to use the hover sentence card or click sentence card to only test a specific portion of the sentence, you can bold the desired selection of the sentence and fill IsTargetedSentenceCard
.
The above example is a Hover TSC, with the last sentence bolded.
"},{"location":"cardtypes/#reveal-hint-card","title":"Reveal Hint Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Hover HintClick Hint TODO image
TODO image
Similarly to a normal hint card, filling the IsHintCard
allows the reveal card type to reveal the sentence below the word (instead of replacing the word). You would test this like any normal reveal card, because this is simply a change in the style of how the information is displayed.
"},{"location":"cardtypes/#hint-cards","title":"Hint Cards","text":"Hint cards are a group of card types that display the sentence below the word. This acts as a better alternative compared to manually adding the sentence in the Hint
(or HintNotHidden
) field.
"},{"location":"cardtypes/#hint-vocab-card","title":"Hint Vocab Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
TODO img
A hint vocab card is simply a vocab card that shows the sentence below the word. The tested content is the word itself, so you would test yourself as if it were a TSC or Hover Vocab card.
How to create: Fill the IsHintCard
field.
"},{"location":"cardtypes/#hint-vocab-card-highlighted","title":"Hint Vocab Card (highlighted)","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
TODO img
This is exactly the same as the Hint Vocab Card, except the word within the sentence is automatically highlighted. This is tested the exact same as the Hint Vocab Card.
The reason why a highlighted word is not the default is because I found that I was focusing too heavily on the highlighted word instead of the word itself. To guarantee that you do not see the sentence unless you actually want to, see reveal cards.
How to create: Fill the IsHintCard
and IsTargetedSentenceCard
fields.
"},{"location":"cardtypes/#hint-sentence-card","title":"Hint Sentence Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
TODO img
A hint sentence card is very similar to a Hint Vocab card, except the tested content is the entire sentence. This is indicated by the fact that the word is colored.
This is tested exactly like a Hover Sentence Card.
How to create: Fill the IsHintCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#hint-tscs","title":"Hint TSCs","text":"TODO img
Similarily to the normal TSC, this can be used to only test yourself on a specific portion of the sentence. This is tested exactly like a Hover TSC.
How to create: Fill the IsHintCard
, IsSentenceCard
and IsTargetedSentenceCard
fields.
Note
For all other card types, only IsTargetedSentenceCard
has to be filled to create a TSC. However, for hint cards, both IsSentenceCard
and IsTargetedSentenceCard
must be filled out.
"},{"location":"cardtypes/#sentence-first-cards","title":"Sentence-First Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
(TODO image)
Sentence-first cards are a group of cards that show the sentence first, and then show the tested word below. For these cards, you must read the entire sentence, but you only test yourself on the tested word. This differs from TSCs, because with TSCs, you do not need to read the entire sentence.
How to create: Fill the IsSentenceFirstCard
field.
"},{"location":"cardtypes/#sentence-first-tscs","title":"Sentence-First TSCs","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
(TODO image)
Just like a TSC, if you only want to read one specific portion of the sentence, you can highlight that specific portion.
It is expected that you use the AltDisplaySentence
field to set the custom highlight. There is no reason to use this with the default highlighted word (because you would then test it exactly the same as a normal TSC).
How to create: Fill the IsSentenceFirstCard
and IsTargetedSentenceCard
fields.
"},{"location":"cardtypes/#sentence-first-cards-hiding-the-word","title":"Sentence-First Cards: Hiding the word","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Hide until hoverHide until click TODO image
TODO image
If you do not wish to see the word accidentally before reading the entire sentence, one can use the IsHoverCard
or IsClickCard
to hide the word until you hover over or click on the sentence, respectively.
You would test yourself on these just like any other sentence-first card.
"},{"location":"cardtypes/#card-creation-summary","title":"Card Creation Summary","text":"The top row contains shorthands for the actual field names used:
- Sent:
IsSentenceCard
- TSC:
IsTargetedSentenceCard
- Click:
IsClickCard
- Hover:
IsHoverCard
- Audio:
IsAudioCard
- Hint:
IsHintCard
- Sent-First:
IsSentenceFirstCard
Card Creation Summary (Common Cards)
Sent TSC Click Hover Audio Result (Card Type) Vocab Card \ud83d\uddf8 Sentence Card \ud83d\uddf8 TSC \ud83d\uddf8 Click Vocab \ud83d\uddf8 \ud83d\uddf8 Click Sentence \ud83d\uddf8 \ud83d\uddf8 Click TSC \ud83d\uddf8 Hover Vocab \ud83d\uddf8 \ud83d\uddf8 Hover Sentence \ud83d\uddf8 \ud83d\uddf8 Hover TSC \ud83d\uddf8 Audio Card \ud83d\uddf8 \ud83d\uddf8 Sentence Audio Card Card Creation Summary (Hint Cards)
This table assumes you have IsHintCard
filled.
Hint Sent TSC Click Hover Result (Card Type) \ud83d\uddf8 Hint Vocab Card \ud83d\uddf8 \ud83d\uddf8 Hint Vocab Card (highlighted) \ud83d\uddf8 \ud83d\uddf8 Hint Sentence Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hint TSC \ud83d\uddf8 \ud83d\uddf8 Click Hint Vocab \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Hint Sentence \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Hint TSC \ud83d\uddf8 \ud83d\uddf8 Hover Hint Vocab \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Hint Sentence \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Hint TSC Card Creation Summary (Sentence-First Cards)
This table assumes you have IsSentenceFirst
filled.
Sent-First TSC Click Hover Result (Card Type) \ud83d\uddf8 Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 Sentence-First TSC \ud83d\uddf8 \ud83d\uddf8 Click Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Sentence-First TSC \ud83d\uddf8 \ud83d\uddf8 Hover Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Sentence-First TSC"},{"location":"cardtypes2/","title":"More on Card Types (TODO)","text":""},{"location":"cardtypes2/#hints","title":"Hints","text":"You can include a customized hint to show at the front of any card, by using the Hint
field. This will show as a collapsible field at the front of card.
If you do not want the hint to be hidden by default, you can use the HintNotHidden
field instead.
HintHintNotHidden "},{"location":"cardtypes2/#testing-pitch-accent","title":"Testing Pitch Accent","text":"TODO UPDATE IMAGES!!
No particular card type specifies how you should test pitch accent. This is because customizing how you should test pitch accent is a common feature of all card types.
By default, no special indicator is shown on whether pitch accent is tested or not, so you are free to choose either to test the pitch accent on all cards, or no cards.
To test for pitch accent, fill the PAShowInfo
field. You should see a circle to the left of the word or sentence.
"},{"location":"cardtypes2/#pitch-accent-indicator","title":"Pitch Accent Indicator","text":"This circle you see is called the \"Pitch Accent Indicator\", or \"PA Indicator\" for short. How this card indicates what pitch accent is tested is by the PA indicator's color.
Here are what the colors represent:
- Green: The entire sentence is tested.
- Blue: Only the word is tested.
- Red: Pitch accent should not be tested in any way.
If you ever forget what the colors mean, you can hover your mouse over the circle to get a description of what is being tested.
Alternatively, you can look at the top right of the screen and look at the value after the /
.
Note
If the tested content is a sentence (card), but you want to only test for word pitch accent, you would not be able to see the word normally. To see the word that is tested, there is a button to toggle whether the word is highlighted or not. The content that is highlighted is exactly what is bolded in the Sentence
(or AltDisplay
/ AltDisplayPASentenceCard
) field, which is the added word by default.
Note
If your card is a vocab card, then full sentence is shown as a collapsed field by default. This is only here to check your hearing with your guessed pitch accent, when used in conjunction with the sentence play button.
"},{"location":"cardtypes2/#selecting-the-pitch-accent","title":"Selecting the Pitch Accent","text":"The following shows how to fill in the proper fields to test pitch accent:
Filled fields PA Indicator Separated Cards (None, default) (Doesn't exist) PAShowInfo
Green (sentence) or blue (word), depending on the tested content PAShowInfo
& PADoNotTest
Red (not tested) PAShowInfo
& PATestOnlyWord
Blue (word) PAShowInfo
& PASeparateWordCard
Red (not tested) Word PAShowInfo
& PASeparateSentenceCard
Blue (word) Sentence PAShowInfo
& PASeparateWordCard
& PASeparateSentenceCard
Red (not tested) Word & Sentence To clarify some of the above:
- By default, if only
PAShowInfo
is filled, then the entire display is tested - For vocab cards, targeted sentence cards, and reveal vocab cards, only the word PA is tested (PA indicator: blue).
- For sentence cards and reveal sentence cards, the entire sentence PA is tested (PA indicator: green).
- To test just the word pitch accent, fill the
PATestOnlyWord
field. - To create completely separate cards to just test pitch accent on, use the fields
PASeparateSentenceCard
and/or PASeparateWordCard
. - If a PA word card is created, then the default card does not test pitch accent. Similarly, if a PA sentence card is created, then the default card only tests the word pitch accent.
"},{"location":"changingcardtype/","title":"Changing Card Type (TODO)","text":""},{"location":"changingcardtype/#individually-change-card-type","title":"Individually Change Card Type","text":"TODO copy/paste from quickstart
- can determine which fields are \"binary fields\" or not by the Fields page
"},{"location":"changingcardtype/#default-card-type","title":"Default Card Type","text":"TODO video
If you want to change the card type for all new cards, you can simply fill the field in Yomichan's Anki Card Format.
For example, if you want to set the default card type to be a sentence card:
- Navigate to Yomichan settings, and then to
Anki
\u2192 Configure Anki card format...
. - Set
IsSentenceCard
to 1
.
This will set all new cards to be a sentence card by default.
However, what if you don't want ALL new cards to be sentence cards? With the power of Yomichan handlebars, it is possible to selectively fill fields depending on select properties of the target word.
"},{"location":"changingcardtype/#is-hiragana","title":"Is Hiragana","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Helpers: {jpmn-filled-if-word-is-hiragana}
\u30fb{jpmn-filled-if-word-is-not-hiragana}
If the word is purely comprised of hiragana, you can create different card types by default using these helpers.
For example, let's say you want the default card to be a vocab card, but want hiragana terms to be TSCs. To do exactly that, do the following:
- Navigate to Yomichan settings, and then to
Anki
\u2192 Configure Anki card format...
. - Set
IsTargetedSentenceCard
to {jpmn-filled-if-word-is-hiragana}
.
Example behavior (click here) Example word {jpmn-filled-if-word-is-hiragana}
{jpmn-filled-if-word-is-not-hiragana}
\u3075\u3089\u3063\u3068 1 \u30c8\u30a4\u30ec 1 \u6210\u308a\u7acb\u3064 1 \u3076\u3064\u3076\u3064 1 \u30d6\u30c4\u30d6\u30c4 1 Note
This was inspired by Marv's hint sentence for kana cards.
"},{"location":"changingcardtype/#is-grammar-point","title":"Is Grammar point","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Helpers: {jpmn-filled-if-grammar-point}
\u30fb{jpmn-filled-if-not-grammar-point}
These helpers check if the word exists in a grammar dictionary. Of course, this can only work if you have a grammar dictionary installed in the first place.
The exact list of grammar dictionaries can be customized with the opt-grammar-override-dict-regex
option.
"},{"location":"changingcardtype/#is-onomatopoeia","title":"Is Onomatopoeia","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Helpers: {jpmn-filled-if-on-mim}
\u30fb{jpmn-filled-if-on-mim}
These helpers check if a dictionary entry is an Onomatopoeia word. It does this specifically by checking if the on-mim
tag exists on any dictionary entry. This design is unique to JMdict, so you must have a JMdict dictionary installed in order for this helper to function.
"},{"location":"changingcardtype/#batch-change-card-type","title":"Batch Change Card Type","text":"You may want to change the card type of many existing cards all at once. For example, you may have cards imported into JPMN, or cards that were simply not created by Yomichan in the first place.
Warning
As always, before mass editing your collection, please backup your Anki data.
There are three ways of batch changing the card type:
Batch CommandAnki's Search & ReplaceBatch Editing Addon You can use the fill_field
and empty_field
batch commands. For example, the following batch commands fill and empty the IsSentenceCard
field, respectively:
fill_field IsSentenceCard\nempty_field IsSentenceCard\n
More info about these batch commands can be found here. TODO
You can use a Batch Editing Addon to do the changes.
"},{"location":"changingcardtype/#batch-change-is-hiragana","title":"Batch Change: Is Hiragana","text":"If you used to have Marv's \"Automatic Hint Sentence for Kana Cards\" setup, you might be interested in replicating that for old cards. In order to do so, the fill_field_if_hiragana
batch command is provided to fill the provided field of all cards that have hiragana-only terms.
For example, the following batch command fills the IsHintCard
, which turns all cards with hiragana-only terms into Hint Cards, meaning a hint sentence is shown below the word.
fill_field_if_hiragana IsHintCard\n
If you want to have this be the default for all new cards, see here.
"},{"location":"compiletimeoptions/","title":"Compile Options (TODO)","text":"Just like runtime options, compile options are also options that are applied globally to each JPMN card.
The difference between runtime options and compile options is that compile options require you to build the note on your machine to use. Runtime options can be accessed and changed without having to build the note.
"},{"location":"compiletimeoptions/#accessing-editing","title":"Accessing & Editing","text":"To access the compile options, build the note.
After building the note, a new file config/config.py
should appear. The compile options can be found in this file.
To use these compile options, edit the config.py
file, and then re-build the note.
Warning
Do not edit the config/example_config.py
file. The example config file can be updated at any time, so if you update the example config through git, it may result in unnecessary merge conflicts.
"},{"location":"compiletimeoptions/#always-filled-never-filled-fields","title":"Always filled & Never filled fields","text":"Using compile options, one can set a field to act as if it has always been filled, or it has never been filled, using the always-filled-fields
and never-filled-fields
options. This will remove the conditional Anki templates ({{#FIELD}}
and {{^FIELD}}
markers) for the specified fields.
Example If your compile-options
is:
\"compile-options\": {\n ...\n \"always-filled-fields\": [\"A\"],\n \"never-filled-fields\": [\"B\"],\n ...\n}\n
and your card template is:
{{#A}} A is filled {{/A}}\n{{^A}} A is not filled {{/A}}\n{{#B}} B is filled {{/B}}\n{{^B}} B is not filled {{/B}}\n{{#C}} C is filled {{/C}}\n{{^C}} C is not filled {{/C}}\n
then upon card build, the resulting card template will be:
A is filled\nB is not filled\n{{#C}} C is filled {{/C}}\n{{^C}} C is not filled {{/C}}\n
This usually renders the actual field value useless. In other words, filling the field for a note will have no effect on the cards.
Warning
Do not delete the field from the fields list! See here for more details.
"},{"location":"compiletimeoptions/#optimized-vocab-card-example","title":"Optimized Vocab Card Example","text":"An example set of compile options to create a more optimized vocab card is shown below.
Vocab card compile options example
\"compile-options\": {\n\"keybinds-enabled\": False,\n\"hardcoded-runtime-options\": True,\n\"always-filled-fields\": [],\n\"never-filled-fields\": [\n\"PAShowInfo\", \"PATestOnlyWord\", \"PADoNotTest\",\n\"PASeparateWordCard\", \"PASeparateSentenceCard\", \"AltDisplayPASentenceCard\",\n\"SeparateClozeDeletionCard\",\n\"IsClickCard\", \"IsHoverCard\", \"IsSentenceCard\", \"IsTargetedSentenceCard\",\n],\n\"enabled-modules\": [\n# HIGHLY RECOMMENDED to have this enabled if you want a nice looking card\n# (unless you are not using images in your cards of course)\n\"img-utils-minimal\",\n],\n}\n
"},{"location":"customcss/","title":"Custom CSS (TODO)","text":"TODO introduction
- CSS: styles for the note
- can change font size, colors, hide elements, reposition certain elements, etc.
"},{"location":"customcss/#how-to-add-custom-css","title":"How To Add Custom CSS","text":"There are two options to add custom CSS:
-
Edit the styles directly.
This is the recommended way for most people to modify the CSS.
-
Add SCSS files.
These SCSS files are built with the note to extend the current CSS.
This is recommended way for people who build the note.
Option 1: Edit the styles directly (click here) TODO video
-
Navigate to the following:
(Main window) \u2192 Browse
\u2192 Cards...
(middle of the screen) \u2192 Styling
(top left)
-
Scroll all the way to the bottom, and add any CSS to the bottom of the styles.
Option 2: Add SCSS Files (click here) -
Build the note if you haven't already, and ensure everything works.
-
Create the following folder structure: (project root)/overrides/scss/extra
. The project root is usually jp-mining-note
.
-
Add the folder to the end of css-folders
list in config.py
. For example:
\"css-folders\": [\"base\", \"responsive\", \"dictionaries\", \"extra\"],\n
TODO update the exact folders
-
Under the extra
folder, use the following files to override the correct CSS:
style.scss
: The main CSS for the card templates. This is likely the file you want to edit, when adding custom CSS. field.scss
: The CSS used by CSS injector to customize individual fields. editor.scss
: The CSS used by CSS injector to customize the editor around the fields.
All of the files are optional. This means you do not need to create all three files for the folder to be valid.
The resulting folder should be of the format:
(project root)\n L overrides\n L scss\n L extra\n L field.scss\n L editor.scss\n L style.scss\n
-
Rebuild and reinstall the template. The CSS should be automatically applied to the note.
"},{"location":"definitions/","title":"Definitions (TODO)","text":"This page is dedicated to showcasing how definitions can be easily chosen, overwritten and customized overall.
"},{"location":"definitions/#dictionary-placement","title":"Dictionary Placement","text":"Dictionaries from Yomichan are sorted into the following fields:
Field Description PrimaryDefinition The highest priority monolingual or bilingual dictionary (depending on the value of opt-first-definition-type
). If you want to manually select a different dictionary, see here SecondaryDefinition All bilingual dictionaries outside of the one selected in the primary definition. ExtraDefinition All monolingual dictionaries outside of the one selected in the primary definition. UtilityDictionaries All dictionaries that fall outside the category of bilingual or monolingual. For example, JMnedict or JMdict Forms. The way that the dictionaries are sorted into the appropriate fields is by assigning a category to each individual dictionary.
"},{"location":"definitions/#verifying-categories","title":"Verifying Categories","text":"You can check that your dictionaries are correctly categorized with the {jpmn-test-dict-type}
helper. Under the Anki Templates code, replace Card field
with {jpmn-test-dict-type}
and press Test
.
An example output of the above (on the word \u7d50\u69cb) is the following:
\u300c\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248\u300d: monolingual\n\u300c\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248\u300d: monolingual\n\u300c\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797\u300d: monolingual\n\u300c\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248\u300d: monolingual\n\u300c\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9\u300d: monolingual\n\u300cNHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\u300d: utility\n\u300cJMDict Surface Forms\u300d: utility\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300c\u65b0\u548c\u82f1\u300d: bilingual\n
If a dictionary is miscategorized, you will have to edit bilingual-dict-regex
or utility-dict-regex
at the top of the template code. Monolingual dictionaries are considered to be dictionaries that aren't either of the two above, so no handlebars code has to be changed if one were to use more monolingual dictionaries.
To see how to edit the regex, go to this section.
"},{"location":"definitions/#ignoring-a-dictionary","title":"Ignoring a Dictionary","text":"If you want to see the dictionary on Yomichan but not have it show on Anki, you can use the ignored-dict-regex
option.
To see how to edit the option, see the section below.
Conversely, if you want to not see the dictionary on Yomichan but want it to show up on Anki, see here.
"},{"location":"definitions/#editing-the-dictionary-regex","title":"Editing the dictionary regex","text":"To modify a regex string:
-
Determine the exact tag your dictionary has. To see this, take a word that has a definition in the desired dictionary, and test {jpmn-test-dict-type}
like above. The string inside the quotes \u300c\u300d is exactly the tag of the dictionary.
-
Add the dictionary tag to the string, by replacing ADD_x_DICTIONARIES_HERE
. For example, if your bilingual dictionary tag is Amazing Dictionary
, change ADD_BILINGUAL_DICTIONARIES_HERE
to Amazing Dictionary
.
If you want to add more than one dictionary, they have to be joined with the |
character. For example, if you want to add the bilingual dictionaries Amazing Dictionary
and Amazing-Dictionary-2
, change ADD_BILINGUAL_DICTIONARIES_HERE
to Amazing Dictionary|Amazing-Dictionary-2
.
"},{"location":"definitions/#primary-definition-selection","title":"Primary Definition Selection","text":"The primary definition can either be selected automatically, or manually via highlighting the dictionary name or a section of the definition.
"},{"location":"definitions/#primary-definition-selection-automatic","title":"Primary Definition Selection: Automatic","text":"The dictionary for the primary definition is the first bilingual dictionary (that appears on Yomichan) by default.
This can be changed to the first monolingual dictionary by changing the following Yomichan template option to monolingual
:
{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n
TODO re-record with only automatic
"},{"location":"definitions/#primary-definition-selection-manual","title":"Primary Definition Selection: Manual","text":"TODO re-record with only manual
Sometimes, you may want to override the primary definition, or highlight the definition that makes sense with the context.
This is enabled by default. In case you want to disable this behavior, set opt-selection-text-enabled
to false
.
This manual selection behavior does the following:
-
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.
To disable this, set opt-selection-text-dictionary
to false
.
-
If a section of text is selected, then that dictionary will replace the first definition. Additionally, that section of text will be highlighted (bolded).
To disable this, set opt-selection-text-glossary
to false
.
Additionally, if you do not want to use the entire dictionary, and prefer that only the selected text is shown in the first definition, then set opt-selection-text-glossary-attempt-bold
to false
.
"},{"location":"definitions/#when-manual-selection-fails","title":"When Manual Selection Fails","text":"In an ideal world, we would have access to exactly what dictionary was selected from the handlebars. For example, a handlebars function could tell us if the n'th dictionary was highlighted. Unfortunately, we do not live in this ideal world, so we must get this information manually.
The handlebars algorithm runs thusly:
- If the selected text exactly matches any dictionary in the exported definition, then the dictionary entry is selected as the primary definition.
- Otherwise, we do the same search as the above, except we search through every dictionary's HTML (in Yomichan's order) for the selected text.
- If the selected text was found in some dictionary, then that dictionary is chosen. Otherwise, we fallback to the selected text itself.
Due to us having to find the information ourselves, there are many edge-cases where this algorithm fails.
-
Selecting formatted text
If you select formatted parts of text then automatic bolding will fail. An incomplete list of of formatted sections is shown below:
Line breaks Line breaks cannot be properly captured by the selected text.
IncorrectCorrect
Furigana Just like line breaks, furigana cannot be properly captured by the selected text.
IncorrectCorrect
List Items (common with JMdict) Avoid highlighting multiple items in a list if you want automatic bolding to work.
IncorrectCorrect
-
Same selected text appearing in multiple dictionaries
Manual selection may occasionally select the wrong dictionary, but this only happens if the selected text also appears in a dictionary above the selected text.
For example, suppose you have two bilingual dictionaries. and for the word \u86f8, you highlight the word \"octopus\" and create the card. Both bilingual dictionaries will list \"octopus\", so even if you highlight the word \"octopus\" in the second bilingual dictionary, only the first bilingual dictionary will be chosen.
Example: \u86f8
This is usually not a problem even if the same text appears in a dictionary above, because you'll be seeing the same definition regardless. However, if you still want a specific dictionary, highlight the dictionary tag as shown above.
-
Selected text in HTML markup
There are very rare edge cases when the highlighted text can be found in the internal HTML markup, leading to invalid HTML and (almost certainly) the incorrect definition.
Example: \u57a3\u6839 On the word \u57a3\u6839, if you have the \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 dictionary before JMdict in Yomichan and you highlight border
, then \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 will be incorrectly selected as the primary definition.
This is due to a perfect storm of events:
- Due to Yomichan's implementation details, definitions with images contain a
border
property in an internal style attribute. - \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 indeed has images for the word \u57a3\u6839.
- \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 is ordered before JMdict in Yomichan
With all these three combined, \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 is prioritized over JMdict, leading to an incorrect dictionary selected and invalid HTML.
"},{"location":"definitions/#usage-on-yomichans-search-page-clipboard-page","title":"Usage on Yomichan's Search Page / Clipboard Page","text":"On Yomichan's Search Page or Clipboard Page, the word is usually highlighted within the example sentence when searching for the word. For example, the word \u300c\u4eba\u91cc\u96e2\u308c\u305f\u300d is highlighted in the following image:
This highlighted word interferes with the definition selector used by the handlebars, and may cause unexpected definitions to be selected as the primary definition instead.
In order to fix this, you have a few different options:
- Simply don't use the search page or clipboard page. Instead, you can use a texthooker setup.
- Create a new Yomichan profile that matches the desired page(s), and disable
Selected matching text
within your new profile in the Yomichan settings. If you must use the search page or clipboard page, this is the recommended way to deal with the issue, as it has minimal impact on the rest of your workflow. - Ensure you always manually select something in the definition.
- Simply disable the
opt-selection-text-glossary
handlebars option completely.
Explanation (click here) Under normal circumstances, i.e. within an embedded popup, the selected text in a sentence does not interfere with the handlebars, because the selected text is not within the popup itself. However, within the search page / clipboard page, the sentence and its selected text is found directly within the page itself.
Internally, the handlebars to get the selected text cannot distinguish between whether the text is selected within a definition or somewhere else. As mentioned before, the handlebars has no way of actually knowing which dictionary entry or dictionary is selected, and must use this algorithm to search for the correct entry. With these two combined, the selected text within the sentence is used to search the definition. This may be especially confusing to see for people who remove the first line of monolingual dictionaries, because it is usually the first line of monolingual dictionaries that is matched and bolded.
"},{"location":"definitions/#simplifying-the-definition","title":"Simplifying the Definition","text":"If you use a monolingual dictionary, there is usually a bunch of extra information in the first line. Additionally, there is usually only one dictionary entry, making the list number redundant. Both of these can be automatically hidden with the following runtime option:
\"blockquotes.simplifyDefinitions.enabled\": true,\n
SimpleDefault "},{"location":"definitions/#simpifying-the-definition-per-blockquote","title":"Simpifying the definition per blockquote","text":"By default, if the above option is enabled, all definitions within the Primary Definition, Secondary Definition and Extra Definitions blockquotes are simplified. One can grant finer control to only simplify definitions within these particular blockquotes:
// Remember to enable this so the options can be used!\n\"blockquotes.simplifyDefinitions.enabled\": true,\n// The following controls precisely whether the simplifying definition is enabled\n// or not for each block.\n\"blockquotes.simplifyDefinitions.primaryDefinition.enabled\": true,\n\"blockquotes.simplifyDefinitions.secondaryDefinition.enabled\": true,\n\"blockquotes.simplifyDefinitions.extraDefinitions.enabled\": true,\n
"},{"location":"definitions/#removing-the-first-line-algorithms-discussion","title":"Removing the first line: Algorithms Discussion","text":"There are plenty of ways to remove the first line within the definition. In order to better understand how these handlebars work as well as its pitfalls, pretty much all possible options are listed below.
-
Remove the first line completely, using Handlebars.
Advantanges:
- The biggest advantage this has is the exported definition is as clean and minimalistic it can possibly be.
Disadvantages:
- This can lead to invalid HTML, because Handlebars does not expose a HTML parser. Additionally, removing the first line completely will remove info from the export.
-
Use JavaScript within the note template to remove the first line.
Advantages:
- No special handlebars are particularly required in order for this method to work, i.e. default handlebars can usually do the trick.
- All info is present / not lost.
- Anki's card reviewer is based off a web browser, so the JavaScript has access to a html parser. In other words, html should remain valid.
- This approach should theoretically work on previously exported cards.
Disadvantages:
- The JavaScript algorithm must assume the definition is of a particular HTML structure, i.e. all
<ol>
elements contain a list of definitions. This is problematic if the user edits the field, as they can change it to pretty much whatever they want. - Javascript must be ran, which will slow down card loads.
- This is not immediately portable between note types, because the JS must be copied/pasted for each note type.
- If the user decides that they want to include the first line, it will likely be non-trivial to do so. Editing the raw HTML may be required to simply specify whether the first line should be removed or not.
-
Wrap the first line with some HTML, using Handlebars.
Advantages:
- This does not require JS to be run at all; Only special CSS has to be used. Note that internally, some extra JS is actually run in order to further filter between dictionaries (
blockquotes.simplifyDefinitions.dictsOverride.hideFirstLineMode
). However, this JS is faster than the above option, because the JS only adds CSS classes to particular elements, and does not do any string or HTML parsing. - All info is present / not lost.
- This algorithm is relatively simple to implement.
- Including the first line is slightly more intuitive compared to the 2nd option: Delete the
<li>
node and create a fresh node.
Disadvantages:
- Just like the first option, this can lead to invalid HTML.
- This is technically not immediately portable, because the CSS must be copied/pasted for each note type.
- This solution will not work on older cards exported with different handlebars, i.e. handlebars that do not wrap the first line.
This is currently the chosen method for this note, primarily due to speed, no info loss and simplicity. The second option may be implemented in the future as a fallback, or for special case handling for specific dictionaries.
"},{"location":"definitions/#when-html-can-break","title":"When HTML can break","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
As mentioned in the algorithms discussion, the method used by this note can lead to invalid HTML. This is because the resulting HTML is parsed with regex in order to match that first line. In computer science, it is recommended that you should not parse HTML with regex, because it is mathematically impossible to fully describe and parse HTML with regex. Unfortunately, Yomichan's handlebars does not expose any HTML parser, so we are left with using regex to parse our HTML. Due to this, an unexpected dictionary format may cause the resulting export to be invalid HTML.
If you do not plan on using this feature, you should set opt-wrap-first-line-spans
to false
to remove the possibility of invalid HTML.
"},{"location":"definitions/#hide-the-first-line-for-select-dictionaries","title":"Hide the first line for select dictionaries","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
The following two options are useful if you want to ignore certain problematic dictionaries, that do not play well with the regex above.
{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv)$ {{~/set~}}\n
opt-first-line-dicts-regex
specifies the list of dictionaries that should be ignored or kept. Whether the dictionaries are ignored or kept is defined in opt-first-line-regex-mode
(except
means that the specified dictionaries are ignored, and only
means that only the specified dictionaries can have their first lines removed.)
"},{"location":"definitions/#exporting-only-one-dictionary-entry","title":"Exporting only one dictionary entry","text":"A \"dictionary entry\" in this context is the single section of text corresponding to a number indicated by Yomichan, to the very far left.
In the following example, \u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248 and \u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248 each have one single entry, corresponding to 1
and 2
respectively. JMdict (English)
has two entries, corresponding to 3
and 4
.
As you may have noticed, it is almost never the case that monolingual dictionaries has multiple dictionary entries. Instead, most monolingual dictionaries store the definition as one gigantic entry.
By default, all dictionary entries are exported in the primary definition. However, if opt-primary-def-one-dict-entry-only
is set to true
, then only the first (or manually selected) dictionary entry will be imported into the primary definition.
Export all entries (default)Export one entry "},{"location":"definitions/#legacy-jmdict-support","title":"Legacy JMdict Support","text":"By default, JMdict is exported in a list format, which allows the note's CSS to re-compact the list. This is required over plaintext, because JMdict Extra cannot compact export a compact definition normally. This is a known issue with Yomichan's default handlebars.
If you prefer using a legacy version of JMdict and prefer a full line of plaintext instead of a CSS list, you can set opt-jmdict-list-format
to false
.
"},{"location":"externallinks/","title":"External Links (TODO)","text":"External links are usually found under the Extra Info
section of the note, to the top right corner.
TODO image
Naturally, these can be customized to your liking.
"},{"location":"externallinks/#customize-external-links","title":"Customize external links","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
Custom external links can be specified under the externalLinks
section in the compile options.
Creating external links is is explained in the config file, and there are plenty of commented-out examples that should work.
"},{"location":"externallinks/#removing-all-external-links","title":"Removing all external links","text":"If you want to remove all external links, set externalLinks
to {}
in the compile options.
For example:
\"externalLinks\": {},\n
"},{"location":"externallinks/#icons-with-multiple-text-characters","title":"Icons with multiple text characters","text":"When using text instead of a picture, it is recommended that you use single characters (e.g. one kanji) to represent the icon.
However, in the cases where you want to use more characters, the default CSS rules causes the icon will use the minimum amount of space, which may mis-aligned the surrounding icons.
Fixing this with SCSS (click here) Using the custom SCSS, you can specify the amount of space it takes (in terms of number of icons):
@use \"../base/common\" as common;\n.glossary__external-links a[data-details=\"DICTIONARY_ID\"] { // (1)!\nwidth: common.maxWidthForXIcons(2);\n}\n
- The DICTIONARY_ID are the key values of
external-links
. For example, the id of the jpdb.io
entry below is exactly jpdb.io
. \"jpdb.io\": {\n\"icon-type\": \"image\",\n\"icon-image-light\": \"_icon_jpdb_lightmode.png\",\n\"icon-image-dark\": \"_icon_jpdb_darkmode.png\",\n\"url\": \"https://jpdb.io/search?q={{text:Word}}\"\n}\n
Warning
This SCSS code is NOT CSS. This cannot be added directly to the template's style sheet in Anki. Please see the link above to see how to use custom SCSS.
An example of this can be found in src/scss/dictionaries/style.scss
"},{"location":"externallinks/#external-links-in-primary-definition","title":"External links in primary definition","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
External links usually appear in the \"Extra Info\" section. If you wish to have the external links to be on the primary definition section, set externalLinksPosition
to \"Primary Definition\"
in the compile options.
"},{"location":"faq/","title":"FAQ & Troubleshooting","text":""},{"location":"faq/#errors-warnings","title":"Errors & Warnings","text":"This section documents frequent errors that may show up on the info circle at the top right.
"},{"location":"faq/#error-ankiconnect-failed-to-issue-request","title":"(Error) AnkiConnect failed to issue request.","text":"This is an indication that Anki-Connect is failing. There are two main reasons that Anki-Connect can fail:
-
Ensure that Anki-Connect is installed. If it is installed, be sure to restart Anki to ensure the add-on is actually running.
-
If you are using an older version of Anki (2.1.49 and below), see the note in the Anki-Connect setup section here.
"},{"location":"faq/#warning-jpmnopts-was-not-defined-in-the-options-file-was-there-an-error","title":"(Warning) JPMNOpts was not defined in the options file. Was there an error?","text":"There are two reasons why you would be getting this warning:
-
You updated your note from a version before 0.12.0.0
, to 0.12.0.0
or higher. In this case, you will have to update your config file.
-
You are using Anki version 2.1.49 or below.
Please check your Anki version to confirm this:
Main Window \u2192 Help
\u2192 About...
How to fix (click here) If your Anki version is indeed 2.1.49 or below, then this should only appear on the front side of your first card of the session. To check, try flipping the card and back. This warning should dissappear once you do.
The only side effect of this is that the user-defined runtime options will not be used for the front side of the first card, and the defaults will be used instead.
There are two ways to fix this:
- Update Anki to a higher version. (highly recommended)
- Compile the card with hard-coded defaults.
Why this happens (click here) The <script ... src=\"_jpmn-options.js\">
tag seems to runs asynchronously on 2.1.49 and below, meaning that the order of when this is ran is not constant compared to the main javascript block. With that being said, the exact tag seems to run synchronously on 2.1.50 and above, so it is guaranteed to run before the main javascript block on these versions.
With my current knowledge, the only way to guarantee the order of this import is asynchronous functions, or some other asynchronous features. For example, a simple await import(...)
should work. However, asynchronous features have been avoided throughout the development of this, as it currently seems to behave unpredictably within Anki.
"},{"location":"faq/#warning-cannot-find-own-card","title":"(Warning) Cannot find own card","text":"This warning usually only appears if you renamed the note from JP Mining Note
to something else. If you rename the note, certain features will no longer function as expected, such as:
- Kanji Hover
- Word Indicators
- Most batch commands
- Automatic duplicate
Key
field checks
To remedy this, it is recommended that you change the note name back to JP Mining Note
.
"},{"location":"faq/#my-error-isnt-listed-or-the-steps-above-do-not-work","title":"My error isn't listed, or the steps above do not work","text":"If none of the above worked, follow the general troubleshooting steps.
"},{"location":"faq/#troubleshooting","title":"Troubleshooting","text":""},{"location":"faq/#the-font-on-the-card-template-is-incorrect","title":"The font on the card template is incorrect","text":"TODO bullet pt to sentences
TODO example picture of the wrong font
- if everything is correct, then fonts should actually be japanese (see: \u76f4\u3059)
- easy way to check for correct fonts: look at bolded serif font
- should look good (example picture)
-
if not, wrong fonts are likely being used
-
steps
- ensure fonts are downloaded and in the correct folder (media folder)
- show screenshot of this!
- ensure fonts are valid (could be corrupted)
- show gif of opening in windows
- restart your entire computer
- sometimes, restarting Anki isn't enough
"},{"location":"faq/#the-font-on-the-card-editor-is-incorrect","title":"The font on the card editor is incorrect","text":" - TODO link to setupanki.md
"},{"location":"faq/#the-sentencereading-field-is-not-updated-is-different-from-the-sentence-field","title":"The SentenceReading
field is not updated / is different from the Sentence
field","text":"This happens because programs such as mpvacious and asbplayer update the sentence manually. For example, assume the subtitles are the following:
- \u3060\u3063\u3066\u3001\u9ebb\u8863\u3055\u3093\u306f\u9045\u523b\u3057\u3066\u304d\u305f\u7537\u3092\u3001\u5065\u6c17\u306b\u4e00\u6642\u9593\u4e09\u5341\u516b\u5206\u3082
- \u5f85\u3063\u3066\u3044\u308b\u3088\u3046\u306a\u53ef\u611b\u3052\u306e\u3042\u308b\u5973\u3058\u3083\u306a\u3044\uff01\u3055\u3066\u306f\u507d\u7269\u3060\u306a\uff01
If you make a card from the highlighted \u507d\u7269, the Sentence
and SentenceReading
field will only contain the text from the 2nd subtitle. If you then use mpvacious or asbplayer to grab both subtitles, the Sentence
field will be updated, but the SentenceReading
field will not be updated.
Partial solutions
Sometimes, the problem appears because one subtitle can span multiple lines. These partial solutions work to solve that problem. However, these do not work for when lines span multiple subtitles.
-
For mpvacious, use a texthooker that can remove all whitespace (i.e. Renji's Texthooker).
-
For asbplayer, you can remove the line breaks in the subtitle file itself (i.e. with SubtitleEdit)
The only full solution I know to this is to disabling automatic furigana generation on card add. If you still want furigana on your cards, bulk generate it after each session.
"},{"location":"faq/#the-word-is-incorrectly-highlighted-not-highlighted-at-all","title":"The word is incorrectly highlighted / not highlighted at all.","text":"The word is usually highlighted by default, but the word may not be highlighted for the following reasons:
- The sentence field got updated by an external program.
- The card was imported from an older deck that did not highlight the tested word.
As of version 0.12.0.0
, the card will automatically attempt to highlight the word if the word was not highlighted in the first place. However, this highlight may yield incorrect results. This is expected behavior, and you are expected to manually bold the sentence if the highlight is incorrect.
See here for more info.
"},{"location":"faq/#the-tools-check-media-interface-removes-the-font-files","title":"The Tools
\u2192 Check Media
interface removes the font files.","text":"This is a known bug, and unfortunately, this bug will not be fixed by default. 1
If you accidentally removed the fonts, redownload the fonts and re-add them into the media folder of your profile. Alternatively, updating the note with JPMN manager should automatically re-install the required font files.
It is possible to fix this by using the following workaround:
- Within the media folder, rename all the font files such that they all have
_
at the beginning. For example, NotoSerifJP-Regular.otf
should be renamed to _NotoSerifJP-Regular.otf
. -
Add the following custom CSS to the very bottom (do not modify the existing CSS!):
@font-face {\n font-family: notoserif;\n src: url(\"_NotoSerifJP-Regular.otf\");\n}\n@font-face {\n font-family: notoserif;\n src: url(\"_NotoSerifJP-Bold.otf\");\n font-weight: bold;\n}\n@font-face {\n font-family: notosans;\n src: url(\"_NotoSansJP-Regular.otf\");\n}\n@font-face {\n font-family: notosans;\n src: url(\"_NotoSansJP-Bold.otf\");\n font-weight: bold;\n}\n
"},{"location":"faq/#the-showhide-button-doesnt-do-anything","title":"The Show/Hide button doesn't do anything.","text":"The show/hide button requires that the displayed sentence has a bolded element. For example, this means if the currently displayed sentence comes from the AltDisplay
field and nothing in that field is bolded, then the show/hide button will do nothing.
"},{"location":"faq/#the-replay-audio-button-plays-the-sentence-word-and-then-sentence","title":"The replay audio button plays the sentence, word, and then sentence.","text":"This is playing the audio from the front of the card, and then the back of the card, in sequence. To fix it so you only hear the audio displayed in the back of the card, go to:
Decks
(main anki browser) \u2192 Deck settings (the gear beside your deck) \u2192 Options
\u2192 Audio
section \u2192 Toggle Skip question when replaying answer
"},{"location":"faq/#general-troubleshooting","title":"General Troubleshooting","text":"The following will be some general troubleshooting tips that can help you figure out what is causing the issue:
-
Disable all of your add-ons.
To do this, start Anki while holding Shift. Note that it is expected that you will get an Anki-Connect error (since Anki-Connect will be disabled).
If the issue was fixed after this step, please let me know which add-on(s) conflicts with this note type! To do this, re-enable the add-ons one-by-one (remembering to restart Anki each time!).
-
Upgrade Anki to the latest version.
After doing this, try disabling all of your add-ons again and see if the issue persists.
-
If you manually added any custom CSS and/or runtime / compile options, make a backup of your collection and then remove all of those options. If it works after this, try re-adding those one-by-one until you find the issue.
If you can't manage to fix it, please let me know!
"},{"location":"faq/#card-editing","title":"Card Editing","text":""},{"location":"faq/#how-do-i-disable-furigana-on-card-generation","title":"How do I disable furigana on card generation?","text":" -
In Yomichan's Anki Card Format, ensure that the SentenceReading
field is empty.
-
If you are using the AJT Furigana addon, navigate to:
AJT
\u2192 Japanese Options
\u2192 Furigana
\u2192 Select profile: Add furigana for sentence
\u2192 Triggered by
\u2192 Uncheck Note Added
.
You likely want to bulk-generate the furigana if you are disabling furigana on card generation. See the question below to do just that.
"},{"location":"faq/#how-do-i-bulk-generate-furigana-and-pitch-accents","title":"How do I bulk generate furigana and pitch accents?","text":" -
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select all notes without furigana, with the following search:
\"note:JP Mining Note\" SentenceReading:\n
-
Head over to:
Edit
(top left corner) \u2192 AJT: Bulk-generate
.
Note
Bulk generating pitch accents will only batch generate the AJTWordPitch
field. Pitch accent graphs and positions cannot be automatically generated. This is important to note if you are using colored pitch accent. If PAPositions
is not filled, then the card cannot be automatically colored.
In version 0.12.0.0
, this no longer matters, because the pitch accent info is properly parsed from AJTWordPitch.
Note
There may be some cards that still have an empty AJTWordPitch
field. This is simply because the add-on did not contain the pitch data for those words.
"},{"location":"faq/#how-do-i-remove-an-empty-card-without-deleting-the-entire-note","title":"How do I remove an empty card without deleting the entire note?","text":"Quote
To remove the empty cards, go to Tools
\u2192 Empty Cards
in the main window. You will be shown a list of empty cards and be given the option to delete them.
Taken directly from Anki's official documentation.
"},{"location":"faq/#how-do-i-edit-the-fields-raw-html","title":"How do I edit the field's raw HTML?","text":"Within the card browser, select a field to edit, and then type Ctrl+Shift+X.
Alternatively, on newer versions of Anki, you can click on the top-right corner on the code button.
"},{"location":"faq/#how-do-i-use-this-note-type-as-an-anime-card","title":"How do I use this note type as an Anime Card?","text":"An anime card is a vocab card with a picture and (native) sentence audio, which is the default setup for this card.
If you want to add hints that aren't collapsed by default, use the HintNotHidden
field.
"},{"location":"faq/#other-questions","title":"Other Questions","text":""},{"location":"faq/#where-is-the-x-folder-in-anki","title":"Where is the (X) folder in Anki?","text":"You must first locate the Anki2
folder. The location of this folder is different for each operating system.
Quote
WindowsMacLinux On Windows, the latest Anki versions store your Anki files in your appdata folder. You can access it by opening the file manager, and typing %APPDATA%\\Anki2
in the location field. Older versions of Anki stored your Anki files in a folder called Anki
in your Documents
folder.
On Mac computers, recent Anki versions store all their files in the ~/Library/Application Support/Anki2
folder. The Library folder is hidden by default, but can be revealed in Finder by holding down the option key while clicking on the Go menu. If you're on an older Anki version, your Anki files will be in your Documents/Anki
folder.
On Linux, recent Anki versions store your data in ~/.local/share/Anki2
, or $XDG_DATA_HOME/Anki2
if you have set a custom data path. Older versions of Anki stored your files in ~/Documents/Anki
or ~/Anki
.
Taken directly from Anki's official documentation.
- Your profile folder is under
Anki2/PROFILE_NAME
. - Your media folder is under
Anki2/PROFILE_NAME/collections.media
. - Your addons folder is under
Anki2/addons21
.
"},{"location":"faq/#how-do-i-backup-my-anki-data","title":"How do I backup my Anki data?","text":"The following makes a complete backup of your collection, including media:
Main Window \u2192 File
(top left corner) \u2192 Export...
\u2192 Anki Collection Package
The following makes a temporary backup of your collection, not including media:
Main Window \u2192 File
(top left corner) \u2192 Create Backup
See Anki's official documentation for more info.
"},{"location":"faq/#how-do-i-backup-yomichan-settings","title":"How do I backup Yomichan settings?","text":" - Navigate to Yomichan Settings.
- Go to the
Backup
section - Select
Export Settings
"},{"location":"faq/#how-do-i-export-notes","title":"How do I export notes?","text":" -
Navigate to the Card Browser, by doing the following:
Main Window \u2192 Browse
-
Select a note. Hold down Ctrl to select multiple individual notes.
-
Right click the selected notes, and navigate to:
Notes
\u2192 Export Notes...
"},{"location":"faq/#how-do-i-see-the-version-of-jp-mining-note","title":"How do I see the version of jp-mining-note?","text":"Preview any card. The version should be displayed at the top left corner.
For mobile, the version is shown in the info circle. Note that the version is only displayed on mobile for versions 0.12.0.0
and above.
TODO redo image for mobile
"},{"location":"faq/#how-do-i-see-the-version-of-anki","title":"How do I see the version of Anki?","text":"Navigate to:
Help
\u2192 About
"},{"location":"faq/#what-card-type-should-i-use","title":"What card type should I use?","text":"The short answer is: whichever one you want. :)
The long answer is: whichever one you want, because everyone has their own preferences on what card types they like. I recommend being open about it and experiment with them, to see which one you like.
"},{"location":"faq/#what-is-the-point-of-the-pasilence-field","title":"What is the point of the PASilence
field?","text":"This is a hack to not play the sentence audio on the front side, even if you set-up your Anki client to do so. With this field filled correctly, the play sentence audio button will appear at the front, and will not be autoplayed.
Leaving this field empty will affect cards where you test pitch accent, i.e. with PAShowInfo
filled. In particular, this will cause Anki to autoplay the sentence audio on the front side of cards that test pitch accent, which is undesirable.
"},{"location":"faq/#do-you-plan-on-supporting-any-other-language-other-than-japanese","title":"Do you plan on supporting any other language other than Japanese?","text":"Unfortunately, other languages outside of Japanese will not be supported.
The reason for this decision is best explained in the \"When are you going to add support for $MYLANGUAGE?\" question within Yomichan's README
Quote
Developing Yomichan requires a decent understanding of Japanese sentence structure and grammar, and other languages are likely to have their own unique set of rules for syntax, grammar, inflection, and so on. Supporting additional languages would not only require many additional changes to the codebase, it would also incur significant maintenance overhead and knowledge demands for the developers. Therefore, suggestions and contributions for supporting new languages will be declined, allowing Yomichan's focus to remain Japanese-centric.
"},{"location":"faq/#how-was-this-documentation-made","title":"How was this documentation made?","text":"Through Material for MkDocs. This site generator is what many other popular sites use, including TheMoeWay and AnimeCards.
"},{"location":"faq/#contact-info","title":"Contact Info","text":" -
Discord
- Username:
aquafina_water_bottle
(user id: 244677612272746496
) - Servers:
- TheMoeWay (I recommend using the jp-mining-note thread in the
#resources-sharing
channel) - Refold (JP) server (I recommend using the jp-mining-note thread in the
#sentence-mining-workflows
channel)
-
Github
- If you don't want to use Discord, please shoot your message here.
-
This will not be fixed by default because to make debugging easier for the developer. When a user is asked to export a card, the exported file will not contain the font files, meaning that the result .apkg
file will be about 1MB instead of some 20MB, allowing it to be shared easily on a place like Discord.\u00a0\u21a9
"},{"location":"fieldref/","title":"Fieldref","text":"This page is dedicated showing how to edit the note fields to change the card to your liking.
Note
If you want to edit the user interface for all cards, see the UI Customization page.
"},{"location":"fieldref/#definitions","title":"Definitions","text":"Binary Field: A field that checks whether it is filled or not with any value, say 1
. The default is implied by the name of the field, and a value of \"true\" means that the field is filled. For example, the IsSentenceCard
field will turn the card into a sentence card if filled. If it is not filled, then the card will be a word card. To fill a field automatically, see here.
PA: Short for \"Pitch Accent\".
"},{"location":"fieldref/#quick-jump","title":"Quick Jump","text":"The table below provides quick links to most of the fields found with the card, as well as some general info on each field. Fields without links are assumed to be either obvious (and do not require documentation), or not meant to be edited.
Click here to reveal the field list Note
Auto-filled
represents fields that should be automatically filled out from Yomichan and Anki add-ons.
Field Auto-Filled Binary Field Notes Key Word WordReading PAOverride PAOverrideText AJTWordPitch PrimaryDefinition PrimaryDefinitionPicture Sentence SentenceReading AltDisplayWord AltDisplaySentence Originally AltDisplay
before 0.12.0.0
AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard Originally SeparateClozeDeletionCard
before 0.12.0.0
SeparateSentenceAudioCard Currently doesn't do anything Picture WordAudio SentenceAudio PAGraphs PAPositions FrequenciesStylized FrequencySort PASilence WordReadingHiragana YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment"},{"location":"fieldref/#modifying-the-front-side-tested-content","title":"Modifying the Front Side (Tested Content)","text":"The front side is exactly the content that we want to test ourselves on. Naturally, since we can test ourselves on many aspects of the word, there are many ways to change this tested content.
"},{"location":"fieldref/#card-types","title":"Card types","text":"Main Page: Card Types
The default card type is a vocab card, where the tested content is simply the word.
To change the card to a sentence card, fill the IsSentenceCard
binary field.
Vocab cardSentence card "},{"location":"fieldref/#altdisplay-changing-the-displayed-content","title":"AltDisplay: Changing the Displayed Content","text":"Vocab cards show the Word
field and sentence cards show the Sentence
fields by default. However, you can modify what is exactly shown in the front by using the AltDisplay
field.
NewlineLast sentence only The previous sentence card looks a little ugly, because the sentence splits off at a strange point. To fix this, we add a newline at a sensible place (after the period) in the AltDisplay
field.
Alternatively, we can simply test the last sentence, by removing the first sentence.
"},{"location":"fieldref/#altdisplay-furigana","title":"AltDisplay: Furigana","text":"One nice feature is that the AltDisplay
has hoverable furigana text enabled by default. In other words, you can use furigana in the field. I personally use this to insert furigana for certain names, since I'm usually not testing myself on how to read a name.
For example, the card below has the following HTML:
\u4e0a\u6761[\u304b\u307f\u3058\u3087\u3046] \u606d\u4ecb[\u304d\u3087\u3046\u3059\u3051]\u541b\u306e\u3053\u3068\u304a<b>\u6155\u3044</b>\u3057\u3066\u307e\u3057\u305f\u306e\n
"},{"location":"fieldref/#altdisplay-final-notes","title":"AltDisplay: Final Notes","text":" -
The example with adding a newline to AltDisplay
is somewhat contrived. More realistically, you would want to add the newline to the Sentence
field.
If you are using AJT Furigana, I recommend deleting the text within the SentenceReading
field before editing the Sentence
field, so the furigana can be automatically generated with the newly formatted Sentence
field.
-
If you are using a vocab card, you can use AltDisplay
to show something that differs from the Word
field.
-
On Hybrid Card types, the AltDisplay
field only affects the sentence, and not the front displayed word.
"},{"location":"fieldref/#modifying-the-back-side","title":"Modifying the Back Side","text":"The main two fields that one can add text to is PrimaryDefinition
and AdditionalNotes
. Bolding anything in these sections will highlight the word in a light yellow (or blue in light mode) tint, to make the bolded text stand out more.
"},{"location":"fieldref/#primarydefinition-field","title":"PrimaryDefinition
field","text":"The PrimaryDefinition
field contains the main content, and should be the main field to edit if one wants to put down more notes about the card.
"},{"location":"fieldref/#additionalnotes-field","title":"AdditionalNotes
field","text":"The AdditionalNotes
field is useful if you want to write down even more notes, but keep it in a collapsible field to reduce vertical space.
Here are some suggestions on how you can use this field:
- Recording the source where the scene came from
- Adding custom notes on the scene's context
- Recording the sentences surrounding the mined sentence
In general, this field should be used for any info that is not crucial to understanding the tested content.
"},{"location":"fieldref/#modifying-images-pitch-accent","title":"Modifying Images & Pitch Accent","text":"As there are plenty of ways to modify images and pitch accent, they are discussed in their respective pages:
- Images (
Picture
and PrimaryDefinitionPicture
) - Pitch Accent (
PAOverride
and PAOverrideText
)
"},{"location":"fieldref/#modifying-pitch-accent-sentence-cards","title":"Modifying Pitch Accent Sentence Cards","text":"The field AltDisplayPASentenceCard
exists to customize the display of the PA sentence card, if it exists. It works similarly to AltDisplay
, and takes priority over AltDisplay
in the PA sentence card.
"},{"location":"fieldref/#other-fields","title":"Other Fields","text":""},{"location":"fieldref/#key-field","title":"Key
field","text":"This contains the tested word. In other words, this contains the exact same content as the field below, but this field is specifically not used in the card template. This is to allow the user to modify the key if duplicates arise, while still being able to test the word.
For example, if I were to test different usages of \u4e0a, I can change this key value to \u4e0a (preposition)
, \u4e0a (grammar)
, etc. and add a new card.
It is expected that this Key
field is unique; a warning will appear on cards that have a duplicate key.
"},{"location":"fieldref/#comment-field","title":"Comment
field","text":"Similarly to the Key
field, this field will not be used in any card template. In other words, this is a place where you can write down notes without affecting the card itself.
"},{"location":"fieldref/#frequencysort-field","title":"FrequencySort
field","text":"By default, this note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in this guide. Visit the aformentioned link (and scroll down to Usage
) to see how to sort and review your cards by frequency.
Note
I personally use this field by re-ordering only some of the most common words in my deck, and then separating it with a step of 1. This ensures that every card in the deck will eventually be reached.
"},{"location":"fields/","title":"Fields (TODO)","text":"This page contains a table with some specific information on the fields used by this note type. If you are instead looking for what a particular field does, try using the search bar instead.
"},{"location":"fields/#fields-table","title":"Fields Table","text":"Fields Font Size Collapsed Binary Notes Key 40
Word 20
WordReading 20
PAOverride 20
PAOverrideText 20
New in v0.11.0.0
AJTWordPitch 20
PrimaryDefinition 20
PrimaryDefinitionPicture 20
New in v0.11.0.0
Sentence 20
SentenceReading 20
AltDisplayWord 20
New in v0.12.0.0
AltDisplaySentence 20
Originally AltDisplay
before 0.12.0.0
AltDisplayPASentenceCard 20
New in v0.12.0.0
AltDisplayAudioCard 20
New in v0.12.0.0
AdditionalNotes 20
Hint 15
HintNotHidden 15
IsSentenceCard 10
IsTargetedSentenceCard 10
IsClickCard 10
IsHoverCard 10
IsHintCard 10
New in v0.12.0.0
IsSentenceFirstCard 10
New in v0.12.0.0
IsAudioCard 10
New in v0.12.0.0
PAShowInfo 10
PATestOnlyWord 10
PADoNotTest 10
PASeparateWordCard 10
PASeparateSentenceCard 10
SeparateAudioCard 10
Originally SeparateClozeDeletionCard
before 0.12.0.0
SeparateSentenceAudioCard 10
Currently doesn't do anything Picture 20
WordAudio 15
SentenceAudio 15
PAGraphs 15
PAPositions 15
FrequenciesStylized 15
FrequencySort 10
PASilence 10
WordReadingHiragana 10
New in v0.11.0.0
YomichanWordTags 10
New in v0.12.0.0
SecondaryDefinition 15
ExtraDefinitions 15
UtilityDictionaries 15
CardCache 20
Comment 20
"},{"location":"fields/#definitions","title":"Definitions","text":" -
Binary Field: A field that checks whether it is filled or not with any value, say 1
. The default is implied by the name of the field, and a value of \"true\" means that the field is filled. For example, the IsSentenceCard
field will turn the card into a sentence card if filled. If it is not filled, then the card will be a word card. To fill a field automatically, see here.
-
PA: Short for \"Pitch Accent\".
"},{"location":"frequencies/","title":"Frequencies (TODO)","text":"The frequencies of a card can be found on the back side of the card, at the top right corner.
By default, the shown frequency is the value in FrequencySort
. All other frequencies can be viewed by hovering over the dropdown arrow.
(TODO gif)
"},{"location":"frequencies/#sorting-by-frequency","title":"Sorting by Frequency","text":"This note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in this guide.
To summarize how FrequencySort
is generated: all frequencies (filtering out the useless ones) are averaged using a harmonic mean, which can be thought of as a mean that heavily leans towards the minimum.
However, some exceptions apply:
- If the word exists in a downloaded grammar dictionary, then the frequency value is set to 0, because we make the assumption that grammar points should be studied as soon as possible.
- If there are no frequencies, then it is set to
9999999
.
By default, nothing is done to re-order your cards according to this value. You will need to manually re-order your cards, or use an add-on to automatically do so. Visit the aformentioned link (and scroll down to Usage
) to see exactly that.
"},{"location":"frequencies/#list-mode","title":"List Mode","text":"Older versions of the note displayed the frequencies similarly to Yomichan: as a list of existing frequencies. If you wish to do this, set the following runtime option to list
:
\"freqUtils.displayMode\": \"list\",\n
(TODO GIF with dropdown)
"},{"location":"frequencies/#list-mode-maximum","title":"List Mode Maximum","text":"The list mode defaults to showing a total of 4 frequencies by default, before overflowing into the dropdown. This limit can be changed with the following runtime option:
\"freqUtils.list.max\": 4,\n
(TODO IMAGE with dropdown and >= 5 frequencies)
If you never want to limit the number of frequencies shown, set this to -1
.
(TODO IMAGE without dropdown and >= 5 frequencies)
"},{"location":"frequencies/#unknown-frequency","title":"Unknown Frequency","text":"When no frequency can be found for a particular word, \"unknown\" is instead shown.
TODO image of unknown
Note
If you see \"unknown\" for all your cards, you likely don't have any Yomichan frequency dictionaries installed.
If you have many cards like this, I recommend backfilling existing cards.
"},{"location":"frequencies/#hiding-unknown-frequency-marker","title":"Hiding Unknown Frequency Marker","text":"If you don't want to see this \"unknown\", you can remove it with the following CSS:
.frequencies [data-is-unknown] {\ndisplay: none;\n}\n
"},{"location":"images/","title":"Images","text":"This page is dedicated to showcasing how images can be displayed and interacted with.
"},{"location":"images/#main-image","title":"Main Image","text":"The main image (shown to the right of the word box) is exactly the contents of the Picture
field. As you likely already know, this image can be clicked to zoom in.
(TODO gif)
This display of the picture automatically adjusts for any aspect ratio. For the best looking cards, it is recommended that you use images with aspect ratios between 16:9 (landscape) to 1:1 (square).
(TODO screenshots)
Note
Instead of a picture, it is possible to use text within the Picture
field. This is useful if you forgot to add the picture (or didn't want to add it in the first place), and would like to describe the scene in words.
Do not use more than one picture, or combine pictures and text within the Picture
field. If you have an image and would like to add text, add the text in the PrimaryDefinition
or AdditionalNotes
field. If you want to add more than one image, add the remaining images under PrimaryDefinitionPicture
or PrimaryDefinition
.
"},{"location":"images/#automatically-add-images-using-tags","title":"Automatically Add Images Using Tags","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
One can automatically add a specific image if a card contains a specific tag.
This is particularily useful for cards made from written media, such as books. One can save an image of the cover (in the media folder), and add the appropriate tag to all of the cards to automatically set the image to the cover of the book.
This is specified under the runtime options:
\"imgStylizer.setMainImageFromTags\": [],\n
Example:
\"imgStylizer.setMainImageFromTags\": [\n{\n\"tag\": \"\u9752\u6625\u30d6\u30bf\u91ce\u90ce\u30fbLN1\",\n\"fileName\": \"_\u9752\u6625\u30d6\u30bf\u91ce\u90ce-LN1.png\"\n}\n],\n
TODO example gif
"},{"location":"images/#collapsed-images","title":"Collapsed Images","text":"Any customly inserted images, including images inserted directly by Yomichan, will be converted to text which you have to hover over to reveal. Of course, this image can also be clicked on to zoom. See the video demo below to see exactly what happens.
"},{"location":"images/#how-to-disable-collapsed-images","title":"How to Disable Collapsed Images","text":"There are several ways of disabling collapsed images.
-
Place your images in the PrimaryDefinitionPicture
field, as shown in the section below.
-
Disable it globally in the runtime options:
// alternatively, try \"none\" instead of \"float\".\n\"imgStylizer.glossary.primaryDef.mode.yomichan\": \"float\",\n
-
Disable it per card, by adding the following tag: img-yomichan-float
. Alternatively, try adding img-yomichan-no-styling
.
-
To disable this for only specific images, edit the HTML of the desired field, and add data-do-not-convert=\"true\"
.
For example:
<img src=\"your_image.png\" data-do-not-convert=\"true\">\n
"},{"location":"images/#the-primarydefinitionpicture-field","title":"The PrimaryDefinitionPicture
Field","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
This field can be used to place images in the Primary Definition section without collapsing the image. Large images are automatically resized to fit the area.
This is useful if one wants to put images in place of, or to suppliment definitions. For example, using images for words such as \"frog\" or \"chair\" is much easier to understand compared to using the monolingual definition.
Right of the definition (Default)No DefinitionBelow the definitionAbove the definition (\u7a81\u3063\u4f0f\u3059) Usually, the image is placed to the right (like on Wikipedia).
(\u96d1\u5dfe) Naturally, the picture appears to the left if there is no definition. As of version 0.12.0.0
, the size of the picture will also be slightly increased.
(\u96d1\u5dfe) The image is below the definition if the appropriate options are set.
(\u96d1\u5dfe) The image is above the definition if the appropriate options are set.
Note
Although not recommended, the PrimaryDefinitionPicture
does not need to contain pictures. For example, one can add text, tables, or links to the field.
"},{"location":"images/#changing-automatic-positioning-behavior","title":"Changing Automatic Positioning Behavior","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
The following runtime option can be used to change how the primary definition picture is positioned:
// Valid options (case sensitive): \"auto\", \"bottom\", \"right\", \"top\"\n\"imgStylizer.glossary.floatImg.position\": \"auto\",\n
The options bottom
, right
, and top
force the image to always be placed below, to the right, and above the definition, respectively. auto
is the default behavior, and will automatically position the picture to the left if there is no text. Otherwise, the image is placed to the right.
"},{"location":"images/#force-positioning","title":"Force Positioning","text":"The automatic repositioning as described above may not be perfect. Fortunately, there are ways to force the position of this image, by adding any of the following tags to the card:
img-right
forces the image to be to the right. img-bottom
forces the image to be below the text. img-top
forces the image to be above the text.
"},{"location":"images/#image-blur","title":"Image Blur","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
Images on cards can be automatically blurred by marking it with a NSFW tag. To mark a card as NSFW, add any of the following tags to the card:
nsfw
\u30fbNSFW
\u30fb-NSFW
This behavior is disabled by default. In other words, you will not be able to blur images unless the following setting is explicitly enabled in the runtime options:
\"imgStylizer.mainImage.blur.enabled\": true, // (1)!\n
- The
imgStylizer
module must be enabled to use the image blur feature. For example: \"imgStylizer.enabled\": true,\n
This is enabled by default, so you likely don't need to manually enable this module.
Note
Recall that you can use custom text in the Picture
field instead of having an actual picture. This is useful if you simply don't want to save a particular image.
"},{"location":"images/#change-review-session-state","title":"Change Review Session State","text":"The above demo shows how you can un-blur an image temporarily. This means that if you see that card again during the same review session, the image will be blurred again.
This state can be changed for a review session. To toggle between review-session states, hover over the info circle, and click on the eyeball to the top left. This state will be maintained for the entire review session, but will be lost on the next session.
The tabs below show the available states. By default, states cycle from left to right.
Only Blur if NSFWAlways BlurredAlways Revealed Not Marked Marked (with NSFW
tag) Not Marked Marked (with NSFW
tag) Not Marked Marked (with NSFW
tag) Demos (click here) Regular, unmarked cardCard marked as NSFW Note
Both examples have the info circle toggled (clicked), so the tooltip persists.
"},{"location":"images/#mobile-usage","title":"Mobile Usage","text":" - TODO the eye to the top right of the image is not shown to prevent fat finger unblurs
- if you want to unblur, you must change review session state via the info circle as shown above
"},{"location":"images/#additional-details","title":"Additional Details","text":" - The eyeball to toggle the blur between an image will not be shown unless the card is marked as NSFW (or the review session state is \"Always Blurred\").
- Clicking on the blurred image will do nothing; you must click on the eye to un-blur the image. Forcing the user to click in a smaller area makes accidental unblurs less common.
- After revealing the image, you can click on the image to zoom, as normal. You cannot click on a blurred image to zoom.
- Most things can be changed in the runtime options, including what tags can be used, the default initial state on PC/mobile, etc.
- This was heavily inspired by Marv's implementation of the same feature.
"},{"location":"importing/","title":"Transfer Existing Notes","text":""},{"location":"importing/#overview","title":"Overview","text":"This section is dedicated to explaining how you can change other Anki cards into this note format.
Note
If you are simply importing old JPMN notes, updating JPMN will properly update all the notes in place. See this section instead.
"},{"location":"importing/#introduction","title":"Introduction","text":"Unfortunately, there are so many card formats out there that it would be impossible to cover how to import from every format with detailed rigor. Instead, this section will give you some general tips on operations that will likely be common across most or all formats, as well as present a small example for Anime Cards.
Additionally, although you maybe able to import most of the card, it is unlikely that you will have complete 100% full functionality after importing the notes.
"},{"location":"importing/#prerequisites","title":"Prerequisites","text":"Before doing anything that affects your Anki collection in a major way (for example, basically everything on this page), please make a complete backup of your collection.
Note
Transferring your previous notes shouldn't change your media files at all. However I recommend exporting with media just in case, so long as you have the disk space for it.
"},{"location":"importing/#anki","title":"Anki","text":"Anki provides a feature to switch between note types, without affecting scheduling information. To do this, follow the proceeding steps:
-
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select all the cards that you want to switch.
Tip
Ctrl+A selects all cards in the browser.
-
Right click the selection \u2192 Notes
\u2192 Change Note Type...
"},{"location":"importing/#mapping-fields","title":"Mapping Fields","text":"Here is where I can't give specific advice, as every note is different. However, here are a few tips:
-
Map Word
to Key
and Word
.
Your card likely doesn't have a separate Key
and Word
field, and instead only contains one Word
field. To import this correctly into JPMN, make sure JPMN's Key
and Word
field are exactly your old card's Word
field.
-
The WordReading
field should ideally be a simplified furigana format. For example, if the word is \u6210\u308a\u7acb\u3064, this field should be \u300c\u6210[\u306a]\u308a \u7acb[\u305f]\u3064\u300d. If you do not have any field that resembles this, use the kana reading (\u306a\u308a\u305f\u3064) or true furigana (\u6210\u306a\u308a\u7acb\u305f\u3064), and continue with the steps below.
-
Leave AJTWordPitch
and SentenceReading
empty.
These fields can be empty as AJT Japanese can batch generate both word pitches and sentence furigana.
-
You may have some word pitch fields already in your card. Pitch accent graphs should be mapped to PAGraphs
, and pitch accent positions should be mapped to PAPositions
.
-
FrequencySort
maps to the frequency value used to sort by frequency, which works exactly the same as Marv's Frequency
field as documented in Marv's Resources page.
-
If you have a field that stores the source of the media, I recommend mapping that to AdditionalNotes
or Comment
.
-
I recommend not setting FrequenciesStylized
to anything, even if you have a field for frequency lists1.
-
When in doubt, look at the format in the example notes.
An example with Anime cards is shown below.
Example for Anime Cards (click here) jp-mining-note fields Anime Cards Fields Key front Word front WordReading Reading PAOverride PAOverrideText AJTWordPitch PrimaryDefinition Glossary PrimaryDefinitionPicture Sentence Sentence SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden Hint IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture Picture WordAudio Audio SentenceAudio SentenceAudio PAGraphs Graph PAPositions FrequenciesStylized FrequencySort PASilence WordReadingHiragana YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment Note
Anything not specified should be set to (Nothing)
"},{"location":"importing/#batch-editing","title":"Batch Editing","text":"After switching your notes, you will have to do the following few steps:
"},{"location":"importing/#correctly-formatting-sentence-field","title":"1. Correctly Formatting Sentence
Field","text":"If your sentence fields have been highlighted in a way that isn't using <b>
, then it will be incompatable with JPMN by default.
To see what the formatting of the sentence is, view the raw HTML of the Sentence
field.
Sentences are usually formatted in one of three ways, as shown below:
(1) Highlighted with <b>
(2) Nothing is highlighted(3) Highlighted, but not with <b>
If the tested content is highlighted with <b>
, then it is already formatted correctly. You can skip this step.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<b>\u7206\u7761</b>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
The note comes with a feature to automatically highlight the word within the sentence. However, this is an imperfect solution, and there is currently no easy way to add accurate highlighting to existing sentences.
As there is nothing to do, you can skip this step.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c\u7206\u7761\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
If the tested content is highlighted with something that isn't <b>
, then continue with the following instructions to change it.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<span style=\"color: #ffc2c7\">\u7206\u7761</span>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
Instructions to port formatted sentences (click here) Note
You may want to make another backup before doing the following, just in case.
-
Determine how the sentence is formatted.
We will be using the above for this example. This example highlights the word using a <span>
with a custom color.
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<span style=\"color: #ffc2c7\">\u7206\u7761</span>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
The above is created from the following Yomichan fields:
{cloze-prefix}<span style=\"color: #ffc2c7\">{cloze-body}</span>{cloze-suffix}\n
-
Testing the Conversion.
In the Anki card viewer, select only one of your old notes.
Afterwards, right click the selection, and head over to:
Notes
\u2192 Find and Replace...
-
Setting the fields.
Set the Find
field to something that can find your highlighted content. We will use the above as an example.
It is extremely likely that you will have to change the Find
field according to your note's sentence format.
Field name Value Find: <span style=\"color: #ffc2c7\">(?P<t>.*?)</span>
Replace With: <b>$t</b>
In: Sentence
Selected notes only Checked () Ignore case Unchecked () Treat input as aregular expression Checked () Example image (click here)
-
Verify.
Press Ok, and then preview the card.
If the highlight is yellow (or blue on light mode), then it it was successful! Repeat steps 2 and 3, except select all of the affected notes instead of just one.
If it was not successful, you likely have to adjust the Find
field. See here to see Anki's official documentation on regex.
"},{"location":"importing/#cleanup-other-fields","title":"2. Cleanup Other Fields","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Run the following batch command:
cleanup\n
Expected this batch command to take quite a bit of time, especially on collections containing many thousands of cards. This is because the batch command does quite a bit behind the scenes:
- Corrects
WordReading
if it is ruby text or regular text. - Backfills
WordReadingHiragana
. - Backfills
PASilence
. - Moves extra pictures in the
Picture
field into the PrimaryDefinitionPicture
field. - Note that this requires
beautifulsoup4
installed (pip install beautifulsoup4
). This is installed by default on Anki, so this will be properly ran if the batch command was ran with JPMN Manager.
- Moves extra audio in the
WordAudio
field into the SentenceAudio
field.
"},{"location":"importing/#batch-generate-pitch-accents-and-sentence-furigana","title":"3. Batch Generate Pitch Accents and Sentence Furigana (optional)","text":"This step requires the AJT Japanese
addon to be correctly setup. Although this step is technically optional, pitch accents likely won't show for imported cards if you had nothing to import into PAPositions
. In that case, this step is highly recommended.
See here on how to backfill pitch accents and sentence furigana.
"},{"location":"importing/#backfill-the-frequencysort-field","title":"4. Backfill the FrequencySort
Field (optional)","text":"See here if you want to backfill the FrequencySort
field.
"},{"location":"importing/#conclusion","title":"Conclusion","text":"If everything went smoothly, then you have successfully transferred your notes to the JPMN template. Enjoy reviewing your old cards with a new template!
"},{"location":"importing/#legacy-instructions","title":"Legacy Instructions","text":"Most steps have now been combined all into the one cleanup
batch command. The legacy instructions for dealing with those steps individually are recorded below just in case.
Legacy instructions: Batch Set PASilence
Field This will ensure all PASilence
are filled correctly. See here to understand what this field does. This can be done with a batch command, or manually within Anki itself.
Batch CommandWithin Anki set_pasilence_field\n
- Head to the Card Browser window.
-
Right click a card, and then head to:
Notes
\u2192 Find and Replace...
-
Set the fields to the following:
Field name Value Find: .*
Replace With: [sound:_silence.wav]
In: PASilence
(IMPORTANT! Do not forget this field!) Selected notes only Unchecked () Ignore case Unchecked () Treat input as aregular expression Checked () ??? example \"Example image <small>(click here)</small>\"\n <figure markdown>\n [![The above table in Anki](assets/importing/bulk_add_silencewav.png)](assets/importing/bulk_add_silencewav.png)\n </figure>\n
Legacy instructions: Correctly Formatting WordReading
Field Your WordReading
field is likely formatted in one of three ways:
Furigana (plain)FuriganaKana only This is generated with the {furigana-plain}
helper.
Example: \u6210[\u306a]\u308a \u7acb[\u305f]\u3064
If your WordReading
field is formatted this way, then the WordReading
field is already formatted correctly. You can skip this step.
This is generated with the {furigana}
helper.
Example: \u6210\u306a\u308a\u7acb\u305f\u3064 (HTML: <ruby>\u6210<rt>\u306a</rt></ruby>\u308a<ruby>\u7acb<rt>\u305f</rt></ruby>\u3064
)
If your WordReading
field is formatted this way, it would be ideal to convert this into plain furigana so the note can properly parse the field.
Instructions for converting furigana into plain furigana (click here) - Head to the Card Browser window.
-
Right click a card, and then head to:
Notes
\u2192 Find and Replace...
-
Set the fields to the following:
Field name Value Find: <ruby>(<rb>)?(?P<kanji>.*?)(</rb>)?<rt>(?P<furigana>.*?)</rt></ruby>
Replace With: \u00a0$kanji[$furigana]
(Keep the whitespace at the beginning!) In: WordReading
Selected notes only Unchecked () Ignore case Unchecked () Treat input as aregular expression Checked () This is generated with the {reading}
helper.
Example: \u306a\u308a\u305f\u3064
This means that your old cards only have a kana reading. It would be ideal to have the WordReading
as the kanji word with furigana. You likely want the kanji word with the furigana, so the kanjis actually show in the proper places. Some examples include the kanji hover tooltip as well as to the left of the picture field.
Instructions for converting kana readings into (plain) furigana (click here) The solution provided below is imperfect, but passable. This will format all of the WordReading
fields to be Word[WordReading]
, which means kana will repeated. For example, a card with Word
as \u6210\u308a\u7acb\u3064, and WordReading
as \u306a\u308a\u305f\u3064, will turn into: \u6210\u308a\u7acb\u3064\u306a\u308a\u305f\u3064
To do this, run the following batch command:
quick_fix_convert_kana_only_reading_all_notes\n
The above will affect ALL notes. If you instead want to affect certain notes, add the kanaonlyreading
tag to all affected notes, and then run the following batch command:
quick_fix_convert_kana_only_reading_with_tag\n
Legacy instructions: Batch set WordReadingHiragana
Field The following automatically fills out the WordReadingHiragana
field.
Filling out the WordReadingHiragana
field is optional but highly recommended. This will enable the usage of Word Indicators on existing cards.
To do this, run the following batch command:
fill_word_reading_hiragana_field\n
-
FrequenciesStylized
uses a custom set of handlebars to store the frequency info in a way that css styles can be easily applied without javascript. This differs heavily from the {frequencies}
helper provided by Yomichan. Mapping an existing field that stores frequencies using {frequencies}
to FrequenciesStylized
will result in incorrect display of data.
There is currently no convenience function to convert it to the proper format.
Additionally, auto-generating frequency info (with the correct css, html, etc.) from arbitrary frequency lists does not seem trivial, and I currently provide no way of doing that (primarily because I'm not sure how to do it in the first place). If you know of a way or would like to help me out with doing this, please let me know!\u00a0\u21a9
"},{"location":"infocircle/","title":"Info Circle (TODO)","text":"hello world
"},{"location":"infocircle/#interface","title":"Interface","text":"DefaultDefault (back)ErrorWarningLeech On hover, the info circle on the top left corner just shows some basic info, However, it also serves as a notification system to the user, when it has a color.
(TODO IMAGE) By default, the info circle shows the tags at the back side of the card only. These tags can be clicked on (to search for the tag).
This should only appear when some javascript code fails. In other words, this should not appear under normal circumstances. If you get this without modifying the note in any way, please see this section for basic troubleshooting.
This serves to warn the user about something. It can appear without completely breaking the functionality of the card. In other words, you can choose to ignore it.
When the card is a leech, the circle is highlighted yellow (or blue in light mode) to indicate that it is a leech. This is only shown on the back side of the card.
"},{"location":"infocircle/#locking-the-info-circle","title":"Locking the Info Circle","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
You can toggle (click on) the info circle to lock the tooltip in place. This may be useful for copying/pasting errors and other debugging purposes.
"},{"location":"infocircle/#buttons","title":"Buttons","text":" - Image Blur Toggle Button
- toggles global status of image blur for the session (link)
- Refresh Button
- refreshes kanji hover and word indicators (link)
"},{"location":"jpmnhandlebars/","title":"JPMN Handlebars Package","text":"This section documents how to use the jp-mining-note handlebars for Yomichan on any template that is not jp-mining-note. If you are using jp-mining-note, please see the Definitions page instead.
"},{"location":"jpmnhandlebars/#features","title":"Features","text":"This handlebars package provides all of the features that comes with the standard jp-mining-note installation:
- A primary dictionary selector that automatically chooses the first bilingual or monolingual dictionary (depending on your settings)
- Ability to manually select a dictionary or highlight a definition, to override the primary dictionary selector
- Automatic separation of auxiliary dictionaries into monolingual and bilingual dictionaries
- Option to hide the first line of monolingual dictionaries
- Compatibility with other portable handlebars
The main difference between these handlebars and the handlebars used by jp-mining-note is that some default settings have been manually changed, so that definitions are exported in a minimalistic HTML format. This minimal format (almost) completely conforms with the default Yomichan handlebars, so it should work for any note type.
"},{"location":"jpmnhandlebars/#setup-handlebars","title":"Setup Handlebars","text":"Before doing anything, please make a backup of your Yomichan settings.
Video demo (click here) - Navigate to Yomichan 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 Yomichan template code:
Click here to show the template code to copy. {{~! ~}}\n{{~! ==================== jp-mining-note handlebars ===================== ~}}\n{{~! v1.0.12 ~}}\n{{~! ~}}\n{{~! https://arbyste.github.io/jp-mining-note/ ~}}\n{{~! ------------------------------------------------------- ~}}\n{{~! ================ Dictionary Categorization Options ================= ~}}\n{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n{{~!\nA bunch of JP and CN bilingual dictionaries covered by default,\nincluding: JMdict, \u65b0\u548c\u82f1, CEDICT, etc\n~}}\n{{~#set \"bilingual-dict-regex\"~}} ^(([Jj][Mm][Dd]ict)(.*)|(.*)\u65b0\u548c\u82f1(.*)|\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|KireiCake|NEW\u658e\u85e4\u548c\u82f1\u5927\u8f9e\u5178|CEDICT|CC-CEDICT|CantoDict|Canto CEDICT|Words\\.hk C-E FS|CE Wiktionary|CC-Canto|Jitendex(.*)|ADD_BILINGUAL_DICTIONARIES_HERE)$ {{~/set~}}\n{{~#set \"utility-dict-regex\"~}} ^(NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178|\u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003|[Jj][Mm][Dd]ict( Surface)? Forms|JMedict)$ {{~/set~}}\n{{~#set \"ignored-dict-regex\"~}} ^(ADD_IGNORED_DICTIONARIES_HERE)$ {{~/set~}}\n{{~! ====================== Selected Text Options ======================= ~}}\n{{set \"opt-selection-text-enabled\" true}}\n{{set \"opt-selection-text-dictionary\" true}}\n{{set \"opt-selection-text-glossary\" true}}\n{{set \"opt-selection-text-glossary-attempt-bold\" true}}\n{{~! ==================== Frequency Sorting Options ===================== ~}}\n{{~! See here for the official documentation on how these options work:\nhttps://github.com/MarvNC/JP-Resources#freq-settings ~}}\n{{~#set \"opt-ignored-freq-dict-regex\"~}} ^(JLPT.*)|(HSK.*)$ {{~/set~}}\n{{~#set \"opt-ignored-freq-value-regex\"~}} \u274c {{~/set~}}\n{{~#set \"opt-keep-freqs-past-first-regex\"~}} ^()$ {{~/set~}}\n{{~set \"opt-no-freq-default-value\" 9999999 ~}}\n{{~set \"opt-freq-sorting-method\" \"harmonic\" ~}} {{~! \"min\", \"first\", \"avg\", \"harmonic\" ~}}\n{{~set \"opt-grammar-override\" true ~}}\n{{~set \"opt-grammar-override-value\" 0 ~}}\n{{~#set \"opt-grammar-override-dict-regex\"~}} ^(\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b|JLPT\u6587\u6cd5\u89e3\u8aac\u307e\u3068\u3081|\u3069\u3093\u306a\u3068\u304d\u3069\u3046\u4f7f\u3046 \u65e5\u672c\u8a9e\u8868\u73fe\u6587\u578b\u8f9e\u5178|\u7d75\u3067\u308f\u304b\u308b\u65e5\u672c\u8a9e)$ {{~/set~}}\n{{~! ============== Dictionary First Line Removal Options =============== ~}}\n{{~set \"opt-wrap-first-line-spans\" true ~}}\n{{~! valid values: \"except\", \"only\" ~}}\n{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~!\nJMdict and jitenbot dictionaries from stephenmk are ignored\n(the latter because the handlebars cannot properly detect the first line.)\nIn particular, removing the first line from jitenbot dictionaries with handlebars alone\nis not trivial, so that feature will not be supported.\n~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv|\u6545\u4e8b\u30fb\u3053\u3068\u308f\u3056\u30fb\u6163\u7528\u53e5\u30aa\u30f3\u30e9\u30a4\u30f3|\u56db\u5b57\u719f\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u56fd\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u5927\u8f9e\u6797\u3000\u7b2c\u56db\u7248|\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u516b\u7248)$ {{~/set~}}\n{{~! ========================== Other Options =========================== ~}}\n{{~set \"opt-primary-def-one-dict-entry-only\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt-jmdict-list-format\" false ~}} {{~! jpmn default: true ~}}\n{{~! ======================== Plaintext Options ========================= ~}}\n{{~!\nWARNING: I recommend not changing these options if you are using the\njp-mining-note template. These options will change the general layout\nof the HTML, which will prevent certain features or stylizations\nfrom properly working. (If you aren't using jp-mining-note, please feel\nfree to change these options!)\nInstead of using these options, see here:\nhttps://aquafina-water-bottle.github.io/jp-mining-note/definitions/\nThese hide specific elements using CSS instead of modifying the raw HTML\nstructure behind it.\n~}}\n{{~set \"opt__plaintext__enabled\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__one-dict-entry-only-no-list\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__remove-dictionary-tag\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__remove-first-line-enabled\" true ~}} {{~! jpmn default: false ~}}\n{{~! ============== ORIGINAL YOMITAN TEMPLATE CODE BELOW ============== ~}}\n
-
Copy and paste the code below to the bottom of the default Yomichan template code:
Click here to show the template code to copy. {{~! ============== ORIGINAL YOMITAN TEMPLATE CODE ABOVE =============== ~}}\n{{~! v1.0.12 ~}}\n{{~!\n==================\nhelper functions\n==================\n~}}\n{{#*inline \"s\"}}{{/inline}}\n{{~! categorizes into 4 types: \"ignored\", \"bilingual\", \"utility\", or \"monolingual\" ~}}\n{{~#*inline \"jpmn-get-dict-type\"~}}\n{{~#scope~}}\n{{~#set \"rx-match-ignored\" ~}}\n{{~#regexMatch (get \"ignored-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-utility\" ~}}\n{{~#regexMatch (get \"utility-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-bilingual\" ~}}\n{{~#regexMatch (get \"bilingual-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if (op \"!==\" (get \"rx-match-ignored\") \"\")~}}\n ignored\n {{~else if (op \"!==\" (get \"rx-match-utility\") \"\")~}}\n utility\n {{~else if (op \"!==\" (get \"rx-match-bilingual\") \"\")~}}\n bilingual\n {{~else~}}\n {{~! assumed that anything else is a monolingual dictionary ~}}\n monolingual\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! returns \"\" if selection text is disabled, or if none existed in the first place ~}}\n{{~#*inline \"_jpmn-selection-text\"~}}\n {{~! text-mode != \"\" and text-mode > 0 ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-enabled\") true)~}}\n {{~! removes leading and trailing whitespace ~}}\n {{~#regexReplace \"^\\s+|\\s+$\" \"\" \"g\"~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n {{~/regexReplace~}}\n {{~/if~}}\n{{~/inline~}}\n{{~! checks that the selection text is indeed a dictionary (returns the text if true, nothing if false) ~}}\n{{~#*inline \"_jpmn-check-dictionary\"~}}\n {{~#scope~}}\n {{~#set \"selection-is-dictionary\" false}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" (get \"selection\") dictionary)~}}\n {{~#set \"selection-is-dictionary\" true ~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"===\" (get \"selection-is-dictionary\") true)~}}\n {{~get \"selection\"~}}\n {{~else~}}\n {{~! null ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n Gives the raw glossary as the search string\n (for searching to see if the selected text is a part of a dictionary)\n Remember: we should NOT use _jpmn-glossary-single because it preprocesses the text!\n If the selected text was on the first line and the first line is removed,\n then using _jpmn-glossary-single will fail to find the selected text!\n~}}\n{{#*inline \"_jpmn-glossary-single-search\"}}\n {{~#scope~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/scope~}}\n{{/inline}}\n{{~! escape a regex string: https://stackoverflow.com/a/6969486~}}\n{{~! /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' ~}}\n{{~! escapes the `regexString` regex to allow it to be used like a normal search in a string ~}}\n{{#*inline \"_jpmn-escape-regex\"}}\n {{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~regexString~}}{{~/regexReplace~}}\n{{/inline}}\n{{~#*inline \"_jpmn-get-dict-if-glossary-selected\"~}}\n {{~#scope~}}\n {{~#set \"result-dictionary\" null}}{{/set~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"search-def\"}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{/set~}}\n {{~#set \"search-regex-match\"}}\n {{~#regexMatch (get \"search-selection\") \"gu\"}}{{~get \"search-def\"~}}{{/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"result-dictionary\") null)\n (op \"!==\" (get \"search-regex-match\") \"\")\n )~}}\n {{~#set \"result-dictionary\" dictionary}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"result-dictionary\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n searches dictionary, determined by `opt-first-definition-type`\n - (opt-first-definition-type === bilingual) -> bilingual dictionaries are searched first\n - (opt-first-definition-type === monolingual) -> monolingual dictionaries are searched first\n~}}\n{{~#*inline \"_jpmn-search-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~#if (op \"===\" (get \"opt-first-definition-type\") \"bilingual\")~}}\n {{~#set \"first-definition-search-type-1\" \"bilingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"monolingual\"}}{{/set~}}\n {{~else~}}\n {{~#set \"first-definition-search-type-1\" \"monolingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"bilingual\"}}{{/set~}}\n {{~/if~}}\n {{~! first-dictionary === null <=> no valid dictionary was found ~}}\n {{~#set \"first-dictionary\" null}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-1\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! uses other dictionary type, last resort ~}}\n {{~#if (op \"===\" (get \"first-dictionary\") null)~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-2\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~/if~}}\n {{~#get \"first-dictionary\"~}}{{~/get~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n return null\n~}}\n{{~#*inline \"_jpmn-check-dictionary-and-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if\n (op \"&&\" (op \"===\" (get \"result\") \"\")\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return null\n if (able to detect dictionary of which the selection-text is highlighting):\n return \"uses-glossary\"\n return null\n~}}\n{{~#*inline \"_jpmn-selection-uses-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text is a dictionary -> null ~}}\n {{~else if\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text dict found -> \"uses-glossary\" ~}}\n uses-glossary\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n if (selection-text-glossary is not enabled):\n return first-dictionary (determined by `opt-first-definition-type`)\n return null\n else:\n return first-dictionary (determined by `opt-first-definition-type`)\n~}}\n{{~#*inline \"_jpmn-get-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~! first checks selection text ~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"selection\") \"\")~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary-and-glossary . ~}}{{/set~}}\n {{~! doesn't return a dictionary if opt-selection-text-glossary is false b/c ~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"result\") \"\")\n (op \"===\" (get \"opt-selection-text-glossary\") false)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-search-primary-definition-dict . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~! no selection text ~}}\n {{~else~}}\n {{~> _jpmn-search-primary-definition-dict . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n get number of primary dictionary entries\n~}}\n{{~#*inline \"_jpmn-primary-dict-entry-count\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~set \"dict-entry-count\" 0 ~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\")) ~}}\n {{~! dict-entry-count += 1 ~}}\n {{~set \"dict-entry-count\" (op \"+\"\n (get \"dict-entry-count\") 1\n )\n ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"dict-entry-count\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-is-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n dictionaryName: dictionary id\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~set \"valid-dict\" null ~}}\n {{~#set \"test-dict-type\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionaryName ~}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"test-dict-type\") validDictType)\n (op \"||\"\n (op \"!==\" (get \"primary-dictionary\") dictionaryName)\n (op \"===\" (get \"use-primary-dictionary\") true)\n )\n ) ~}}\n {{~set \"valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~get \"valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-has-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~!\n without this set statement, the parameters\n magically disappears within the bottom 'each' loop...\n ~}}\n {{~ set \"valid-dict-type\" validDictType ~}}\n {{~ set \"entry-count\" entryCount ~}}\n {{~set \"has-valid-dict\" null ~}}\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=(get \"valid-dict-type\") entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n {{~set \"has-valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"has-valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~#*inline \"_jpmn-get-primary-definition-value\"~}}\n {{~!\n ASSUMPTION: \"primary-dictionary\" and \"search-selection\" is available to us from previous functions\n ~}}\n {{~#scope~}}\n {{~#if\n (op \"&&\"\n (op \"!==\" (get \"search-selection\") \"\")\n (get \"opt-primary-def-one-dict-entry-only\")\n )\n ~}}\n {{~! text was highlighted -> use primary dictionary entry with highlighted text ~}}\n {{~set \"found-dict-entry\" false ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-dict-entry\" ~}}\n {{~#regexMatch (get \"search-selection\") \"gu\"~}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"found-dict-entry\") false)\n (op \"&&\"\n (op \"!==\" (get \"rx-match-dict-entry\") \"\")\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else if (get \"opt-primary-def-one-dict-entry-only\") ~}}\n{{~! use first primary dictionary entry ~}}\n{{~set \"found-dict-entry\" false ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n{{~/if~}}\n{{~#each definition.definitions~}}\n{{~#if\n(op \"&&\"\n(op \"===\" (get \"found-dict-entry\") false)\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else~}}\n{{~! use all primary dictionary entries ~}}\n{{~#if (get \"opt__plaintext__one-dict-entry-only-no-list\") ~}}\n{{~! must manually calculate number of primary-dictionary entries... ~}}\n{{~set \"t\" 0 ~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <ol> {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <li data-details=\"{{~dictionary~}}\"> {{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \">=\" (get \"t\") 2)~}} </li> {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} </ol> {{~/if~}}\n {{~else~}}\n <ol> {{~s~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol> {{~s~}}\n{{~/if~}}\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\nif (mode === \"except\" and (regex doesn't match) or mode === \"only\" and (regex matches)):\n return true\n return null\n~}}\n{{#*inline \"_jpmn-check-first-line-dict\"}}\n {{~#scope~}}\n {{~#set \"rx-match-first-line-dict\" ~}}\n {{~#regexMatch (get \"opt-first-line-dicts-regex\") \"u\"~}}{{dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"||\"\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"except\")\n (op \"===\" (get \"rx-match-first-line-dict\") \"\")\n )\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"only\")\n (op \"!==\" (get \"rx-match-first-line-dict\") \"\")\n )\n )\n ~}}\n true\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! custom glossary-single function for additional regex parsing per dictionary ~}}\n{{~! OVERRIDES brief and noDictionaryTag ~}}\n{{#*inline \"_jpmn-glossary-single\"}}\n {{~#scope~}}\n {{~#if (op \"===\" dictionary \"NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\")~}}\n {{~#regexReplace \"<br></span> \u30fb\" \"<br></span>\" \"g\"~}}\n {{~#regexReplace \"<br> \u30fb\" \"<br>\" \"g\"~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/regexReplace~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! custom glossary-single function to add custom html around the dictionary and tags ~}}\n{{#*inline \"_jpmn-glossary-single2\"}}\n {{~#scope~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__tag-list\"> {{~s~}}\n {{~#each definitionTags~}}\n <span class=\"dict-group__tag dict-group__tag--name\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~name~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~/each~}}\n <span class=\"dict-group__tag dict-group__tag--dict\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~dictionary~}}\n </span> {{~s~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~else~}}\n {{~#scope~}}\n {{~#set \"any\" false}}{{/set~}}\n {{~#each definitionTags~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{name}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/each~}}\n {{~#if (op \"!\" (get \"opt__plaintext__remove-dictionary-tag\"))~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{dictionary}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/if~}}\n {{~#if (get \"any\")}}) {{/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__glossary\"> {{~s~}}\n {{~/if~}}\n {{~!\n option to not wrap with spans because it may break dictionaries\n (this is the hell that is parsing html with regex)\n ~}}\n {{~#if (op \"&&\"\n (get \"opt-wrap-first-line-spans\")\n (op \"!\" (get \"opt__plaintext__enabled\"))\n )\n }}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1<span class=\\\"dict-group__glossary--first-line\\\">$2</span><span class=\\\"dict-group__glossary--first-line-break\\\"><br></span>\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else if (get \"opt__plaintext__remove-first-line-enabled\")~}}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~! none match means the dictionary is not an exception, i.e. replace newline ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n </span> {{~s~}}\n {{~/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n{{/inline}}\n{{#*inline \"_jpmn-glossary-single3\"}}\n {{~#scope~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"opt-jmdict-list-format\") true)\n (op \"||\"\n (op \"===\" dictionary \"JMdict (English)\")\n (op \"||\"\n (op \"===\" dictionary \"JMdict Extra\")\n (op \"===\" dictionary \"JMdict\")\n )\n )\n )\n ~}}\n {{~#if (op \"<=\" glossary.length 1)~}}\n {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}\n {{~else~}}\n <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>\n {{~/if~}}\n {{~else~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n =============\n frequencies\n =============\n~}}\n{{#*inline \"jpmn-frequencies\"}}\n {{~#if (op \">\" definition.frequencies.length 0)~}}\n {{~#each definition.frequencies~}}\n <div class=\"frequencies__group\" data-details=\"{{~dictionary~}}\"> {{~s~}}\n <div class=\"frequencies__number\"> {{~s~}}\n <span class=\"frequencies__number-inner\"> {{~s~}}\n {{~! removes the \"X\" in JPDB's frequency and replaces it with a less assuming character\n(it interferes with the color of the card, since you see red\nat the top corner which is somewhat distracting) ~}}\n{{~#regexReplace \"\u274c\" \"\u2716\" \"g\"~}}\n{{~frequency~}}\n{{~/regexReplace~}}\n </span> {{~s~}}\n </div> {{~s~}}\n <div class=\"frequencies__dictionary\"> {{~s~}}\n <span class=\"frequencies__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </span> {{~s~}}\n </div> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~! base code taken from: https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency ~}}\n{{~! NOTE: THIS IS ONLY KEPT FOR LEGACY PURPOSES, and is now deprecated. Please use {jpmn-frequency-sort} instead. ~}}\n{{~#*inline \"jpmn-min-freq\"~}}\n{{~#scope~}}\n{{~#set \"min-freq\" 0~}}{{~/set~}}\n{{~#each definition.frequencies~}}\n{{~#set \"rx-match-ignored-freq\" ~}}\n{{~#regexMatch (get \"ignored-freq-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if\n(op \"&&\"\n(op \"||\"\n(op \"===\" (get \"min-freq\") 0)\n (op \">\" (op \"+\" (get \"min-freq\")) (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency)))\n )\n (op \"===\" (get \"rx-match-ignored-freq\") \"\")\n )\n ~}}\n {{~#set \"min-freq\" (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency))}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"min-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-frequency-sort\"}}\n {{~! Frequency sort handlebars: v24.01.06.1 ~}}\n {{~! The latest version can be found at https://github.com/MarvNC/JP-Resources#freq-handlebar ~}}\n {{~#scope~}}\n {{~! Do not change the code below unless you know what you are doing. ~}}\n {{~set \"result-freq\" -1 ~}} {{~! -1 is chosen because no frequency dictionaries should have an entry as -1 ~}}\n {{~set \"prev-freq-dict\" \"\" ~}}\n {{~set \"t\" 1 ~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#each definition.frequencies~}}\n {{~! rx-match-ignored-freq is not empty if ignored <=> rx-match-ignored-freq is empty if not ignored ~}}\n {{~#set \"rx-match-ignored-freq\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#set \"rx-match-ignored-value\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-value-regex\") \"u\"~}}{{this.frequency}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\" (op \"===\" (get \"rx-match-ignored-freq\") \"\") (op \"===\" (get \"rx-match-ignored-value\") \"\"))~}}\n {{~!\n only uses the 1st frequency of any dictionary.\n For example, if JPDB lists 440 and 26189\u32d5, only the first 440 will be used.\n ~}}\n {{~set \"read-freq\" false ~}}\n {{~#if (op \"!==\" (get \"prev-freq-dict\") this.dictionary ) ~}}\n {{~set \"read-freq\" true ~}}\n {{~set \"prev-freq-dict\" this.dictionary ~}}\n {{/if~}}\n {{~#if (op \"!\" (get \"read-freq\") ) ~}}\n {{~#set \"rx-match-keep-freqs\" ~}}\n {{~#regexMatch (get \"opt-keep-freqs-past-first-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-keep-freqs is not empty if keep freqs ~}}\n {{~#if (op \"!==\" (get \"rx-match-keep-freqs\") \"\") ~}}\n {{~set \"read-freq\" true ~}}\n {{/if~}}\n {{/if~}}\n {{~#if (get \"read-freq\") ~}}\n {{~#set \"numericFrequencyMatch\"}}{{~#regexMatch \"\\d+\" \"\"}}{{~this.frequency~}}{{/regexMatch~}}{{/set~}}\n {{~set \"f\" (op \"+\" (get \"numericFrequencyMatch\")) ~}}\n {{~#if (op \"===\" (get \"opt-freq-sorting-method\") \"min\") ~}}\n {{~#if\n (op \"||\"\n (op \"===\" (get \"result-freq\") -1)\n (op \">\" (get \"result-freq\") (get \"f\"))\n )\n ~}}\n {{~set \"result-freq\" (op \"+\" (get \"f\")) ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"first\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~else~}}\n {{~!\n iterative mean formula (to prevent floating point overflow):\n $S_{(t+1)} = S_t + \\frac{1}{t+1} (x - S_t)$\n - example java implementation: https://stackoverflow.com/a/1934266\n - proof: https://www.heikohoffmann.de/htmlthesis/node134.html\n ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\"\n (op \"-\"\n (get \"f\")\n (get \"result-freq\")\n )\n (get \"t\")\n )\n )\n }}\n {{~/if~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~#if (op \">\" (get \"f\") 0) ~}} {{~! ensures only positive numbers are used ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (op \"/\" 1 (get \"f\")) ~}}\n {{~else ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\" 1 (get \"f\"))\n )\n }}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"debug\") ~}}\n {{ this.dictionary }}: {{ this.frequency }} -> {{ get \"f\" }} <br>\n {{~else~}}\n (INVALID opt-freq-sorting-method value)\n {{~/if~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! (x) >> 0 apparently floors x: https://stackoverflow.com/a/4228528 ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"opt-no-freq-default-value\") ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~set \"result-freq\"\n (op \">>\" (get \"result-freq\") 0 )\n ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~set \"result-freq\"\n (op \">>\"\n (op \"*\"\n (op \"/\" 1 (get \"result-freq\"))\n (get \"t\")\n )\n 0\n )\n ~}}\n {{~/if~}}\n {{~! override final result if grammar dictionary ~}}\n {{~#if (\n op \"&&\"\n (op \"===\" (get \"found-grammar-dict\") true)\n (op \"===\" (get \"opt-grammar-override\") true)\n )\n ~}}\n {{~set \"result-freq\" (get \"opt-grammar-override-value\") ~}}\n {{/if}}\n {{~get \"result-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n ==============\n pitch accent\n ==============\n~}}\n{{#*inline \"jpmn-pitch-accent-graphs\"}}\n {{~#if (op \">\" pitchCount 0)~}}\n {{~#each pitches~}}\n <div class=\"pa-graphs__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-graphs__dictionary\"> {{~s~}}\n <div class=\"pa-graphs__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"graph\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-pitch-accent-positions\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#each pitches~}}\n <div class=\"pa-positions__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-positions__dictionary\"> {{~s~}}\n <div class=\"pa-positions__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"position\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~!\n==============\ndictionaries\n==============\n~}}\n{{~! primary def: first monolingual (or first bilingual if no monolingual dicts found) ~}}\n{{~! does the reverse if opt-first-definition-type is \"bilingual\" ~}}\n{{~#*inline \"jpmn-primary-definition\"~}}\n{{~#scope~}}\n{{~! output warning if no dictionaries are found ~}}\n{{~#if (op \"===\" definition.definitions.length undefined)~}}\nWARNING: JPMN Handlebars cannot find any definitions to export.\nThis is usually because your Yomichan settings has \"Result grouping mode\"\nset to \"No grouping\". Please set this to \"Group term-reading pairs\".\n {{~/if~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~#if (op \"===\" (get \"primary-dictionary\") \"\")~}}\n {{~> _jpmn-selection-text ~}}\n {{~else~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#set \"selection-uses-glossary\"~}}\n {{~> _jpmn-selection-uses-glossary . ~}}\n {{~/set~}}\n {{~! not \"\" <=> is a filled string, i.e. selection uses glossary ~}}\n {{~#if (op \"!==\" (get \"selection-uses-glossary\") \"\")~}}\n {{~! escape regex ~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#set \"search-selection-bold\"}}<b>{{~> _jpmn-selection-text ~}}</b>{{/set~}}\n {{~#regexReplace (get \"search-selection\") (get \"search-selection-bold\") \"g\"~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~#set \"search-selection\"}}{{/set~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! extra def: bilingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-secondary-definition\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~! looks to see if another dictionary exists ~}}\n {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n {{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n {{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n {{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! extra def: monolingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-extra-definitions\"~}}\n{{~#scope~}}\n{{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n{{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! pitch accent info: all pitch accent info dictionaries ~}}\n{{~#*inline \"jpmn-utility-dictionaries\"~}}\n{{~#scope~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! 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) ~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"utility\"~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") \"utility\")~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\n=======\nother\n=======\n~}}\n{{~#*inline \"jpmn-word-reading-hiragana\"~}}\n{{~#set \"word-reading\" ~}}{{> reading}}{{/set~}}\n{{~#if (op \"\" (get \"word-reading\")) ~}}\n{{~#set \"word-reading\" ~}}{{> expression}}{{/set~}}\n{{~/if~}}\n{{#hiragana (get \"word-reading\") keepProlongedSoundMarks=false}}{{/hiragana}}\n{{~/inline~}}\n{{~!\nthanks to:\n- https://github.com/FooSoft/yomichan/issues/1952#issuecomment-922671489 for the base code\n- DaNautics#8833 for finding the above + removing the span classes\n~}}\n{{#*inline \"jpmn-sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-hiragana\"}}\n{{~#scope~}}\n{{~#set \"expression\" ~}}{{> expression}}{{/set~}}\n{{~#set \"reading\" ~}}{{> reading}}{{/set~}}\n{{~#set \"expression-hiragana\" ~}}{{> jpmn-word-reading-hiragana}}{{/set~}}\n{{~#if (op \"&&\" (op \"===\" (get \"expression\") (get \"reading\")) (op \"===\" (get \"expression\") (get \"expression-hiragana\")))~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-not-hiragana\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-word-is-hiragana}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-grammar-point\"}}\n {{~#scope~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#if (get \"found-grammar-dict\") ~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-grammar-point\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-grammar-point}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-on-mim\"}}\n {{~#scope~}}\n {{~#set \"rx-match-on-mim\" ~}}\n {{~#regexMatch \"(, |^)on-mim(, |$)\" \"gu\"~}}{{> tags }}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"!==\" (get \"rx-match-on-mim\") \"\") ~}}\n 1\n {{/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-on-mim\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-not-on-mim}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! my personal settings:\n- sentence card if grammar point\n- otherwise, if it's on-mim, then hint card\n- otherwise, default\n~}}\n{{#*inline \"jpmn-is-sentence-card\"}}\n {{~> jpmn-filled-if-grammar-point ~}}\n{{/inline}}\n{{#*inline \"jpmn-is-hint-card\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n {{~> jpmn-filled-if-on-mim ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-is-click-card\"}}\n {{~#scope~}}\n {{~#set \"filled1\" ~}}{{> jpmn-is-hint-card}}{{/set~}}\n {{~#set \"filled2\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"filled1\") \"\")\n (op \"===\" (get \"filled2\") \"\")\n )~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! a test to check if your dictionaries are correctly classified. ~}}\n{{~! Only meant to be used for debugging purposes, not Anki. ~}}\n{{~#*inline \"jpmn-test-dict-type\"~}}\n{{~#scope~}}\n{{~#each definition.definitions~}}\n\u300c{{dictionary}}\u300d: {{> jpmn-get-dict-type . dictionaryName=dictionary}}\n{{/each~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"jpmnhandlebars/#monolingual-definitions","title":"Monolingual definitions","text":"By default, the handlebars exports bilingual cards. Set opt-first-definition-type
to monolingual
if you want monolingual Anki cards. See here for more info.
"},{"location":"jpmnhandlebars/#setup-fields","title":"Setup Fields","text":"Video demo TODO (click here) TODO video
- Navigate to Yomichan Settings.
- Go to the
Anki
section. - Select
Anki card format...
. - Under your definition field (
Glossary
, VocabDef
, etc.), type {jpmn-primary-definition}
into the input box. - If you have a field for bilingual definitions, set that field to
{jpmn-secondary-definition}
- If you have a field for all other definitions, set that field to
{jpmn-extra-definitions}
"},{"location":"jpmnhandlebars/#common-problems","title":"Common Problems","text":" -
If you transferred from the legacy Anime Cards handlebars (step 6 of this), then your pitch accent graphs might look a bit different. This is because the legacy Anime Cards handlebars removes a bunch of extra styling from the exported SVG, which is unfortunately non-standard.
Nonetheless, the easy way to fix this is by simply replacing the current pitch accent handlebars with Anime Card's modified pitch accent handlebars:
Legacy pitch accent handlebars (click here) {{! Pitch Accents }}\n{{#*inline \"pitch-accent-item\"}}\n{{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}\n{{/inline}}\n{{#*inline \"pitch-accent-item-disambiguation\"}}\n{{~#scope~}}\n{{~#set \"exclusive\" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}\n{{~#if (op \">\" (property (get \"exclusive\") \"length\") 0)~}}\n{{~#set \"separator\" \"\"~}}{{/set~}}\n <em>({{#each (get \"exclusive\")~}}\n{{~#get \"separator\"}}{{/get~}}{{{.}}}\n{{~/each}} only) </em>\n{{~/if~}}\n{{~/scope~}}\n{{/inline}}\n{{#*inline \"pitch-accent-list\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~#each pitches~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~/each~}}\n{{~/each~}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~else~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"pitch-accents\"}}\n{{~> pitch-accent-list format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs\"}}\n{{~> pitch-accent-list format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions\"}}\n{{#regexReplace \"<(.|\\n)*?>\" \"\"}}{{~> pitch-accent-list format='position'~}}{{/regexReplace}}\n{{/inline}}\n{{! End Pitch Accents }}\n
Alternatively, you can use these handlebars to get one pitch accent only. This does not modify existing handlebars.
"},{"location":"jpmnhandlebars/#introduced-handlebars","title":"Introduced Handlebars","text":""},{"location":"jpmnhandlebars/#definitions","title":"Definitions","text":"Main Page: Definitions: Dictionary Placement
The most important handlebars that this package introduces is {jpmn-primary-definition}
. This handlebars automatically selects the first monolingual or bilingual dictionary, depending on the opt-first-definition-type
option.
To summarize the introduced definition handlebars:
Handlebars Description {jpmn-primary-definition}
The highest priority monolingual or bilingual dictionary (depending on the value of opt-first-definition-type
). {jpmn-secondary-definition}
All bilingual dictionaries outside of the one selected in the primary definition. {jpmn-extra-definitions}
All monolingual dictionaries outside of the one selected in the primary definition. {jpmn-utility-dictionaries}
All dictionaries that fall outside the category of bilingual or monolingual. For example, JMnedict or JMdict Forms. If you want to select a different dictionary, highlight the dictionary, or a portion of the definition before importing. This will override the primary definition with the selected dictionary / definition.
"},{"location":"jpmnhandlebars/#frequency-sorting","title":"Frequency Sorting","text":"This package introduces {jpmn-frequency-sort}
, which behaves the exact same as Marv's {freq}
handlebars. The only difference is that the options are placed at the very top of the handlebars, instead of within the function.
In other words, feel free to use this in the exact same way as you would with {freq}
.
"},{"location":"jpmnhandlebars/#other-handlebars","title":"Other handlebars","text":" - TODO
jpmn-sentence-bolded-furigana-plain
- TODO binary field handlebars
- link to appropriate yomichan template section
"},{"location":"jpmnhandlebars/#plaintext-options","title":"Plaintext Options","text":"This section describes all the plaintext options, which are all prefixed with opt__plaintext__
.
-
If you are not using jp-mining-note, all these options should be set to true
by default. This means definitions are as minimal as possible in both internal HTML structure and in content.
-
If you are using jp-mining-note, then all of these should be set to false
by default.
If you are looking for information about the other options, please see the Definitions page.
"},{"location":"jpmnhandlebars/#opt__plaintext__stylize-glossary","title":"opt__plaintext__stylize-glossary
","text":"Setting this option to true
will no longer stylize the definition handlebars for jp-mining-note usage, and instead stylizes it to be virtually the same as Yomichan's default HTML structure.
Differences between default Yomichan format and JPMN plaintext (click here) There are a few minor differences between Yomichan's format and these non-stylized definitions:
- The dictionary and tags are not italicized. This is to avoid seeing italic kanjis/kana.
-
The div that left-aligns the text is not present. If this breaks your card, (for example, the definition gets centered), try surrounding your definition field. For example, if your field name is Definition
, then within your Anki card templates, surround {{ Definition }}
with the following:
<div style=\"text-align: left\"> {{Definition}} </div>\n
-
Dictionaries with only one entry is formatted as a list of one element by default. This is usually not desired. To disable this behavior and make the behavior more like Yomichan, set opt__plaintext__one-dict-entry-only-no-list
to true
.
-
The first line for most dictionaries are removed by default. This can be controlled with the following options:
opt__plaintext__remove-first-line-enabled
opt-first-line-dicts-regex
There are som dictionaries simply cannot have their first line be removed by the handlebars, due to its complicated internal structure. Those dictionaries are specified under opt-first-line-dicts-regex
by default.
"},{"location":"jpmnhandlebars/#opt__plaintext__one-dict-entry-only-no-list","title":"opt__plaintext__one-dict-entry-only-no-list
","text":"If this is true
, then a definition that only contains one dictionary entry will export without being in a list.
For the following examples, we take the definition of \u7d68\u6bef from the \u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248 dictionary.
true
(single definition has no list)false
(single definition exported in list) \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
- \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
Note
If there are multiple definitions, then it is exported in a list format by default. This is almost never present in monolingual dictionaries, but almost always present for JMdict. For example, \u5730\u96f7 (in the old JMdict dictionary) will always be exported as the following, regardless of the setting:
- (n, JMdict (English)) land mine
- (n, col, JMdict (English)) topic that sets someone off | sensitive topic | taboo topic | trigger
- (n, col, JMdict (English)) something that seems fine at first but turns out to be very bad (e.g. product, business) | booby trap | pitfall
"},{"location":"jpmnhandlebars/#opt__plaintext__remove-dictionary-tag","title":"opt__plaintext__remove-dictionary-tag
","text":"Whether the dictionary tag is exported or not.
true
(no dictionary tag)false
(keep dictionary tag) \u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
(\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248) \u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
"},{"location":"jpmnhandlebars/#opt__plaintext__remove-first-line-enabled","title":"opt__plaintext__remove-first-line-enabled
","text":"Whether the first line is exported or not.
true
(first line removed)false
(first line kept) \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
\u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
This affects almost all dictionaries by default. If you want to ignore certain dictionaries, use the opt-first-line-dicts-regex
option as described here.
"},{"location":"jpmnhandlebars/#compatibility-with-other-handlebars","title":"Compatibility with other Handlebars","text":"These handlebars are fully compatable SO LONG AS your other handlebars are based off of the most recent set of default handlebars. A non-example is the classic animecard's {test}
. {test}
requires outdated handlebars in order to work, and is therefore incompatible with these handlebars.
There are two reasons why these handlebars are compatible with most other handlebars:
- Everything is prefixed with
jpmn
(or _jpmn
). These prefixes prevent the JPMN handlebars from overriding any other custom handlebars you may have defined. - These handlebars do not modify the default handlebars code. This is in order to preserve the original handlebars functionality, and so other handlebars can rely on the original handlebars to work properly.
"},{"location":"jpresources/","title":"JP Resources","text":"A collection of tips and tricks, primarily related to CSS, Yomichan templates, and ShareX. Other resources can be found to the left sidebar.
This page was inspired by Marv's resources page, which has a bunch of different but equally awesome resources. I highly recommend checking it out!
If you encounter any problems, have any questions, etc., feel free to contact me on discord aquafina_water_bottle
, or submit an issue. I exist on the TheMoeWay and Refold (Japanese) servers.
"},{"location":"jpresources/#master-project-list","title":"Master Project List","text":"This contains the list of all my current projects that relate to learning Japanese.
-
jp-mining-note
jp-mining-note is a highly customizable Anki card template for studying Japanese, designed to be visually appealing and simple to use without sacrificing functionality. Easily paired with most automatic card creation workflows, this aims to make your experience with Anki as smooth as possible.
-
JPMN Manager
JPMN Manager is a simple Anki add-on that makes it possible to seemlessly install and update jp-mining-note, and makes working with the note a little easier.
-
Local Audio Server for Yomichan
This Anki add-on runs a local server of which Yomichan can fetch audio files from, using a database containing over 200,000 unique expressions. With this setup, you are able to create Anki cards nearly instantaneously, and get word audio without a working internet connection.
-
JPMN Handlebars Package
Instructions on how to use the JPMN handlebars for any note type, not just jp-mining-note. Most notably, these handlebars make it very easy to select and export dictionaries into Anki.
-
All Anki note templates I can find
I catalogue all note templates I can possibly find (that isn't jp-mining-note, and made for learning Japanese) here.
-
JMdict (English) for Yomichan
This simply contains a Yomichan dictionary version of JMdict (English)
from the main website (from files JMdict_e
and JMdict_e_examp
), compiled using yomichan-import. (Disclaimer: I did not make any of these tools.)
This repository exists to simply give people a more up-to-date version of this dictionary, for people who don't want to compile the dictionary themselves. A more up-to-date version of JMdict usually provides better definitions and coverage compared to older versions, so I would recommend updating this dictionary every few months.
"},{"location":"jpresources/#css-yomichan","title":"CSS (Yomichan)","text":""},{"location":"jpresources/#how-to-add-custom-css-in-yomichan","title":"How-To: Add Custom CSS In Yomichan","text":"To add custom CSS in Yomichan, do the following:
- Head over to Yomichan settings (Yomichan extension marker -> cogwheel)
- Go to
Appearance
\u2192 Configure custom CSS...
- Add the CSS to the top section.
- Close the window.
Demo (click here) "},{"location":"jpresources/#not-selecting-or-copying-furigana","title":"Not selecting or copying furigana","text":"If you want to select / copy the main word within Yomichan without copying the furigana, you can use the following CSS:
.headword-term ruby rt {\nuser-select: none;\n}\n
Note
The above is actually general enough to use for Anki cards itself, say with the following CSS:
ruby rt {\nuser-select: none;\n}\n
"},{"location":"jpresources/#limiting-the-number-of-frequency-lists","title":"Limiting the number of frequency lists","text":"/* Only shows the first 2 frequency lists */\nspan.frequency-group-item:nth-child(n+3) {\ndisplay: none;\n}\n
(Thanks Marv#5144 for the CSS. Original message on TMW server) Demo (click here)"},{"location":"jpresources/#limiting-the-number-of-pitch-accent-dictionaries","title":"Limiting the number of pitch accent dictionaries","text":"The following CSS displays only the first 2 pitch accent dictionaries:
/* Only shows the first 2 pitch accent dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n
Make the pitch accent dictionary text a bit grey by default, and to make specifically the \"NHK\" and \"\u5927\u8f9e\u6cc9\" white (change these two to any dictionary you find to be of higher quality)
/* Greys out all pitch accent dictionary names */\n/* Sets NHK and \u5927\u8f9e\u6cc9 pitch accent dictionaries to a white name */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\n
Demo (click here) "},{"location":"jpresources/#hide-the-dictionary-but-allow-it-to-be-used-by-anki","title":"Hide the dictionary, but allow it to be used by Anki","text":"The default way to hide a dictionary is by disabling the dictionary under Yomichan's Dictionaries
section. However, if you disable the dictionary, you cannot export it into Anki, which is a problem if you are using a bilingual profile but you want to export monolingual definitions.
Steps:
- Ensure that the dictionary is enabled in your Yomichan profile.
- Add the following CSS for the desired dictionaries (this has to be done for each individual dictionary):
li.definition-item[data-dictionary='DICTIONARY'] {\ndisplay: none;\n}\n
Example CSS for JMdict (click here) li.definition-item[data-dictionary='JMdict (English)'] {\ndisplay: none;\n}\n
Demo (click here) "},{"location":"jpresources/#hide-bilingual-definitions-until-hover","title":"Hide bilingual definitions until hover","text":"Add the following CSS for the desired dictionaries (this has to be done for each individual dictionary):
li.definition-item[data-dictionary='DICTIONARY'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='DICTIONARY']:hover .gloss-list {\nopacity: 1;\n}\n
Example CSS for JMdict (click here) li.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\n
Demo (click here) "},{"location":"jpresources/#remove-the-add-reading-button","title":"Remove the \"Add Reading\" button","text":"This removes the small green button to add the reading.
button[title^=\"Add reading\"] {\ndisplay:none;\n}\n
Demo (click here) Left: without CSS. Right: with CSS.
"},{"location":"jpresources/#coloring-dictionaries","title":"Coloring Dictionaries","text":"Darius has some CSS here that uniquely colors popular dictionaries.
"},{"location":"jpresources/#css-other","title":"CSS (Other)","text":""},{"location":"jpresources/#ensuring-properly-quotes-the-text","title":"Ensuring \u300c\u300d properly quotes the text","text":"If your text contains quotes, the following CSS ensures that it is properly stylized:
.jp-quote-text {\ntext-indent: -1em;\npadding-left: 1em;\n}\n
On the example to the right, the first quote is the standard display without any custom CSS. The second quote is with the aforementioned CSS.
An example JSFiddle can be found here.
"},{"location":"jpresources/#changing-the-japanese-font-on-discord","title":"Changing the Japanese font on Discord","text":"Note
Discord's codebase is always subject to change, so this method may not work in the future.
- Get BetterDiscord so you can use custom CSS.
- In Discord Settings \u2192
Custom CSS
section, add the following: :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"YOUR-PREFERRED-FONT\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: var(--font-primary);\n}\n
Example CSS for Noto Sans (click here) :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"Noto Sans CJK JP\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: var(--font-primary);\n}\n
Discord's default CSS (click here) :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: \"gg sans\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n}\n
Note
If you are using the browser version of Discord, you can also change the font with the Stylus extension. I personally don't use this, so I'll leave it to the user to figure out the settings. ;)
Changelog 22/12/01
: Changed Whitney
to gg sans
to match with Discord's new font 22/12/05
: Added --font-display
, added missing Noto Sans
to all the fonts
"},{"location":"jpresources/#yomichan-templates-handlebars","title":"Yomichan Templates / Handlebars","text":"Note
If you are using the jp-mining-note template, most things here will likely not be useful for you as the Yomichan templates that comes with the note already contains most of these features and more.
"},{"location":"jpresources/#how-to-edit-yomichan-fields","title":"How-To: Edit Yomichan Fields","text":" - Navigate to Yomichan Settings.
- Go to the
Anki
section. - Select
Anki card format...
.
Demo (click here) The above showcases option 2 of this example.
"},{"location":"jpresources/#how-to-edit-yomichan-templates-handlebars","title":"How-To: Edit Yomichan Templates (Handlebars)","text":" - Navigate to Yomichan Settings.
- Make sure that advanced settings are turned on (bottom left corner).
- Go to the
Anki
section - Select
Configure Anki card templates...
Demo (click here)"},{"location":"jpresources/#grab-only-the-first-pitch-accent-dictionary","title":"Grab only the first pitch accent dictionary","text":"Adds the following Yomichan Fields:
{pitch-accents-single-dict}
: Pitch accent in text (downstep) format {pitch-accent-graphs-single-dict}
: Pitch accent in svg graph format {pitch-accent-positions-single-dict}
: Pitch accent in positions (number) format
Template code (click here) {{#*inline \"pitch-accent-list-single-dict\"}}\n{{~#if (op \">\" pitchCount 1)~}}<ol>{{~/if~}}\n{{~#eachUpTo pitches 1~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}<li>{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}</li>{{~/if~}}\n{{~/each~}}\n{{~else~}}\n No pitch accent data\n{{~/eachUpTo~}}\n{{/inline}}\n{{#*inline \"pitch-accents-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='position'~}}\n{{/inline}}\n
Modified version of the above for Anime Cards (click here) {{#*inline \"pitch-accent-list-single-dict\"}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~#eachUpTo pitches 1~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~/each~}}\n{{~else~}}\n{{~/eachUpTo~}}\n{{/inline}}\n{{#*inline \"pitch-accents-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions-single-dict\"}}\n{{#regexReplace \"<(.|\\n)*?>\" \"\"}}{{~> pitch-accent-list-single-dict format='position'~}}{{/regexReplace}}\n{{/inline}}\n
(Thanks An#7416 for the template code. Original message on TMW server).
"},{"location":"jpresources/#export-only-the-selected-text-only-if-text-is-selected","title":"Export only the selected text (only if text is selected)","text":"Adds: {selection-text-or-glossary}
Tip
I recommend using {jpmn-primary-definition}
from the JPMN Handlebars Package instead of this handlebars, because the handlebars package can do this and much more.
Allows you to export only a section of a glossary by highlighting over it, and uses the glossary by default if you don't have anything highlighted.
Template code (click here) {{#*inline \"selection-text-or-glossary\"}}\n{{~#if (op \"!==\" (getMedia \"selectionText\") \"\")~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n{{~else~}}\n{{~> glossary ~}}\n{{/if~}}\n{{/inline}}\n
Note
Related Github issue.
"},{"location":"jpresources/#grab-only-the-first-dictionary","title":"Grab only the first dictionary","text":"Adds: {glossary-first}
Tip
I recommend using {jpmn-primary-definition}
from the JPMN Handlebars Package instead of this handlebars, because the handlebars package can do this and much more.
The following grabs the first dictionary (including every definition within said dictionary).
For further customization on how the first dictionary is selected (say, for automatic bilingual / monolingual separation), see the handlebars code used by jp-mining-note here.
Template code (click here) {{~#*inline \"glossary-first\"~}}\n{{~#scope~}}\n{{~#set \"first-dictionary\" null}}{{/set~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"!==\" null (get \"first-dictionary\"))~}}\n <div style=\"text-align: left;\"><ol>\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"first-dictionary\"))~}}\n <li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>\n{{~/if~}}\n{{~/each~}}\n </ol></div>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"jpresources/#automatically-highlight-the-tested-word-within-the-sentence-upon-card-creation","title":"Automatically highlight the tested word within the sentence upon card creation","text":"Option 1: Bold only {cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}\n
Option 2: Bold + Styling (recommended) Yomichan Fields:
{cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}\n
Anki Note CSS (the Styling
page under the editing card templates page):
b {\ncolor: #fffd9e; /* bright yellow */\n}\n
If your card template is formatted like <div class=\"sentence\">{{ Sentence }}</div>
:
.sentence b {\ncolor: #fffd9e; /* bright yellow */\n/* if you want to make the word not bolded, un-comment the following */\n/*font-weight: normal;*/\n}\n
Option 3: Custom div Yomichan Fields:
{cloze-prefix}<span class=\"word-highlight\">{cloze-body}</span>{cloze-suffix}\n
Anki Note CSS:
.word-highlight {\ncolor: #fffd9e;\n}\n
Note
I personally prefer using Option 2 (bold + styling) over a custom div because it makes editing the note easier. For example, if you want to edit the highlighted region, you only have to bold the desired region (say, with Ctrl+B) instead of having to edit the raw HTML of the field (say, with Ctrl+Shift+X).
See also: How to automatically highlight the targetted word within the sentence for already existing cards.
"},{"location":"jpresources/#plain-style-sentence-furigana","title":"Plain-Style Sentence Furigana","text":"Adds: {sentence-bolded-furigana-plain}
This does the following:
- Generates plain style furigana on the sentence (e.g. \u300c \u65e5\u672c\u8a9e[\u306b\u307b\u3093\u3054]\u300d
- Bolds the added word
To use this in Anki, add furigana:
in front of the field within the template code. For example, if your field is SentenceReading
, use {{furigana:SentenceReading}}
.
Template code (click here) {{#*inline \"sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n
Thanks to Skillesss: for the base code and DaNautics#8833 for finding the above + removing the span classes
Comparisons to alternatives (click here) -
AJT Furigana can auto-generate furigana on card add and can add furigana to any text within a field even after a card add. However, generating furigana cannot be done within this addon on Android, as this is a PC add-on.
Nonetheless, I recommend keeping AJT Furigana so furigana can be generated even after editing the sentence field.
-
The {furigana}
helper provided by default in Yomichan does not generate plain style furigana, which makes editing furigana more difficult in Anki.
"},{"location":"jpresources/#further-reading","title":"Further Reading","text":"Official documentation om Yomichan's templates:
- Yomichan template helper functions
- Yomichan template structure
Example template code can be found here:
-
Helpers for individual dictionaries: here
- This has certain extended capabilities over my template code, such as removing the first line.
-
Template code for this note: here and here
-
Old template code for this note (NO LONGER USED / MAINTAINED): here
"},{"location":"jpresourcesother/","title":"Other","text":""},{"location":"jpresourcesother/#settings-css-for-renjis-texthooker","title":"Settings / CSS for Renji's texthooker","text":"I use the following stylizations to remove unnecessary padding within the document, and to behave more similarly to Anacreon's texthooker.
Settings:
Setting Value Preserve Whitespace Remove Whitespace Custom CSS:
main > p {\npadding: 0rem !important;\n}\nmain {\npadding-left: min(5%, 5rem) !important;\npadding-right: min(5%, 5rem) !important;\n}\nbody > div > textarea {\nfont-size: 24px !important;\n}\n
Using a custom font (click here) I set the font to be Noto Sans, but this will likely not work without downloading and installing the font first (e.g. from here). Below is the actual full CSS that I use in conjuction with the installed font:
main > p {\npadding: 0rem !important;\n}\nmain {\npadding-left: min(5%, 5rem) !important;\npadding-right: min(5%, 5rem) !important;\nfont-family: \"Noto Sans CJK JP\" !important; /* <-- new! */\n}\nbody > div > textarea {\nfont-size: 24px !important;\n}\n
"},{"location":"jpresourcesother/#send-text-from-anki-to-your-texthooker","title":"Send text from Anki to your texthooker","text":"Warning
THIS CODE IS DEPRECATED in favor of AJT Autocopy. If you still wish to use a websocket setup to prevent clipboard flooding, I recommend writing an Anki Add-on instead of the code below.
This is a very quick hack to have text from Anki to appear on a websocket based texthooker.
Requires Python, written for Renji's texthooker.
Instructions (click here) -
Save as server.py
:
import asyncio\nimport websockets\nCONNECTIONS = set()\nasync def register(websocket):\nCONNECTIONS.add(websocket)\ntry:\nasync for message in websocket:\nprint(f\"server will now echo '{message}' to all other connections\")\nconnections = [c for c in CONNECTIONS if c != websocket]\nwebsockets.broadcast(connections, message)\nawait websocket.wait_closed()\nfinally:\nCONNECTIONS.remove(websocket)\nasync def main():\nasync with websockets.serve(register, \"localhost\", 6678):\nawait asyncio.Future() # run forever\nif __name__ == \"__main__\":\nasyncio.run(main())\n
-
Paste this on the back side of your Anki template:
<script>\n(() => {\nfunction sendText(id) {\nconst sentEle = document.getElementById(id);\nif (sentEle !== null) {\nconst sentence = sentEle.innerText.trim();\nif (sentence.length > 0) {\nsocket.send(sentence);\n}\n}\n}\nconst url = \"ws://localhost:6678\";\nconst socket = new WebSocket(url);\nsocket.onopen = (_e) => {\nsendText(\"full_sentence\");\nsendText(\"primary_definition_raw_text\");\n};\n})();\n</script>\n
-
Replace full_sentence
and primary_definition_raw_text
with whatever id.
- Install
websockets
with pip, i.e. pip3 install websockets
- Change the web port on the texthooker page to
6678
.
Whenever you want to connect Anki to the texthooker page:
- Run
server.py
, i.e. python3 server.py
- Ensure the web port is the same on the texthooker page, i.e.
6678
- Enable the websocket connection on the texthooker page.
"},{"location":"jpresourcesother/#mikagu-pitch-accent-alternatives","title":"Mikagu pitch accent alternatives","text":" - migaku updated
- Fork of migaku to be updated for anki version 2.1.50+
- anki-jrp
- Completely stand-alone plugin from migaku with a completely different codebase
- Only does one thing: adds pitch accent colors (along with furigana)
"},{"location":"kanjihover/","title":"Kanji Hover (TODO)","text":"Kanji Hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
Note that Kanji Hover does not search for words outside of your deck of \"JP Mining Note\" types. This means if you have notes of any other type, those notes will not be included in the resulting popup.
"},{"location":"kanjihover/#interface","title":"Interface","text":""},{"location":"kanjihover/#interface-new-cards","title":"Interface: New Cards","text":"You may have noticed that some results are greyed out. These represent words from cards that have not been reviewed yet. Conversely, as non-greyed out results come from cards that you have already reviewed, they should represent words that you already know.
(TODO image)
"},{"location":"kanjihover/#interface-pitch-accents","title":"Interface: Pitch Accents","text":"Pitch accents are shown when you hover over a particular word within the tooltip. You can change this to always be shown with RTO:tooltips.displayPitchAccent
.
(TODO image)
"},{"location":"kanjihover/#interface-sentence-search","title":"Interface: Sentence Search","text":"If there are not enough results to display, the kanji is searched within the sentences of existing cards.
(TODO image)
"},{"location":"kanjihover/#interface-open-card","title":"Interface: Open Card","text":"You can click on the word to open the specified card within Anki's card browser.
(TODO image)
"},{"location":"kanjihover/#refresh-button","title":"Refresh Button","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
TODO
- If editing
WordReading
field or some other card shown as the results, the changes will not show due to cache - pressing the refresh button on the info circle + hovering over the kanji again should work
"},{"location":"kanjihover/#related-programs","title":"Related Programs","text":"Warning
None of the above will work with jp-mining-note by default. In fact, it's almost guaranteed that Cade's Kanji Hover will conflict with this note's kanji hover ability, if placed directly in the word reading field.
"},{"location":"kanjihover/#cades-kanji-hover","title":"Cade's Kanji Hover","text":" - Hover over a kanji to see its readings, meanings (english), and other info.
- This does not show example words from other cards.
- My implmentation of kanji hover was heavily inspired by this.
"},{"location":"kanjihover/#hanzi-web-for-anki","title":"Hanzi Web for Anki","text":" - The end result of this is to JPMN's implementation of kanji hover, in the sense that it is used to see kanjis that have been used in other notes. However, it differs primarily in the fact that all the information must be mass-generated. This indeed has several advantages, such as being able to use the infomation on Android, where Anki-Connect isn't full supported.
"},{"location":"kanjihover/#kanjieaters-kanji-connections","title":"KanjiEater's Kanji Connections","text":" - Ability to show kanjis with heisig's RTK keywords, as well as related vocabulary.
- Has stylization options to show maturity and difficulty (number of possible readings) for each individual kanji.
"},{"location":"kanjihover/#kanjikeywordoverlay","title":"KanjiKeywordOverlay","text":" - Shows kanji hover on info, based off of existing cards. Works similarly to KanjiEater's Kanji Connections add-on.
"},{"location":"kanjihover/#anki-wanikani-hints","title":"Anki-WaniKani-Hints","text":" - Shows WaniKani information on kanji hover, which includes stories for radicals and pronunciations.
"},{"location":"kanjihover/#glutanimates-pop-up-dictionary","title":"Glutanimate's Pop-up Dictionary","text":" - An old add-on that searches highlighted text across all cards.
- Requires a download from file
- Also see p1000's version, which should work with jp-mining-note by default
"},{"location":"keybinds/","title":"Keybinds","text":"This note ships with some keybinds to do some common actions.
Keybind What it does P Play sentence audio W Play word audio N Reveals the sentence or word (for reveal cards) 8 Toggles Secondary Definition
field 9 Toggles Additional Notes
field 0 Toggles Extra Definitions
field [ Toggles Extra Info
field . Reveals and hides the hint TODO wtf is keybinds.toggleFrontFullSentenceDisplay
See the runtime options if you would like to edit / disable any keybind, and/or to view the full list of keybinds.
"},{"location":"modding/","title":"Modding Overview","text":""},{"location":"modding/#modding-the-obvious-way","title":"Modding (The Obvious Way)","text":"Throughout the documentation and within the templates alone, you will likely see warning messages to not edit the templates directly unless you are willing to lose your changes when you update the note.
The most obvious way to mod the note is directly in the pre-built template downloaded. If you are completely fine with losing your changes upon each update, and don't want to take advantages of certain tools that comes with this note (such as compile options), then you can simply edit the template and ignore the rest of this page.
"},{"location":"modding/#modding-the-recommended-way","title":"Modding (The Recommended Way)","text":"To ensure that your changes aren't lost, the recommended way to make changes to the existing templates is to add new files, rather than editing existing ones. This allows you to continuously update with the note, while having your custom files stay in place.
Warning
There is no guaranteed backwards compatability for anything mentioned here (especially while the note is still in beta). Although you won't lose your changes upon update, your changes might also not work on the next update. For example, if the file that you are overriding gets renamed, you will have to rename the file to match the newly renamed file.
I will try my best to keep things backwards compatable, but given the current state of the note (particularily the CSS), it might not be possible to do most of the time. When this note comes out of beta, backward-incompatable changes should be harshly reduced.
"},{"location":"modding/#prerequisites","title":"Prerequisites","text":"You must be able to successfully build the template in order to start modding the note.
Click here to see how to build the template!
"},{"location":"moddingtips/","title":"Tips & Tricks (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"moddingtips/#ankiwebview-inspector","title":"AnkiWebView Inspector","text":"TODO non-point-form
- addon: https://ankiweb.net/shared/info/31746032
- note has built-in support with this due to providing all the typescript
.map
files - one can view source typescript code and debug with breakpoints all in Anki
"},{"location":"moddingtips/#custom-runtime-options","title":"Custom Runtime Options","text":"The runtime options file (default: config/jpmn_opts.jsonc
) can be specified at build time.
If you are working with modding the note, it is recommended that you create your own runtime options file, so you can edit the options at build time, while ensuring your runtime options file is up to date.
Here is how you can create and use a custom runtime options file:
-
Create the local runtime options file (e.g. user_jpmn_opts.jsonc
)
cd config\ncp jpmn_opts.jsonc user_jpmn_opts.jsonc\n
-
Change opts-path
under config/config.py
:
\"opts-path\": \"user_jpmn_opts.jsonc\",\n
-
(optional) Make the runtime options hard-coded to remove the file dependency during runtime, by changing the following setting in config/config.py
:
\"compile-options\": {\n \"hardcoded-runtime-options\": True,\n}\n
-
Build and install the note as normal.
Note
If you are not using hard-coded runtime options and you have edited the contents of the local runtime options file, please run the installation script with --install-options
to replace the existing options file in Anki's media folder.
"},{"location":"moddingtips/#field-list-editing","title":"Field List Editing","text":"This section describes import PSAs on what you should you if you want to edit the fields of the note (i.e. adding, removing, renaming, and moving).
Fields editing in this context refers to the fields that you can edit in the Fields
(list) menu, found under (Main window) \u2192 Browse
\u2192 Fields...
.
Note
If you never plan on updating the note, you can safely modify the field list to your heart's content, and ignore the rest of this section.
"},{"location":"moddingtips/#installer-details","title":"Installer details","text":"The installer, when detecting a higher version, attempts to find and apply any changes to the field list when necessary. These changes are specified under tools/note_changes.py
.
By default, the installer expects the field list to be completely un-changed after installation, and does many checks to verify this before and after installation.
"},{"location":"moddingtips/#do-not-remove-fields","title":"Do not remove fields","text":"One of the checks that the installer does is to ensure that all fields are present. This is a design choice to remove as many assumptions as possible, so that it is easier for the installer to update the note.
Note
This design choice may be changed in the future, but will likely remain until the end of the beta release.
If you want to remove a field, the best alternative is to do the following:
- Move the field below the
Comment
field, so the field is out of your way. - Whenever you decide to update the note to a new version, run the installation script with the
--ignore-order
flag.
"},{"location":"moddingtips/#do-not-rename-fields","title":"Do not rename fields","text":"There is currently no way to let the installer know that you renamed a field. Therefore, you should not rename fields at all, as this will cause the initial field list check to fail.
If you are completely insistent on renaming a field, you must change all templates that uses the field to match your preferred field name.
Note
Similarily to the above, this may be changed in the future, but will likely remain until the end of the beta release.
"},{"location":"moddingtips/#how-to-add-reorder-fields","title":"How to add & reorder fields","text":"If you want to add a field while preserving the existing field order upon updates, add the field under the Comment
field. This is because the installer only checks the subset of fields above the Comment
field, when verifying correctness.
If you don't care about preserving field order, you can simply add the field anywhere you want, and then run the installation script with --ignore-order
whenever you want to update the note to a new version.
"},{"location":"moddingtips/#javascript-print-statements","title":"Javascript print statements","text":"Anki doesn't come with a way to use console.log()
normally, so I made one myself.
// global logger\nLOGGER.error(\"message\");\nLOGGER.warn(\"message\");\nLOGGER.info(\"message\");\nLOGGER.debug(\"message\");\n// module-specific logger\nconst logger = JPMNLogger(\"module-name\");\nlogger.error(\"message\");\nlogger.warn(\"message\");\nlogger.info(\"message\");\nlogger.debug(\"message\");\n
The above functions prints a message of the given log level to the info circle. To see the message, hover over the info circle.
To use the debug
function, make sure that the debug
option is set to true
in the javascript options.
"},{"location":"moddingtips/#avoid-asynchronous-javascript-features-in-anki","title":"Avoid asynchronous javascript features in Anki","text":"Example Asynchronous Javascript <script>\n// Example 1: normal asynchronous functions\nasync function runMeAsynchronously() {\n// ...\n}\n// Example 2: promises\nfunction giveMeAPromise() {\nreturn new Promise((resolve, reject) => {\nsetTimeout(() => {\nresolve(\"Success!\");\n}, 1000);\n});\n}\ngiveMeAPromise().then(() => {\nLOGGER.warn(\"The promise is complete!\", unique=false);\n});\n</script>\n<!-- Example 3: anything wrapped in type=\"module\" -->\n<script type=\"module\">\n// everything here is run asynchronously\n// ...\n</script>\n
TODO reason:
- functions can be executed multiple times
- reproducible way: use example 2 on both the front/back side of the card, and switch sides quickly
- should be two warnings
- but worst case is for cases which I don't know how to reproduce
- rarely, asynchronous functions run more than once
- it seems like anki randomly loads the page twice, causing all asynchronous functions to also run twice
- including the async functions defined currently in modules like
kanji-hover
- to cirumvent having their actions done twice, define the affected elements outside the asynchronous section
- the function still runs twice (so any side-effects of the function will still happen)
- however, other instances of the function should not work on the elements defined outside
-
additionally, many modules require things to be loaded before the card is shown
- Anki displays the page only when all of the synchronous javascript is ran
- If these become asynchronous, the user will be able to see split-second changes to the layout as the javascript is running
- Two solutions to this:
- (1) To only show the page when specific asynchronous functions are complete, the entire page must be hidden, with say, a
hidden
class on the <body>
element - Problem: if the main javascript fails, then you will get a blank page!
- making this approach very risky
- (2) Avoid asynchronous functions alltogether
-
avoiding asynchronous features makes things more predictable within anki
Example (safer) asynchronous javascript let ele = document.getElementById(\"example\");\nasync function runMeAsynchronously() {\n// ...\nele.innerText += \"this should only appear once!\";\n}\n
"},{"location":"modules/","title":"Custom JS (Modules) (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"modules/#overview","title":"Overview","text":"Modules (not to be confused with regular javascript modules) is a hybrid template/javascript system that allows code separation at the file level, but allows the javascript to be compiled into each template, rather than separate files.
The biggest advantage of this over a monolithic system is that individual modules can be enabled, disabled, created, and modified at ease, all without editing the source files.
"},{"location":"modules/#example-hello-world","title":"Example (Hello World)","text":"The following will enable a the hello world module, which prints a \"Hello world!\" at the front of any card (as a warning on the info circle).
-
Under config/config.py
, add \"example\"
to enabled-modules
.
\"compile-options\": {\n \"allow-user-defined-modules\": True,\n\n \"enabled-modules\": [\n ...\n \"customize-open-fields\", # Make sure a comma is here!\n \"example\"\n ]\n},\n
-
Under config/jpmn_opts.jsonc
(or more preferably, your own options file specified under opts-path
in config.py
), add the following:
\"modules\": {\n \"customize-open-fields\": {\n ...\n }, // Make sure there is a comma here!\n\n \"example\": {\n \"enabled\": true\n }\n}\n
-
Rebuild the note, and preview any card. The front side of any card should have a \"Hello world!\" warning, while the back side should remain normal.
"},{"location":"modules/#quickstart","title":"Quickstart","text":"If you want to get to inserting your own javascript as soon as possible, do the following:
- Follow the steps of the example above, and make sure the example module is working.
-
Copy the example
module into overrides/modules
.
This should result in the following file structure:
overrides\n L modules\n L example\n L main.html\n L main.js\n
From here, all you have to do is edit the main.js
and main.html
to your liking.
Note
The js
module is of type JavascriptContainer
, which is defined under tools/make.py
. This interface allows you to define javascript within certain parts of a card, and restrict it to a certain subset of templates (sides and card types). Please see the aformentioned file to view the existing interface. Likewise, see the base javascript file (src/jp-mining-note/base.js
) to view how the interface is used.
If you want more detailed explanations on what has been happening up until this point, continue reading below.
"},{"location":"modules/#enabling-disabling-modules","title":"Enabling & Disabling Modules","text":"Modules can be easily enabled and disabled by modifying the enabled-modules
option under config/config.py
. Comment out any existing module, or add any modules you want to the list.
Additionally, if you are using modules outside the default modules that come enabled with the note (including the example
module), the allow-user-defined-modules
option should be set to True
.
"},{"location":"modules/#modding-existing-modules","title":"Modding Existing Modules","text":"Modules can be defined in the same style as the template overrides above. This means that if you want to edit a module, you can simply override the module files themselves by copying the module folder into overrides/modules
folder.
For example, if you want to override the auto-pitch-accent
module, copy the auto-pitch-accent
folder into overrides/module/auto-pitch-accent
.
Note
In the quickstart, we did exactly this with the example
module. Since the example module is completely overwritten by the user, the previous example module code is completely ignored.
"},{"location":"modules/#creating-more-modules","title":"Creating More Modules","text":"The easiest way to create a new module is by copying the example
folder, and renaming it to something different. This folder should be placed under overrides/modules
under most cases. However, if you are looking to contribute to the project, place this under src/modules
instead.
Certain parts of the code should be renamed as well to avoid conflicts with the existing example
module, including the MOD.id
, import path, JPMNLogger
constructor, and runtime option call (utils.opt
).
Of course, make sure all the renames are consistent. For example, all of the following should be the same:
MOD.id
- module folder name
JPMNLogger
constructor argument
Afterwards, make sure to add the module id to enabled-modules
, and ensure that allow-user-defined-modules
is set to True
.
If everything is done correctly, the note should include your custom module after the next build!
"},{"location":"modules/#why-not-just-separate-the-code-with-files","title":"Why not just separate the code with files?","text":"Short answer: In an attempt to keep the card as stable as possible between versions.
Long answer: Anki specifically states this in its official documentation:
Quote
Javascript functionality is provided without any support or warranty.
Many javascript-related things seem to behave strangely in Anki, which prevents the ability to separate files easily. Here have been the solutions I have tried before moving to this approach:
Link an external script with the <script>
tag There are two main problems with this approach:
-
On older Anki versions (2.1.49 and below), all <script>
tags loads asynchronously compared to each other.
This means if any file must be ran before a file is loaded, then the script would fail.
On versions 2.1.50 and above, it appears that Anki loads <script>
tags synchronously. However, there is no guarantee that this will be the case for the future.
-
Certain javascript in the main template has to be ran before loading in any file.
This requirement exists for this note type due to the runtime-options file exists. The global JPMNOpts
has to exist for any external files that uses runtime options to work.
This can be fixed by importing the options separately for each file, but that naturally leads us to the examples shown in the following section.
Regular imports within Javascript All other examples of importing without a separate <script src=\"...\">
requires asynchronous javascript features, which should be avoided as much as possible.
Examples:
<script>\n// https://forums.ankiweb.net/t/linking-to-external-javascript/1713\nvar injectScript = (src) => {\nreturn new Promise((resolve, reject) => { // a Promise is an asynchronous feature!\nconst script = document.createElement('script');\nscript.src = src;\nscript.async = true;\nscript.onload = resolve;\nscript.onerror = reject;\ndocument.head.appendChild(script);\n});\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import\n// this import function is an asynchronous function!\n(async () => {\nawait import(\"/modules/my-module.js\");\n// ...\n})();\n</script>\n<!-- type=\"module\" forces this entire script to run asynchronously! -->\n<script type=\"module\">\n// for the `import` statement to work, the script must be of type=\"module\"\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import\nimport { export1 } from \"module-name\";\n</script>\n
In conclusion, this is a design decision made after lots of trial and error when attempting to work with Anki's Javascript parser.
I believe this is the best way to ensure that the note stays resilient across Anki updates, as the javascript itself has very few hacks to get it to behave well.
"},{"location":"other/","title":"Other (TODO)","text":""},{"location":"other/#design-decisions","title":"Design Decisions","text":""},{"location":"other/#pc-template-design-decisions","title":"PC Template Design Decisions","text":" - everything should be available to the user even for words with very long definitions
- the definitions are below everything specifically due to that
- potential issue: people who speed through cards
- potential solution: use theme
- front side has no guarantee to be consistent
- thus, for vocab cards, the word is repeated again below the line
- similarly, for sentence cards, the sentence is repeated again
- also see: cardtypes.md
- word and pitch accent are on separate lines
- because both can expand very far to the left/right
- minimize vertical space taken from word info / image
- if certain elements are removed, can result in an uneven shape
- however, this is preferable over an even shape because it minimizes vertical space
- TODO option to have a consistent shape?
"},{"location":"other/#mobile-template-design-decisions","title":"Mobile Template Design Decisions","text":" -
make definition show up ASAP, i.e. by the first quarter of the screen
-
this means elements that were previously above the definition on the PC version, like the audio buttons, image, and sentence, is now below the definition
-
unfortunately, putting the sentence above the definition can easily take up a lot of room
- the limited space for mobile users makes placing the definition above the sentence actually more important, otherwise the sentence can easily push down the bulk of the definition (and thus you must scroll to see the definition)
- comes at the cost of potentially not being able to see the sentence without scrolling
-
the image is small by design
- otherwise, will take up too much room or will require scrolling to see
- goal is to always be able to immediately see the image on card flip
-
replace collapsible sections with tabs for easier mobile navigation, and to prevent unnecessary scrolling
"},{"location":"other/#comment-field","title":"Comment
field","text":"Similarly to the Key
field, this field will not be used in any card template. In other words, this is a place where you can write down notes without affecting the card itself. I personally like using this field to test handlebars from Yomichan.
This is named Comment
in reference to comments in code (comments do not change the execution of the code).
"},{"location":"other/#remove-the-na-on-cards-with-no-pitch-accents","title":"Remove the \"(N/A)\" on cards with no pitch accents","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
If the word has no pitch accent, the pitch accent is usually displayed as (N/A)
. This indicator can be removed with the following CSS:
.dh-left__word-pitch-text:empty:before {\ncontent: \"\"\n}\n
"},{"location":"other/#removing-the-furigana-on-the-word-reading","title":"Removing the furigana on the word reading","text":"TODO image
The following CSS removes the furigana on the word reading, while keeping the furigana on the kanjis within hover.
.dh-left__reading > ruby > rt {\ndisplay: none;\n}\n
"},{"location":"other/#changing-colors","title":"Changing colors","text":"Most color changes can be done by simply overriding a CSS variable. These variables are shown at the very top of the main CSS sheet. For example, --accent
is the variable that specifies the main accent color of the card, as well as the color of the text when bolded. To override this variable, place this at the end of the styles sheet:
:root {\n--accent: #ff1fd1; /* hot pink */\n}\n.night_mode {\n--accent: #ff7777; /* light red */\n}\n
Warning
To change any variable color for dark mode, you cannot use :root
, even if you are only setting the color for night mode. You must use .night_mode
.
For example, doing the following will NOT change the accent for night mode:
:root {\n/* only changes light mode accent, and will NOT change dark mode accent! */\n--accent: #ff7777;\n}\n
You must do this instead:
/* changes the color for both light and dark mode */\n:root {\n--accent: #ff7777;\n}\n.night_mode {\n--accent: #ff7777;\n}\n
"},{"location":"other/#removing-the-word-sentence-at-the-top-of-the-back-side","title":"Removing the word / sentence at the top of the back side","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Hidden tested contentShown tested content (default) TODO image
TODO image
For users who are only using one card type (e.g. only vocab cards with no sentence cards, TSCs, or anything else), it might be better to remove the tested content and the line below it.
The tested content is shown at the back by default to allow the user to differentiate between card types on both sides of the card. However, this take up extra vertical space which is unnecessary if you are only using one card type. This can be hidden with the following CSS:
.jpmn--back > .card-main .expression-wrapper {\ndisplay: none;\n}\n.jpmn--back > .card-main .answer-border {\ndisplay: none;\n}\n
"},{"location":"other/#mobile-unbolded-text","title":"Mobile Unbolded Text","text":"By default, most text that would be bolded on desktop is unbolded in mobile. This is because the bolded text makes the kanji feel much more squished together, especially on Android where the custom bold font cannot be used. Additionally, the bolded text is still highlighted in the accent color of the note, so the text still stands out compared to other text.
If you want to bold the text again, use the following CSS:
(TODO link to extra/style.scss and all)
@media (max-width: 620px) {\n :root {\n --bold-font-weight: bold;\n }\n}\n
"},{"location":"overrides/","title":"Custom HTML (Overrides) (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"overrides/#overview","title":"Overview","text":"An easy way to override and extend parts of the card templates is by using an overrides
folder. This folder (specified under config.py
under the templates-override-folder
option) allows you to override any file under the src
folder (outside of scss
files).
Primarily, this allows you to override sections of template code found under src/jp-mining-note
, such as src/jp-mining-note/partials/hint.html
.
The structure of the overrides
folder must match the structure in the src
folder. For example, if you want to override the hint file (src/jp-mining-note/partials/hint.html
), the new file must be created under overrides/jp-mining-note/partials/hint.html
"},{"location":"overrides/#example-add-external-links","title":"Example (Add external links)","text":"Warning
The following is deprecated starting from Version 0.10.3.0. Version 0.10.3.0 allows the user to customize external links in the compile options (config.py
).
This is only here to serve as a placeholder example (while I try to think of other practical examples people would use). Let me know if you have any ideas!
Let's say we want to rewrite the Extra Info
section to have external links that search for the tested word.
-
Look for the partial within the src
folder. This leads us to the src/jp-mining-note/partials/extra_info.html
file.
-
Override the partial. Now that we know the location of the partial, we create the same file in overrides
. This new file should be of the path overrides/jp-mining-note/partials/extra_info.html
.
-
Write the code. Using the partial under src
as an example, the following code is a modified version of the original HTML where we removed the dependency on the PAGraphs
and UtilityDictionaries
fields. Additionally, at the very bottom, a link to Jisho and Yourei is provided.
Copy and paste the code below to your newly created file (overrides/jp-mining-note/partials/extra_info.html
).
Extra Info with External Links <details class=\"glossary-details glossary-details--small\" id=\"extra_info_details\">\n<summary>Extra Info</summary>\n<blockquote class=\"glossary-blockquote glossary-blockquote--small highlight-bold\">\n<div class=\"glossary-text glossary-text--extra-info\">\n{% call IF(\"PAGraphs\") %}\n<div class=\"pa-graphs\">\n{{ T(\"PAGraphs\") }}\n</div>\n{% endcall %}\n{% call IF(\"UtilityDictionaries\") %}\n<div class=\"utility-dicts\">\n{{ T(\"UtilityDictionaries\") }}\n</div>\n{% endcall %}\n<a href=\"https://jisho.org/search/{{ T('Word') }}\">\u8f9e\u66f8</a\n>\u30fb<a href=\"http://yourei.jp/{{ T('Word') }}\">\u7528\u4f8b</a>\n</div>\n</blockquote>\n</details>\n
-
Rebuild and reinstall the template. After rebuilding and reinstalling, your Extra Info
section should now have two links at the bottom.
"},{"location":"personalsetup/","title":"Personalsetup","text":"Welcome to my (hidden) personal setup page! This section is very likely outdated and is not very easy to go through.
If you want to use this note type, I recommend looking at other pages of the wiki.
"},{"location":"personalsetup/#texthooker-css-renji","title":"Texthooker CSS (Renji)","text":"main > p {\n padding: 0rem !important;\n}\n\nmain {\n padding-left: min(5%, 5rem) !important;\n padding-right: min(5%, 5rem) !important;\n font-family: \"Noto Sans CJK JP\" !important;\n}\n
"},{"location":"personalsetup/#anki","title":"Anki","text":"plugins:
1344485230 1225470483 2055492159 580654285
- ajt furigana / ajt pitch accent / ankiconnect / local forvo
- config under normal setup page
- custom audio sources:
http://localhost:8770/?expression={expression}&reading={reading}
- local audio plugin w/ sqlite
- get audio zips from existing computer / backup
.\n\u251c\u2500\u2500 jpod_alternate_files\n\u2502 \u2514\u2500\u2500 \u3088\u3080 - \u8aad\u3080.mp3\n\u2502 \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 jpod_files\n\u2502 \u2514\u2500\u2500 \u3088\u3080 - \u8aad\u3080.mp3\n\u2502 \u2514\u2500\u2500 ...\n\u2514\u2500\u2500 nhk16_files\n \u251c\u2500\u2500 audio\n \u2502 \u2514\u2500\u2500 20170616125910.aac\n \u2502 \u2514\u2500\u2500 ...\n \u2514\u2500\u2500 entries.json\n
- forvo plugin
"},{"location":"personalsetup/#yomichan","title":"Yomichan","text":" - import settings from an existing computer / backup drive
- TMW dicts
- Yomichan settings \u2192 \"Popup Appearance\":
- \"Compact glossaries\": on
- \"Compact tags\": off,
monolingual:
- hold shift: bilingual (at any level)
- mouseover: monolingual
monolingual shift:
- hold shift:
- access monolingual at first level
- bilingual at all other levels
- mouseover to access monolingual at other levels
bilingual:
- mouseover: bilingual
pa:
- hold shift: pitch accent and utilities
{{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n{{~#set \"ignored-dict-regex\"~}} ^(\u65b0\u548c\u82f1)$ {{~/set~}}\n{{~set \"opt-jmdict-list-format\" false ~}} {{~! still using regular jmdict ~}}\n
"},{"location":"personalsetup/#monolingual-profile","title":"monolingual profile","text":" - scale: 110%
- condition: modifier keys are shift
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\nli.definition-item[data-dictionary='NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)']:hover .gloss-list {\nopacity: 1;\n}\n
"},{"location":"personalsetup/#other-monolingual-profiles","title":"other monolingual profiles","text":"URL - Matches Domain - doc.rust-jp.rs\n - tag: rust\n - scale: 90%\n
"},{"location":"personalsetup/#bilingual-profile","title":"bilingual profile","text":" - scale: 100%
- NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178 and \u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003 should have lower priority compared to bilingual dicts
- condition: modifier keys are ctrl
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\nli.definition-item[data-dictionary='\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6f22\u5b57\u6e90'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b9f\u7528\u65e5\u672c\u8a9e\u8868\u73fe\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b66\u7814 \u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u4e09\u7701\u5802\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u4fd7\u8a9e\u8f9e\u66f8'] {\ndisplay: none;\n}\n
"},{"location":"personalsetup/#pa-and-grammar-profile","title":"PA and grammar profile","text":" - scale: 100%
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\nli.definition-item[data-dictionary='\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6f22\u5b57\u6e90'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b9f\u7528\u65e5\u672c\u8a9e\u8868\u73fe\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b66\u7814 \u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u4e09\u7701\u5802\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u4fd7\u8a9e\u8f9e\u66f8'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='Nico/Pixiv'] {\ndisplay: none;\n}\n
"},{"location":"personalsetup/#phone-profile","title":"Phone profile","text":" - \u65b0\u548c\u82f1 is not installed on the phone
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\n/* Only shows the first freq list */\nspan.frequency-group-item:nth-child(n+2) {\ndisplay: none;\n}\nli.definition-item[data-dictionary='NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)']:hover .gloss-list {\nopacity: 1;\n}\n
"},{"location":"personalsetup/#yomichan-fields","title":"Yomichan Fields","text":"Example Anki Fields Yomichan Format Key {expression} Word {expression} WordReading {furigana-plain} PAOverride PAOverrideText AJTWordPitch PrimaryDefinition {jpmn-primary-definition} PrimaryDefinitionPicture Sentence {cloze-prefix}{cloze-body}{cloze-suffix} SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden IsSentenceCard {jpmn-is-sentence-card} IsTargetedSentenceCard IsClickCard {jpmn-is-click-card} IsHoverCard IsHintCard {jpmn-is-hint-card} IsSentenceFirstCard IsAudioCard PAShowInfo 1 PATestOnlyWord 1 PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture WordAudio {audio} SentenceAudio PAGraphs {jpmn-pitch-accent-graphs} PAPositions {jpmn-pitch-accent-positions} FrequenciesStylized {jpmn-frequencies} FrequencySort {jpmn-frequency-sort} PASilence [sound:_silence.wav] WordReadingHiragana {jpmn-word-reading-hiragana} YomichanWordTags {tags} SecondaryDefinition {jpmn-secondary-definition} ExtraDefinitions {jpmn-extra-definitions} UtilityDictionaries {jpmn-utility-dictionaries} CardCache Comment DICTIONARY:\u300c{_jpmn-get-primary-definition-dict}\u300dSELECTION:\u300c{_jpmn-selection-text}\u300d"},{"location":"personalsetup/#discord","title":"Discord","text":""},{"location":"personalsetup/#custom-css","title":"Custom CSS","text":":lang(ja), :lang(ja-JP) {\n--font-primary: Whitney, \"Noto Sans CJK JP\", \"Hiragino Sans\", \"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\"\u30e1\u30a4\u30ea\u30aa\",Meiryo,Osaka,\"MS PGothic\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n}\ncode {\nfont-family: Ubuntu Mono, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, Consolas,Andale Mono WT,Andale Mono,Lucida Console,Lucida Sans Typewriter,DejaVu Sans Mono,Bitstream Vera Sans Mono,Liberation Mono,Nimbus Mono L,Monaco,Courier New,Courier,monospace !important;\n}\n
"},{"location":"personalsetup/#mobile-changes","title":"Mobile Changes","text":" - the following are notes of what to change for mobile support
- nothing is set in stone, etc. etc. things are likely not even implemented yet
"},{"location":"personalsetup/#other","title":"Other","text":" - TMW github source since I keep losing this link
"},{"location":"preface/","title":"Preface","text":"Before committing and going through the setup process, it would be best to make sure that the note aligns with exactly what you want.
"},{"location":"preface/#why-you-would-not-want-to-use-jp-mining-note","title":"Why you would NOT want to use jp-mining-note","text":" - You have an existing setup and are happy with it.
- You want to study only from pre-made decks (or are not willing to spend the time to import notes into this template).
- You want to use this template to study something outside of Japanese.
- You want an extremely minimal template, with little/no javascript.
- You do not like its overall layout, and are not willing to customize the note to suit your needs.1
- You are not comfortable with bearing a slightly higher maintenance cost than most other setups.2
"},{"location":"preface/#why-you-would-want-to-use-jp-mining-note","title":"Why you would want to use jp-mining-note","text":" - You agree with jp-mining-note's philosophy.
"},{"location":"preface/#alternatives","title":"Alternatives","text":"There are many, many Anki templates out there in the wild. This page is my attempt to assemble together some of the the popular and/or interesting card templates.
If you are not satisfied with this template, or are not interested in using this template, feel free to refer to the above list of alternatives. Of course, you can always create one from scratch, or modify any of these notes to your heart's content.
"},{"location":"preface/#supported-systems","title":"Supported Systems","text":"The most important step is to see if jp-mining-note (JPMN) works on your device.
"},{"location":"preface/#card-creation-yomichan","title":"Card Creation (Yomichan)","text":"The card creation process requires a working instance of Yomichan, Anki-Connect, and Anki.
By default, this works on PC (Windows, Mac, Linux), and the instructions shown will be for PC. However, with the proper setup, one can also create cards on the following platforms:
- Android (including Android based e-readers such as ONYX BOOX)
- Kindle (export a list of sentences to the PC to manually create)
I'm not aware of a workflow for iOS that works with Yomichan.
Note
JPMN currently requires Yomichan to create the Anki cards. As common as Yomichan is, this dependency to Yomichan can be considered a weakness (especially now that Yomichan is no longer getting updates).
There are many popular setups out there that do not use Yomichan and instead have their own card exporter, such as JL and jidoujisho.
It is almost guaranteed that one can create JPMN cards with these card exporters. However, it is also almost guaranteed that various minor features will likely be missing.
In the future, more workarounds will be developed to work with alternative card exporters.
"},{"location":"preface/#anki-desktop","title":"Anki Desktop","text":"This note supports Anki versions 2.1.50 and above, with primary support given to the latest stable Anki versions (23.10.1+ & Qt6).
It is important to note that this note is no longer supported for Anki versions 2.1.49 or older. There are certain features that are known to break on these versions.
"},{"location":"preface/#mobile-ankidroid-and-ankimobile","title":"Mobile (AnkiDroid and AnkiMobile)","text":"JPMN finally supports AnkiDroid and AnkiMobile, and comes with a new interface specifically designed for mobile devices.
However, there are some limitations on mobile. Mainly, anything requiring Anki-Connect within the note (kanji hover and word indicators) will not work. The current workaround is to cache the tooltip results.
"},{"location":"preface/#ankiweb","title":"AnkiWeb","text":"JPMN is not tested on AnkiWeb, and there are currently no plans to support AnkiWeb.
"},{"location":"preface/#themes","title":"Themes","text":"Both light mode and dark mode are supported. The note's theme changes accordingly with your Anki theme.
"},{"location":"preface/#updating","title":"Updating","text":"If you ever wish to update the note, this can only be done on PC, and cannot be done on mobile. The note does not auto-update; it must be done manually.
"},{"location":"preface/#setup","title":"Setup","text":"Excited to take this note on a whirl?
Click here to set it up!
-
Most minor things, such as colors, font size, etc. can be customized fairly easily with custom CSS. However, customizing the overall layout (i.e. customizing where the image is placed relative to the word), requires a lot more technical skill. Alternatively, if plan on using a custom theme within the themes
folder, these require you to build the note, which at least requires basic knowlwedge of command line.\u00a0\u21a9
-
In general, this template is a little more fragile than other templates due to its heavy usage of JavaScript. This is combined with updates to Anki and external add-ons. These updates have been known to break a bit more compared to other setups, and usually require some user intervention to deal with (whether it is updating the note, or manually changing some settings outside the note). If something breaks and a fix is released, they will usually be recorded under Setup Changes.
Note that updating the template itself has been smoothlined as much as possible, due to JPMN Manager.\u00a0\u21a9
"},{"location":"principles/","title":"Philosophy","text":""},{"location":"principles/#made-for-japanese-learning","title":"Made for Japanese Learning","text":"The absolute fundamental goal of this note type is to make learning Japanese easier. Every feature you see is to simply make this learning process easier and smoother.
"},{"location":"principles/#minimalistic-design","title":"Minimalistic Design","text":"This note is visually designed to be minimalistic because the fundamental goal is to learn Japanese, not to have eye catching graphics. The main focus is on the content, not the fluff.
"},{"location":"principles/#minimal-dependencies","title":"Minimal Dependencies","text":"The only fundamental dependencies are Yomichan
(to create the note) and the Anki-Connect
add-on (to export the note from Yomichan
, update the note, and for certain features to work within the note). Absolutely nothing else is required. This helps with maintaining stability across various Anki versions.
"},{"location":"principles/#modularized-customizable-extendable","title":"Modularized, Customizable & Extendable","text":"This project ships with built-in tools to easily disable/enable features, or even completely remove them from the base template via compile options. Additionally, there are many built-in ways to extend the note to suit your exact needs.
"},{"location":"principles/#documentation-first","title":"Documentation First","text":"What's the point of having a powerful tool if you don't know how to use it? Lots of time has been spent in order to make sure that this note type is well documented and updated so you can use it to the best of your ability.
"},{"location":"principles/#free-open-source","title":"Free & Open Source","text":"Everything here, including the documentation itself, is completely free and open source, licensed under MIT. Rest easy knowing you will keep full ownership of your note, forever.
"},{"location":"quickstart/","title":"Quick Start (TODO)","text":"Welcome to jp-mining-note's quick start page! This page summarizes the main features that jp-mining-note has to offer, as well as common changes that people may want to make with the note.
"},{"location":"quickstart/#ui-summary","title":"UI Summary","text":""},{"location":"quickstart/#ui-summary-front","title":"UI Summary: Front","text":"(TODO image front)
The front side of the card was designed to be as minimal as possible. Information such as tags, source, frequency, reading, audio, etc. are not shown here, by design.
Tested contentCard typeInfo Circle This can be a sentence, word, etc. depending on the card type.
This simply describes exactly what the card type is.
Hovering over the info circle displays a tooltip that contains general infomation about the note type. When the info circle is not grey, this acts as a notifications window to the user. (TODO link)
You may notice some buttons to the top left. These are explained here TODO.
"},{"location":"quickstart/#ui-summary-back","title":"UI Summary: Back","text":"(TODO image back)
Compared to the front side of the card, the back side was designed to contain as much as information as possible. However, only the important information is shown by default, while all the auxilary information is hidden behind various tooltips and dropdowns.
Tested contentFrequencyWord boxMain imagePrimary DefinitionBlockquotes The tested content is repeated on the back side of the card, and is separated by a line.
Contains the value in the FrequencySort
field. Hovering over the dropdown to the right should show all other frequencies, found in the FrequenciesStylized
field.
Contains the word, its reading, its pitch accent, and the word/sentence audio, in that order.
This is where the image from the Picture
field appears. If there is no picture, then the word box takes up the entire space.
This is where the text in PrimaryDefinition
, and optionally, the picture(s) in PrimaryDefinitionPicture
appears.
In general, this contains all the other information and dictionaries from Yomichan. See here for more info.
"},{"location":"quickstart/#ui-summary-mobile","title":"UI Summary: Mobile","text":"(TODO image, mark w/ numbers)
The interface for mobile should be mostly the same as the desktop. However, there are a few important differences to note:
- Collapsing sections, are replaced with tabs.
- The sentence appears below the definition instead of above.
- The audio buttons appear at the bottom left of the card, instead of right below the pitch accent.
See here TODO to see the reasons why these design decisions were made.
"},{"location":"quickstart/#changing-the-card-type","title":"Changing the Card Type","text":"Main Page: Changing Card Type
For the purposes of this documentation, the \"card type\" of a card refers to how the content is displayed and tested. For example, vocab cards and sentence cards are two different \"card types\".
In order to change the card type of any card:
(TODO video)
- Select any JPMN card within Anki's Card browser
- Within the card editor, fill in any binary field. For example, fill
IsSentenceCard
with 1
. - Preview the card. You should now see that the card is a sentence card!
As you can tell, this only changes the card type for one individual card. Of course, this does not mean you must manually edit each individual card to change its card type!
- If you want to change the default card type (i.e. change the card type for all new/future cards), see here.
- If you want to change the card type for all currently existing cards, see here.
- A comprehensive list of all possible card types can be found here.
"},{"location":"quickstart/#selecting-definitions","title":"Selecting Definitions","text":"Main Page: Definitions: Primary Definition Selection (Manual)
If you don't want to use the first bilingual/monolingual definition, you can select the dictionary or text that you want to use.
Here is exactly what's happening:
- 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.
"},{"location":"quickstart/#simplify-definitions","title":"Simplify Definitions","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
If you want to remove the list numbers, as well as the first line of most definitions, set the following runtime option:
\"blockquotes.simplifyDefinitions.enabled\": true,\n
SimpleDefault "},{"location":"quickstart/#kanji-hover","title":"Kanji Hover","text":"Main Page: Kanji Hover
Kanji hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
Note
Kanji hover does not show words outside of your collection.
"},{"location":"quickstart/#word-indicators","title":"Word Indicators","text":"Main Page: Word Indicators
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found.
\u540c (\u540c\u3058)\u8aad (\u8aad\u307f\u65b9)\u5b57 (\u6f22\u5b57) (TODO image)
This indicates the card is a duplicate.
(TODO update image)
This shows cards with the same reading, ignoring pitch accent (also known as \u540c\u97f3\u7570\u7fa9\u8a9e.) For example, the word \u81ea\u8eab is still shown, despite having a different pitch accent to \u5730\u9707.
(TODO image)
This indicates that there are other card(s) with the same kanji, but different reading.
"},{"location":"quickstart/#images-in-the-primary-definition","title":"Images in the Primary Definition","text":"Main Page: Images: Primary Definition Image TODO
DefaultPrimaryDefinitionPictureChanging the Default (TODO gif)
Images in the PrimaryDefinition
field are collapsed by default.
(TODO gif)
The main way to have images not be collapsed is by pasting the desired images in the PrimaryDefinitionPicture
field.
(TODO gif)
However, you may want existing images in PrimaryDefinition
to not be collapsed. To do this, there are two runtime options that you can set:
\"imgStylizer.glossary.primaryDef.mode.yomichan\": \"none\",\n\"imgStylizer.glossary.primaryDef.mode.user\": \"none\",\n
"},{"location":"quickstart/#image-blur","title":"Image Blur","text":"Main Page: Images: Image Blur
The main image can be blurred on specific cards, if desired.
This behavior is disabled by default, and must be manually enabled by setting the following runtime option to true
:
\"imgStylizer.mainImage.blur.enabled\": true,\n
After setting the runtime option, you can blur the image of any card by marking as NSFW. To mark a card as NSFW, add any of the following tags to the card:
nsfw
\u30fbNSFW
\u30fb-NSFW
"},{"location":"quickstart/#pitch-accent","title":"Pitch Accent","text":"Main Page: Pitch Accent
This note template displays pitch accent using binary pitch over katakana by default. If you don't know what pitch accent is, see here.
"},{"location":"quickstart/#pitch-accent-modification","title":"Pitch Accent Modification","text":"The displayed pitch accent is usually the first position found in PAPositions
. However, you can override this automatically chosen position using the PAOverride
field.
TODO update video with interface
"},{"location":"quickstart/#pitch-accent-coloring","title":"Pitch Accent Coloring","text":"Main Page: Pitch Accent
The card can be colored according to the pitch accent of the word, if desired.
This behavior is disabled by default, and must be manually enabled by setting the following runtime option to true
:
\"autoPitchAccent.coloredPitchAccent.enabled\": true,\n
TODO update video with new colors + interface
"},{"location":"quickstart/#other-common-changes","title":"Other Common Changes","text":""},{"location":"quickstart/#adjusting-zoom","title":"Adjusting Zoom","text":"You can increase (or decrease) the size of the card, (without affecting any of Anki's GUI) with custom CSS.
:root {\n/* Times 1.1 of the original size.\n * If you want to make the note smaller, use a value below 1, like 0.9.\n */\n--zoom: 1.1;\n}\n
"},{"location":"quickstart/#adjusting-font-size","title":"Adjusting Font Size","text":"In case overall zoom isn't enough, you can adjust the font sizes for individual sections of the card.
TODO list CSS variables
"},{"location":"quickstart/#changing-the-display-language","title":"Changing the display Language","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
By default, the display language is in English. Currently, Japanese and English are supported as display languages.
To change the display language (say, to Japanese), use the following compile option:
\"display-languages\": [\"jp\", \"en\"],\n
Note
Currently, only some text is supported. This means that various tooltips on hover, warning messages, etc. will still be in English.
"},{"location":"quickstart/#sorting-by-frequency","title":"Sorting by Frequency","text":"Main Page: Frequencies: Sorting by Frequency
This note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in his guide.
This note does not sort via frequency by default. It simply contains the frequency data so you can sort by frequency if you choose to do so. Visit Marv's guide (and scroll down to Usage
) to see how to sort and review your cards by frequency.
"},{"location":"quickstart/#key-field","title":"Key Field","text":"This field contains the tested word. In other words, this contains the exact same content as the Word
. However, this field is purposefully not displayed anywhere in the card template. This is so you can modify the key if duplicates arise, while still being able to test the word.
For example, if you want to test different usages of \u4e0a, you can change this key value to \u4e0a (preposition)
, \u4e0a (grammar)
, etc. and add a new card.
It is expected that this Key
field is unique for internal purposes; a warning will appear on cards that have a duplicate key.
"},{"location":"quickstart/#conclusion","title":"Conclusion","text":"Congratulations, you have reached the end of the Quick Start page, and are ready to use jp-mining-note to its fullest! If you did not find what you want within this page, feel free to look through the other pages on the left sidebar.
"},{"location":"runtimeoptions/","title":"Runtime Options (TODO)","text":"Runtime options are card options that are applied globally to all JPMN cards. This differs from binary fields, as binary fields are options that only affects the one card.
"},{"location":"runtimeoptions/#accessing-editing","title":"Accessing & Editing","text":"Video demo (click here) To access the runtime options, navigate to your profile's media folder, and open the _jpmn-options.js
file with your favorite text editor.
The contents of the file should look something like the following:
window.JPMNOptions = {\n// Add your runtime options here.\n// ...\n}\n
"},{"location":"runtimeoptions/#adding-options","title":"Adding Options","text":"You can add a runtime option anywhere between the two outer-most curly brackets. For example:
window.JPMNOptions = {\n// Add your runtime options here.\n\"autoPitchAccent.coloredPitchAccent.enabled\": true,\n// ...\n}\n
Note
You should only add options that you want to override. This is to allow the default options to change, which usually only happens if the old option is no longer valid due to implementation details. In the rare occasion that default options do change, they will be recorded in the changelog (TODO link changelog).
"},{"location":"runtimeoptions/#available-options","title":"Available options","text":"All available options can be found in the runtime_opts.json5 file. (TODO not dev branch!)
You can safely copy/paste anything there into your runtime options file.
Warning
This json5
file is, strictly speaking, NOT an example configuration file. There are a few differences between the runtime_opts.json5
file and the actual _jpmn-opts.js
configuration file:
runtime_opts.json5
does not have the window.JPMNOptions
variable set at the very top. -
runtime_opts.json5
has an additional overrides
key at the very bottom. This overrides
key is an implementation detail, and should NOT be used anywhere in the true configuration file.
The overrides
key contains a dictionary that overrides the true value of the original key/value pair defined. For example,
\"kanjiHover.enabled\": true,\n\"overrides\": {\n \"kanjiHover.enabled\": false,\n}\n
renders in the built card as:
\"kanjiHover.enabled\": false,\n
- TODO this info is outdated, refer to
rto_overrides.json5
"},{"location":"runtimeoptions/#override-options","title":"Override Options","text":"TODO link to tooltipresults? or visa versa?
There are a few option groups that can be used to override other options:
tooltips.overrideOptions.sentenceParser
tooltips.overrideOptions.autoPitchAccent
kanjiHover.overrideOptions.tooltips
wordIndicators.overrideOptions.tooltips
The tooltips internally use an instance of the sentence parser and auto pitch accent modules to display the content. However, one may want to display content differently in tooltips than in the regular card. If that is desired, these override options can be used to exactly define what options are used by the internal sentence parser, auto pitch accent and/or tooltips modules.
"},{"location":"runtimeoptions/#option-branch-values","title":"Option Branch Values","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
All runtime options are formatted as a key/value pair. A simple example is the following:
\"kanjiHover.enabled\": true,\n
In the above example, the key is kanjiHover.enabled
, whereas the value is true
.
All runtime options can take special values (known as \"option branch values\"), which are always formatted as the following:
{\n\"type\": \"IDENTIFIER_STRING\",\n// potentially extra arguments in \"args\": { ... }\n\"resultTrue\": VALUE,\n\"resultFalse\": VALUE,\n},\n
For example, we can change the above kanjiHover.enabled
to use this branch value, with type type of isMobile
:
This can be changed to:
\"kanjiHover.enabled\": {\n\"type\": \"isPC\",\n\"resultTrue\": true, // kanji hover is enabled on PC\n\"resultFalse\": false, // kanji hover is not enabled on non-PC devices, i.e. mobile\n},\n
A full list of option branch values is shown below. The source code for these can be found under src/ts/options.ts. (TODO not dev branch)
"},{"location":"runtimeoptions/#ismobile-and-ispc","title":"isMobile
and isPC
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
The isMobile
and isPC
type allows you to specify different values depending if you are using Anki on a mobile device, or PC (non-mobile).
\"key\": {\n\"type\": \"isMobile\",\n\"resultTrue\": VALUE_IF_MOBILE,\n\"resultFalse\": VALUE_IF_PC,\n},\n
isPC
is the exact opposite of isMobile
, and be used similarly.
\"key\": {\n\"type\": \"isPC\",\n\"resultTrue\": VALUE_IF_PC,\n\"resultFalse\": VALUE_IF_MOBILE,\n},\n
"},{"location":"runtimeoptions/#isiphoneipad","title":"isiPhoneiPad
","text":"TODO
"},{"location":"runtimeoptions/#viewportwidth","title":"viewportWidth
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
The viewportWidth
type allows you to specify different values depending on the screen width. Note that the viewport width is read for each card flip. This means that viewport width changes after resizing a window will not be detected, and will only be updated when you flip the side or go to a new card.
This is formatted as the following:
\"key\": {\n\"type\": \"viewportWidth\",\n\"args\": {\n\"op\": MATH_OP,\n\"value\": WIDTH,\n},\n\"resultTrue\": ...,\n\"resultFalse\": ...,\n},\n
TODO MATH_OP
and WIDTH
"},{"location":"runtimeoptions/#viewportwidthbreakpoint","title":"viewportWidthBreakpoint
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
\"key\": {\n\"type\": \"viewportWidthBreakpoint\",\n\"args\": {\n\"op\": MATH_OP,\n\"value\": BREAKPOINT_VAR,\n},\n\"resultTrue\": ...,\n\"resultFalse\": ...,\n},\n
BREAKPOINT_VAR
can be one of:
displaySentenceShrink
displaySentenceRemoveNewlines
maxWidthBackside
(tablet) combinePicture
(mobile)
"},{"location":"runtimeoptions/#cardtype","title":"cardType
","text":"TODO
"},{"location":"runtimeoptions/#cardside","title":"cardSide
","text":"TODO
"},{"location":"runtimeoptions/#fieldsallempty","title":"fieldsAllEmpty
","text":"TODO
"},{"location":"runtimeoptions/#fieldsallfilled","title":"fieldsAllFilled
","text":"TODO
"},{"location":"runtimeoptions/#fieldsanyfilled","title":"fieldsAnyFilled
","text":"TODO
"},{"location":"runtimeoptions/#troubleshooting","title":"Troubleshooting","text":"TODO record specific errors
If you have any error, or an option is simply not working, please check the following:
- If a runtime option is not working, or you get an error saying that an option doesn't exist, you may have an outdated option. Please check that your option is indeed recorded in the available options.
"},{"location":"scripts/","title":"Anki Hotkeys (TODO)","text":"This page serves as a collection of small Anki-related scripts primarily for the usage automating repetitive tasks with hotkeys.
It is separated into two main sections:
- ShareX Hotkeys: Hotkeys meant to be specifically used with media files generated from ShareX.
- Anki Hotkeys: General purpose hotkeys that act on the most recent card(s). Does not require media files to operate.
TODO demo
Note
The ShareX hotkeys are originally based off of Stegatxins0's Mining Setup. That was itself originally based off of AnimeCard's ShareX Setup.
"},{"location":"scripts/#sharex-hotkeys","title":"ShareX Hotkeys","text":"Windows users can use ShareX as a general purpose tool to automatically add images and audio to your most recently created card. There are two main hotkeys that this setup introduces:
- A screenshot hotkey
- An audio hotkey
Note
If you are using Linux, I recommend using ames instead of ShareX. Unfortunately, I'm not aware of a good solution for macOS users.
"},{"location":"scripts/#feature-summary","title":"Feature Summary","text":" - Audio is automatically normalized, and attempts to remove silence at the beginning of the audio.
- Images are saved as webp, to save disk space.
- The screenshot hotkey automatically adds the Window name as a tag to the card.
- Work with any note type, given that the correct flags are provided. By default, these work with jp-mining-note and AnimeCards.
- Instead of using PowerShell, this setup uses Python. Unfortunately, this is a little bit more difficult to setup for the average user, but using Python makes it much easier to develop and maintain the underlying scripts. Most people, including myself, know Python much more than PowerShell. Additionally, Python is generally cross platform and easy enough to setup on all operating systems.
"},{"location":"scripts/#sharex-hotkeys-prerequisites","title":"ShareX Hotkeys Prerequisites","text":"To use these hotkeys with ShareX, you must have the following installed:
- ShareX
- Python (Python 3.10 or above should work)
- Anki-Connect (You probably have this installed already if you're using Yomichan or jp-mining-note).
hotkey.py
(see below)
The hotkey.py
file can be downloaded in any of the following ways:
Option 1: JPMN Manager (click here) If you have JPMN Manager installed, then this script is already available to you! It is located under the Anki folder:
Anki2/addons21/301910299/tools/hotkey.py\n
Option 2: With git
(click here) For git
users, simply clone the JPMN repository in somewhere you'll remember:
git clone https://github.com/arbyste/jp-mining-note.git\n
The hotkey.py file will be found under (repo root)/tools/hotkey.py
. Option 3: Manually (click here) If none of the above works / you don't know what git
is:
- Navigate to a folder you'll remember.
- Right click on some blank space, and then create a new text file (
New
-> Text Document
). Name this text file hotkey.py
. - Copy the script text into the new text file, and save (
Ctrl+S
). TODO gif!
"},{"location":"scripts/#sharex-screenshot-hotkey","title":"ShareX Screenshot Hotkey","text":" -
Create the hotkey:
- Open ShareX, if you haven't already.
- On the sidebar to the left, click on
Hotkey settings...
. (TODO image) - Within the Hotkey Settings window, click
Add
. (TODO image) - Set the task to be
Screen capture
-> Capture region
. - Set the hotkey value to whatever you want. For example,
F6
.
(TODO gif)
-
Change the hotkey settings:
-
Click on the gear of your new Capture Region
hotkey. (TODO image)
-
Navigate to the Task
tab.
- Check
Override after capture settings
() - Navigate to the capture tasks dropdown, and only have the following two items selected:
- Save image to file
- Perform actions (TODO image)
- Check
Override screenshots folder
() - Click
Browse
and select your Anki collection media location. Your media location can be found under: C:\\Users\\YOUR_USER_NAME\\AppData\\Roaming\\Anki2\\YOUR_ANKI_PROFILE_NAME\\collection.media\n
Tip: An easy way to navigate to this is by entering %APPDATA%
in the path of the file browser. - To make it easier for you to remember what this hotkey does, set the
Description
to anki-screenshot
. Your Task
tab should now look something like this: (TODO image)
-
Navigate to the General
tab.
- Check
Override general settings
() (TODO image)
-
Navigate to the General
-> Notifications
tab.
- Uncheck
Play sound after capture is made
() - Uncheck
Play sound after task is completed
() The sound on screenshot is removed so one can take a screenshot while recording the audio, without having the screenshot sound affect the recording. (TODO image)
-
Add the ffmpeg-to-webp
action:
Explanation: This action saves the image as a webp image, to reduce file space while retaining the same quality. Unfortunately, as of writing this, ShareX does not support webp natively, so this action must be explicitly defined to save the image as a webp.
- Navigate to the
Actions
tab. - Check
Override actions
() - Click
Add...
. -
A new window should pop up. Under this new window, fill out the following values:
ffmpeg-to-webp action (click here) - Name:
ffmpeg-to-webp
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-i \"$input\" -quality 95 \"$output\"\n
- Output file name extension:
webp\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Add the card-add-image
action:
Explanation: This adds the image to the Anki card itself, using Anki-Connect and Python.
- Under the
Actions
tab, click Add...
. -
A new window should pop up. Under this new window, fill out the following values:
card-add-image action (click here) - Name:
card-add-image
- File path: (change the path to your exact path to
python.exe
) C:\\PATH\\TO\\YOUR\\PYTHON\\EXECUTABLE\\python.exe\n
- Your
python.exe
file is usually under C:\\PythonXX\\python.exe
, where XX
is the version number. If you can't find it, you can always search for python.exe
on the search bar, and then copying the full path of the file.
- Argument: (change the path to your exact path to
hotkey.py
) C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\"\n
- This is the
hotkey.py
file from the prerequisites step.
- Check
Hidden window
()
(TODO image)
Picture field
The expected name of the picture field is exactly Picture
. If your card uses a different field name, say Image
, then the --field-name
flag must be used (change Image
to whatever your field name is):
C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\" --field-name Image\n
TODO gif
-
Test the hotkey: TODO
"},{"location":"scripts/#sharex-screenshot-hotkey-nsfw","title":"ShareX Screenshot Hotkey (NSFW)","text":"For people using jp-mining-note or using Marv's Anki Card Blur, you might want to setup a different hotkey to specifically tag the card as NSFW when adding the image.
The following hotkey does the same as the above, while also adding the -NSFW
tag to the card.
- Duplicate the screenshot hotkey above, and set the hotkey to something else (i.e. Shift+F6)
- Navigate to the
Actions
tab. - Select
card-add-image
action. - Change the
Argument
to the following: C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\" --nsfw True\n
TODO gif
"},{"location":"scripts/#sharex-audio-hotkey","title":"ShareX Audio Hotkey","text":" -
Create the hotkey:
- Open ShareX, if you haven't already.
- On the sidebar to the left, click on
Hotkey settings...
. (TODO image) - Within the Hotkey Settings window, click
Add
. - Set the task to be
Screen record
-> Start/Stop screen recording using pre configured region
. - Set the hotkey value to whatever you want. For example,
F7
.
(TODO gif)
-
Change the hotkey settings:
-
Click on the gear of your new Start/Stop screen recording ...
hotkey. (TODO image)
-
Navigate to the Task
tab.
- Check
Override after capture settings
() - Navigate to the capture tasks dropdown, and only have the following two items selected:
- Save image to file
- Perform actions
- Check
Override screenshots folder
() - Click
Browse
and select your Anki collection media location. Your media location can be found under: C:\\Users\\YOUR_USER_NAME\\AppData\\Roaming\\Anki2\\YOUR_ANKI_PROFILE_NAME\\collection.media\n
This should be the exact same folder as the anki-screenshot
hotkey. - To make it easier for you to remember what this hotkey does, set the
Description
to anki-audio
.
Your Task
tab should now look something like this: (TODO image)
-
Navigate to the Capture
tab.
- Check
Override capture settings
() - Click
Select region
, and select anywhere on the screen. This region would preferably not overlap with whatever you want to capture. If it does and you attempt to screenshot while using the audio hotkey, then the dotted region marked by ShareX will be captured as well. (TODO image)
-
Navigate to the Capture
-> Screen recorder
tab. Within this, tab, click on the Screen recording options...
button to open a new window.
- Press the
Install recorder devices
button - Set
Video source
to None
- Set
Audio source
to virtual-audio-capturer
- Set
Audio codec
to Opus
(This will be configurable later) - Click on the
Opus
tab right underneath Audio codec
, and ensure the quality is set to 128k
. - Close this new window.
-
Add the process audio action(s):
Explanation: This adds a ffmpeg call to normalize the audio and remove the beginning silence. Ideally, we would put these audio filters in the Screen recording options
custom commands box. Unfortunately, if placed there, the flags to normalize the audio ends up cutting off the audio. Therefore, this action is required to accurately run the desired audio filters.
You have two options:
- Store as Opus. The Opus audio codec provides much better quality at lower bitrates (which saves a lot of space and makes syncing large collections faster). However, Opus is NOT compatible with AnkiMobile (iOS), Android 4, and AnkiWeb. If you use any of these, please use the 2nd option (MP3 audio) below.
- Store as MP3. Older and less efficient codec, but needed for compatibility with pretty much all devices.
Option 1. Opus (click here) Explanation: ShareX does not natively support storing audio as .wav or .flac files. ShareX does not provide a simply way to copy a file. FFmpeg does not allow us to read and write to the exact same file. Finally, ShareX cannot run the audio filters in the Screen recording options
custom commands box, as mentioned above. With all these limitations, the only way to store it as opus while running the audio filters is to first convert the file to something else (we use .wav), and then re-convert it back to opus again while applying the audio filters.
- Navigate to the
Actions
tab. - Check
Override actions
() -
Create the first action, by clicking Add...
. A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-wav action (click here) - Name:
ffmpeg-process-audio-wav
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -i \"$input\" \"$output\"\n
- Output file name extension:
wav\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Close the above ffmpeg-process-audio-wav
action window.
-
Create the second action, by clicking Add...
. A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-opus action (click here) - Name:
ffmpeg-process-audio-opus
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -c:a opus -i \"$input\" -af \"silenceremove=1:0:-50dB, loudnorm=I=-16:TP=-6.2:LRA=11:dual_mono=true\" -b:a 64k \"$output\"\n
- Output file name extension:
opus\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
Option 2. MP3 (click here) - Navigate to the
Actions
tab. - Check
Override actions
() - Click
Add...
. -
A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-mp3 action (click here) - Name:
ffmpeg-process-audio-mp3
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -i \"$input\" -af \"silenceremove=1:0:-50dB, loudnorm=I=-16:TP=-6.2:LRA=11:dual_mono=true\" -q:a 3 \"$output\"\n
- Output file name extension:
mp3\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Add the card-add-audio
action:
This adds the image to the Anki card itself.
- Under the
Actions
tab, click Add...
. -
A new window should pop up. Under this new window, fill out the following values:
card-add-audio action (click here) - Name:
card-add-audio
- File path: (change the path to your exact path to
python.exe
) C:\\PATH\\TO\\YOUR\\PYTHON\\EXECUTABLE\\python.exe\n
- Argument: (change the path to your exact path to
hotkey.py
) C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_audio \"$input\"\n
- These paths should be the exact same as the
card-add-audio
action within the anki-screenshot
hotkey.
- Check
Hidden window
()
(TODO image)
Sentence Audio field
The expected name of the sentence audio field is exactly SentenceAudio
. If your card uses a different field name, say SentAudio
, then the --field-name
flag must be used (change SentAudio
to whatever your field name is):
\"$input\" set_audio --field-name SentAudio\n
TODO gif
"},{"location":"scripts/#troubleshooting","title":"Troubleshooting","text":" -
Do NOT view the card in the card browser when running any script, because if you do, the affected fields may not update. Close the card browser before running the scripts.
However, you do not need to worry about this if you are running the python script with the --enable-gui-browse
flag.
"},{"location":"scripts/#other-hotkeys","title":"Other Hotkeys","text":"These are a set of scripts that may help you to prevent doing repetitive actions when adding notes.
Unlike the above, these scripts are not meant to be used with audio or picture files. Rather, they are stand-alone scripts that modify the most recent cards added.
These scripts are written in two formats: one that works automatically with your usual ShareX
setup, and one in Python for cross-platform portability.
"},{"location":"scripts/#how-to-running-with-sharex","title":"How-To: Running with ShareX","text":"As shown above, ShareX has the ability to run custom user scripts. However, for ShareX to only run the script and do nothing else, the hotkey must be configured with steps shown below.
"},{"location":"scripts/#steps","title":"Steps","text":"(TODO video)
- Under the main window, go to
Hotkey Settings
, and add a new hotkey. - Click on the settings icon (of the newly added hotkey).
- In the
Task
tab (to the left): - Set:
Task
to Screen capture
\u2192 Capture active window
- Check
Override After Capture Tasks
() - Under
After Capture
, un-check everything, and check the following: Save Image to File
Perform Actions
Delete Locally
- In the
Actions
tab (to the left): - Check
Override Actions
() - Uncheck all existing actions.
- Add a new action by clicking on
Add
. - Set the following values of the action:
- File Path:
C:\\PATH\\TO\\python.exe
- Argument:
C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py FUNCTION_NAME
Note
If you are adding multiple scripts with ShareX, instead of re-doing all of the steps above, you can instead duplicate the keybind, and simply set the Argument
of the action to a different function name.
Explanation of the setup (click here) The reason that the After Capture
settings include Save Image to File
and Delete Locally
is because without those settings, the Perform Actions
section doesn't appear to run. Fortunately, the combination of Save Image to File
and Delete Locally
means the hotkey does the following:
- Saves the image file
- Runs the custom script
- Deletes the image file
In other words, the image file is only temporarily created, and then deleted immediately after running the script. This effectively means that ShareX is only running the script whenever the keybind is used.
"},{"location":"scripts/#how-to-running-with-command-line","title":"How-To: Running with Command Line","text":"If you don't want to use ShareX, or you are not using Windows, you can simply run a python script with command line.
# Your python version should be 3.9 or higher.\n# It may work for lower python versions, but I make no guarantee.\npython3 /path/to/jp-mining-note/tools/hotkey.py FUNCTION_NAME\n
Examples (click here) # default\npython3 /path/to/jp-mining-note/tools/hotkey.py update_sentence\n\n# opens card browser automatically\npython3 /path/to/jp-mining-note/tools/hotkey.py update_sentence --enable-gui-browse\n
If you want to use these as keybinds, I will leave it up to you to determine how to do that (as there are too many different setups and programs that people can use to create keybinds). However, some tips for ShareX and AutoKey are given below.
"},{"location":"scripts/#how-to-running-with-autokey","title":"How-To: Running with AutoKey (Not AutoHotKey)","text":"If you are using AutoKey for Linux, it should be possible to do the following instead:
-
Go to: Settings
\u2192 Configure AutoKey
\u2192 Script Engine
\u2192 User Module file
\u2192 (add the jp-mining-note/tools
directory)
-
Create a script
type hotkey,
-
Within the script, run any function thusly:
import hotkey\nhotkey.FUNCTION_NAME()\n
Example:
import hotkey\nhotkey.update_sentence()\n
Example with GUI:
import hotkey\nhotkey._browse_anki(\"nid:1\")\nnote_id = hotkey.update_sentence()\nhotkey._browse_anki(f\"nid:{note_id}\")\n
"},{"location":"scripts/#update-sentence-with-clipboard","title":"Update Sentence with Clipboard","text":"Function Name: update_sentence
This script updates the sentence with the current clipboard (while preserving the bolded word), and removes the SentenceReading
field (of the newest note added).
This script is useful when Yomichan's parsed sentence does not match the recorded audio. This is also useful for when Yomichan's word parser doesn't match the word itself (steps shown below).
Note
After running this script, you must manually generate the SentenceReading
field if you want the furigana reading. Of course, this can be done in bulk at any point, as shown here.
How-To: Fix incorrectly-bolded words (click here) As an example, The target word \u5e0c\u671b in the sentence \u300c\u5165\u90e8\u5e0c\u671b\u306a\u3093\u3067\u3059\u3051\u3069\u2026\u300d will be parsed by Yomichan as the following:
\u5165\u90e8<b>\u5e0c\u671b\u306a</b>\u3093\u3067\u3059\u3051\u3069\u2026\n
Within the original popup, you can add two versions of the word by default:
- The one with JMdict only. Adding this word will add the sentence with incorrect bolding.
- The one with everything else other than JMdict. Adding this word will have the correct bold, but will be missing some definitions.
To add the above sentence that solves both problems (no weird bold, and contains all definitions), do NOT add the word within the sentence. Instead, do the following:
-
Highlight over the header word itself (or the word in the orthographic forms dictionary), and add that word instead.
Demo (click here) -
Copy the desired sentence.
-
Run this script.
Note
It is assumed that you have multiple popups enabled.
How the bolded word is preserved (click here) The bolded word is preserved if the exact content within the bolded word is found within the clipboard, which should be almost always the case.
For example, assume the added sentence is the following:
\u3055\u3066\u306f<b>\u507d\u8005</b>\u3060\u306a\uff01\n
As long as the clipboard contains the word \u300c\u507d\u8005\u300d, then the bold is preserved. For example, the following clipboard contents will preserve the bold:
\u304b\u308f\u3044\u3052\u306e\u3042\u308b\u5973\u3058\u3083\u306a\u3044\u3002\u3055\u3066\u306f\u507d\u8005\u3060\u306a\uff01\n
TODO sharex_display(sharex.update_sentence)
"},{"location":"scripts/#update-additionalnotes-with-clipboard","title":"Update AdditionalNotes with Clipboard","text":"Function Name: update_additional_notes
This script does the exact same thing as the above script, but with AdditionalNotes
instead of Sentence
. The tested word, if found, is also automatically highlighted.
This is useful to copy/paste context for the sentence (the surrounding lines around the sentence).
TODO sharex_display(sharex.update_additional_notes)
"},{"location":"scripts/#copy-from-previous-card","title":"Copy from Previous Card","text":"Function Name: copy_from_previous
This script does the following:
- Set the
AdditionalNotes
and Picture
field of the newest card to the previous (second-newest) card's fields. - Copies all the tags of the previous card.
This is useful for when you are adding more than one sentence with the same text box of a visual novel, as it prevents you from having to run the screenshot hotkey.
"},{"location":"scripts/#how-to-use","title":"How to use","text":" - Create a card from the first unknown word in the text box.
- Create a card from the second unknown word in the text box.
- Run this script.
TODO sharex_display(sharex.copy_from_previous)
"},{"location":"scripts/#orthographic-variants-fix-sentence-and-frequency","title":"Orthographic Variants: Fix Sentence and Frequency","text":"Function Name: fix_sent_and_freq
This script does the following:
- Sets the previous note's fields to the newest note's fields:
FrequencyStylized
Sentence
SentenceReading
- Deletes the newest note
This is useful for when you want to add the the word within the Orthographic Variants dictionary. The Orthographics Variants dictionary is extremely useful for monolingual definitions, where dictionaries only contain entries for more kanjified words.
In practice, I've personally found numerous examples of this in everyday media, so this has helped me immensely.
Examples (to test the dictionary on) \u300c\u30b9\u30da\u30eb\u30c9\u65cf\u3078\u306e\u6050\u6016\u306f\u6050\u3089\u304f\u3053\u306e\u4e16\u754c\u306b\u6839\u3065\u3044\u3066\u3044\u308b\u3093\u3060\u308d\u3046\u300d
\u300c\u30eb\u30fc\u306f\u305f\u304f\u3055\u3093\u3042\u308b\u306e\u3067\u3001\u4eca\u304a\u4ee3\u308f\u308a\u3092\u304a\u6301\u3061\u3057\u307e\u3059\u306d\u300d
\u300c\u305f\u3060\u3001\u4e00\u3064\u3060\u3051\u91d8\u3092\u3055\u3055\u305b\u3066\u3082\u3089\u3046\u3051\u3069\u2026\u8cb4\u65b9\u304c\u3053\u308c\u304b\u3089\u4f55\u3092\u3059\u308b\u306b\u3057\u3066\u3082\u3001\u4ed5\u4e8b\u306f\u4eca\u307e\u3067\u901a\u308a\u3053\u306a\u3057\u3066\u3082\u3089\u3046\u308f\u3088\uff1f\u300d
It is assumed that you have multiple popups enabled for monolingual definitions, so you can easily look up the word in the Orthographic Forms dictionary.
"},{"location":"scripts/#how-to-use_1","title":"How to use","text":" - Create a card from the word in the Orthographic Variants dictionary.
- Create a card from the word in original sentence.
- Run this script.
"},{"location":"scripts/#deprecated-scripts","title":"Deprecated Scripts","text":"These contain powershell code for some scripts above. This powershell code has been replaced with Python scripts for easier maintainability
Screenshot and Clipboard Hotkey Follow the steps for setting up the screenshot hotkey, and use this script in place of step 8's argument
.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne \\\"\\\"}) -join \\\"<br>\\\"; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_clipboard = $clipboard; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_clipboard = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = \\\"<img data-editor-shrink=`\\\"true`\\\" src=`\\\"$media_name`\\\">\\\"; AdditionalNotes = $result_clipboard; } } } }; if ($media_name -match '(?<tag>.+)_.*') { $tag = $matches['tag']; } Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne \"\"}) -join \"<br>\";\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n# attempts to bold the found word within the clipboard\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_clipboard = $clipboard;\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_clipboard = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n};\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = \"<img data-editor-shrink=`\"true`\" src=`\"$media_name`\">\";\nAdditionalNotes = $result_clipboard;\n}\n}\n}\n};\nif ($media_name -match '(?<tag>.+)_.*') {\n$tag = $matches['tag'];\n}\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n};\n
Screenshot (only) Hotkey This is the same as the above, but without setting the AdditionalNotes
field to the current clipboard.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = \\\"<img data-editor-shrink=`\\\"true`\\\" src=`\\\"$media_name`\\\">\\\"; } } } }; if ($media_name -match '(?<tag>.+)_.*') { $tag = $matches['tag'] } Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = \"<img data-editor-shrink=`\"true`\" src=`\"$media_name`\">\";\n}\n}\n}\n};\nif ($media_name -match '(?<tag>.+)_.*') {\n$tag = $matches['tag']\n}\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n};\n
Audio Hotkey This script works exactly the same as stegatxins0's version, except rewritten in a more readable format. If you already have the audio hotkey setup, there is no reason to change the old script.
To use this, follow the steps for setting up the audio hotkey, and use this script in place of step 14's Argument
.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ SentenceAudio = \\\"[sound:$media_name]\\\"; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nSentenceAudio = \"[sound:$media_name]\";\n}\n}\n}\n};\n
Update Sentence with Clipboard ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne ''}) -join ''; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_sent = ''; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_sent = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); } else { $result_sent = $clipboard; }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Sentence = $result_sent; SentenceReading = ''; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne ''}) -join '';\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_sent = '';\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_sent = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n} else {\n# default\n$result_sent = $clipboard;\n};\n# updates current card with result_sent\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nSentence = $result_sent;\nSentenceReading = '';\n}\n}\n}\n};\n
Update AdditionalNotes with Clipboard ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne \\\"\\\"}) -join \\\"<br>\\\"; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_sent = ''; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_sent = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); } else { $result_sent = $clipboard; }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ AdditionalNotes = $result_sent; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne \"\"}) -join \"<br>\";\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_sent = '';\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_sent = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n} else {\n# default\n$result_sent = $clipboard;\n};\n# updates current card with result_sent\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nAdditionalNotes = $result_sent;\n}\n}\n}\n};\n
Copy from Previous Card ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $prev_note_id = $sorted_list[1]; $curr_note_id = $sorted_list[0]; $prev_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($prev_note_id); } }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = $prev_note_data.result.fields.Picture.value; AdditionalNotes = $prev_note_data.result.fields.AdditionalNotes.value; } } } }; foreach ($tag in $prev_note_data.result.tags) { Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$prev_note_id = $sorted_list[1];\n$curr_note_id = $sorted_list[0];\n$prev_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($prev_note_id);\n}\n};\n# copies picture & additional notes to current note\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = $prev_note_data.result.fields.Picture.value;\nAdditionalNotes = $prev_note_data.result.fields.AdditionalNotes.value;\n}\n}\n}\n};\n# copies tags\nforeach ($tag in $prev_note_data.result.tags) {\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n}\n};\n
Orthographic Variants: Fix Sentence and Frequency ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $prev_note_id = $sorted_list[1]; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $prev_note_id; fields = @{ FrequenciesStylized = $curr_note_data.result.fields.FrequenciesStylized.value; Sentence = $curr_note_data.result.fields.Sentence.value; SentenceReading = $curr_note_data.result.fields.SentenceReading.value; } } } }; Run-Json @{ action = 'deleteNotes'; version = 6; params = @{ notes = @($curr_note_id); } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$prev_note_id = $sorted_list[1];\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n# copies frequency, sentence, sentence reading to previous note\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $prev_note_id;\nfields = @{\nFrequenciesStylized = $curr_note_data.result.fields.FrequenciesStylized.value;\nSentence = $curr_note_data.result.fields.Sentence.value;\nSentenceReading = $curr_note_data.result.fields.SentenceReading.value;\n}\n}\n}\n};\n# removes current note\nRun-Json @{\naction = 'deleteNotes';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n
"},{"location":"sentences/","title":"Sentences (TODO)","text":""},{"location":"sentences/#display-sentence-vs-full-sentence","title":"Display sentence vs Full sentence","text":"We will use the following terms to differentiate between the different sentences present in this note:
- Display sentence refers to the sentence(s) shown at the front side of the card. Most topics on this page will be relating to the display sentence.
- Full sentence to refers to the sentence(s) shown at the back with furigana. This is called the \"full sentence\" as this is usually just the
Sentence
(or SentenceReading
) field with minimal styling.
TODO image
"},{"location":"sentences/#sentence-cards","title":"Sentence cards","text":"If you are looking on how to make sentence cards or targeted sentence cards (sentence cards where the tested word is bolded), see Card Types: Sentence Card and Card Types: Targeted Sentence Card respectively.
"},{"location":"sentences/#customize-the-display-sentence","title":"Customize the display sentence","text":"You can use the AltDisplaySentence
field you ever wish to customize the display sentence without modifying the full sentence (Sentence
field),
Last sentence onlyFuriganaKanjifying the word For example, we can use AltDisplaySentence
to only test the last sentence.
One nice feature is that AltDisplaySentence
has hoverable furigana text enabled by default. In other words, you can write furigana within the field. I personally use this to insert furigana for certain names, since I'm usually not testing myself on how to read a name.
For example, the card below has the following HTML:
\u4e0a\u6761[\u304b\u307f\u3058\u3087\u3046] \u606d\u4ecb[\u304d\u3087\u3046\u3059\u3051]\u541b\u306e\u3053\u3068\u304a<b>\u6155\u3044</b>\u3057\u3066\u307e\u3057\u305f\u306e\n
TODO image
It is not uncommon for words to be written in kana, but have a kanji variant. Instead of modifying the Sentence
field, you can copy the Sentence
field into the AltDisplaySentence
field, and then manually replace the kana with its kanji variant. This may be useful for any card type that isn't a vocab or audio card.
"},{"location":"sentences/#adding-line-breaks","title":"Adding line breaks","text":"TODO this is basically the only time I ever edit the Sentence
field
- if you have furigana, make sure you refresh the
SentenceReading
field, i.e. with the AJT Japanese
plugin
"},{"location":"sentences/#sentence-max-width-indicator","title":"Sentence Max Width Indicator","text":"TODO sentence-max-width
under cssFolders
- warning: experimental, may have weird bugs
"},{"location":"sentences/#automatic-word-highlighting","title":"Automatic word highlighting","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Usually, the word within the sentence is already bolded by Yomichan. However, there are some cases where the word within the sentence may not be bold, such as when external programs update the Sentence
field, or if you are using imported cards.
By default, the note attempts to highlight the word within the sentence.
With that being said, it is not uncommon that the automatic highlighting fails to highlight the full word. For example, verb and i-adj. conjugations are not highlighted whatsoever. In order to keep the javascript lightweight, any improper highlighting is considered as expected behavior, and will not be changed or fixed. I recommend manually bolding the word if the word is incorrectly highlighted.
Examples (click here) Any text in red is not highlighted automatically. They are considered as examples of when automatic highlighting doesn't work.
WordReading Sentence Result \u6295\u7a3f\u3068\u3046\u3053\u3046 \u300c\u3042\u306e\u6642\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u4e0a\u3067\u8272\u3093\u306a\u8cea\u554f\u304c\u3067\u304d\u308b\u30b5\u30a4\u30c8\u306b\u6295\u7a3f\u3057\u305f\u3089\u3001\u89aa\u5207\u306a\u4eba\u304c\u5546\u54c1\u540d\u3068\u58f2\u3063\u3066\u3044\u308b\u5834\u6240\u3092\u6559\u3048\u3066\u304f\u308c\u305f\u3093\u3067\u3059\u300d \u4e00\u5148\u3072\u3068\u307e\u305a \u300c\u3075\u30fc\u2026\u3053\u308c\u3067\u3072\u3068\u307e\u305a\u306f\u5927\u4e08\u592b\u305d\u3046\u306d\u2026\u300d \u7363\u3051\u3060\u3082\u306e \u300c\u305d\u306e\u5834\u5408\u2026\u300e\u5acc\u3063\uff01\u3053\u306e\u30b1\u30c0\u30e2\u30ce\uff01\u300f\u3068\u66b4\u308c\u305f\u65b9\u304c\u3001\u98a8\u898b\u3055\u3093\u306f\u304a\u597d\u307f\u3067\u3057\u3087\u3046\u304b\uff1f\u300d \u7532\u6590\u7532\u6590\u304b\u3044\u304c\u3044\u3057\u3044 \u300c\u306a\u306b\u3088\u3045\u2026\u7532\u6590\u7532\u6590\u3057\u304f\u4f1a\u3044\u306b\u6765\u305f\u5973\u306b\u5bfe\u3057\u3066\u3001\u6700\u521d\u306b\u8a00\u3046\u30bb\u30ea\u30d5\u304c\u305d\u308c\uff1f\u300d \u5c71\u3084\u307e\u3054\u3082\u308a \u300c\u3067\u306f\u3001\u308f\u305f\u3057\u3082\u4eca\u304b\u3089\u5c71\u3054\u3082\u308a\u306e\u4fee\u884c\u3092\u59cb\u3081\u307e\u3059\u300d \u5c71\u7c60\u3084\u307e\u3054\u3082\u308a \u300c\u3067\u306f\u3001\u308f\u305f\u3057\u3082\u4eca\u304b\u3089\u5c71\u3054\u3082\u308a\u306e\u4fee\u884c\u3092\u59cb\u3081\u307e\u3059\u300d \u629c\u306c\u304d\u3093\u51fa\u306c\u308b \u300c\u201c\u3059\u3054\u3044\u201d\u3067\u3059\u304b\u3089\u3001\u826f\u304f\u3082\u60aa\u304f\u3082\u3001\u629c\u304d\u3093\u51fa\u3066\u3044\u308b\u3068\u3044\u3046\u610f\u5473\u306b\u306f\u306a\u308b\u3068\u601d\u3044\u307e\u3059\u300d Note
Much of the base code was taken from Marv's implementation of the same thing.
"},{"location":"sentences/#removing-sentence-periods","title":"Removing sentence periods","text":"The display sentence will have the period at the end of the sentence removed by default. If you want to keep the period, you can set the desired runtime options to false
:
\"sentenceParser.removeFinalPeriod.fullSent.quoted\": true, // (1)!\n\"sentenceParser.removeFinalPeriod.fullSent.unquoted\": false,\n\"sentenceParser.removeFinalPeriod.display.quoted\": true,\n\"sentenceParser.removeFinalPeriod.display.unquoted\": false,\n\"sentenceParser.removeFinalPeriod.altDisplay.quoted\": false,\n\"sentenceParser.removeFinalPeriod.altDisplay.unquoted\": false,\n
- For example,
\"sentenceParser.removeFinalPeriod.fullSent.quoted\": true,
means that the final period is removed from the full sentence if it is quoted. The other options follow similarly.
TODO image
"},{"location":"sentences/#adding-or-removing-quotes","title":"Adding or removing quotes","text":"The sentence display has quotes surrounding the sentence by default, to provide a simple indicator to differentiate between a sentence and vocab card.
If you do not want quotes around the sentence, you can set the following runtime options to remove
:
\"sentenceParser.fullSent.quotes.processMode\": \"remove\",\n\"sentenceParser.display.quotes.processMode\": \"add\",\n\"sentenceParser.altDisplay.quotes.processMode\": \"as-is\",\n
All available process modes are explained within the example config file.
If you want to add or remove quotes on a card-by-card basis, add the quote-add
tag or quote-remove
tag to the card, respectively.
TODO image????
"},{"location":"sentences/#sentencereading-furigana-options","title":"SentenceReading
Furigana Options","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
By default, the furigana for the full sentence (on the back side of the card) is shown on hover, given that this SentenceReading
field is filled out. If SentenceReading
is not filled out, then the sentence will show as usual (without furigana).
The following options change how the furigana is displayed within the full sentence, if any exists.
Note
These options do NOT affect furigana elsewhere, such as any in the displayed sentence.
"},{"location":"sentences/#furigana-simple-css-options","title":"Furigana: Simple CSS options","text":"Most problems that people face with ruby is that there is added spacing within the furigana. The following are some simple CSS-only solutions that solves this main problem.
Shown on sentence hoverShown on word hover .full-sentence ruby rt {\nvisibility: visible !important;\nfont-size: 0%;\ntransition: 0.2s;\n}\n.full-sentence:hover ruby rt {\nfont-size: 50%;\ntransition: 0.2s;\n}\n
.full-sentence ruby rt {\nvisibility: visible !important;\nfont-size: 0%;\ntransition: 0.2s;\n}\n.full-sentence ruby:hover rt {\nfont-size: 50%;\ntransition: 0.2s;\n}\n
If you want more control over the furigana, more options are shown below. However, note that the options below require you to compile the note.
"},{"location":"sentences/#furigana-when-to-show","title":"Furigana: When to show","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
By default, furigana is shown on hover. This can be changed to only be shown on click, or always/never shown.
On clickOn hover (default)On hover and clickAlways revealedNever revealed TODO gif: show on click
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"click\",\n
This is commonly paired with the hide furigana spacing option, so furigana does not impede with the sentence whatsoever until toggled.
TODO gif: show on hover
This is the default behavior.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"hover\",\n
TODO gif: show on hover and click
This allows furigana to be shown on hover, and toggled on click.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"both\",\n
TODO gif: static with mouseover
This is not recommended, because you should not be relying on furigana to understand Japanese.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"always\",\n
TODO gif: static with mouseover
If you are looking to not see furigana at all, feel free to use this option. However, I personally recommend toggling on click instead of removing furigana completely.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"never\",\n
"},{"location":"sentences/#furigana-hide-spacing","title":"Furigana: Hide spacing","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Furigana that extends past the length of the kanji will add additional spacing around the kanjis, which may be unpleasant to look at.
One solution to this is to simply hide the spacing until hover or click. This has the unintentional consequence where kanjis can potentionally change position, or overflow into the next line. There is also a possibility that the entire sentence shifts over a bit to the left due to (what I think is a) chromium based bug1.
Hide SpacingHide spacing with no transitionKeep spacing (default) TODO img
Instructions (click here) Change the following compile options:
\"fullSentenceRuby.fillMode\": \"font-size\",\n\"fullSentenceRuby.fillModeFontSizeTransition\": true,\n
TODO img
Instructions (click here) Change the following compile options:
\"fullSentenceRuby.fillMode\": \"font-size\",\n\"fullSentenceRuby.fillModeFontSizeTransition\": false,\n
TODO img
This is the default behavior.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.fillMode\": \"opacity\",\n
Note
All of the examples above are shown with furigana on hover. They will also work with furigana on click.
"},{"location":"sentences/#generating-sentence-furigana","title":"Generating Sentence Furigana","text":"TODO AJT Japanese and {jpmn-sentence-bolded-furigana-plain}
"},{"location":"sentences/#furigana-generation-ajt-japanese","title":"Furigana Generation: AJT Japanese","text":"TODO
"},{"location":"sentences/#furigana-generation-yomichan-helper","title":"Furigana Generation: Yomichan Helper","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
helper: {jpmn-sentence-bolded-furigana-plain}
TODO add details on how to even use this
This automatically uses Yomichan's internal furigana generator to add furigana to your sentence. Use this under SentenceReading
.
This is useful if:
- You are not using AJT Japanese, or
- You are using a device that doesn't have AJT Japanese installed (say, a phone), and you do not want to bulk generate furigana after each session.
"},{"location":"sentences/#keeping-and-removing-newlines-within-the-display-sentence","title":"Keeping and removing newlines within the display sentence","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
You can add newlines to the Sentence
field to make the full sentence field have cleaner line breaks. If you do this, you will need to regenerate the SentenceReading
field if you are using furigana.
However, these newlines are automatically removed from the display sentence if the width of the screen is determined to be too small. To override this option, you can use the following custom CSS:
Instructions (click here) Keep all newlinesRemove all newlinesRemove all newlines when AltDisplay is not used .expression .expression-inner br {\ndisplay: inline !important;\n}\n
.expression .expression-inner br {\ndisplay: none !important;\n}\n
This only removes newlines when the AltDisplay
(or AltDisplayPASentenceCard
) field is not being used as the display sentence.
.expression .expression-inner br {\ndisplay: inline !important;\n}\n.expression .expression-inner:not(.expression-inner--altdisplay) br {\ndisplay: none !important;\n}\n
"},{"location":"sentences/#multiple-sentences","title":"Multiple Sentences","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
- TODO
- summary: split with multiple newlines, i.e.
<br><br>
- TODO pictures
-
See #4 in the minor visual bugs list.\u00a0\u21a9
"},{"location":"setup/","title":"Setup: Installing","text":""},{"location":"setup/#overview","title":"Overview","text":"A full sentence mining workflow requires two main parts:
- Text to make the cards from.
- The card exporter, to create cards from the text.
- And optionally, the image and sentence audio from the media (if the media has either).
These next few sections (Installing, Anki and Yomichan) are all dedicated to providing the minimal setup to setup the card exporter to create cards with this note type.
Getting the text (the first part) and getting the image and sentence audio (the optional part of part two) are not heavily focused on within this site, but can be found under Setup: Text & Media page.
Note
There's quite a few things to setup to use this note. If you ever get lost, remember that this site has a search bar!
"},{"location":"setup/#installing-anki","title":"Installing Anki","text":"Download and install Anki from the official website if you haven't already. I recommend downloading the latest version, to avoid having to do extra steps during the setup.
"},{"location":"setup/#installing-jp-mining-note","title":"Installing jp-mining-note","text":"There are three ways of installing the note:
- Via JPMN Manager, a small Anki add-on that can install and update jp-mining-note, as well as notify you when updates are available. If you don't know which method to choose, choose this one.
- Via command line. This method is recommended for people who are familiar with
git
and python
, and don't want to download another Anki add-on. - Manually, using Anki. This tends to be more error-prone due to having many more potential points of failure. Therefore, I wouldn't recommend installing the note this way. It should only be used if the first two options didn't work.
Option 1: JPMN Manager (click here) Note
If you have previously installed Aquafina's old version of the JPMN add-on, then you must remove it before installing the new version below. The old and new versions will conflict with each other if they are both installed. In your list of Anki add-ons, you should only see JPMN Manager with prereleases New Version
. If you see JPMN Manager with prereleases
then please remove it and restart Anki before proceeding.
-
To install any Anki add-on, navigate to:
(Main Window) \u2192 Tools
\u2192 Add-ons
\u2192 Get Add-ons...
From here, you can install JPMN Manager and Anki-Connect by using the following add-on codes:
301910299 2055492159\n
-
Restart Anki, to load the new add-ons.
-
Within Anki, navigate to the following:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Install jp-mining-note
This will install latest version of the note, as well as the fonts required for the note to work. Note: Installing jp-mining-note might take a while, and Anki may appear frozen.
-->
Option 2: Command Line (click here) WindowsmacOS & Linux git clone \"https://github.com/arbyste/jp-mining-note.git\"\n:: TODO change this to master branch\ncd jp-mining-note\ngit checkout dev\n\n:: Ensure you have Anki open, and with Anki-Connect running\n:: Also ensure that you have python 3.9+ installed.\n:: It *MAY* work with lower versions of python, but I make no such guarantee. ;)\npython tools\\install.py\n
git clone \"https://github.com/arbyste/jp-mining-note.git\"\n:: TODO change this to master branch\ncd jp-mining-note\ngit checkout dev\n\n# Ensure you have Anki open, and with Anki-Connect running\n# Also ensure that you have python 3.9+ installed.\n# It *MAY* work with lower versions of python, but I make no such guarantee. ;)\n# You may have to use `python3` instead of `python`.\npython tools/install.py\n
install.py
will install latest stable version of the note, as well as the fonts required for the note to work.
Option 3: Manually (click here) - Go to the releases page and download the cards from the latest release. You should download the
{version}-jpmn_example_cards.apkg
file. -
After you download the cards, import them by navigating to Anki by doing the following:
File
(top left corner) \u2192 Import...
-
By default, the custom fonts do not come with the .apkg
file. To install these fonts, head over to this repository's media folder and download the 4 .otf
files.
- Move the
.otf
files into the media folder of your profile (Anki2/PROFILENAME/collections.media
).
"},{"location":"setup/#verifying-the-note-works","title":"Verifying the Note Works","text":"You should see a deck JPMN-Examples
in your collection. View one of the cards and make sure the card looks similar to the one below:
Dark ThemeLight Theme Please check the following in particular:
-
The fonts should match with the above example.
If the fonts don't match, try restarting Anki and/or your computer. If the fonts still don't match, the note was likely installed manually. Please verify you manually installed the fonts and placed them in the correct folder (see steps 3 and 4).
-
Notice how at the top left corner, the info circle (the \"i\" encased within the circle) is the default grey color.
If this circle is red or orange, there may be something wrong with the template. Please see this section for basic troubleshooting.
-
Clicking on the image to zoom should work out of the box.
Kanji hover may not work yet. If it doesn't work, continue reading to the Anki-Connect setup instructions on the next page.
If the image suddenly appears without a zoom animation, then you must enable animations on Anki.
"},{"location":"setup/#anki-setup","title":"Anki Setup","text":"This note requires some additional setup to Anki. In particular, some add-ons are required for the note to work.
Click here see how to setup Anki!
"},{"location":"setupandroid/","title":"Extra: Android","text":""},{"location":"setupandroid/#summary","title":"Summary","text":"On Android, it is possible to review and create JPMN cards similarly to desktop. It is expected that you have setup Anki and Yomichan properly on your desktop machine before continuing with this page.
"},{"location":"setupandroid/#reviewing","title":"Reviewing","text":"To review Anki cards on Android, use AnkiDroid.
In order to review the same cards on desktop, you must sync your collection with AnkiWeb. More tech savy users can sync their collections using a self-hosted server.
Note
If your collection on AnkiWeb is large, your initial sync to AnkiWeb will likely take a very long time. After your first sync, your collection may not actually be fully synced even if AnkiDroid says so. Keep pressing the sync button until you are sure that everything is indeed synced.
"},{"location":"setupandroid/#ankidroid-usage-tips","title":"AnkiDroid Usage Tips","text":" - Set the night theme to \"Dark\" if you want a similar dark theme to Anki's desktop client.
- Under the card browser, the default settings show the
Question
and Answer
as columns, which likely looks very strange. I recommend changing the columns to Sort field
and Due
respectively. -
If you are using pass/fail, you can remove the bottom bar by doing the following:
Settings
\u2192 Appearance
\u2192 Answer buttons position
\u2192 Select None
In replacement of the bottom bar, you can use custom gestures. I personally use:
- Show answer: Swipe up
- Answer button 1: Swipe right
- Answer recommended: Swipe left
- If you are using custom gestures, I recommend disabling most (if not all) tap gestures. This is because you will likely have to tap on various parts of the screen when reviewing, to reveal various parts of the card.
"},{"location":"setupandroid/#creating-cards","title":"Creating Cards","text":"There are two main ways of creating cards on Android. Both require AnkiDroid to be installed.
-
AnkiconnectAndroid (recommended)
AnkiconnectAndroid is an implementation of Anki-Connect, on Android. Combined with Kiwi browser, you can use Yomichan directly on your Android device, and have the exact same setup as you would on desktop. To do this, follow the instructions on the AnkiconnectAndroid's README page.
It might help to export a copy of Yomichan settings from your PC and import said settings on Android, instead of re-doing all of the steps on Android.
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, which is mostly useful for novels. See here for more info.
-
jidoujisho
This is a all-in-one solution app that allows you to immerse in various ways. However, jidoujisho provides a more limited interface when exporting the note, meaning that some features will be not be supported. See here for basic instructions on how to use the app to export JPMN cards.
"},{"location":"setupanki/","title":"Setup: Anki","text":""},{"location":"setupanki/#new-to-anki","title":"New to Anki?","text":"If you have never used Anki before, I recommend using fsrs4anki to get more optimized settings than the default settings.
That article showcases only one way of setting up Anki's settings for language learning. Feel free to view some other examples here.
"},{"location":"setupanki/#updating-anki","title":"Updating Anki","text":"It is highly recommended that you are using the latest (stable) Anki version (or as close as you can get to the latest Anki version). This includes using the Qt6 version instead of Qt5 if possible.
Using the latest version of Anki is recommended for the following reasons:
- The note is primarily tested and maintained on the latest versions of Anki.
- There are a few minor but known bugs that this note type has with older Anki versions. These bugs do not exist in newer Anki versions.
Worst case scenario, if any essential add-ons no longer work, you can always downgrade back to a previous version.
If you aren't upgrading Anki from an older version, you can skip the rest of this section.
Tips on Updating Anki (click here) Official Documentation:
-
The official documentation on how to install and upgrade Anki is shown below:
Windows\u30fbmacOS\u30fbLinux
Note that for all three, there are additional sections in the table of contents to the left that could be helpful.
Add-ons Breaking:
-
If an add-on (that worked in a previous version of Anki) no longer works, you have a few options you can try:
- As a sanity check, click the
Check for Updates
button on Anki's Addons
window. -
Check that the add-on supports the current version of Anki in the official AnkiWeb page. If the page says that the current Anki version is supported, try reinstalling it again from AnkiWeb.
Occasionally, the Check for Updates
button doesn't properly work, so this method ensures that your addon is actually updated.
"},{"location":"setupanki/#enable-animations-2161-2163","title":"Enable Animations (2.1.61 - 2.1.63)","text":"If you are using Anki versions 2.1.61, 2.1.62 or 2.1.63, animations are disabled by default. The note works best with animations enabled. To enable animations, head over to:
Tools
\u2192 Preferences
\u2192 Appearance
\u2192 Reduce Motion
\u2192 (unchecked)
Note
Starting Anki 2.1.64, Reduce Motion
no longer affects animations within templates. 1
"},{"location":"setupanki/#fixing-your-editor-fonts","title":"Fixing your Editor Fonts","text":"By default, your editor fonts may be showing Japanese characters using a Chinese font. To determine this, compare the \u76f4 character in the \u53e9\u304d\u76f4\u3059 example card with the following pictures:
Japanese (correct)Chinese (incorrect!)
If you are using a Chinese font, you likely want to switch to using a Japanese font.
How to fix Chinese Fonts within Anki Card Editor (click here) - Within Anki's card browser, select any JPMN card. You may have to select a deck on the left sidebar.
- Click on the
Fields
tab within the card editor. -
Change the Editing Font
to a Japanese font.
If you don't know what Japanese fonts exist, try searching for any of the following (courtesy of TMW):
- IPAexGothic
- Meiryo
- MS Gothic
- Yu Gothic
- Hiragino Kaku Gothic Pro
- Noto Sans CJK JP Regular
If you cannot find any of these, you may have to install a Japanese font.
-
After finding a correct font, you will have to set all other fields to this same font. This can be done manually, or with the following batch command:
set_fonts_to_key_font\n
The above batch command sets the font of all fields to the font in the Key
field.
More info on how to change the font everywhere else can be found here.
"},{"location":"setupanki/#dark-mode","title":"Dark Mode","text":"Both light mode and dark mode are supported by this note.
The note automatically adjusts according to Anki's theme. To change Anki's theme, head over to:
Tools
\u2192 Preferences
\u2192 Basic
\u2192 Theme (dropdown)
Note
The note's theme currently cannot be forced to be a particular theme without changing Anki's settings.
"},{"location":"setupanki/#anki-add-ons","title":"Anki Add-ons","text":"There are certain add-ons that must be installed for this note type to work.
"},{"location":"setupanki/#downloading-add-ons","title":"Downloading Add-ons","text":"To download an add-on, copy the add-on's code, and navigate to the following to paste the code:
Tools
\u2192 Add-ons
\u2192 Get Add-ons...
"},{"location":"setupanki/#required-add-ons","title":"Required Add-ons","text":""},{"location":"setupanki/#anki-connect","title":"Anki-Connect","text":"Code: 2055492159
Required for Yomichan and most other Anki-related automated tasks to work. I use the default config that comes with the add-on.
If you installed JPMN Manager, you likely already have this installed.
Note for Anki versions 2.1.49 and below (click here) This is left for legacy purposes, because jp-mining-note no longer officially supports versions 2.1.49 or below.
Anki versions 2.1.49 and below require a hack to the Anki-Connect config for certain features within the card to work. In particular, Anki-Connect is used for the \"Kanji Hover\" feature and the \"Open Fields on New Card\" feature.
To make those features work, add \"null\"
to the webCorsOriginList
list in the Anki-Connect config file. An example of how the config should look is shown below:
\"webCorsOriginList\": [\n \"http://localhost\",\n \"null\"\n]\n
Of course, this isn't very safe and it is highly recommended that you upgrade Anki to avoid this problem.
If you aren't interested in those features, you can skip this step and disable them in the runtime options.
"},{"location":"setupanki/#optional-add-ons","title":"Optional Add-ons","text":"These are a set of optional, but useful add-ons that can easily work with the card. If this is your first time here, I recommend skimming through the descriptions and choosing the add-ons that seem appealing for you.
Note
Make sure to head over to the final steps section afterwards!
"},{"location":"setupanki/#css-injector","title":"CSS Injector","text":"Code: 181103283
I strongly recommend using this, because if you don't use this, the fields within the Anki field editor won't have certain stylizations that makes the field actually interpretable.
There are two ways of using css injector with this note type:
Option 1: Automatically updates with the card (recommended) WindowsmacOSLinux As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
:: be sure to change USERNAME to your computer username!\ndel \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\field.css\"\ndel \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\editor.css\"\n
Afterwards, open command prompt with elevated permissions.
Note
Be sure to open command prompt, and not PowerShell. If you've never used command prompt before, see this.
With command prompt opened, run the following command:
:: be sure to change USERNAME to your computer username and PROFILENAME to your Anki profile.\n:: There are **two** USERNAME's to replace, and **one** PROFILENAME to replace\n:: in the commands below.\n:: Make sure to replace all the fields!\nmklink \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\field.css\" \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\PROFILENAME\\collection.media\\_field.css\"\nmklink \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\editor.css\" \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\PROFILENAME\\collection.media\\_editor.css\"\n
As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
rm \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/field.css\"\nrm \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/editor.css\"\n
Afterwards, run the following command:
# be sure to change `PROFILENAME` to your Anki profile\nln -s \"$HOME/Library/Application Support/Anki2/PROFILENAME/collection.media/_field.css\" \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/field.css\"\nln -s \"$HOME/Library/Application Support/Anki2/PROFILENAME/collection.media/_editor.css\" \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/editor.css\"\n
As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
rm \"$HOME/.local/share/Anki2/addons21/181103283/user_files/field.css\"\nrm \"$HOME/.local/share/Anki2/addons21/181103283/user_files/editor.css\"\n
Afterwards, run the following command:
# be sure to change `PROFILENAME` to your Anki profile\nln -s \"$HOME/.local/share/Anki2/PROFILENAME/collection.media/_field.css\" \"$HOME/.local/share/Anki2/addons21/181103283/user_files/field.css\"\nln -s \"$HOME/.local/share/Anki2/PROFILENAME/collection.media/_editor.css\" \"$HOME/.local/share/Anki2/addons21/181103283/user_files/editor.css\"\n
Option 2: Manually without respecting updates - Navigate to css injector addon folder (
Anki2/addons21/181103283/user_files
) - Remove the existing
field.css
and editor.css
files - Copy the
_field.css
file and _editor.css
file (found under your profile's media folder) into the css injector add-on directory. - Rename
_field.css
to field.css
. - Rename
_editor.css
to editor.css
.
Note
If either of the two css files ever update, you will have to manually copy and rename the file again.
"},{"location":"setupanki/#ajt-japanese","title":"AJT Japanese","text":"Code: 200813220
JP Mining Note uses a slightly modified version of AJT Japanese that has been pre-configured to work with this note type.
Warning
As of writing this (2023/04/28), AJT Japanese is only guaranteed to work on Anki versions 2.1.60 and above, because it is no longer maintained on previous versions. If you are using an older version of Anki and you want to use this add-on, please update Anki to 2.1.60 or above.
This is an add-on that automatically adds furigana and pitch accents to cards upon Yomichan card creation. Previously known as AJT Furigana
, and now comes packaged with AJT Pitch Accent
.
If this add-on is not used, then the following features will be missing:
- Automatically generated furigana
- Devoiced and nasal information to pitch accents
- Less coverage on pitch accents
- If your Yomichan pitch accent dictionaries did not contain any pitch accent info for the word but the add-on does, then it will use the add-on data. This will likely happen for expressions containing more than one word. Fortunately, AJT Japanese can usually detect the existence of multiple words, and add the pitch accent for each individual word.
The version of AJT Japanese that is linked above has already been configured to work with JP Mining Note, so there is no need to modify the configuration. After installation, you can move on to Final Steps.
"},{"location":"setupanki/#additional-info","title":"Additional Info","text":"Furigana generation is occasionally incorrect, so if you plan on using furigana regularly, you should double-check the readings to make sure they are correct.
JapaneseSupport v.s. AJT Japanese (Furigana) If you use JapaneseSupport, bolded words and other styles within a field are not transferred over from the original field to the reading field. Additionally, JapaneseSupport does not have an option to automatically add the reading upon card creation. AJT Japanese supports both of those of those features.
"},{"location":"setupanki/#config-changes","title":"Config Changes","text":"If you want to manually modify the configuration of AJT Japanese, this section might be useful. It details the changes that have been made to the default AJT Japanese configuration file. Documentation for configuring AJT Japanese can be found from the page for the original version of the add on.
To view the config of any Anki add-on, head over to:
Tools
\u2192 Add-ons
\u2192 (select the add-on) \u2192 Config
.
Below is an annotated copy of the config file that JP Mining Note uses:
Click here to see the full AJT Japanese config The important changes to the config are:
fields
profiles
pitch_accent.reading_separator
pitch_accent.word_separator
pitch_accent.maximum_results
pitch_accent.style
{\n\"cache_lookups\": 1024,\n\"last_file_save_location\": \"\",\n\"profiles\": [ // (2)!\n{\n\"name\": \"Add furigana for sentence\",\n\"note_type\": \"JP Mining Note\",\n\"source\": \"Sentence\",\n\"destination\": \"SentenceReading\",\n\"mode\": \"furigana\",\n\"split_morphemes\": true,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add furigana for word -- UNUSED BY jp-mining-note\",\n\"note_type\": \"AJT_JAPANESE_IGNORE_PROFILE\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabFurigana\",\n\"mode\": \"furigana\",\n\"split_morphemes\": false,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add pitch accent for word\",\n\"note_type\": \"JP Mining Note\",\n\"source\": \"Word\",\n\"destination\": \"AJTWordPitch\",\n\"mode\": \"pitch\",\n\"split_morphemes\": false,\n\"output_format\": \"html\",\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add audio for word -- UNUSED BY jp-mining-note\",\n\"note_type\": \"AJT_JAPANESE_IGNORE_PROFILE\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabAudio\",\n\"mode\": \"audio\",\n\"split_morphemes\": false,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n}\n],\n\"pitch_accent\": {\n\"lookup_shortcut\": \"Ctrl+8\",\n\"output_hiragana\": false,\n\"kana_lookups\": true,\n\"skip_numbers\": true,\n\"reading_separator\": \"\u30fb\", // (3)!\n\"word_separator\": \"\u3001\",\n\"blocklisted_words\": \"\u3053\u3068,\u3078,\u304b,\u3088,\u3093,\u3060,\u3073,\u306e,\u3084,\u306d,\u3070,\u3066,\u3068,\u305f,\u304c,\u306b,\u306a,\u306f,\u3082,\u307e\u3059,\u304b\u3089,\u3044\u308b,\u305f\u3061,\u3066\u308b,\u3046,\u307e\u3057\u3087,\u305f\u3044,\u3059\u308b,\u3067\u3059,\u306a\u3044\",\n\"maximum_results\": 100, // (4)!\n\"discard_mode\": \"discard_extra\",\n\"style\": \"none\" // (1)!\n},\n\"furigana\": {\n\"skip_numbers\": true,\n\"prefer_literal_pronunciation\": false,\n\"reading_separator\": \", \",\n\"blocklisted_words\": \"\u4eba\",\n\"mecab_only\": \"\u5f7c,\u732b,\u9996,\u6bcd,\u9854,\u6728,\u982d,\u79c1,\u5f1f,\u7a7a,\u4f53,\u884c\u304f\",\n\"maximum_results\": 1, // (5)!\n\"discard_mode\": \"discard_extra\"\n},\n\"context_menu\": {\n\"generate_furigana\": true,\n\"to_katakana\": true,\n\"to_hiragana\": true,\n\"literal_pronunciation\": true,\n\"look_up_word\": true\n},\n\"toolbar\": { // (6)!\n\"generate_all_button\": {\n\"enabled\": false,\n\"shortcut\": \"Alt+P\",\n\"text\": \"\u5165\"\n},\n\"regenerate_all_button\": {\n\"enabled\": false,\n\"shortcut\": \"Alt+;\",\n\"text\": \"\u518d\"\n},\n\"furigana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u632f\"\n},\n\"hiragana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u5e73\"\n},\n\"clean_furigana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u524a\"\n},\n\"audio_search_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u691c\"\n},\n\"add_definition_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u610f\"\n}\n},\n\"audio_sources\": [\n{\n\"enabled\": false, // (7)!\n\"name\": \"NHK-2016\",\n\"url\": \"https://github.com/Ajatt-Tools/nhk_2016_pronunciations_index/releases/download/v1.2/NHK_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"NHK-1998\",\n\"url\": \"https://github.com/Ajatt-Tools/nhk_1998_pronunciations_index/releases/download/v1.1/NHK_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"Shinmeikai-8\",\n\"url\": \"https://github.com/Ajatt-Tools/shinmeikai_8_pronunciations_index/releases/download/v1.5/Shinmeikai-8_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"Daijisen\",\n\"url\": \"https://github.com/Ajatt-Tools/daijisen_pronunciations_index/releases/download/v1.0/Daijisen_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"TAAS\",\n\"url\": \"https://github.com/Ajatt-Tools/taas_pronunciations_index/releases/download/v1.0/TAAS_main.zip\"\n}\n],\n\"audio_settings\": {\n\"dictionary_download_timeout\": 30,\n\"audio_download_timeout\": 6,\n\"attempts\": 4,\n\"maximum_results\": 99,\n\"ignore_inflections\": false,\n\"stop_if_one_source_has_results\": false,\n\"search_dialog_field_name\": \"VocabAudio\",\n\"tag_separator\": \"<br>\"\n},\n\"definitions\": {\n\"timeout\": 10,\n\"remove_marks\": true,\n\"dict_name\": \"meikyou\",\n\"search_type\": \"exact\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabDef\",\n\"behavior\": \"append\"\n}\n}\n
-
\"style\": \"none\"
formats the pitch accent data using a simple html span structure, which makes it easy to control how pronunciation information is displayed. Without this, pitch accent information in the AJTWordPitch field will not render correctly.
-
The Add audio for word
and Add furigana for word
profiles are not used. In order to disable them, the note type is set to AJT_JAPANESE_IGNORE_PROFILE
, which only matches note types containing the string AJT_JAPANESE_IGNORE_PROFILE
. It is very unlikely that your Anki notes will unintentionally contain this string.
-
This makes the separators behave like the old version, and has to be changed to this for the default config of jp-mining-note to work.
-
This is set to a high number in order for many pitch accents to be displayed for long expressions. This is fine because the pitch accent display is usually overwritten by the PAPositions
field, so it's rare to see the AJTWordPitch
field results anyways. Additionally, a higher number increases the sample size for the internal auto-pitch-accent module, to better search for devoiced and nasal markers.
-
(Optional) This is to restrict the generated furigana to only show one reading. Feel free to leave this as the default (3
).
-
(Optional) I personally have the buttons removed because I don't want it to clutter up the editor toolbar. Feel free to have these enabled.
-
(Optional) These are disabled because it slows down Anki's startup time. Additionally, the note does not use this feature. If you want to use this feature, feel free to enable these.
"},{"location":"setupanki/#final-steps-after-installing-add-ons","title":"Final Steps: After Installing Add-ons","text":"After the above setup, make sure to restart Anki for the add-ons and config changes to take effect. If the css injector add-on is installed correctly, your Anki field editor should now have color!
Additionally, now that Anki-Connect is installed, kanji hover should also be functioning. Hover over a kanji within the word reading to make sure that a popup appears. In particular, the \u8005 kanji in the example \u507d\u8005 and \u4e0d\u5be9\u8005 cards should point to each other.
Note
Hovering over the other kanjis will display a Kanji not found.
message, because the template only searches for kanjis within existing jp-mining-note cards.
If you wish to see usages of the kanji within words outside of your deck, I highly recommend using Marv's JPDB Kanji Yomichan Dictionary.
"},{"location":"setupanki/#transfer-existing-notes","title":"Transfer Existing Notes","text":"If you wish to transfer existing cards into this note type (say, to make kanji hover work on existing cards), please see this page.
"},{"location":"setupanki/#updating-the-note","title":"Updating the Note","text":"If you wish to update the note, follow the steps in this page.
This note does not auto-update. This should keep your setup stable, as long as you do not update Anki.
When updating Anki, don't forget to check if there is a new version of this note available, because this note should update along with Anki.
"},{"location":"setupanki/#setting-up-yomichan","title":"Setting up Yomichan","text":"Of course, you can have an Anki template, but what's the point of it if you can't make cards with it?
We will use Yomichan to create these cards.
Click here see how to setup Yomichan!
-
https://github.com/ankitects/anki/commit/c54b897b4f456124f0b1956a05deb8f12e98f23c \u21a9
"},{"location":"setupasbplayer/","title":"asbplayer","text":"asbplayer is a browser-based media player and Chrome extension, used for subtitle sentence mining and video playing. asbplayer works on both video streaming sites and downloaded videos. However, codec support for downloaded videos is limited, and is purely dependent on the browser used.
If you are looking to create cards using downloaded videos, I recommend mpvacious.
"},{"location":"setupasbplayer/#existing-guides","title":"Existing Guides","text":"There are a bunch of existing guides out there for asbplayer. A few are listed below.
- mikumino's mining workflow (asbplayer + jp-mining-note)
- asbplayer's list of community guides
- Shiki's mining workflow (asbplayer)
- Contact info:
boundary-of-emptiness#3065
on the Refold (JP) Discord server
- Tigy01's mining workflow (asbplayer)
- Contact info:
Tigy01#1231
on the Refold (JP) Discord server
- Brian's \"Sentence mining from Netflix and YouTube with asbplayer\"
"},{"location":"setupasbplayer/#installation","title":"Installation","text":"Install the extension from asbplayer's releases page.
"},{"location":"setupasbplayer/#configuration","title":"Configuration","text":"asbplayer's settings can be found here.
I recommend filling out the following fields as follows:
asbplayer field JPMN field Sentence Field Sentence
Definition Field Word Field Audio Field SentenceAudio
Image Field Picture
Source Field AdditionalNotes
URL Field AdditionalNotes
"},{"location":"setupasbplayer/#card-creation","title":"Card Creation","text":"To create JPMN cards with asbplayer:
- Attach asbplayer to the desired video, or drag/drop a downloaded video into the asbplayer site.
- Create the card with Yomichan
- Capture the audio (TODO specific instructions! What default keybinds?)
- Update the last card (TODO is this the exact text?)
"},{"location":"setupasbplayer/#other","title":"Other","text":" -
A common issue with asbplayer is that the SentenceReading
field may differ from the Sentence
field. See the FAQ on how to fix it.
-
You have to export the audio as mp3
if you plan on using AnkiMobile (iOS), or AnkiWeb.
"},{"location":"setupchanges/","title":"Setup Changes","text":"This page documents any changes to the setup as recorded in previous pages, as well as any important handlebars and JPMN updates. Most importantly, this documents the existance of breaking changes from external programs and if there are fixes or workarounds for them.
If something breaks, and you suspect it's due to an external program updating, please check here first! If you can't find any solution, please let me know!
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13","title":"2023/10/08 (JPMN 0.12.0.0-prerelease-13)","text":"This version of jp-mining-note fixes a bug that was introduced with a recent AJT Japanese update. This bug resulted in an Unexpected flattened.childNode
error on new cards, and prevented pitch accent information from being displayed correctly. See the Updating page on how to update the note. Afterwards, see below for the other necessary changes that must be made to properly update the note.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-ajt-config","title":"AJT Japanese Config Update","text":"This update requires you to update your AJT Japanese config settings. To do so, go to the AJT Japanese setup instructions and follow the instructions. The main changes are the removal of the \"styles\"
key, and the addition of the \"style\"
key under the \"pitch_accent\"
settings.
Note
After updating the AJT Japanese config, make sure you restart Anki. Do this before moving on to the next step.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-ajt-regen","title":"Regenerating the AJTWordPitch field","text":"After updating your AJT Japanese config settings, you will need to regenerate the AJTWordPitch field for all your cards.
Warning
This procedure will delete data from all your cards, however, under normal use, the AJTWordPitch field should only contain autogenerated content, so this shouldn't be a problem. If, for some reason, you have manually edited the AJTWordPitch field for any cards, those edits should be recorded somewhere before running this procedure.
- Run the following batch command:
empty_field AJTWordPitch\n
- Regenerate the AJT Japanese data for all of your notes.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-reformat-paoverride","title":"Reformat any entries in the PAOverrideText field","text":"Since the HTML format for displaying pronunciation data has changed, any pronunciation data that has been manually entered into the PAOverrideText field will need to be rewritten. The new format is described here.
A simple way to find all cards that contain manually edited data in the PAOverrideText field is to run the following query in the Anki browser:
PAOverrideText:_*\n
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-final-steps","title":"Final Steps","text":"After changing everything, don't forget to test that the card works! If you reached this point, then congratulations! You are finally done with updating the note! Pitch accent and pronunciation data should now be displayed correctly on all cards.
If your cards still don't display properly, then it's possible you forgot to restart Anki after updating the AJT Japanese configuration. Restart Anki to confirm the config change, and then go back and regenerate the AJTWordPitch field again.
"},{"location":"setupchanges/#v0-12-0-0","title":"2023/??/?? (JPMN 0.12.0.0)","text":"This version of jp-mining-note comes with many changes, including an entire backend javascript rework. See the Updating page on how to update the note. Afterwards, see below for the other necessary changes that must be made to properly update the note.
"},{"location":"setupchanges/#v0-12-0-0-config-rework","title":"Config Rework","text":"The _jpmn-options.js
runtime options file has been completely reworked, meaning your previous config will no longer work. With this update, the file has been replaced automatically, so the note can work for future versions.
If you have changed any runtime options before, you will need change them again. Common runtime-options (pitch accent coloring and image blur) are included as examples; remove the comment to re-enable them. To see all available runtime options, see Runtime Options: Available Options.
A backup of your previous runtime options should be made. The location of the backup is different depending on the updating method used:
JPMN ManagerCommand Line Anki2/addons21/1732829476/user_files/backup\n
(repo root)/backup\n
Note
For people using pitch accent coloring, the entire card is now highlighted with the pitch accent group. To restore the previous behavior, use these runtime options:
\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": false,\n\"autoPitchAccent.coloredPitchAccent.color.definitions\": false,\n
"},{"location":"setupchanges/#v0-12-0-0-multiple-devices","title":"Updating Multiple Devices","text":"A common issue with updating multiple devices (for example, updating your phone) is that the new runtime options file may not be synced properly. In the case that the file is not synced properly, you will get the following warning:
JPMNOptions was not defined in the options file. Was there an error?\n
The official documentation says that adding or removing a media file should fix this issue. However, I received various reports from people saying this does not work. A fool-proof workaround that is guaranteed to work is documented below.
Batch CommandsManually - Make sure all devices are synced.
-
Run the following batch command:
move_runtime_options_file_to_temp\n
-
Sync to AnkiWeb (from the computer).
-
Run the following batch command:
move_runtime_options_file_to_original\n
-
Sync to AnkiWeb (from the computer).
- On all other devices, sync from AnkiWeb.
- Make sure all devices are synced.
- Rename the
_jpmn-options.js
file to something different manually, i.e. _jpmn-options-TEMP.js
. - Sync to AnkiWeb (from the computer).
- Rename the temporary file (in the example above:
_jpmn-options-TEMP.js
) to the original name (_jpmn-options.js
). - Sync to AnkiWeb (from the computer).
- On all other devices, sync from AnkiWeb.
"},{"location":"setupchanges/#v0-12-0-0-handlebars","title":"Yomichan Handlebars","text":"Yomichan's Handlebars has been updated, with some new helpers and features being added.
- To update Yomichan's Anki Card Format, see here.
- To update your handlebars templates, see here.
After updating the templates, the following fields must be changed:
FrequencySort
: {jpmn-min-freq}
\u2192 {jpmn-frequency-sort}
- Newer users might already have this set correctly. In that case, you don't have to change anything.
YomichanWordTags
: (empty)
\u2192 {tags}
- See here for instructions on how to update Anki Card Format.
Note
Remember that these settings must be updated on every device that you use Yomichan on! This includes Android (if you use AnkiConnectAndroid), and all active Yomichan profiles.
"},{"location":"setupchanges/#v0-12-0-0-frequency-display","title":"Frequency Display","text":"The frequency at the top right now defaults to using the FrequencySort value. This is because it is usually more useful to see a summary of the values, instead of all the literal values itself.
- If you prefer the list display, see Frequencies: List Mode. Also see Frequencies: List Mode Maximum.
- If you prefer the frequency sort display but you don't have a frequency sort value, backfill the frequencies.
- If you prefer the frequency sort display but your frequency sort is somehow invalid:
- Clear out your
FrequencySort
field entirely through the following batch command: clear_field \"FrequencySort\"\n
- Backfill the frequencies.
"},{"location":"setupchanges/#v0-12-0-0-automatic-field-collapsing","title":"Automatic Field Collapsing","text":"For newer versions of Anki, you can set a field to be collapsed by default by heading over to:
(Note editor) \u2192 Fields...
\u2192 Collapse by default
Feel free to automatially collapse any fields you don't use, or very rarely use. The fields that are collapsed by default can be found here.
"},{"location":"setupchanges/#v0-12-0-0-custom-scss","title":"Custom SCSS","text":"For people who are using custom SCSS (usually through src/scss/extra
, when building the note), it is now recommended that the extra
folder is moved to the overrides/scss
folder. This is purely a stylistic change, to better separate user-defined changes and source code.
"},{"location":"setupchanges/#font-size-changes","title":"Font Size Changes","text":"The default font sizes of certain sections have been changed to be a bit bigger, in order to make kanji more readable. If you prefer the original smaller font sizes, the following CSS will revert the changes:
.hover-tooltip__word-div {\nfont-size: 1em;\n}\n.hover-tooltip__word-div b {\nfont-weight: var(--bold-font-weight);\n}\n.hover-tooltip__card--sentence-only .hover-tooltip__sent-div b {\nfont-weight: var(--bold-font-weight);\n}\n:root {\n--glossary-font-size: 1.125rem;\n}\n@media (max-width: 850px), (max-height: 700px) {\n:root {\n--glossary-font-size: 0.9375rem;\n}\n}\n
"},{"location":"setupchanges/#v0-12-0-0-final-steps","title":"Final Steps","text":"After changing everything, don't forget to test that the card works! If you reached this point, then congratulations! You are finally done with updating the note! Enjoy 0.12.x.x
and all its new features!
"},{"location":"setupchanges/#20230407-ajt-japanese-update","title":"2023/04/07 (AJT Japanese Update)","text":"AJT Japanese got updated to include automatic audio file downloading. The example config was updated to disable this by default, because having it enabled increased Anki startup time. Feel free to re-enable this if you plan on using this feature.
"},{"location":"setupchanges/#20230401-anki-2161","title":"2023/04/01 (Anki 2.1.61)","text":"Anki 2.1.61 sets Reduce motion
to be enabled by default. This breaks all animations in templates. To re-enable animations in templates, please turn this option off.
Note that this is a temporary change on Anki's side, and should be fixed at some point in the future.
"},{"location":"setupchanges/#20230318-handlebars-101","title":"2023/03/18 (Handlebars 1.0.1)","text":"The handlebars got an update to support other note types other than jp-mining-note. Documentation has still not been released on the new options, so this update has not been officially announced yet.
- See the full changelog here.
- See how to update your handlebars here.
"},{"location":"setupchanges/#20230307-ajt-anki-add-ons-update","title":"2023/03/07 (AJT Anki Add-ons Update)","text":"AJT Furigana and AJT Pitch Accent got combined into one add-on: AJT Japanese. AJT Japanese takes the place of AJT Furigana, and should've be automatically updated.
To use this new add-on, the config must be updated. This new config can be found here.
Additionally, please disable or remove the \"AJT Pitch Accent\" add-on, as it is now redundant and may interfere with \"AJT Japanese\".
"},{"location":"setupchanges/#20230222-css-injector-update","title":"2023/02/22 (CSS Injector Update)","text":"The CSS Injector was updated by the author, to support Anki versions 2.1.55 and above. Any local version of CSS Injector should be removed, and the AnkiWeb version should be used instead. If you are already using the AnkiWeb version, nothing has to be done.
See the setup instructions here.
"},{"location":"setupchanges/#v0-11-0-0","title":"2022/11/19 (JPMN 0.11.0.0)","text":" - Yomichan's handlebars was updated. See how to update your handlebars here.
- Yomichan's 'Anki Card Format' section was updated, and the following fields must be changed:
WordReadingHiragana
: (empty)
\u2192 {jpmn-word-reading-hiragana}
- See here for instructions on how to update Anki Card Format.
- If you are using the nsfw-toggle function, the option name was changed from
nsfw-toggle
to image-blur
. Please change it in your runtime options to continue using it. Example config - The way keybinds are specified has been changed (to allow keys to still function as expected even with CapsLock enabled.) Keybinds will no longer work until you update the runtime options values. For example, update
n
to KeyN
. Example config
"},{"location":"setupchanges/#everything-before","title":"Everything before","text":"Lower versions of JPMN are not recorded here. Full details of the changes can be found in the main changelog instead.
"},{"location":"setupereaders/","title":"Extra: eReaders","text":""},{"location":"setupereaders/#summary","title":"Summary","text":"I do not own any eReader, so I cannot personally test or verify any of these methods. However, there are a few ways of creating Anki Cards with various eReaders.
"},{"location":"setupereaders/#kindle","title":"Kindle","text":"One can use something like ann2html to export a Yomichan-able HTML file based on the Kindle's vocabulary builder. This allows you to add the cards through Yomichan on the PC.
"},{"location":"setupereaders/#onyx-boox","title":"ONYX BOOX","text":"ONYX BOOX internally uses Android. You should be able to follow the steps under the Android setup page in order to get this eReader working.
Also see:
- Use Boox Side Buttons to Navigate ttu Reader
"},{"location":"setupextraanki/","title":"Extra: Anki","text":""},{"location":"setupextraanki/#various-anki-resources","title":"Various Anki Resources","text":"This documentation is primarily focused on how to use this note, rather than Anki itself, so little will be written about the details of Anki here.
Instead, here is a small list of resources on setting up and using Anki itself:
- Cade's blog: Optimizing Anki for Language Learning
- Tatsumoto's blog: Setting up Anki
- Lazy Guide: Anki
- Showcases an example note type, addons used and tips
- Refold's Recommended Anki Setup
- FSRS4Anki
- Twenty Rules
- These are general rules for learning (with an SRS), written for SuperMemo. Some rules are not applicable for specifically language learning, but I believe the first 4 rules are very important.
- Awesome Anki
- \"A curated list of awesome Anki add-ons, decks and resources.\"
Note that every website here has different recommendations. You will likely have to play with the settings and actually use Anki for an extended period of time to find the most optimal setup for yourself.
"},{"location":"setupextraanki/#other-anki-add-ons","title":"Other Anki Add-ons","text":"If you're interested in copying my setup, I provide the list of addons I personally use here. I also provide a small list of other popular add-ons that I don't use, but may be useful for you.
List of Add-ons I use (click here) Documented above (I use all required and optional addons for the note type):
- Anki-Connect
- CSS Injector
- AJT Japanese
Algorithm Changing:
- FSRS4Anki Helper
Stats:
- Learning Step and Review Interval Retention
- True Retention by Card Maturity Simplfied
- Kanji Grid
Usability:
- Adjust Sound Volume
- Used to normalize volume automatically (so adjusting the volume of recorded files is not necessary)
- Advanced Browser
- Used for sorting notes by frequency
- AJT Flexible Grading
- I use this to change Anki to pass/fail
- If you are using Anki dark mode, I recommend these colors (change in the config):
\"again\": \"#ff8c74\"
\"good\": \"#9cff98\"
- Paste Images As WebP
Other:
- AnkiWebView Inspector
- Local Audio Server for Yomichan
- Yomichan Forvo Server
Useful Add-ons that I don't use (click here) - AJT Mortician
- Edit Field During Review Cloze
- Generate Batch Audio
- Review Heatmap
- Straight Reward
"},{"location":"setupextraanki/#minimalist-mode","title":"Minimalist Mode","text":"Did you know that Anki comes with a theme that makes the display a lot simpler?
If you like this look, then it can be enabled by heading over to:
Tools
\u2192 Preferences
\u2192 Distractions
\u2192 Minimalist mode
"},{"location":"setupextrayomichan/","title":"Extra: Yomichan","text":""},{"location":"setupextrayomichan/#summary","title":"Summary","text":"This page contains a bunch of completely optional tips for making the best use of Yomichan. It is expected that you have setup Yomichan properly before continuing with this page.
"},{"location":"setupextrayomichan/#yomichan-appearance","title":"Yomichan Appearance","text":"If you want to follow my exact Yomichan popup appearance:
- Go to (Yomichan settings) \u2192
Popup Appearance
. - Set
Compact glossaries
to ON. - Set
Compact tags
to OFF.
There are also plenty of CSS customizations for Yomichan listed out in the JP Resources page. Some popular customizations within that page include:
- Setting the max number of frequency lists or pitch accent dictionaries shown
- Hiding bilingual dictionaries by default, until hovered over
"},{"location":"setupextrayomichan/#yomichan-themes","title":"Yomichan Themes","text":"I personally haven't changed the theme / color scheme of Yomichan. However, many others have. Here's a small list of some popular custom themes:
- Rudnam's Dark Mode
- Nord Theme
- Tutorial on editing Yomichan's color scheme
"},{"location":"setupextrayomichan/#jmdict","title":"JMdict","text":"If you are planning on using the JMdict dictionary, the ones provided from most sources (TMW's google drive - The \"JMdict Extra\" version is fine, Matt's video on Yomichan, and Yomichan's main github page) are all somewhat outdated, which usually means less accurate definitions and less coverage.
To get the most recent version of JMdict, download it from the official site (download JMdict_e_examp.gz
) and use yomichan-import to get the latest JMdict version available.
If you don't want to compile it from source, I provide a download link here, which should only be a few months stale at most.
"},{"location":"setupextrayomichan/#other-dictionaries","title":"Other dictionaries","text":" -
JMdict Forms
This is a dictionary placed in the UtilityDictionaries
field by default. Although I don't use it when studying Anki, it helps to use this when creating Anki notes for monolingual definitions.
-
I highly recommend getting some pitch accent dictionaries and frequency lists if you have not already, as these will be shown and used in the note type. See TheMoeWay's folder to browse through some examples.
I personally recommend NHK, \u5927\u8f9e\u6cc9, and \u30a2\u30af\u30bb\u30f3\u30c8\u8f9e\u5178.
-
JPDB frequency list
I personally recommend using the JPDB frequency list as one of your frequency lists, because it has high word coverage, and seems very high quality (particularly for fiction content).
-
JPDB Kanji dictionary
This dictionary is extremely useful to see the most popular words where a particular kanji is used. I like using this to see how rare a kanji is at a glance.
This synergizes well with kanji frequency dictionaries.
"},{"location":"setupextrayomichan/#local-audio-server-for-yomichan","title":"Local Audio Server for Yomichan","text":"See here if you want to be able to create Anki cards nearly instanteously, and fetch audio without a working internet connection.
I personally recommend using this setup if you can.
"},{"location":"setupgoldendict/","title":"goldendict (TODO)","text":"TODO
WordReading
must be filled with AJT Japanese WordReadingHiragana
cannot be backfilled with AJT Japanese currently, since there's no option to only generate the kana reading Key
cannot be autofilled? probably the biggest problem with this setup
"},{"location":"setupios/","title":"Extra: iOS","text":""},{"location":"setupios/#summary","title":"Summary","text":"On iOS (iPhone and iPad), it is possible to review JPMN cards. However, I am not currently aware of a setup that can create cards with iOS. If you do know of a setup that can create cards on iOS, please let me know!
It is expected that you have setup Anki and Yomichan properly on your desktop machine before continuing with this page.
"},{"location":"setupios/#reviewing","title":"Reviewing","text":"To review Anki cards on iOS, use AnkiMobile.
You'll probably notice that AnkiMobile costs a bit of money. If you don't want to pay for whatever reason, the best free alternative is to simply use AnkiWeb.
Warning
Other \"Anki\"-like apps on the App Store are not officially supported by Anki, and will almost certainly not work with this note. Please only use AnkiMobile or AnkiWeb if you are on iOS. More info can be found from the official Anki documentation here.
Warning
This note does not officially support AnkiWeb as of writing this (2023/06/21). However, the main features of the note will almost likely still work.
In order to review the same cards on desktop, you must sync your collection with AnkiWeb. More tech savy users can sync their collections using a self-hosted server.
"},{"location":"setupios/#tap-gestures","title":"Tap Gestures","text":"You will likely tap on various parts of the screen when reviewing, to reveal various parts of the card. However, AnkiMobile has tap gestures are enabled by default, which will interfere with using the note.
Tap gestures can be customized under:
(settings gear) \u2192 Review
\u2192 Taps
I recommend using the following tap gesture settings:
Side Position Action When question shown Bottom Left Show Answer When question shown Bottom Center Show Answer When question shown Bottom Right Show Answer When answer shown Bottom left Replay Audio (Everything else) None To explain what the above does:
-
There is no other way to show the answer outside of gestures. There is usually nothing on the bottom third of the screen when the question is shown, so it is safe to use that to show the answer. This is compared to the top third of the screen, where various parts of the card can be interacted with, such as the info circle and click cards.
-
You may have noticed that audio buttons do not show on AnkiMobile. This is due to an AnkiMobile bug. In order to emulate the intended experience (where the audio buttons are shown on the bottom left), I recommend setting the \"Bottom Left\" tap gesture to \"Replay Audio\".
"},{"location":"setupjidoujisho/","title":"jidoujisho (TODO)","text":"TODO actually test this app out, and update the fields / limitations as necessary
"},{"location":"setupjidoujisho/#limitations","title":"Limitations","text":""},{"location":"setupjidoujisho/#major","title":"Major","text":"None that I am aware of.
"},{"location":"setupjidoujisho/#minor","title":"Minor","text":" Sentence
: The tested word won't be automatically bolded on export (TODO: will be possible if/when handlebars is implemented) PrimaryDefinition
field is a bit limited, cannot stylize the definition output as much as Yomichan, such as: - The first line / dictionary name cannot be removed
- Lists cannot be collapsed into a compact list
- Pitch accent display is generated from AJT Japanese, and there is no control on card export.
- Note that pitch accent can still be overwritten per card when necessary.
- Also note that you should be able to see the exported pitch accent within
PAGraphs
. This can be used as a reference if you want to override the pitch accent.
"},{"location":"setupjidoujisho/#extremely-minor","title":"Extremely Minor","text":" SentenceReading
and AJTWordPitch
: cannot be automatically generated on card export. These must be batch filled later, on PC. FrequenciesStylized
: List of frequencies cannot be exported, only the sort value can WordReadingHiragana
can contain katakana. This should ideally be 100% hiragana, but this is a very minor issue (TODO explanation: the field is only used for word indicator queries, not pre-processed in order to optimize for speed, so must be processed when card is added. katakana can interfere with the process, but it is very unlikely to have a katakana-reading word to have the same reading as a hiragana-reading word)
"},{"location":"setupjidoujisho/#setup","title":"Setup","text":"jp-mining-note fields jidoujisho's creator fields Key Term Word Term WordReading Furigana PAOverride PAOverrideText AJTWordPitch PrimaryDefinition Meaning PrimaryDefinitionPicture Sentence Sentence SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Notes Hint HintNotHidden IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture Image WordAudio Term Audio SentenceAudio Sentence Audio PAGraphs Pitch Accent PAPositions FrequenciesStylized FrequencySort Frequency PASilence WordReadingHiragana Reading YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment Context - additionally, highly recommend using a
jidoujisho
tag to all cards generated from jidoujisho (under the Tags
creator field?) - currently does nothing, but may be useful for future compatability purposes
"},{"location":"setupjidoujisho/#notes","title":"Notes","text":" - Binary fields can use any arbitrary field, like
Term
. The content of the field doesn't matter, what matters is that the field is filled.
"},{"location":"setupjl/","title":"JL (TODO)","text":"TODO
- are readings in plain furigana form?
- if not, might have to auto generate with AJT Japanese
- can the PrimarySpelling JLField be set to multiple Anki fields?
- can an Anki field be set to multiple JLFields?
- how do frequencies look? Can be used properly?
"},{"location":"setupmpvacious/","title":"mpvacious","text":"mpvacious is a user script made for of mpv, a cross platform media player. mpv itself can be used on pretty much anything, including streamed videos. However, mpvacious
was designed for downloaded videos, and almost certainly does not work on streamed videos.
If you are looking to create cards using streamed videos, I recommend asbplayer.
"},{"location":"setupmpvacious/#installation","title":"Installation","text":"Installation steps for mpvacious can be found here.
You must install this under your mpv scripts folder. This scripts
folder does not exist by default; it must be created manually.
Expected file structure (click here) WindowsmacOS and Linux C:/Users/USERNAME/AppData/Roaming\n\u2514\u2500 mpv\n \u2514\u2500 scripts\n \u2514\u2500 mpvacious\n \u251c\u2500 ankiconnect.lua\n \u251c\u2500 main.lua\n \u251c\u2500 subs2srs.lua\n \u2514\u2500 ...\n
~/.config\n\u2514\u2500 mpv\n \u2514\u2500 scripts\n \u2514\u2500 mpvacious\n \u251c\u2500 ankiconnect.lua\n \u251c\u2500 main.lua\n \u251c\u2500 subs2srs.lua\n \u2514\u2500 ...\n
"},{"location":"setupmpvacious/#configuration","title":"Configuration","text":"You will have to change mpvacious's configuration in order for mpvacious to work with JPMN.
Note
In case nothing works, always make sure to check the official documentation, as it is guaranteed to have the latest instructions if they ever change.
WindowsMac / Linux (Terminal) - Navigate to
%APPDATA%\\Roaming
You can access this by opening the file manager, and typing %APPDATA%\\Roaming
in the location field. - Create the
mpv
folder if it doesn't exist, and open the folder. - Create the
script-opts
folder if it doesn't exist, and open the folder. By now, you should be under: %APPDATA%\\Roaming\\mpv\\script-opts\n
- Create a text file with your favorite text editor. If you do not have any custom text editor downloaded, notepad should work. TODO exact steps on creating the text file
-
Copy/paste the following, and save as subs2srs.conf
:
Example config file (click here) # A full example config file can always be found in the mpvacious repository:\n# - https://github.com/Ajatt-Tools/mpvacious#configuration\n# - https://github.com/Ajatt-Tools/mpvacious/blob/master/.github/RELEASE/subs2srs.conf\n# ================= #\n# REQUIRED SETTINGS #\n# ================= #\n# These settings are required in order to be usable by JPMN.\n# Model names are listed in `Tools -> Manage note types` menu in Anki.\nmodel_name=JP Mining Note\n# Field names as they appear in the selected note type.\n# If you set `audio_field` or `image_field` empty,\n# the corresponding media file will not be created.\nsentence_field=Sentence\n#secondary_field=SentEng # Not used by the note. This is ignored entirely.\naudio_field=SentenceAudio\nimage_field=Picture\n# ========================= #\n# COMMONLY CHANGED SETTINGS #\n# ========================= #\n# Uncomment to disable native language subs entirely.\n#secondary_sub_visibility=auto\n# If you do not want the Anki browser to appear every time you add a card,\n# uncomment the following:\n#disable_gui_browse=yes\n# ====================== #\n# MEDIA QUALITY SETTINGS #\n# ====================== #\n# The following settings provide saner defaults to audio and image quality,\n# when using opus and webp. Feel free to play around with these as you see fit.\n# Sane values are 16k-32k for opus, 64k-128k for mp3.\naudio_bitrate=32k\n# Quality of produced image files. 0 = lowest, 100=highest.\n#snapshot_quality=15\nsnapshot_quality=50\n# Image dimensions\n# If either (but not both) of the width or height parameters is -2,\n# the value will be calculated preserving the aspect-ratio.\n#snapshot_width=-2\n#snapshot_height=200\nsnapshot_width=800\nsnapshot_height=-2\n
Ensure that your file is indeed a .conf file when saved. If your file browser says that it is a text file, then the file was likely incorrectly saved as subs2srs.conf.txt
. TODO exact instructions on renaming
Expected file structure (click here) C:/Users/Username/AppData/Roaming\n\u2514\u2500 mpv\n \u2514\u2500 script-opts\n \u2514\u2500 subs2srs.conf\n
The following installs the correct configuration, along with all the recommended settings stated below.
mkdir -p ~/.config/mpv/script-opts\n# TODO change this to the master branch eventually\ncurl https://raw.githubusercontent.com/arbyste/jp-mining-note/dev/docs/docs/assets/setupmpvacious/subs2srs.conf > ~/.config/mpv/script-opts/subs2srs.conf\n
Be sure to restart mpv after changing the config to make sure your configuration is applied.
The example configuration includes plenty of commonly changed settings by default. In general, I recommend looking through the example configuration to see if there are other options that you may want to change.
"},{"location":"setupmpvacious/#card-creation","title":"Card Creation","text":"To create JPMN cards with mpvacious:
- Create a card from Yomichan. The text is usually gotten via a texthooker.
- Within mpv, navigate to the desired subtitle, and then press Ctrl+M.
- If you instead want to add audio from multiple subtitles at a time:
- Navigate to the beginning subtitle.
- Press A+C
- Navigate to the ending subtitle.
- Press M.
- Much more can be found under mpvacious's usage section.
"},{"location":"setupmpvacious/#other","title":"Other","text":" -
A common issue with mpvacious is that the SentenceReading
field may differ from the Sentence
field, say, if you export multiple subtitles into one card. See the FAQ on how to fix it.
-
You have to export the audio as mp3
if you plan on using AnkiMobile (iOS), or AnkiWeb.
"},{"location":"setuptextmedia/","title":"Setup: Text & Media","text":""},{"location":"setuptextmedia/#overview","title":"Overview","text":"This page is dedicated to providing resources on how to do the following:
- Getting the actual text to use Yomichan on.
- Getting the pictures and/or sentence audio from the media.
There are plenty of well established resources out there on how to do just that, ranging from software to written & video guides. Instead of repeating what others have already said, those programs and guides will be linked.
If you are looking to setup jp-mining-note, see this page instead.
Note
If you already have a sentence mining workflow, you can likely skip to this section. TODO update link!
"},{"location":"setuptextmedia/#troubleshooting-support","title":"Troubleshooting & Support","text":"If you are having troubles with any of the guides or programs below, I unfortunately will not be able to provide very detailed support.
Instead, I would recommend that you contact the creators of the guides / programs, or the communities surrounding said guides / programs.
Additionally, the guides listed here usually do not use JPMN, and instead link to other note types. This shouldn't be an issue as long as you change the appropriate the field names.
"},{"location":"setuptextmedia/#getting-the-text-to-create-the-cards","title":"Getting the Text to Create the Cards","text":"I use a texthooker setup, which is able to extract subtitles or text into the browser. Once the text is on the browser, you can use Yomichan to select the word and create the Anki card (by clicking on the green plus button).
The standard texthooker setup works for most games, and any show with subtitle files.
"},{"location":"setuptextmedia/#texthooker-websocket-based","title":"Texthooker: Websocket based","text":"These pages display the hooked content, where the hooked content is communicated via Websockets. Websocket based texthookers are better than the classic clipboard-based texthookers in almost every aspect:
- They are generally faster and more reliable.
- They do not flood your clipboard.
- They do not require an extension that constantly polls the clipboard.
However, it requires more specialized coordination between programs. Fortunately, most standard workflows support websockets nowadays.
Resources (click here) -
Renji's Texthooker Page (recommended)
- Open source and more featureful alternative to the more popular Anacreon's texthooker page.
- This texthooker page comes with built in support for both websockets and clipboard inserter plugins.
- I use these settings to make the text more compressed.
-
exSTATic (recommended for stats lovers)
- Its primary use is for automatic stats collection and visualizing said statistics.
- Integrates seamlessly with many workflows, including non-texthooker related workflows.
- Uses a custom texthooker page, which connects with Textractor with its own custom extension.
- A video installation guide is available on the project's README page.
Supported Workflows:
- Textractor with textractor-websocket or TextractorSender
- mpv with mpv_websocket
Legacy Resources (click here) These resources are considered legacy, and I highly recommend using the standard resources above in favor of these.
-
Marv's Websocket Userscript
- A more featureful version of the patch below.
- Written for Anacreon's texthooker page.
-
Zetta's Custom Patch
- Patch Instructions for existing clipboard-based texthookers.
- This patch is intended to be used in conjunction with this Textractor extension.
- This patch was written for Anacreon's texthooker page. However, it will likely work for most other texthooker pages.
Instructions to use the patch (click here) Warning
This is a monkey patch, even according to the author. Now that better alternatives have came out (see above), I recommend to use said alternatives.
- Download your favorite texthooker page into a raw html file.
- Copy/paste the code below to the very end of the raw html file.
- If you are currently viewing the page, refresh.
<script>\nlet socket = null;\nlet wsStatusElem = null;\nconst createStatusElem = () => {\nwsStatusElem = document.createElement(\"span\")\nlet node = document.getElementById('menu').firstChild\nwsStatusElem.setAttribute(\"class\", \"menuitem\")\nwsStatusElem.addEventListener('click', (e) => {\nif(wsStatusElem.innerText == \"Reconnect\") {\nconnect()\n}\n})\nnode.insertBefore(wsStatusElem, node.firstChild)\n}\nconst updateStatus = (connected) => {\nif(wsStatusElem === null) { createStatusElem() }\nwsStatusElem.innerText = connected ? \"Connected\" : \"Reconnect\"\nwsStatusElem.style.cssText = \"margin-right: 1.5em; display: inline-block;\"\nwsStatusElem.style.cssText += connected ? \"color:rgb(24, 255, 24);\" : \"color:rgb(255, 24, 24);\"\n}\nconst connect = () => {\nsocket = new WebSocket(\"ws://localhost:6677/\")\nsocket.onopen = (e) => { updateStatus(true) }\nsocket.onclose = (e) => { updateStatus(false) }\nsocket.onerror = (e) => { updateStatus(false); console.log(`[error] ${e.message}`) }\nsocket.onmessage = (e) => {\nlet container = document.getElementById('textlog')\nlet textNode = document.createElement(\"p\")\ntextNode.innerText = e.data\ndocument.body.insertBefore(textNode, null)\n}\n}\nconnect()\n</script>\n
(Original discord message, on TMW server. Thanks Zetta#3033 for the code.)
"},{"location":"setuptextmedia/#texthooker-clipboard-based","title":"Texthooker: Clipboard based","text":"These pages display the hooked content, where the hooked content is communicated via automated clipboard (copy/paste) tools. Most classic setups documented are for clipboard based texthooker pages. If possible, I highly recommend trying out a websocket based texthooker approach instead.
Resources (click here) - Clipboard Inserter Redux (Extension)
- Updated version of the original Clipboard Inserter extension
- Still using manifest v2, so this extension will be deprecated in the future unless updated
- Lap Clipboard Inserter (Extension) (Firefox)
- Rewritten version of the original Clipboard Inserter extension, to use manifest v3
- Works on Firefox, but Chrome is currently not supported. Use Clipboard Inserter Redux if you are using a chromium based browser.
- Renji's Texthooker Page (recommended)
- Open source and more featureful alternative to the more popular Anacreon's texthooker page.
- I use these settings to make the text more compressed.
Guides (click here) - TMW: Texthooker & Visual Novels
- Lazy Guide: Texthooker
- stegatxins0's mining guide: Texthooker
- Anime Cards: Texthooker & Visual Novels
Legacy Resources (click here) These resources are considered legacy, and I highly recommend using the standard resources above in favor of these.
- Original Clipboard Inserter (Extension) (WARNING: NO LONGER MAINTAINED!)
- WARNING: No longer works on Firefox as of Firefox version 107.0. Use either extensions above if you are using Firefox.
- Anacreon's Texthooker Page
- TMW's Texthooker Page
"},{"location":"setuptextmedia/#game-like-content-getting-text","title":"Game-Like Content: Getting Text","text":"The following are primarily for text-heavy games, such as visual novels.
Resources (click here) - Textractor (recommended)
- agent
- This is a good fallback for when Textractor doesn't work
Guides (click here) - TMW: Installing Visual Novels
- TMW: Texthooker & Visual Novels
- Anime Cards: Texthooker & Visual Novels (slightly outdated compared to others)
- Lazy Guide: Playing Visual Novels on Mobile
- Playing Emulated DS, 3DS, PSP and Gameboy Advanced games on Android devices
- Contact info:
OrangeLightX#2907
on the Refold (JP) Discord server or TMW server
- See this section to get sentence audio and images
"},{"location":"setuptextmedia/#video-content-getting-text-sentence-audio-picture","title":"Video Content: Getting Text, Sentence Audio, Picture","text":"Video content includes streamed content (Youtube, Netflix, etc.) and locally downloaded files.
Resources (click here) - mpvacious (recommended for downloaded videos / if you are using mpv)
- Add-on for mpv, a cross platform media player. Personally tested.
- Basically universal codec support since it uses mpv.
- This addon has capabilities to extract the video clip itself as the form of a gif (autoplayable webp).
- See here for basic setup instructions.
- asbplayer (recommended for streamed sites)
- Cross platform (chromium) browser video player. Personally tested.
- Works on video streaming sites, as well as downloaded videos.
- Does not require a texthooker page: subtitles are displayed on the site itself.
- Codec support is limited, and depends on the browser used.
- See here for basic setup instructions.
- Animebook
- Cross platform (chromium) browser video player.
- Does not require a texthooker page: subtitles are displayed on the site itself.
- Codec support is limited, and depends on the browser used.
- See Cade's sentence mining guide for basic setup instructions. Note that the aformentioned guide is not using JPMN.
- Contact info:
eminent#8189
on Perdition's server or TMW server)
- All of the above require subtitle files to function. See here and/or here for some websites where you can get subtitles from.
- One challenge for video content is that subtitles are usually not aligned properly if the subtitles are downloaded separately from the video. I've always used a combination of mkvextract (to extract the subtitle file from the
.mkv
file) and alass (to align the native subtitles with reference subtitles, usually in a different language) to get the job done. If you want more options, see this page.
Other:
- jidoujisho
- Android e-book reader and media player. Advertises itself as an all-in-one app.
- Immersive
- Add-on for MPV. Alternative to mpvacious.
- WARNING: This is potentially outdated and/or abandoned. The most recent commit as of writing (2022/10/19) was done in 2022/01/27. This is listed here for completeness only.
"},{"location":"setuptextmedia/#manga-getting-text","title":"Manga: Getting Text","text":"mokuro (recommended) mokuro pre-processes manga, so you don't have to run any OCR program afterwards.
Guides:
- Lazy guide (recommended)
- (For Windows users) Make sure to check the \"Add Python to Path\" on install.
- If you are using online processing (google colab), be sure that you are using the gpu to speed up the process.
- Josuke's mokuro setup guide
- Contact info:
Josuke#7212
on the Refold (JP) Discord server - This doesn't include instructions on how to process online (whereas the Lazy guide does)
Other Resources:
- If you are on Android, this can be paired with Anki Connect for Android to create Anki cards.
- WeebAlt's RemoteMokuro setup
- This includes setup instructions on using Mokuro remotely (from google drive, i.e. no disk storage)
- leermangamokureado is a site with various manga ran through mokuro.
If any error occurs, check the following:
-
Check your Python version (python --version
, or python3 --version
). Python 3.10 is not supported yet.
If your Python version is too old, I recommend using pyenv (for Linux users). Linux users can use the automatic installer. For Windows users, it should be sufficient to uninstall mokuro
, install a newer version of Python, and then re-install mokuro with the newer version.
-
Make sure your directory is a string and not a number. For example, mokuro ./01
on unix, and mokuro .\\01
on Windows.
Manga OCR Manga OCR allows you to automatically OCR any image. As the name suggests, this works best on manga.
Guides:
- Lazy guide (Windows)
"},{"location":"setuptextmedia/#books-epubs-htmlz-pdf","title":"Books (EPUBs, HTMLZ, PDF)","text":"As long as you're not using a scan (image-based), the text should already be available. Below will list a few ways to view these files in a browser to Yomichan.
Resources (click here) - \u30c3\u30c4 Ebook Reader (EPUBs, HTMLZ) (recommended)
- Mozilla's PDF Viewer (PDF)
Other:
- jidoujisho
- Android e-book reader and media player. Advertises itself as an all-in-one app.
- Uses \u30c3\u30c4 Ebook Reader as its backend.
Guides (click here) - Like with Mokuro, if you are on Android, this can be paired with Anki Connect for Android to create Anki cards.
"},{"location":"setuptextmedia/#audiovideo-with-no-subtitles","title":"Audio/Video with No Subtitles","text":"KanjiEater's AudiobookTextSync is a relatively new set of tools that generates subtitles using machine learned models.
"},{"location":"setuptextmedia/#getting-images-sentence-audio-manually","title":"Getting Images & Sentence Audio Manually","text":"Sometimes, there is no easy way to get the image and sentence audio other than with a screen recorder. The primary example for this is game-like content.
Here are the two popular approaches to automatically adding the image and sentence audio:
ShareX (Windows) ShareX
- Windows media recorder which can both take screenshots and record audio. Personally tested.
Guides:
- stegatxins0's mining guide: ShareX (recommended)
- The scripts written here works by default with this note. These scripts are meant used with stegatxins0's setup.
- Xeliu's mining guide: ShareX
- ShareX setup is based off of stegatxins0's setup
- Anime Cards: Handling Media
- Not recommended: introduces additional steps compared to the above two guides
ames (Linux) ames
- ShareX alternative for Linux. Personally tested.
- Primarily used to automate audio and picture extraction to the most recently added Anki card.
"},{"location":"setuptextmedia/#resource-lists","title":"Resource Lists","text":"Other websites have significantly larger resource lists that may prove useful for you.
Resource Lists (click here) - TheMoeWay
- Tatsumoto
- itazuraneko
- kuzuri
- Refold (JP) (Old Google doc) (Mirror)
- Refold (General) (Mirror)
- IgrecL/japanese
- donkuri/learn-japanese
"},{"location":"setupyomichan/","title":"Setup: Yomichan","text":""},{"location":"setupyomichan/#overview","title":"Overview","text":"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.
"},{"location":"setupyomichan/#preliminary-steps","title":"Preliminary Steps","text":" -
If you have used Yomitan before, please make a backup of your settings (just in case).
-
On top of the standard dictionaries, I highly recommend installing some frequency and pitch accent dictionaries, as that information is used by jp-mining-note. Many of these dictionaries can be found within TheMoeWay's drive. These dictionaries are installed in the exact same way as the standard Yomitan dictionaries.
In particular, I recommend the JPDB frequency list.
"},{"location":"setupyomichan/#yomichan-fields","title":"Yomichan Fields","text":"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
, and \"Deck\" to whatever your Anki deck is. - Copy and paste the following values into the fields (the custom helpers won't be available in the dropdown arrow):
Click here to see the fields to copy and paste. Anki Fields Yomichan Format Key {expression}
Word {expression}
WordReading {furigana-plain}
PAOverride PAOverrideText AJTWordPitch PrimaryDefinition {jpmn-primary-definition}
PrimaryDefinitionPicture Sentence {cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}
SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden *IsSentenceCard *IsTargetedSentenceCard *IsClickCard *IsHoverCard *IsHintCard *IsSentenceFirstCard *IsAudioCard *PAShowInfo *PATestOnlyWord *PADoNotTest *PASeparateWordCard *PASeparateSentenceCard *SeparateAudioCard *SeparateSentenceAudioCard Picture WordAudio {audio}
SentenceAudio PAGraphs {jpmn-pitch-accent-graphs}
PAPositions {jpmn-pitch-accent-positions}
FrequenciesStylized {jpmn-frequencies}
FrequencySort {jpmn-frequency-sort}
PASilence [sound:_silence.wav]
WordReadingHiragana {jpmn-word-reading-hiragana}
YomichanWordTags {tags}
SecondaryDefinition {jpmn-secondary-definition}
ExtraDefinitions {jpmn-extra-definitions}
UtilityDictionaries {jpmn-utility-dictionaries}
CardCache 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 fields used to determine the resulting card type, 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 with anything, e.g. 1
.
See the Changing Card Type page for more info.
The custom helpers like {jpmn-primary-definition}
is not provided by Yomitan by default. See the section below to make these helpers usable.
"},{"location":"setupyomichan/#yomichan-templates","title":"Yomichan Templates","text":"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 helpers 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. {{~! ~}}\n{{~! ==================== jp-mining-note handlebars ===================== ~}}\n{{~! v1.0.12 ~}}\n{{~! ~}}\n{{~! https://arbyste.github.io/jp-mining-note/ ~}}\n{{~! ------------------------------------------------------- ~}}\n{{~! ================ Dictionary Categorization Options ================= ~}}\n{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n{{~!\nA bunch of JP and CN bilingual dictionaries covered by default,\nincluding: JMdict, \u65b0\u548c\u82f1, CEDICT, etc\n~}}\n{{~#set \"bilingual-dict-regex\"~}} ^(([Jj][Mm][Dd]ict)(.*)|(.*)\u65b0\u548c\u82f1(.*)|\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|KireiCake|NEW\u658e\u85e4\u548c\u82f1\u5927\u8f9e\u5178|CEDICT|CC-CEDICT|CantoDict|Canto CEDICT|Words\\.hk C-E FS|CE Wiktionary|CC-Canto|Jitendex(.*)|ADD_BILINGUAL_DICTIONARIES_HERE)$ {{~/set~}}\n{{~#set \"utility-dict-regex\"~}} ^(NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178|\u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003|[Jj][Mm][Dd]ict( Surface)? Forms|JMedict)$ {{~/set~}}\n{{~#set \"ignored-dict-regex\"~}} ^(ADD_IGNORED_DICTIONARIES_HERE)$ {{~/set~}}\n{{~! ====================== Selected Text Options ======================= ~}}\n{{set \"opt-selection-text-enabled\" true}}\n{{set \"opt-selection-text-dictionary\" true}}\n{{set \"opt-selection-text-glossary\" true}}\n{{set \"opt-selection-text-glossary-attempt-bold\" true}}\n{{~! ==================== Frequency Sorting Options ===================== ~}}\n{{~! See here for the official documentation on how these options work:\nhttps://github.com/MarvNC/JP-Resources#freq-settings ~}}\n{{~#set \"opt-ignored-freq-dict-regex\"~}} ^(JLPT.*)|(HSK.*)$ {{~/set~}}\n{{~#set \"opt-ignored-freq-value-regex\"~}} \u274c {{~/set~}}\n{{~#set \"opt-keep-freqs-past-first-regex\"~}} ^()$ {{~/set~}}\n{{~set \"opt-no-freq-default-value\" 9999999 ~}}\n{{~set \"opt-freq-sorting-method\" \"harmonic\" ~}} {{~! \"min\", \"first\", \"avg\", \"harmonic\" ~}}\n{{~set \"opt-grammar-override\" true ~}}\n{{~set \"opt-grammar-override-value\" 0 ~}}\n{{~#set \"opt-grammar-override-dict-regex\"~}} ^(\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b|JLPT\u6587\u6cd5\u89e3\u8aac\u307e\u3068\u3081|\u3069\u3093\u306a\u3068\u304d\u3069\u3046\u4f7f\u3046 \u65e5\u672c\u8a9e\u8868\u73fe\u6587\u578b\u8f9e\u5178|\u7d75\u3067\u308f\u304b\u308b\u65e5\u672c\u8a9e)$ {{~/set~}}\n{{~! ============== Dictionary First Line Removal Options =============== ~}}\n{{~set \"opt-wrap-first-line-spans\" true ~}}\n{{~! valid values: \"except\", \"only\" ~}}\n{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~!\nJMdict and jitenbot dictionaries from stephenmk are ignored\n(the latter because the handlebars cannot properly detect the first line.)\nIn particular, removing the first line from jitenbot dictionaries with handlebars alone\nis not trivial, so that feature will not be supported.\n~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv|\u6545\u4e8b\u30fb\u3053\u3068\u308f\u3056\u30fb\u6163\u7528\u53e5\u30aa\u30f3\u30e9\u30a4\u30f3|\u56db\u5b57\u719f\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u56fd\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u5927\u8f9e\u6797\u3000\u7b2c\u56db\u7248|\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u516b\u7248)$ {{~/set~}}\n{{~! ========================== Other Options =========================== ~}}\n{{~set \"opt-primary-def-one-dict-entry-only\" false ~}}\n{{~set \"opt-jmdict-list-format\" true ~}}\n{{~! ======================== Plaintext Options ========================= ~}}\n{{~!\nWARNING: I recommend not changing these options if you are using the\njp-mining-note template. These options will change the general layout\nof the HTML, which will prevent certain features or stylizations\nfrom properly working. (If you aren't using jp-mining-note, please feel\nfree to change these options!)\nInstead of using these options, see here:\nhttps://aquafina-water-bottle.github.io/jp-mining-note/definitions/\nThese hide specific elements using CSS instead of modifying the raw HTML\nstructure behind it.\n~}}\n{{~set \"opt__plaintext__enabled\" false ~}}\n{{~set \"opt__plaintext__one-dict-entry-only-no-list\" false ~}}\n{{~set \"opt__plaintext__remove-dictionary-tag\" false ~}}\n{{~set \"opt__plaintext__remove-first-line-enabled\" false ~}}\n{{~! ============== ORIGINAL YOMITAN TEMPLATE CODE BELOW ============== ~}}\n
-
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 YOMITAN TEMPLATE CODE ABOVE =============== ~}}\n{{~! v1.0.12 ~}}\n{{~!\n==================\nhelper functions\n==================\n~}}\n{{#*inline \"s\"}}{{/inline}}\n{{~! categorizes into 4 types: \"ignored\", \"bilingual\", \"utility\", or \"monolingual\" ~}}\n{{~#*inline \"jpmn-get-dict-type\"~}}\n{{~#scope~}}\n{{~#set \"rx-match-ignored\" ~}}\n{{~#regexMatch (get \"ignored-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-utility\" ~}}\n{{~#regexMatch (get \"utility-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-bilingual\" ~}}\n{{~#regexMatch (get \"bilingual-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if (op \"!==\" (get \"rx-match-ignored\") \"\")~}}\n ignored\n {{~else if (op \"!==\" (get \"rx-match-utility\") \"\")~}}\n utility\n {{~else if (op \"!==\" (get \"rx-match-bilingual\") \"\")~}}\n bilingual\n {{~else~}}\n {{~! assumed that anything else is a monolingual dictionary ~}}\n monolingual\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! returns \"\" if selection text is disabled, or if none existed in the first place ~}}\n{{~#*inline \"_jpmn-selection-text\"~}}\n {{~! text-mode != \"\" and text-mode > 0 ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-enabled\") true)~}}\n {{~! removes leading and trailing whitespace ~}}\n {{~#regexReplace \"^\\s+|\\s+$\" \"\" \"g\"~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n {{~/regexReplace~}}\n {{~/if~}}\n{{~/inline~}}\n{{~! checks that the selection text is indeed a dictionary (returns the text if true, nothing if false) ~}}\n{{~#*inline \"_jpmn-check-dictionary\"~}}\n {{~#scope~}}\n {{~#set \"selection-is-dictionary\" false}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" (get \"selection\") dictionary)~}}\n {{~#set \"selection-is-dictionary\" true ~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"===\" (get \"selection-is-dictionary\") true)~}}\n {{~get \"selection\"~}}\n {{~else~}}\n {{~! null ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n Gives the raw glossary as the search string\n (for searching to see if the selected text is a part of a dictionary)\n Remember: we should NOT use _jpmn-glossary-single because it preprocesses the text!\n If the selected text was on the first line and the first line is removed,\n then using _jpmn-glossary-single will fail to find the selected text!\n~}}\n{{#*inline \"_jpmn-glossary-single-search\"}}\n {{~#scope~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/scope~}}\n{{/inline}}\n{{~! escape a regex string: https://stackoverflow.com/a/6969486~}}\n{{~! /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' ~}}\n{{~! escapes the `regexString` regex to allow it to be used like a normal search in a string ~}}\n{{#*inline \"_jpmn-escape-regex\"}}\n {{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~regexString~}}{{~/regexReplace~}}\n{{/inline}}\n{{~#*inline \"_jpmn-get-dict-if-glossary-selected\"~}}\n {{~#scope~}}\n {{~#set \"result-dictionary\" null}}{{/set~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"search-def\"}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{/set~}}\n {{~#set \"search-regex-match\"}}\n {{~#regexMatch (get \"search-selection\") \"gu\"}}{{~get \"search-def\"~}}{{/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"result-dictionary\") null)\n (op \"!==\" (get \"search-regex-match\") \"\")\n )~}}\n {{~#set \"result-dictionary\" dictionary}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"result-dictionary\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n searches dictionary, determined by `opt-first-definition-type`\n - (opt-first-definition-type === bilingual) -> bilingual dictionaries are searched first\n - (opt-first-definition-type === monolingual) -> monolingual dictionaries are searched first\n~}}\n{{~#*inline \"_jpmn-search-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~#if (op \"===\" (get \"opt-first-definition-type\") \"bilingual\")~}}\n {{~#set \"first-definition-search-type-1\" \"bilingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"monolingual\"}}{{/set~}}\n {{~else~}}\n {{~#set \"first-definition-search-type-1\" \"monolingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"bilingual\"}}{{/set~}}\n {{~/if~}}\n {{~! first-dictionary === null <=> no valid dictionary was found ~}}\n {{~#set \"first-dictionary\" null}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-1\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! uses other dictionary type, last resort ~}}\n {{~#if (op \"===\" (get \"first-dictionary\") null)~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-2\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~/if~}}\n {{~#get \"first-dictionary\"~}}{{~/get~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n return null\n~}}\n{{~#*inline \"_jpmn-check-dictionary-and-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if\n (op \"&&\" (op \"===\" (get \"result\") \"\")\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return null\n if (able to detect dictionary of which the selection-text is highlighting):\n return \"uses-glossary\"\n return null\n~}}\n{{~#*inline \"_jpmn-selection-uses-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text is a dictionary -> null ~}}\n {{~else if\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text dict found -> \"uses-glossary\" ~}}\n uses-glossary\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n if (selection-text-glossary is not enabled):\n return first-dictionary (determined by `opt-first-definition-type`)\n return null\n else:\n return first-dictionary (determined by `opt-first-definition-type`)\n~}}\n{{~#*inline \"_jpmn-get-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~! first checks selection text ~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"selection\") \"\")~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary-and-glossary . ~}}{{/set~}}\n {{~! doesn't return a dictionary if opt-selection-text-glossary is false b/c ~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"result\") \"\")\n (op \"===\" (get \"opt-selection-text-glossary\") false)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-search-primary-definition-dict . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~! no selection text ~}}\n {{~else~}}\n {{~> _jpmn-search-primary-definition-dict . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n get number of primary dictionary entries\n~}}\n{{~#*inline \"_jpmn-primary-dict-entry-count\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~set \"dict-entry-count\" 0 ~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\")) ~}}\n {{~! dict-entry-count += 1 ~}}\n {{~set \"dict-entry-count\" (op \"+\"\n (get \"dict-entry-count\") 1\n )\n ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"dict-entry-count\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-is-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n dictionaryName: dictionary id\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~set \"valid-dict\" null ~}}\n {{~#set \"test-dict-type\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionaryName ~}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"test-dict-type\") validDictType)\n (op \"||\"\n (op \"!==\" (get \"primary-dictionary\") dictionaryName)\n (op \"===\" (get \"use-primary-dictionary\") true)\n )\n ) ~}}\n {{~set \"valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~get \"valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-has-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~!\n without this set statement, the parameters\n magically disappears within the bottom 'each' loop...\n ~}}\n {{~ set \"valid-dict-type\" validDictType ~}}\n {{~ set \"entry-count\" entryCount ~}}\n {{~set \"has-valid-dict\" null ~}}\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=(get \"valid-dict-type\") entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n {{~set \"has-valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"has-valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~#*inline \"_jpmn-get-primary-definition-value\"~}}\n {{~!\n ASSUMPTION: \"primary-dictionary\" and \"search-selection\" is available to us from previous functions\n ~}}\n {{~#scope~}}\n {{~#if\n (op \"&&\"\n (op \"!==\" (get \"search-selection\") \"\")\n (get \"opt-primary-def-one-dict-entry-only\")\n )\n ~}}\n {{~! text was highlighted -> use primary dictionary entry with highlighted text ~}}\n {{~set \"found-dict-entry\" false ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-dict-entry\" ~}}\n {{~#regexMatch (get \"search-selection\") \"gu\"~}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"found-dict-entry\") false)\n (op \"&&\"\n (op \"!==\" (get \"rx-match-dict-entry\") \"\")\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else if (get \"opt-primary-def-one-dict-entry-only\") ~}}\n{{~! use first primary dictionary entry ~}}\n{{~set \"found-dict-entry\" false ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n{{~/if~}}\n{{~#each definition.definitions~}}\n{{~#if\n(op \"&&\"\n(op \"===\" (get \"found-dict-entry\") false)\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else~}}\n{{~! use all primary dictionary entries ~}}\n{{~#if (get \"opt__plaintext__one-dict-entry-only-no-list\") ~}}\n{{~! must manually calculate number of primary-dictionary entries... ~}}\n{{~set \"t\" 0 ~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <ol> {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <li data-details=\"{{~dictionary~}}\"> {{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \">=\" (get \"t\") 2)~}} </li> {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} </ol> {{~/if~}}\n {{~else~}}\n <ol> {{~s~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol> {{~s~}}\n{{~/if~}}\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\nif (mode === \"except\" and (regex doesn't match) or mode === \"only\" and (regex matches)):\n return true\n return null\n~}}\n{{#*inline \"_jpmn-check-first-line-dict\"}}\n {{~#scope~}}\n {{~#set \"rx-match-first-line-dict\" ~}}\n {{~#regexMatch (get \"opt-first-line-dicts-regex\") \"u\"~}}{{dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"||\"\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"except\")\n (op \"===\" (get \"rx-match-first-line-dict\") \"\")\n )\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"only\")\n (op \"!==\" (get \"rx-match-first-line-dict\") \"\")\n )\n )\n ~}}\n true\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! custom glossary-single function for additional regex parsing per dictionary ~}}\n{{~! OVERRIDES brief and noDictionaryTag ~}}\n{{#*inline \"_jpmn-glossary-single\"}}\n {{~#scope~}}\n {{~#if (op \"===\" dictionary \"NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\")~}}\n {{~#regexReplace \"<br></span> \u30fb\" \"<br></span>\" \"g\"~}}\n {{~#regexReplace \"<br> \u30fb\" \"<br>\" \"g\"~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/regexReplace~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! custom glossary-single function to add custom html around the dictionary and tags ~}}\n{{#*inline \"_jpmn-glossary-single2\"}}\n {{~#scope~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__tag-list\"> {{~s~}}\n {{~#each definitionTags~}}\n <span class=\"dict-group__tag dict-group__tag--name\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~name~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~/each~}}\n <span class=\"dict-group__tag dict-group__tag--dict\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~dictionary~}}\n </span> {{~s~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~else~}}\n {{~#scope~}}\n {{~#set \"any\" false}}{{/set~}}\n {{~#each definitionTags~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{name}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/each~}}\n {{~#if (op \"!\" (get \"opt__plaintext__remove-dictionary-tag\"))~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{dictionary}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/if~}}\n {{~#if (get \"any\")}}) {{/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__glossary\"> {{~s~}}\n {{~/if~}}\n {{~!\n option to not wrap with spans because it may break dictionaries\n (this is the hell that is parsing html with regex)\n ~}}\n {{~#if (op \"&&\"\n (get \"opt-wrap-first-line-spans\")\n (op \"!\" (get \"opt__plaintext__enabled\"))\n )\n }}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1<span class=\\\"dict-group__glossary--first-line\\\">$2</span><span class=\\\"dict-group__glossary--first-line-break\\\"><br></span>\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else if (get \"opt__plaintext__remove-first-line-enabled\")~}}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~! none match means the dictionary is not an exception, i.e. replace newline ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n </span> {{~s~}}\n {{~/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n{{/inline}}\n{{#*inline \"_jpmn-glossary-single3\"}}\n {{~#scope~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"opt-jmdict-list-format\") true)\n (op \"||\"\n (op \"===\" dictionary \"JMdict (English)\")\n (op \"||\"\n (op \"===\" dictionary \"JMdict Extra\")\n (op \"===\" dictionary \"JMdict\")\n )\n )\n )\n ~}}\n {{~#if (op \"<=\" glossary.length 1)~}}\n {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}\n {{~else~}}\n <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>\n {{~/if~}}\n {{~else~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n =============\n frequencies\n =============\n~}}\n{{#*inline \"jpmn-frequencies\"}}\n {{~#if (op \">\" definition.frequencies.length 0)~}}\n {{~#each definition.frequencies~}}\n <div class=\"frequencies__group\" data-details=\"{{~dictionary~}}\"> {{~s~}}\n <div class=\"frequencies__number\"> {{~s~}}\n <span class=\"frequencies__number-inner\"> {{~s~}}\n {{~! removes the \"X\" in JPDB's frequency and replaces it with a less assuming character\n(it interferes with the color of the card, since you see red\nat the top corner which is somewhat distracting) ~}}\n{{~#regexReplace \"\u274c\" \"\u2716\" \"g\"~}}\n{{~frequency~}}\n{{~/regexReplace~}}\n </span> {{~s~}}\n </div> {{~s~}}\n <div class=\"frequencies__dictionary\"> {{~s~}}\n <span class=\"frequencies__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </span> {{~s~}}\n </div> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~! base code taken from: https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency ~}}\n{{~! NOTE: THIS IS ONLY KEPT FOR LEGACY PURPOSES, and is now deprecated. Please use {jpmn-frequency-sort} instead. ~}}\n{{~#*inline \"jpmn-min-freq\"~}}\n{{~#scope~}}\n{{~#set \"min-freq\" 0~}}{{~/set~}}\n{{~#each definition.frequencies~}}\n{{~#set \"rx-match-ignored-freq\" ~}}\n{{~#regexMatch (get \"ignored-freq-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if\n(op \"&&\"\n(op \"||\"\n(op \"===\" (get \"min-freq\") 0)\n (op \">\" (op \"+\" (get \"min-freq\")) (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency)))\n )\n (op \"===\" (get \"rx-match-ignored-freq\") \"\")\n )\n ~}}\n {{~#set \"min-freq\" (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency))}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"min-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-frequency-sort\"}}\n {{~! Frequency sort handlebars: v24.01.06.1 ~}}\n {{~! The latest version can be found at https://github.com/MarvNC/JP-Resources#freq-handlebar ~}}\n {{~#scope~}}\n {{~! Do not change the code below unless you know what you are doing. ~}}\n {{~set \"result-freq\" -1 ~}} {{~! -1 is chosen because no frequency dictionaries should have an entry as -1 ~}}\n {{~set \"prev-freq-dict\" \"\" ~}}\n {{~set \"t\" 1 ~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#each definition.frequencies~}}\n {{~! rx-match-ignored-freq is not empty if ignored <=> rx-match-ignored-freq is empty if not ignored ~}}\n {{~#set \"rx-match-ignored-freq\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#set \"rx-match-ignored-value\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-value-regex\") \"u\"~}}{{this.frequency}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\" (op \"===\" (get \"rx-match-ignored-freq\") \"\") (op \"===\" (get \"rx-match-ignored-value\") \"\"))~}}\n {{~!\n only uses the 1st frequency of any dictionary.\n For example, if JPDB lists 440 and 26189\u32d5, only the first 440 will be used.\n ~}}\n {{~set \"read-freq\" false ~}}\n {{~#if (op \"!==\" (get \"prev-freq-dict\") this.dictionary ) ~}}\n {{~set \"read-freq\" true ~}}\n {{~set \"prev-freq-dict\" this.dictionary ~}}\n {{/if~}}\n {{~#if (op \"!\" (get \"read-freq\") ) ~}}\n {{~#set \"rx-match-keep-freqs\" ~}}\n {{~#regexMatch (get \"opt-keep-freqs-past-first-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-keep-freqs is not empty if keep freqs ~}}\n {{~#if (op \"!==\" (get \"rx-match-keep-freqs\") \"\") ~}}\n {{~set \"read-freq\" true ~}}\n {{/if~}}\n {{/if~}}\n {{~#if (get \"read-freq\") ~}}\n {{~#set \"numericFrequencyMatch\"}}{{~#regexMatch \"\\d+\" \"\"}}{{~this.frequency~}}{{/regexMatch~}}{{/set~}}\n {{~set \"f\" (op \"+\" (get \"numericFrequencyMatch\")) ~}}\n {{~#if (op \"===\" (get \"opt-freq-sorting-method\") \"min\") ~}}\n {{~#if\n (op \"||\"\n (op \"===\" (get \"result-freq\") -1)\n (op \">\" (get \"result-freq\") (get \"f\"))\n )\n ~}}\n {{~set \"result-freq\" (op \"+\" (get \"f\")) ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"first\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~else~}}\n {{~!\n iterative mean formula (to prevent floating point overflow):\n $S_{(t+1)} = S_t + \\frac{1}{t+1} (x - S_t)$\n - example java implementation: https://stackoverflow.com/a/1934266\n - proof: https://www.heikohoffmann.de/htmlthesis/node134.html\n ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\"\n (op \"-\"\n (get \"f\")\n (get \"result-freq\")\n )\n (get \"t\")\n )\n )\n }}\n {{~/if~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~#if (op \">\" (get \"f\") 0) ~}} {{~! ensures only positive numbers are used ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (op \"/\" 1 (get \"f\")) ~}}\n {{~else ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\" 1 (get \"f\"))\n )\n }}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"debug\") ~}}\n {{ this.dictionary }}: {{ this.frequency }} -> {{ get \"f\" }} <br>\n {{~else~}}\n (INVALID opt-freq-sorting-method value)\n {{~/if~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! (x) >> 0 apparently floors x: https://stackoverflow.com/a/4228528 ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"opt-no-freq-default-value\") ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~set \"result-freq\"\n (op \">>\" (get \"result-freq\") 0 )\n ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~set \"result-freq\"\n (op \">>\"\n (op \"*\"\n (op \"/\" 1 (get \"result-freq\"))\n (get \"t\")\n )\n 0\n )\n ~}}\n {{~/if~}}\n {{~! override final result if grammar dictionary ~}}\n {{~#if (\n op \"&&\"\n (op \"===\" (get \"found-grammar-dict\") true)\n (op \"===\" (get \"opt-grammar-override\") true)\n )\n ~}}\n {{~set \"result-freq\" (get \"opt-grammar-override-value\") ~}}\n {{/if}}\n {{~get \"result-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n ==============\n pitch accent\n ==============\n~}}\n{{#*inline \"jpmn-pitch-accent-graphs\"}}\n {{~#if (op \">\" pitchCount 0)~}}\n {{~#each pitches~}}\n <div class=\"pa-graphs__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-graphs__dictionary\"> {{~s~}}\n <div class=\"pa-graphs__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"graph\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-pitch-accent-positions\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#each pitches~}}\n <div class=\"pa-positions__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-positions__dictionary\"> {{~s~}}\n <div class=\"pa-positions__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"position\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~!\n==============\ndictionaries\n==============\n~}}\n{{~! primary def: first monolingual (or first bilingual if no monolingual dicts found) ~}}\n{{~! does the reverse if opt-first-definition-type is \"bilingual\" ~}}\n{{~#*inline \"jpmn-primary-definition\"~}}\n{{~#scope~}}\n{{~! output warning if no dictionaries are found ~}}\n{{~#if (op \"===\" definition.definitions.length undefined)~}}\nWARNING: JPMN Handlebars cannot find any definitions to export.\nThis is usually because your Yomichan settings has \"Result grouping mode\"\nset to \"No grouping\". Please set this to \"Group term-reading pairs\".\n {{~/if~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~#if (op \"===\" (get \"primary-dictionary\") \"\")~}}\n {{~> _jpmn-selection-text ~}}\n {{~else~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#set \"selection-uses-glossary\"~}}\n {{~> _jpmn-selection-uses-glossary . ~}}\n {{~/set~}}\n {{~! not \"\" <=> is a filled string, i.e. selection uses glossary ~}}\n {{~#if (op \"!==\" (get \"selection-uses-glossary\") \"\")~}}\n {{~! escape regex ~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#set \"search-selection-bold\"}}<b>{{~> _jpmn-selection-text ~}}</b>{{/set~}}\n {{~#regexReplace (get \"search-selection\") (get \"search-selection-bold\") \"g\"~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~#set \"search-selection\"}}{{/set~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! extra def: bilingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-secondary-definition\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~! looks to see if another dictionary exists ~}}\n {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n {{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n {{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n {{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! extra def: monolingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-extra-definitions\"~}}\n{{~#scope~}}\n{{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n{{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! pitch accent info: all pitch accent info dictionaries ~}}\n{{~#*inline \"jpmn-utility-dictionaries\"~}}\n{{~#scope~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! 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) ~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"utility\"~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") \"utility\")~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\n=======\nother\n=======\n~}}\n{{~#*inline \"jpmn-word-reading-hiragana\"~}}\n{{~#set \"word-reading\" ~}}{{> reading}}{{/set~}}\n{{~#if (op \"\" (get \"word-reading\")) ~}}\n{{~#set \"word-reading\" ~}}{{> expression}}{{/set~}}\n{{~/if~}}\n{{#hiragana (get \"word-reading\") keepProlongedSoundMarks=false}}{{/hiragana}}\n{{~/inline~}}\n{{~!\nthanks to:\n- https://github.com/FooSoft/yomichan/issues/1952#issuecomment-922671489 for the base code\n- DaNautics#8833 for finding the above + removing the span classes\n~}}\n{{#*inline \"jpmn-sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-hiragana\"}}\n{{~#scope~}}\n{{~#set \"expression\" ~}}{{> expression}}{{/set~}}\n{{~#set \"reading\" ~}}{{> reading}}{{/set~}}\n{{~#set \"expression-hiragana\" ~}}{{> jpmn-word-reading-hiragana}}{{/set~}}\n{{~#if (op \"&&\" (op \"===\" (get \"expression\") (get \"reading\")) (op \"===\" (get \"expression\") (get \"expression-hiragana\")))~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-not-hiragana\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-word-is-hiragana}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-grammar-point\"}}\n {{~#scope~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#if (get \"found-grammar-dict\") ~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-grammar-point\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-grammar-point}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-on-mim\"}}\n {{~#scope~}}\n {{~#set \"rx-match-on-mim\" ~}}\n {{~#regexMatch \"(, |^)on-mim(, |$)\" \"gu\"~}}{{> tags }}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"!==\" (get \"rx-match-on-mim\") \"\") ~}}\n 1\n {{/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-on-mim\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-not-on-mim}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! my personal settings:\n- sentence card if grammar point\n- otherwise, if it's on-mim, then hint card\n- otherwise, default\n~}}\n{{#*inline \"jpmn-is-sentence-card\"}}\n {{~> jpmn-filled-if-grammar-point ~}}\n{{/inline}}\n{{#*inline \"jpmn-is-hint-card\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n {{~> jpmn-filled-if-on-mim ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-is-click-card\"}}\n {{~#scope~}}\n {{~#set \"filled1\" ~}}{{> jpmn-is-hint-card}}{{/set~}}\n {{~#set \"filled2\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"filled1\") \"\")\n (op \"===\" (get \"filled2\") \"\")\n )~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! a test to check if your dictionaries are correctly classified. ~}}\n{{~! Only meant to be used for debugging purposes, not Anki. ~}}\n{{~#*inline \"jpmn-test-dict-type\"~}}\n{{~#scope~}}\n{{~#each definition.definitions~}}\n\u300c{{dictionary}}\u300d: {{> jpmn-get-dict-type . dictionaryName=dictionary}}\n{{/each~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"setupyomichan/#make-an-example-card","title":"Make an example card!","text":"TODO re-record with renji's texthooker, and show result card
At this point, you should be able to make cards with Yomitan!
Click here to show some example Japanese sentences. \u300c\u3084\u3001\u3044\u3089\u3063\u3057\u3083\u3044\u3002\u307e\u3001\u6bd2\u3092\u98df\u3089\u308f\u3070\u76bf\u307e\u3067\u3063\u3066\u8a00\u3046\u3057\u306d\u3002\u3042\u3001\u9055\u3046\u304b\u3002\u4e57\u308a\u639b\u304b\u3063\u305f\u8239\uff1f\u300d
\u300c\u3042\u306e\u6642\u9003\u3052\u51fa\u3057\u305f\u79c1\u306e\u7f70\u2026\u3042\u306e\u6642\u306e\u6c5a\u8fb1\u306f\u4eca\u3053\u3053\u3067\u3001\u5168\u90e8\u305d\u305d\u3044\u3067\u3084\u308b\u3093\u3060\u2026\u300d
\u300c\u3068\u306b\u304b\u304f\u5229\u6575\u884c\u70ba\u3055\u3048\u3057\u306a\u3044\u3088\u3046\u306b\u3059\u308c\u3070\u57fa\u672c\u7684\u306b\u554f\u984c\u306f\u306a\u3044\u306f\u305a\u3067\u3059\u3057\u3001\u6c7a\u307e\u308a\u304d\u3063\u305f\u30e0\u30fc\u30d6\u3060\u3051\u3067\u7d76\u5bfe\u306b\u52dd\u3066\u308b\u3068\u3044\u3046\u308f\u3051\u3067\u3082\u7121\u3044\u306e\u3067\u3001\u305d\u306e\u6642\u3005\u306e\u72b6\u6cc1\u3092\u843d\u3061\u7740\u3044\u3066\u898b\u3066\u3001\u67d4\u8edf\u306b\u884c\u52d5\u3059\u308b\u3053\u3068\u304c\u5927\u5207\u3067\u3059\u300d
\u300c\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u306f\u3001IEEE-754\u898f\u683c\u306b\u5f93\u3063\u3066\u8868\u73fe\u3055\u308c\u3066\u3044\u307e\u3059\u3002f32
\u304c\u5358\u7cbe\u5ea6\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u3001 f64
\u304c\u500d\u7cbe\u5ea6\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u3067\u3059\u300d
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.
"},{"location":"setupyomichan/#monolingual-cards","title":"Monolingual Cards","text":"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:
{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n
to {{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n
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.
"},{"location":"setupyomichan/#enjoy-your-new-one-click-cards","title":"Enjoy your new one-click cards!","text":"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 minimal 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: Text & Media 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, and have should be set to SentenceAudio
and Picture
respectively.
Finally, remember that up until now, this has been the minimum setup in order to use jp-mining-note. There are likely many ways you can improve this current setup. See the \"Extra Setup\" pages to the left sidebar for more information.
"},{"location":"themes/","title":"Themes (TODO)","text":"TODO
- defined under
(root)/themes
- overrides folder for partials is pointed directly at the theme folder, i.e. the two are equivalent:
(root)/overrides/jp-mining-note/partials/js/post.js\n(root)/themes/THEME/jp-mining-note/partials/js/post.js\n
"},{"location":"tooltipresults/","title":"Tooltip Results (TODO)","text":"TODO add intro
- for kanji hover and same reading indicator
- TODO generalize this page to not only be for kanji hover
"},{"location":"tooltipresults/#pitch-accent-display","title":"Pitch Accent Display","text":" - pitch accents should be exactly the same pitch accents as shown on the specified card
- pitch accents are stripped of extra information (nasal and devoiced)
- all the extra color was very distracting, and stole the attention away from the important part (the example words found)
"},{"location":"tooltipresults/#cache-tooltip-results","title":"Cache Tooltip Results","text":"TODO
- problem: mobile (and anki-web) does not have access to Anki-Connect
- yes, Android has AnkiConnect Android, but its implementation is incomplete
- even if it were complete, it is currently a lot slower than the standard desktop Anki-Connect
- kanji hover and word indicators fully depend on Anki-Connect in order to work!
- solution: cache results of kanji hover and word indicators, into the
CardCache
field - requires building the note!!!
- may be implemented as a separate note in the future (so you can run the script within Anki)
- also requires node (npx node)
"},{"location":"tooltipresults/#cache-script-warnings","title":"Cache Script Warnings","text":" - cannot use Anki while running the script (Anki-Connect blocks using Anki, and the script continuously makes calls to Anki-Connect during its lifetime)
- will take a long time to run!!! this is because Anki-Connect itself is a bit slow when doing mass operations like this
- 1000 cards took about 45 minutes for me
"},{"location":"tooltipresults/#prerequisites","title":"Prerequisites","text":" - Open Anki (so that Anki-Connect is running)
-
Build the note! You might have to refresh the npm dependencies npm ci
.
-
If using runtime options (i.e. colored pitch accent), Use the following CTO:
\"hardcodedRuntimeOptions\": true,\n
- required because runtime options currently cannot be read from Anki.
- must also use
runtime_options.json(5)
file if you want any runtime options
-
Close your card viewer, so you are not viewing any card when running the script.
"},{"location":"tooltipresults/#test-cache-script-single-card","title":"Test Cache Script - Single Card","text":" - Test the script out first, by running it on a single card (preferably one with visible word indicators) For example, take a note ID of any JPMN note (Card browser \u2192 Right click a note \u2192
Info...
), and use the following: node ./src/_js/jpmn_card_cache.js --custom-query=\"nid:1234567890\"\n
- Sync on both PC and mobile.
- Check that kanji hover and word indicators work!
"},{"location":"tooltipresults/#test-cache-script-show-card-list","title":"Test Cache Script - Show Card List","text":"TODO --print-notes-only
"},{"location":"tooltipresults/#run-cache-script","title":"Run Cache Script","text":" -
Run the following:
node ./src/_js/jpmn_card_cache.js\n
-
above caches for 8 days (expected that you run this, say, once every saturday)
- run with
--help
for list of all available flags - TODO: macOS cannot find Anki-Connect???
"},{"location":"tooltipresults/#ignore-cache-results","title":"Ignore Cache Results","text":" - TODO results are ignored by default on PC (TODO not currently the case as of writing)
- so PC always gets the most current results, at the cost of slight performance
- can be edited via runtime option
cardCache.enabled
"},{"location":"tooltipresults/#remove-cached-results","title":"Remove Cached Results","text":" - TODO can clear the
CacheField
field (make sure to edit HTML! TODO link FAQ) - can remove all results via
clear_field CardCache
batch command
"},{"location":"tooltipresults/#result-queries-categorization","title":"Result Queries & Categorization","text":"TODO add writeup on new.newest
The exact results shown through Kanji Hover is not completely trivial, so this process is explained below.
The words are searched and sorted into 3 categories:
- The two oldest, not new cards (already reviewed before, in order of add date)
- The two latest, not new cards (the most recent two cards that you have reviewed, in order of add date)
- The two oldest, new cards (the first 2 new cards that you will see with the kanji)
The last category (the new cards) are greyed out to show that you haven't reviewed the card yet (i.e. you may not know the word yet). Conversely, the first two categories (the non-new cards) represent words that you likely already know, so they are not greyed out.
The exact numbers shown in each category can be changed in the runtime option:
// maximum number of words per category\n\"tooltips.categoryMax.nonNew.oldest\": 2,\n\"tooltips.categoryMax.nonNew.newest\": 2,\n\"tooltips.categoryMax.new.oldest\": 2,\n\"tooltips.categoryMax.new.newest\": 0,\n
TODO: add this to each query to hide results from cards that are due today
-(prop:due=0 -rated:1)\n
"},{"location":"tooltipresults/#results-sorting","title":"Results Sorting","text":"The above makes the assumption that you are reviewing in order of creation date, rather than the time of first review, to save resources. In other words, if you re-ordered your cards to be different from the add-date, then the kanji hover will not be able to recognize that.
For people who review in order of frequency only, then the assumption above is completely broken.
Unfortunately, there is currently no way to order the results by anything other than by the creation date.
"},{"location":"tooltipresults/#suspended-cards","title":"Suspended Cards","text":"TODO make sure this is correct with hidden
now removed
Some assumptions are made about suspended cards. For example, suspended cards flagged as green
are counted in the \"non-new\" cards category (known words), and suspended cards flagged as red
are counted as words that you do not know AND will not study in the future (not shown in any category). This can be changed in the runtime options:
\"tooltips.query.nonNew.base\": \"-is:new OR (is:suspended is:new flag:3)\",\n\"tooltips.query.nonNew.removed\": \"is:suspended flag:1\",\n
"},{"location":"tooltipresults/#customizing-sentences-pitch-accent","title":"Customizing Sentences & Pitch Accent","text":"TODO link to runtime options? or visa versa?
Any runtime option under the sentParser
and autoPA
group can be set under tooltips.overrideOptions.sentenceParser
and tooltips.overrideOptions.autoPitchAccent
respectively. Additionally, the kanjiHover
and wordIndicators
category has their own overrideOptions
section that behaves the exact same as the above, except they only affect Kanji Hover and Word Indicators, respectively.
This allows for very fine grained control on how the sentences and pitch accent should be displayed.
Note
When the sentence is being parsed by the tooltip builder, it is considered a \"full sentence\" internally. Therefore, only the fullSent
group of options will affect the resulting sentence.
"},{"location":"tooltipresults/#highlight-the-word-within-the-tooltips","title":"Highlight the word within the tooltips","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
Within the tooltips, the word within the sentence is not highlighted by default. This is to emphasize the importance of the kanji over the word. However, this comes at the cost of having to scan through the entire sentence to find the word.
The following runtime option re-enables the highlighted word:
\"tooltips.highlightWordInSentence\": true,\n
HighlightedNot Highlighted (default) TODO this is no longer bolded
"},{"location":"tooltipresults/#display-newlines-in-mobile-tooltip-sentences","title":"Display newlines in mobile tooltip sentences","text":"TODO wrap with custom css text
.mobile-popup .hover-tooltip__sent-div br {\ndisplay: inline;\n}\n
"},{"location":"ui/","title":"Ui","text":"This page is dedicated to showcasing various aspects of the common user interface.
"},{"location":"ui/#summary","title":"Summary","text":"Most of the user interface is already shown off in the GUI demo, and I would recommend watching it before continuing.
However, to dispell any mysteries, here is a fully annotated summary of the user interface.
Additional information on some parts of the UI is stated below.
"},{"location":"ui/#keybinds","title":"Keybinds","text":"This note ships with some keybinds to do basic actions.
Keybind What it does p
Play sentence audio w
Play word audio 8
Toggles Secondary Definition
field 9
Toggles Additional Notes
field 0
Toggles Extra Definitions
field [
Toggles Extra Info
field See the runtime options if you would like to edit / disable any keybind, and/or to view the full list of keybinds.
"},{"location":"ui/#info-circle","title":"Info Circle","text":"DefaultErrorWarningLeech On hover, the info circle on the top left corner just shows some basic info. However, it also serves as a notification system to the user, when it has a color.
This should only appear when some javascript code fails. In other words, this should not appear under normal circumstances. If you get this without modifying the note in any way, please see this section for basic troubleshooting.
This serves to warn the user about something. It can appear without completely breaking the functionality of the card. In other words, you can choose to ignore it.
When the card is a leech, the circle is highlighted yellow (or blue in light mode) to indicate that it is a leech. This is only shown on the back side of the card.
"},{"location":"ui/#locking-the-info-circle","title":"Locking the Info Circle","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
You can toggle (click on) the info circle to lock the tooltip in place. This may be useful for copying/pasting errors and other debugging purposes.
"},{"location":"ui/#kanji-hover","title":"Kanji Hover","text":"Kanji hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
By default, it searches for the kanji within the \"Word\" field, within \"JP Mining Note\" types.
Various Details:
-
You may have noticed that some results are greyed out. These represent words from cards that have not been reviewed yet. Conversely, as non-greyed out results come from cards that you have already reviewed, they should represent words that you already know.
-
Pitch accents are shown when you hover over a particular word within the tooltip. You can change this to always be shown in the runtime options.
-
You can click on the word to open the specified card within Anki's card browser.
See here for information on how the examples are chosen, and how to customize it.
Related Programs (click here) Cade's Kanji Hover
- Hover over a kanji to see its readings, meanings (english), and other info.
- This does not show example words from other cards.
- My implmentation of kanji hover was heavily inspired by this.
Hanzi Web for Anki
- The end result of this is to this note's implementation of kanji-hover, in the sense that it is used to see kanjis that have been used in other notes. However, it differs primarily in the fact that all the information must be mass-generated. This indeed has several advantages, such as being able to use the infomation on Android, where Anki-Connect isn't full supported.
KanjiEater's Kanji Connections
- Ability to show kanjis with heisig's RTK keywords, as well as related vocabulary. Similar to Hanzi Web for Anki.
Warning
None of the above will work with jp-mining-note by default. In fact, it's almost guaranteed that Cade's Kanji Hover will conflict with this note's kanji hover ability.
"},{"location":"ui/#word-indicators","title":"Word Indicators","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found. The indicators are as follows:
- \u540c (short for \u540c\u3058) indicates that the card is a duplicate.
- \u8aad (short for \u8aad\u307f\u65b9) indicates that there are other card(s) with the same reading (ignoring pitch accent). In Japanese, these words are \u540c\u97f3\u7570\u7fa9\u8a9e. I consider this the most useful of the three.
- \u6f22 (short for \u6f22\u5b57) indicates that there are other card(s) with the same kanji, but different reading.
As you can see from the above, the query ignores pitch accent. The word \u81ea\u8eab is still shown, despite having a different pitch accent compared to \u5730\u9707.
Note
This indicator will be yellow (or blue on light mode) for new cards only. After the first review, the indicator will be the same color as the default info circle (grey).
The tooltip behaves very similarly properties to Kanji hover's tooltip:
- New cards are greyed out.
- You can click on words to open them in Anki's card browser.
- Pitch accent is shown without requiring the user to hover over the word by default. This is different from Kanji hover's tooltip.
See here for information on how the examples are chosen, and how to customize it.
"},{"location":"ui/#images-pitch-accent","title":"Images & Pitch Accent","text":"See the Images page for information on the following:
- Blurring images
- Specifying default images
- Automatically formatting pictures within the definition
See the Pitch Accent page for information on the following:
- Pitch accent notation
- Automatic pitch accent coloring
- How to override the pitch accent of any word
"},{"location":"ui/#external-links","title":"External Links","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
External links are shown as icons in the Extra Info
collapsable field by default. By default, hovering over them will show the url. Click on the desired icon to visit to the desired site.
See also: UI Customization (External Links).
"},{"location":"ui/#conclusion","title":"Conclusion","text":"This page shows various aspects of the user interface, but says little about actually modifying it. Head over to the UI Customization page to see just that.
"},{"location":"updating/","title":"Updating: Overview","text":"So you want to update jp-mining-note? Awesome, here's what you got in store!
"},{"location":"updating/#what-to-expect","title":"What to Expect","text":"Updating JPMN usually comprises of updating two things separately:
- The JPMN template itself within Anki. The internal updater does most of the work, so you should not have to do much on this end.
- External settings, such as the Yomichan settings required to interface with Anki. The internal updater CANNOT interface with these, so you will have to manually update these if they exist.
"},{"location":"updating/#what-to-expect-updating-the-jpmn-template","title":"What to Expect: Updating the JPMN template","text":" - Any changes you made to the templates WILL BE LOST (outside of the small dedicated section at the bottom of the CSS). This is because the updater replaces your template in place, and overrides any changes.
- Fields may be added, repositioned, etc. Existing fields should not be removed.
- It runs any necessary batch edits to all notes, meaning the data within any given note may be subtly changed.
As the updater can do many things to your collection, it is always recommended to make a complete backup of your collection before updating.
"},{"location":"updating/#what-to-expect-external-settings","title":"What to Expect: External Settings","text":"After running the main updater, there may be changes that the user must make, because the updater simply cannot update those particular details. User-required changes are usually present for major updates (i.e. if any of the first two numbers in the version change).
Some common user-required changes include:
- Updating the Yomichan templates
- Updating optional add-on configs
All of these user required changes should be listed under the Setup Changes page, which should be read after running the main installer.
"},{"location":"updating/#updating","title":"Updating!","text":"Now that you have a general idea of what's going to happen...
See how to update JPMN here!
"},{"location":"updatingfinalsteps/","title":"Final Steps","text":""},{"location":"updatingfinalsteps/#final-steps","title":"Final Steps","text":"By now, you should be done updating the note! Please do the following checks to make sure everything properly works:
- Preview an existing card, to ensure that nothing looks odd.
-
Create a new card and make sure nothing looks odd.
Example Japanese sentences to test card creation \u300c\u6211\u306a\u304c\u3089\u99ac\u9e7f\u99ac\u9e7f\u3057\u3044\u3053\u3068\u3092\u601d\u3044\u3064\u3044\u305f\u3082\u306e\u3060\u3068\u5606\u606f\u3057\u3064\u3064\u3082\u3001\u79c1\u306f\u9759\u304b\u306b\u30d9\u30c3\u30c9\u306b\u8fd1\u4ed8\u304f\u300d
\u300c\u30b8\u30a7\u30e9\u30fc\u30c8\u3092\u8cb7\u3046\u304a\u91d1\u304c\u306a\u3044\u3068\u306f\uff01\u7d66\u6599\u65e5\u307e\u3067\u53ce\u5165\u306e\u5f53\u3066\u3082\u306a\u3057\u3001\u81ea\u708a\u3059\u308b\u3057\u304b\u3042\u308a\u307e\u305b\u3093\u306d\u300d
\u300c\u3053\u308c\u304c\u5c11\u5e74\u8a8c\u3060\u3063\u305f\u3089\u9806\u4f4d\u4e0a\u304c\u3063\u3066\u308b\u305e\u3002\u305d\u3057\u3066\u30c8\u30fc\u30ca\u30e1\u30f3\u30c8\u7de8\u3067\u30a2\u30cb\u30e1\u5316\u6c7a\u5b9a\u3060\u300d
\u300c\u3042\u306e\u6642\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u4e0a\u3067\u8272\u3093\u306a\u8cea\u554f\u304c\u3067\u304d\u308b\u30b5\u30a4\u30c8\u306b\u6295\u7a3f\u3057\u305f\u3089\u3001\u89aa\u5207\u306a\u4eba\u304c\u5546\u54c1\u540d\u3068\u58f2\u3063\u3066\u3044\u308b\u5834\u6240\u3092\u6559\u3048\u3066\u304f\u308c\u305f\u3093\u3067\u3059\u300d
\u300c\u7b2c\u4e8c\u6b21\u4e16\u754c\u5927\u6226\u306b\u304a\u3051\u308b\u9023\u5408\u56fd\u8ecd\u306e\u91cd\u8981\u62e0\u70b9\u3067\u3059\u2026\u300d
"},{"location":"updatingjpmn/","title":"Updating: JPMN","text":"This section is dedicated to updating the JPMN template in Anki.
"},{"location":"updatingjpmn/#preliminary-steps","title":"Preliminary steps","text":" -
Ensure that your note is named exactly JP Mining Note
. To do this, head over to:
(Main Window) \u2192 Tools
\u2192 Manage Note Types
.
If your note is named differently, please rename it to JP Mining Note
.
-
Please make a backup of your entire Anki collection, if you haven't already.
"},{"location":"updatingjpmn/#updating-the-note","title":"Updating the Note","text":"You can update the note in one of two ways:
- Via JPMN Manager, an Anki add-on. If you don't know which method to choose, choose this one.
- Via command line. This method is recommended for people who are familiar with
git
and python
, and don't want to download an Anki add-on.
Option 1: Via JPMN Manager (click here) Note
If you have previously installed Aquafina's old version of the JPMN add-on, then you must remove it before installing the new version below. The old and new versions will conflict with each other if they are both installed. In your list of Anki add-ons, you should only see JPMN Manager with prereleases New Version
. If you see JPMN Manager with prereleases
then please remove it and restart Anki before proceeding.
This add-on simply wraps around the python script mentioned below, and should behave the exact same as running the script manually.
Video demo (click here) - If you haven't installed the JPMN Manager add-on yet, do so with the following code:
301910299
. Be sure to restart Anki after installing. -
Make sure there is something to update to in the first place. You can do this by:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Check for note updates
-
Update the note by navigating to the following:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Update jp-mining-note
-
You may see additional instructions. If you do, please continue the updating process with the Setup Changes page
There may be further steps outside of just updating the card, such as updating Yomichan's templates / format. These should be recorded in the Setup Changes page.
Afterward seeing that page, please view the final steps section.
-->
Option 2: Via Command Line (click here) WindowsLinux & macOS :: assuming you are at the root of the repo, i.e. after the following commands:\n:: $ git clone https://github.com/arbyste/jp-mining-note.git\n:: $ cd jp-mining-note\n:: Since we are using the prerelease version, make sure you switch\n:: to the dev branch\ngit checkout dev\n:: grabs the latest version of the dev branch\ngit pull --force\n\n:: Make sure you have Anki open and Anki-Connect installed!\n:: Also ensure that your python version is 3.9 or higher.\npython tools\\install.py --update\n
# assuming you are at the root of the repo, i.e. after the following commands:\n# $ git clone https://github.com/arbyste/jp-mining-note.git\n# $ cd jp-mining-note\n# Since we are using the prerelease version, make sure you switch\n# to the dev branch\ngit checkout dev\n# grabs the latest version of the dev branch\ngit pull --force\n\n# Make sure you have Anki open and Anki-Connect installed!\n# Also ensure that your python version is 3.9 or higher.\npython3 tools/install.py --update\n
There may be further steps outside of just updating the card, such as updating Yomichan's templates / format. These should be recorded in the Setup Changes page.
Afterward seeing that page, please view the final steps section.
Why can't I just copy/paste the templates, or just re-install the .apkg file to update the note? In short, updating via Anki or Python performs many operations that cannot be done with a simple note transfer. Most importantly, there are operations (usually under batch.py) that change the data within the actual fields themselves, and these are ran automatically on note update. If you attempt to update your note manually, these actions will not be ran, and can result in unwanted changes to your note!
Additionally, many manual operations are done for you by updating the note with the Python script, such as automatically creating and re-arranging new fields.
If you still want to attempt manually updating the note, then there will be little to no support given.
"},{"location":"updatingjpmn/#common-errors","title":"Common Errors","text":"This section will document common errors that occur when attempting to update the note.
"},{"location":"updatingjpmn/#anki-connect-is-missing-actions","title":"Anki-Connect is missing actions","text":"Anki-Connect is likely outdated. To fix this, remove and re-download Anki-Connect from the AnkiWeb page.
Note
It seems that the Check for Updates
occasionally fails to update the add-on, despite the fact that a newer version of the add-on exists. That is why I recommend re-downloading from the AnkiWeb page instead of using this feature.
"},{"location":"updatingjpmn/#fieldverifierexception","title":"FieldVerifierException","text":"This class of errors means that the field list was edited at some point after the installation or last update of JPMN. The field list can be accessed by navigating to the following:
(Main window) \u2192 Browse
\u2192 Fields...
.
The installation script is picky about fields and its order, and by default, the script will reject any note type with modifications to the field list.
To fix this, there are a few cases to go through.
The field order has been changed. If the field order has been changed, and nothing else has been changed, you should be able to preserve your existing field list order by running the installation script with the --ignore-order
flag:
JPMN ManagerPython Script Tools
\u2192 JPMN Manager
\u2192 Run installer with arguments
--update --ignore-order\n
python3 install.py --update --ignore-order\n
Alternatively, you can re-order the field list beforehand. This can be done with the following batch command:
reposition_fields\n
New field(s) have been created. You have two options. Neither of these will delete your existing field(s).
-
If you want to preserve your existing field list order, then you can run the script with the --ignore-order
flag, like above.
-
If you want to have the field list order match exactly with the current note, then re-order all the new fields to be below the last Comment
field. Of course, this can be a temporary move; you can move the fields back to their previous positions after the update.
Note
On rare occasions, you might have added a field that serves the same purpose as a field that will be created on update. If so, rename your field to the field that will be added, and move the field under the Comment
field.
For example, if your note doesn't have PAPositions
but you added a field Positions
that fulfills the same purpose, then rename Positions
to PAPositions
.
Field(s) were removed or renamed. Unfortunately, there is no way to ignore removed or renamed fields. If you removed a field, please re-add the field. Likewise, if you renamed a field, please rename it back to the original name. See here for more info on why they cannot be ignored.
"},{"location":"updatingyomichan/","title":"Updating: Yomichan","text":"This section is dedicated to updating Yomichan settings required to use JPMN.
"},{"location":"updatingyomichan/#updating-yomichans-anki-card-format","title":"Updating Yomichan's Anki Card Format","text":"To update the Yomichan Format, the steps should be almost the same as the one specified already in the setup. The most important difference is that if a new field was added or a field has been renamed, then the field will not show up automatically in Yomichan.
"},{"location":"updatingyomichan/#refreshing-yomichan-fields","title":"Refreshing Yomichan Fields","text":"Video Demo (click here) TODO update the video...
- As always, create a backup of your Yomichan settings, just in case.
- After installing the note update, create a temporary copy of the note by:
Tools
\u2192 Manage Note Types
\u2192 Add
\u2192 Select Clone: JP Mining Note
\u2192 Ok
\u2192 Name this to anything you want. The following examples will use JP Mining Note copy
. \u2192 Ok
\u2192 Close
- If you are currently viewing Yomichan Settings, please refresh the page.
- Head over to Anki Card Format as before.
- In the top right corner, change
Model
to JP Mining Note copy
, and then change it back to JP Mining Note
. (If you don't see JP Mining Note copy
, please refresh the page.) - Update the fields as specified.
- It should be specified in the text you see when updating. However, you should also simply compare the table on the setup page to your filled out fields.
- Remove the temporary note:
Tools
\u2192 Manage Note Types
\u2192 (select JP Mining Note copy
) \u2192 Delete
Explanation
Using the temporary copy of the updated card means that fields that remain unchanged between the old card and new card will be transferred automatically in the Yomichan Format. If you simply choose some random model like Basic
, then almost none of the fields will be preserved, as the Basic
card does not have any matching fields with the JP Mining Note
model.
"},{"location":"updatingyomichan/#updating-yomichan-templates","title":"Updating Yomichan Templates","text":"Like the above, you can simply follow the steps already specified in setup.
Again, please make a backup of your Yomichan settings just in case, and again, please make sure you reset the existing templates (unless you know what you are doing).
Note that your Yomichan template options will be reset if you follow all the steps. I recommend temporarily saving a copy of the Yomichan templates so you can easily reset your Yomichan template options after updating.
"},{"location":"wordindicators/","title":"Word Indicators (TODO)","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found.
\u540c (\u540c\u3058)\u8aad (\u8aad\u307f\u65b9)\u5b57 (\u6f22\u5b57) This indicates the card is a duplicate.
(TODO image)
This shows cards with the same reading, ignoring pitch accent (also known as \u540c\u97f3\u7570\u7fa9\u8a9e.) For example, the word \u81ea\u8eab is still shown, despite having a different pitch accent to \u5730\u9707.
(TODO update image)
This indicates that there are other card(s) with the same kanji, but different reading.
(TODO image)
"},{"location":"wordindicators/#interface","title":"Interface","text":"This indicator will be yellow (or blue on light mode) for new cards only. After the first review, the indicator will be the same color as the default info circle (grey).
"},{"location":"wordindicators/#interface-new-cards","title":"Interface: New Cards","text":"Just like with Kanji Hover, new cards are greyed out.
(TODO image)
"},{"location":"wordindicators/#interface-pitch-accents","title":"Interface: Pitch Accents","text":"Unlike Kanji Hover, pitch accents are automatically shown (without having to hover over the word), to emphasize the importance of different word pitches on similar words.
(TODO image)
"},{"location":"wordindicators/#interface-open-card","title":"Interface: Open Card","text":"Just like with Kanji Hover, you can click on the word to open the specified card within Anki's card browser.
(TODO image)
"},{"location":"wordindicators/#refresh-button","title":"Refresh Button","text":"TODO - Connected with Kanji Hover: editing some other card shown in the results will not show due to cache - pressing the refresh button on the info circle should fix
"},{"location":"wordindicators/#prefetching-results","title":"Prefetching Results","text":"TODO safe mode
"},{"location":"yomichantemplates/","title":"Yomichan Template Options (TODO)","text":"Yomichan template options are options that are specified, as you may have guessed, in Yomichan's templates. These options are applied on card creation, so changing these options will only affect cards created in the future.
"},{"location":"yomichantemplates/#accessing-editing","title":"Accessing & Editing","text":"TODO video
To access the Yomichan template options, head to the Yomichan templates as normal:
- Navigate to Yomichan Settings.
- Make sure that advanced settings are turned on (bottom left corner).
- Go to the
Anki
section - Select
Configure Anki card templates...
The options should be available at the very top of the template code.
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"Foreword
This project is a fork of the outstanding JP Mining Note project created by Aquafina-Water-Bottle. Aquafina went silent a couple of months ago, and in the meantime, bugs have started to creep into this project as other supporting software has received updates.
The purpose of this fork is to provide bugfixes for JPMN until Aquafina returns to take over maintenance again. I don't have the time or expertise to continue adding features to the note, but hopefully I can keep it functional.
Version 0.12.0.0-prerelease-13
has been released alongside this fork. It resolves a bug that was introduced by a recent AJTJapanese update, which resulted in an Unexpected flattened.childNode
error and prevented pitch accent information from being displayed correctly. Note that some user actions are required after this update. Click here for instructions on updating.
When Aquafina returns and resumes maintenance of the main project, I will close down this fork. The documentation for the original project can be found here.
jp-mining-note (JPMN) is a highly customizable Anki card template for studying Japanese, designed to be visually appealing and simple to use without sacrificing functionality. Easily paired with most automatic card creation workflows, this aims to make your experience with Anki as smooth as possible.
Current version: 0.12.0.0-prerelease-16
GUIFieldsCard CreationFront | DarkBack | DarkFront | LightBack | Light Click here to get started!
"},{"location":"alternatives/","title":"Alternatives","text":"This page is dedicated to gathering various note types and decks that isn't jp-mining-note. These are added in order of when I first come across the note type, so it's roughly ordered from the oldest to newest note types.
I personally try to add as many templates as I can find here, but it's likely I will miss some. Feel free to let me know of any note types you find interesting (including your own note type, or modified versions of this note), and I will very likely add it here! (Brownie points if you make a pull request for it too!)
"},{"location":"alternatives/#note-types","title":"Note Types","text":""},{"location":"alternatives/#anime-cards","title":"Anime Cards","text":" Website\u30fbDownload\u30fbContact
Example images
Image 1Image 2 "},{"location":"alternatives/#lazy-guide-xelieus-modified-anime-card","title":"(Lazy Guide) Xelieu's Modified Anime Card","text":" Website & Download\u30fbContact: Xelieu#8158
(TMW server)
Example images (bilingual examples not shown)
Modern | DarkModern | LightSimple | DarkSimple | Dark (alternative)Simple | Light "},{"location":"alternatives/#stegatxins0s-modified-anime-card","title":"stegatxins0's Modified Anime Card","text":" Website & Download\u30fbContact: Private1
Example image
"},{"location":"alternatives/#tatsumotos-tsc","title":"Tatsumoto's TSC","text":" Website\u30fbDownload\u30fbMirror\u30fbContact
- TSC is short for \"Targeted sentence cards\"
- jp-mining-note is a heavily modified version of this (to the point of it being completely rewritten)
Example image
"},{"location":"alternatives/#ajatt-tools-ankinotetypes","title":"AJATT-Tool's AnkiNoteTypes","text":" Website\u30fbContact
- A collection of user-created notes. Most are based off of the above TSC template.
- The examples below do not showcase every note. Visit the
templates
folder on the website to see all the available notes.
Examples
JP1K TSC (dark)JP1K TSC (light)FallbackWordSentence (cyphar) /templates/Japanese JP1K TSC
/templates/Japanese JP1K TSC
/templates/Japanese fallback
/templates/Japanese words
/templates/Japanese Mined Sentences (cyphar)
"},{"location":"alternatives/#mooniebiloneys-note-types","title":"MoonieBiloney's Note Types","text":" Website\u30fbDownload\u30fbContact
- Some require a Patreon subscription to access
"},{"location":"alternatives/#eminent-note-type","title":"Eminent Note Type","text":" Website & Download\u30fbContact: eminent#8189
(Perdition's server)
Example images
FrontBack "},{"location":"alternatives/#elaxs-note-type","title":"Elax's Note Type","text":" Download\u30fbContact: \u3069\u3093\u5e95#6628
(TMW server)
Example images
Front | DarkBack | DarkFront | LightBack | Light Description from the author This is my anki card format it is based in the Gruvbox color scheme (https://github.com/morhetz/gruvbox) and changes dynamically with your Anki theme, you will need this handlebars in yomichan for it to work: https://pastebin.com/KSjbwrHk (It is a modified version of the one in animecards, the only thing it changes is the color of the pitch pattern so it changes dynamically with the Anki theme) although if you're going to use the dark theme and you already have the animecards handlebars is not neccessary to download it although I still recommend it.
You can change between vocab card, sentence card, vocab audio card, and sentence audio card.
(Original discord message, on TMW server)
"},{"location":"alternatives/#timms-anki-template","title":"Timm's Anki Template","text":" Download\u30fbDownload (alternative theme)\u30fbContact: Timm#3250
(TMW server)
Examples
ImageVideo Description from the author UPDATE1: tango wasn't being colored in the sentence so i fixed it, check yomichan screen shot and add the css UPDATE2: added css
Here is my anki template, which is the result of bits I liked from other templates which I tried to glue together with my limited knowledge of programming.
https://streamable.com/j3etpw
Includes a card mined from the VN Steins;Gate 0 and a card from the LN \u5fd8\u5374\u63a2\u5075
Yomichan: https://i.imgur.com/vuHoVlM.png
Add this to the styling page of the template in anki
- Handlebars: https://pastebin.com/TeSJc6ij
Features:
- Automatic pitch coloring from https://ankiweb.net/shared/info/1557722832 iirc
- Semi-automatic title generation, so you know from which anime/VN etc. a word is from
- drop down page for multiple definitions, that are automatically added
- The same features as look below (you can reverse a word to be a sentence card, audio card etc, with one click)
- has full coverage with the intergration of embedded websites (more on this in the next section)
- NSFW filter to blur pictures from here https://rentry.co/mining
- stroke order for vocab that can be activated if you do so (most of the time the stroke order is clear, but what i implemented it for, is for that \u4e07\u304c\u4e00 case where a word has a weird stroke order, making it easier to remember)
- horrible and clusstered code made by me
Note: This template is has following imperfections:
- Idk how to insert a line break when a word has multiple readings, picture of the problem https://i.imgur.com/YQpRgOj.png
- Websites for more coverage are not displayed correct on mobile, also idk how to fix it
- I think images are not responsively sized on mobile
DM me if you have problems recreating the template (\u7de8\u96c6\u6e08)
CSS update:
Add this to the styling of the template in anki and check the yomichan screenshot above
.jpsentence {\nmargin: 20px 0 0 0;\nfont-size: 35px;\ntext-align:center;\n}\n.pcolor {\ndisplay: inline-block;\n}\n
add this to .img2 and .img:
display:flex;\njustify-content: center;\nalign-items:center;\nmargin: 0 auto;\n
add this exclusively to .img2:
margin-bottom: 25px;\n
Remove on the front template the div with jpsentence for the tango
(Original discord message, on TMW server)
"},{"location":"alternatives/#tigy01s-note-type","title":"Tigy01's Note Type","text":" Website\u30fbDownload\u30fbContact: Tigy01#1231
(Refold (JP) Server)
Example images
FrontBack "},{"location":"alternatives/#stazors-note-type","title":"Stazor's Note Type","text":" Download\u30fbOriginal discord message\u30fbContact: Stazor#6633
(TMW server)
- The download link contains a
readme.txt
that has instructions on how to setup the fields & basic info on the card
Example images
FrontFront (on hover)BackBack (light) "},{"location":"alternatives/#rudnams-note-type","title":"rudnam's Note Type","text":" Website & Download\u30fbContact: rudnam#8661
(Refold (JP) Server)
Example images
Full demoVocabSentence "},{"location":"alternatives/#jidoujishos-note-type","title":"jidoujisho's Note Type","text":"The app jidoujisho comes with its own Anki template, that should be automatically generated on the first card add when using the app.
"},{"location":"alternatives/#jo-mako-audio","title":"Jo-Mako - Audio","text":" Website & Download & Contact
- Audio and picture at the front, everything else at the back
Example images
FrontBackKanji Popup "},{"location":"alternatives/#jo-mako-reading","title":"Jo-Mako - Reading","text":" Website & Download & Contact
- Sentence at the front (with revealable picture and reading). Meaning at the back.
Example images
Example 1Example 2 "},{"location":"alternatives/#mallys-note-type","title":"Mally's Note Type","text":" Website & Download
Example images
FrontBack "},{"location":"alternatives/#nocompos-note-type","title":"Nocompo's Note Type","text":" Website & Download
Example images
FrontBack "},{"location":"alternatives/#klierets-templates","title":"Klieret's Templates","text":" Website & Download
"},{"location":"alternatives/#anacreons-template","title":"Anacreon's Template","text":" Website & Download
Example image
"},{"location":"alternatives/#decks","title":"Decks","text":""},{"location":"alternatives/#kanken-deck","title":"Kanken deck","text":" Website & Download\u30fbContact
- The definitive deck to use for learning how to write kanji
- Not a note type used for mining
- Also see: Xelieu's alternative theme
Example image
"},{"location":"alternatives/#nihongokyoshi-anki-deck","title":"NihongoKyoshi Anki Deck","text":" Download\u30fbOriginal discord message\u30fbContact: medamayaki#0328
(TMW server)
- Monolingual grammar deck
Example images
Front | DarkBack | DarkFront | LightBack | Light "},{"location":"alternatives/#other-decks","title":"Other Decks","text":" - Decks from AJATT
- Decks from TMW
"},{"location":"alternatives/#everything-else-not-made-specifically-to-learn-japanese","title":"Everything Else (Not made specifically to learn Japanese)","text":" - Prettify
- Modern Card Themes
- Anki Cards Templates SuperList
- Raagaception's 12STD CBSE Deck (Science stream, PCM)
- Anki Minimal Language Learning Template
- Awesome Anki
-
He seems to have left TMW Discord server, and his demo video on Youtube was privated. I assume he no longer wants to be contacted. If you have any questions about this setup, you should be able to ask in TMW server instead.\u00a0\u21a9
"},{"location":"autopa/","title":"Pitch Accent","text":"This page is dedicated to showcasing how pitch accent is displayed, and various ways to edit said display.
"},{"location":"autopa/#what-is-pitch-accent","title":"What Is Pitch Accent?","text":"Here is a (slightly modified) excerpt taken from the AJT Japanese Github page that explains the notation well:
Quote
For more information on the Japanese pitch accent, I would like to refer you to this wikipedia article. In short, the following notations can be found:
- Overline: Indicates \"High\" pitch (see \"Binary pitch\" in Wikipedia article).
- Overline downstep: usually means stressing the mora/syllable before.
-
Red circle mark: Nasal pronunciation.
For example, \u3052 would be a nasal \u3051, and would represented as \u3051\u00b0.
-
Blue color: Devoiced mora (barely pronounced at all).
For example, \u30d2 would be closer to h than hi. Likewise, \u30af would be more like a k than ku.
"},{"location":"autopa/#specifying-pitch-accent","title":"Specifying Pitch Accent","text":"The displayed pitch accent is usually the first position found in PAPositions
. However, you can override this automatically chosen position using the PAOverride
field.
The demo above covers the most basic usage of PAOverride
, which should suffice for most people.
The rest of the page covers the details on exactly how PAOverride
works, and all the ways to customize how the pitch accent is displayed.
"},{"location":"autopa/#colored-pitch-accent","title":"Colored Pitch Accent","text":"The reading, word and pitch overline can be automatically colored in Migaku style colors, according to the pitch accent.
This automatic coloring behavior is disabled by default, and must be enabled in the runtime options:
\"autoPitchAccent.coloredPitchAccent.enabled\": true, // (1)!\n
- The
autoPitchAccent
module must be enabled to use colored pitch accent. For example: \"autoPitchAccent.enabled\": true,\n
This is enabled by default, so you likely don't need to manually enable this module.
"},{"location":"autopa/#pitch-accent-groups","title":"Pitch Accent Groups","text":"Anki Tag \u65e5\u672c\u8a9e Example Reading heiban \u5e73\u677f \u81ea\u7136 \u3057\u305c\u3093\uffe3 atamadaka \u982d\u9ad8 \u4eba\u751f \u3058\uff3c\u3093\u305b\u3044 nakadaka \u4e2d\u9ad8 \u5f31\u70b9 \u3058\u3083\u304f\u3066\uff3c\u3093 odaka \u5c3e\u9ad8 \u9053\u5177 \u3069\u3046\u3050\uff3c kifuku \u8d77\u4f0f \u9a5a\u304f \u304a\u3069\u308d\uff3c\u304f"},{"location":"autopa/#controlling-what-gets-colored","title":"Controlling What Gets Colored","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
There are many runtime options that change exactly what is colored. By default, everything except words found in tooltips (kanji hover and word indicators) are highlighted.
\"autoPitchAccent.coloredPitchAccent.color.wordReadingPitchOverline\": true,\n\"autoPitchAccent.coloredPitchAccent.color.wordReadingKanji\": true,\n\"autoPitchAccent.coloredPitchAccent.color.testedContent\": true,\n\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": true,\n\"autoPitchAccent.coloredPitchAccent.color.definitions\": true,\n\"tooltips.overrideOptions.autoPitchAccent\": {\n// highlights bolded kanji\n\"autoPitchAccent.coloredPitchAccent.color.wordReadingKanji\": false,\n// highlights bolded sentence below word\n\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": false, // (1)!\n},\n
- If you want enable word coloring within the sentence, the word within the sentence must be able to be highlighted in the first place. To enable this, use the following runtime option:
\"tooltips.highlightWordInSentence\": true,\n
"},{"location":"autopa/#when-pitch-is-not-automatically-colored","title":"When Pitch Is Not Automatically Colored","text":"Pitch accent coloring requires a numeric position value somewhere within the card. This is usually found in one of these places:
PAPositions
PAOverride
AJTWordPitch
(the numeric position is automatically calculated through the HTML)
Usually, PAPositions
is automatically filled.
In the cases where pitch accent coloring does not work as expected, your two main options are:
- Using
PAOverride
with a number (recommended). - Force the pitch accent group with tags (see below).
"},{"location":"autopa/#kifuku-coloring","title":"Kifuku Coloring","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
) A word is automatically colored as \u8d77\u4f0f if the WordTags
field contains a verb tag, and its pitch accent group is not \u5e73\u677f.
This WordTags
field can only be filled out if you have a modern version of the JMdict dictionary for Yomichan For old cards that do not have this field filled, you will have to manually mark the word with -1
(in PAOverride
).
"},{"location":"autopa/#override-pitch-accent-group","title":"Override Pitch Accent Group","text":"In some extremely rare cases, you must set manually set the pitch accent group, if the available options do not work. To do this, add the appropriate tag to the card.
The exact tags that can be used are shown in the summary table above, under the Anki Tag
and \u65e5\u672c\u8a9e sections. For example, the tag can be heiban
, \u5e73\u677f
, etc.
Note
The tag only overrides the pitch accent color, and does not affect the pitch accent representation itself.
This fact can be useful for certain exceptions, such as how \u901a\u308b is [1] instead of [2]. If you want to use the \u8d77\u4f0f pattern on \u901a\u308b, you will have to set the PAOverride
value to 1
, and then add the \u8d77\u4f0f
tag.
TODO image of above (without tag, with tag)
"},{"location":"autopa/#how-pitch-accent-is-selected","title":"How Pitch Accent is Selected","text":"Pitch accent is selected based on the following priority:
- PAOverrideText
- PAOverride
- PAPositions
- AJTWordPitch
The first field that is non-empty will be the field that is used to display the pitch accent.
Note
When the auto-pitch-accent
module is disabled, the priority changes to the following:
PAOverrideText
PAOverride
AJTWordPitch
Of course, as the module is disabled, PAOverride
will not be parsed in any way. More info on this can be found in the PAOverride field section below.
"},{"location":"autopa/#1-paoverridetext","title":"(1) PAOverrideText","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
If the PAOverrideText
field is filled, then this field is displayed exactly as is, without any changes or parsing. This provides the most flexibility, but the least ease of usage.
PAOverrideText with: \"Hello world!\""},{"location":"autopa/#2-paoverride","title":"(2) PAOverride","text":"The PAOverride
allows for two primary formats: positions and text format. If the field contents cannot be parsed in either of these formats, then the field is displayed without any special formatting. This will act just like PAOverrideText
.
"},{"location":"autopa/#21-paoverride-positions-format","title":"(2.1) PAOverride: Positions Format","text":"When the PAOverride
field contains any number, that number will be considered as the downstep position, and be rendered as such. The number -1
represents the \u8d77\u4f0f pattern, and can be used to set the downstep to be after the second last mora.
Examples (on the \u507d\u8005 card):
PAOverride Result Notes 0
\u30cb\u30bb\u30e2\u30ce 1
\u30cb\ua71c\u30bb\u30e2\u30ce -1
\u30cb\u30bb\u30e2\ua71c\u30ce \u8d77\u4f0f"},{"location":"autopa/#multiple-numbers","title":"Multiple Numbers","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Multiple numbers can be used, as long as they are separated by commas. This is useful on certain words with devoiced mora, where the pitch accent can be multiple positions with little real distinction.
Additionally, individual numbers can be bolded to grey out the other positions. This is useful to highlight the correct pitch accent among all possiblities.
Examples (on the \u507d\u8005 card):
PAOverride Result Notes 0,2,4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c 0 ,2, 4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c The parser ignores all whitespace. <b>0</b>,2,4
\u30cb\u30bb\u30e2\u30ce\u30fb\u30cb\u30bb\ua71c\u30e2\u30ce\u30fb\u30cb\u30bb\u30e2\u30ce\ua71c Restrictions on bolded numbers
Multiple numbers cannot be bolded together. If you want to bold multiple numbers, they have to be bolded individually. Additionally, commas cannot be bolded.
For example, 0,<b>1</b>,<b>2</b>,3
is valid, but 0,<b>1,2</b>,3
and 0,<b>1,</b>2,3
are invalid.
"},{"location":"autopa/#22-paoverride-text-format","title":"(2.2) PAOverride: Text Format","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
How To Type Special Characters (click here) This section requires you to type certain special characters. You can type these characters on any standard IME.
Characters Result \\
\uff3c \u3046\u3048
(ue
) \uffe3 ,
\u3001 /
\u30fb If no number is found within the PAOverride
field, the contents will be parsed using this format.
To define any pitch accent in text format, use \u300c\uff3c\u300d to specify downstep. For example, \u4eba\u751f should be written as \u300c\u3058\uff3c\u3093\u305b\u3044\u300d.
For words with no downstep (\u5e73\u677f\u578b), the \u300c\uffe3\u300d character must be placed at the end of the word. For example, \u8eab\u9577 should be written as \u300c\u3057\u3093\u3061\u3087\u3046\uffe3\u300d.
Removing the required \uffe3 symbol (click here) The restriction that \u5e73\u677f words require the \uffe3 symbol at the end can be removed using the following runtime option:
\"autoPitchAccent.paOverride.heibanMarkerRequired\": false,\n
This would allow any words without any downstep marker to be rendered as \u5e73\u677f. Using the above example, one can instead type \u8eab\u9577 as \u300c\u3057\u3093\u3061\u3087\u3046\u300d.
Examples:
PAOverride Result \u3058\uff3c\u3093\u305b\u3044 \u30b8\ua71c\u30f3\u30bb\u30a4 \u3044\u304d\u304a\uff3c\u3044 \u30a4\u30ad\u30aa\ua71c\u30a4 \u3069\u3046\u3050\uff3c \u30c9\u30a6\u30b0\ua71c \u3057\u3093\u3061\u3087\u3046\uffe3 \u30b7\u30f3\u30c1\u30e7\u30a6"},{"location":"autopa/#multiple-words","title":"Multiple Words","text":"Multiple words can be defined, as long as they are separated with either the \u300c\u30fb\u300d or \u300c\u3001\u300d characters.
This is particularly useful on expressions with multiple words, such as \u300c\u6bd2\u3092\u98df\u3089\u308f\u3070\u76bf\u307e\u3067\u300d.
Examples:
PAOverride Result \u3069\u304f\uff3c\u3001\u304f\u3089\u3046\uffe3\u3001\u3055\u3089\uffe3 \u30c9\u30af\ua71c\u3001\u30af\u30e9\u30a6\u3001\u30b5\u30e9 \u3061\uff3c\u304b\u30fb\u3061\u304b\uff3c \u30c1\ua71c\u30ab\u30fb\u30c1\u30ab\ua71c Note
This renderer will not accept any field with formatting. This means that bold, italics, overlines, etc. cannot be present in the field. For example, the input <b>\u306b\u305b\u3082\u306e</b>
will be rejected.
"},{"location":"autopa/#23-paoverride-raw-text","title":"(2.3) PAOverride: Raw Text","text":"As a last case resort, if the input of this field cannot be parsed as either of the two, the exact contents of PAOverride
will be displayed. This will behave exactly the same as PAOverrideText
.
"},{"location":"autopa/#3-papositions","title":"(3) PAPositions","text":"This field is automatically filled out as long as Yomichan has pitch accent dictionaries, and the tested word is covered in said dictionary.
By default, the first pitch of the first dictionary is shown.
"},{"location":"autopa/#show-all-possibilities-in-dictionary","title":"Show All Possibilities in Dictionary","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO: update pictures with correct config + add new config value for all dictionaries
Sometimes, pitch accent dictionaries show multiple pitch accents for a word. However, only the first pitch accent is shown by default.
One entry (default)All entriesOne entry + boldAll entries + bold If you want to show all of the pitch accent entries (in the first dictionary), use the following runtime option:
\"autoPitchAccent.paPositions.displayMode\": \"selected-dictionary\",\n
If you want to select the correct pitch accent, bold that position in PAPositions
(or simply use PAOverride
as described above)
Note
This option only works on cards formatted with JPMN's {jpmn-pitch-accent-positions}
helper. This means this option will not work on old cards that were imported to the JPMN
format.
"},{"location":"autopa/#4-ajtwordpitch","title":"(4) AJTWordPitch","text":"If you have the optional AJT Japanese add-on installed and correctly configured, then this field is automatically generated on all cards.
This is used as a fallback option, in case your installed pitch accent dictionaries does not cover the tested content, but this add-on does.
"},{"location":"autopa/#how-the-reading-is-selected","title":"How the Reading is Selected","text":"The reading consists of the actual kana that is shown on the card. By default, the word reading is selected based on the following priority:
AJTWordPitch
WordReading
"},{"location":"autopa/#reading-ajtwordpitch","title":"Reading: AJTWordPitch","text":"Usually, the reading is selected from AJTWordPitch
. This has a few features over the raw word reading:
AJTWordPitch
usually includes devoiced and nasal info, whereas WordReading
does not. - Readings are katakana, and cannot be changed to hiragana.
Note
If you do not want the reading in AJTWordPitch
to be used, change the following runtime option to false
:
\"autoPitchAccent.searchForAJTWord\": false,\n
"},{"location":"autopa/#reading-wordreading","title":"Reading: WordReading","text":"If the word cannot be found under AJTWordPitch
, then the default reading in WordReading
is used, and displayed in katakana.
Unlike AJTWordPitch
, this reading can be changed to the word reading kana (usually hiragana), katakana, or katakana with long vowel marks in the runtime options:
// The reading display to show if nothing is generated by AJT Japanese.\n// Valid options:\n// \"word-reading\"\n// \"katakana\"\n// \"katakana-with-long-vowel-marks\"\n\"autoPitchAccent.readingDisplayMode\": \"katakana\",\n
"},{"location":"autopa/#pitch-accent-styling-details","title":"Pitch Accent Styling Details","text":"This covers some details if you are directly using PAOverrideText
, and want to have a similar format to the generated pitch accent. You very likely won't be doing this.
Styling Details (click here) -
The generated style is very similar to the generated style of the AJTWordPitch field. To display the style properly, you can simply copy and edit the HTML tags directly. If you want to see the true generated output, use the AnkiWebView Inspector and inspect the element.
-
If you want to grey out other words, you will have to use the bold <b>
tag. However, you must wrap the greyed out words with the <b>
tag.
This is the opposite of what would expect from everything in this page, but the behavior is this way due to restrictions in the current CSS specification.
-
Note that AJT Japanese also outputs the following span classes, however these are simply ignored by JPMN. You can include them if you want, but they will have no effect on the styling:
<span class=\"low\"></span>
<span class=\"low_rise\"></span>
-
Example with all possible styles:
\u30c1\u30e5<span class=\"high_drop\">\u30fc\u30ab<span class=\"nasal\">\u00b0</span></span><span class=\"devoiced\">\u30af</span>\u30bb\u30a4<b>\u30fb\u30cb<span class=\"high\">\u30bb\u30e2\u30ce</span></b>\n
"},{"location":"backfilling/","title":"Backfilling (TODO)","text":"TODO introduction
"},{"location":"backfilling/#backfill-pitch-accents-and-sentence-furigana","title":"Backfill Pitch Accents & Sentence Furigana","text":"TODO outdated! rerecord!
This requires the AJT Japanese
addon to be correctly setup.
-
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select the desired notes. The following Anki query selects all notes without sentence furigana or without generated pitch accents:
\"note:JP Mining Note\" (AJTWordPitch: OR SentenceReading:)\n
Don't forget to Ctrl+A to select all of the resulting cards! -
Head over to:
Edit
(top left corner) \u2192 AJT: Bulk-generate
.
"},{"location":"backfilling/#backfill-wordaudio","title":"Backfill WordAudio
","text":"To backfill word audio, I recommend using the Local Audio Server for Yomichan add-on, combined with DillonWall's Generate Batch Audio add-on.
To use the Generate Batch Audio add-on, simply select the desired notes in Anki's card browser, and then navigate to:
Edit
\u2192 Generate Bulk Audio
Tip
You can use the following query within Anki's card browser to find all cards without word audio:
\"note:JP Mining Note\" WordAudio:\n
Don't forget to Ctrl+A to select all of the resulting cards! The Generate Batch Audio add-on requires a few changes to its fields in order to work with JPMN:
- All URLs should have
{wordreading}
instead of {reading}
. Audio field
should be WordAudio
. Filter kana
should be WordReading
.
An example is shown below:
"},{"location":"backfilling/#backfill-frequencysort","title":"Backfill FrequencySort
","text":"FrequencySort
behaves exactly the same as Marv's Frequency
field as documented in Marv's JP Resources page page.
That page also contains instructions on how to backfill the field if it is empty.
If you are following the command line instructions, use the following command:
python backfill.py \"Word\" --freq-field \"FrequencySort\" --query \"FrequencySort: \\\"note:JP Mining Note\\\"\"\n
"},{"location":"batch/","title":"Batch Commands (TODO)","text":"Batch commands are actions that affect multiple notes all at once. Usually, these commands affect all JP Mining Note
notes. Please use these commands with caution, and always backup your collection before doing large changes to your Anki collection!
"},{"location":"batch/#running-batch-commands","title":"Running batch commands","text":"Before running any batch command, ensure Anki is open, and Anki-Connect is installed.
There are two ways of running batch commands.
-
If you are using JPMN Manager, you can run it by navigating to the following:
Tools
\u2192 JPMN Manager
\u2192 Run batch command
-
Alternatively, you can run batch commands directly through command line:
WindowsmacOS & Linux :: Ensure you have Anki open, and with Anki-Connect running\n:: Also ensure that you have python 3.9+ installed.\npython tools\\batch.py YOUR_BATCH_COMMAND\n
# Ensure you have Anki open, and with Anki-Connect running\n# Also ensure that you have python 3.9+ installed.\n# You may have to use `python3` instead of `python`.\npython3 tools/batch.py YOUR_BATCH_COMMAND\n
"},{"location":"batch/#available-batch-commands","title":"Available batch commands","text":"Below contains an incomplete list of available batch commands.
Most batch commands are ad-hoc commands written for one-time usage, usually for importing notes or updating notes. If you want the full list, run the following command:
python3 tools/batch.py --help\n
"},{"location":"batch/#fill_field","title":"fill_field","text":"usage: fill_field [-h] [--value VALUE] [--query QUERY] field_name
Sets the given field to 1
.
Some examples:
# set all cards to sentence cards\nfill_field IsSentenceCard\n\n# does the above, but fills the field with `x` instead of `1`:\nfill_field IsSentenceCard --value \"x\"\n
"},{"location":"batch/#empty_field","title":"empty_field","text":"usage: empty_field [-h] [--query QUERY] field_name
Empties the given field.
"},{"location":"batch/#copy_field","title":"copy_field","text":"usage: copy_field [-h] [--query QUERY] src dest
Copies the contents of the source (src) field to the destination (dest) field.
"},{"location":"batch/#verify_fields","title":"verify_fields","text":"usage: verify_fields [-h] [--version VERSION]
Checks that the fields and its order is correct with the current version.
"},{"location":"batch/#reposition_fields","title":"reposition_fields","text":"usage: reposition_fields [-h] [--version VERSION]
Automatically reorders the field list to be the expected order
"},{"location":"blockquotes/","title":"Blockquotes (TODO)","text":"For the purposes of this note type, a blockquote is simply a name given to group together the following sections of text:
- Primary Definition
- Secondary Definition
- Additional Notes
- Extra Definitions
- Extra Info
These are called \"blockquotes\" because they are stylized as a blockquote, and are internally contained inside a blockquote
HTML tag.
Topics such as how dictionaries are selected are not covered here. For those topics, see the Definitions page instead.
"},{"location":"blockquotes/#desktop-interface","title":"Desktop Interface","text":"TODO image
On desktop, only the Primary definition is revealed by default. All other blockquotes are shown by un-collapsing the individual sections.
"},{"location":"blockquotes/#automatically-reveal-collapsed-blockquotes","title":"Automatically reveal collapsed blockquotes","text":"Collapsed sections can be set to be automatically opened under the following runtime option:
\"blockquotes.open.enabled\": true,\n
Example Config (click here) \"blockquotes.open.enabled\": true,\n\"blockquotes.open.secondaryDefinition\": true,\n\"blockquotes.openOnNew.enabled\": true, // (1)!\n\"blockquotes.openOnNew.extraInfo\": true,\n
- This allows a blockquote to be open on new cards only. The
blockquotes.open.enabled
option always opens a blockquote. regardless of whether the card is new or not.
DefaultUsing example config (new card)Using example config (non-new card) "},{"location":"blockquotes/#grey-out-empty-collapsed-blockquotes","title":"Grey out empty collapsed blockquotes","text":"Collapsable fields that are empty are completely hidden by default. These can be greyed out instead, using the following runtime option:
\"blockquotes.hideEmpty\": false,\n
Empty fields greyed outEmpty fields not shown (default) "},{"location":"blockquotes/#grey-out-collapsed-blockquotes-until-hover","title":"Grey out collapsed blockquotes until hover","text":"Even when collapsed blockquotes are hidden, it may take up more eye space than desired. One solution to this is to grey out the collapsed blockquotes until hover, with the following CSS:
/* greys out the summary text until hover */\n.glossary-details > summary {\ncolor: var(--text-color--3);\n}\n.glossary-details:hover > summary {\ncolor: var(--text-color--1);\n}\n/* non-grey when open */\n.glossary-details[open] > summary {\ncolor: var(--text-color);\n}\n
Greyed out until hoverDefault behavior TODO
TODO
Note
This is NOT recommended if you set blockquotes.hideEmpty
to false
, because it makes differentiating between empty blockquotes and non-empty blockquotes much more difficult.
"},{"location":"blockquotes/#mobile-interface","title":"Mobile Interface","text":"On mobile, the collapsible sections are replaced with tabs. Clicking on these tabs reveal the relevant section.
TODO table of icon to section
"},{"location":"blockquotes/#folder-tab-mode","title":"Folder Tab Mode","text":"As folder tabs are inheriently a bit different than collapsible sections, a few different modes exist to control how they behave:
Unique (default)MultipleLinked \"blockquotes.folderTab.mode\": \"unique\",\n
Only one unique tab can show up at once. This is the default behavior.
TODO image
\"blockquotes.folderTab.mode\": \"multiple\",\n
Anywhere from 0 to all tabs can be shown at once. This best mimics the behavior on PC.
TODO image
\"blockquotes.folderTab.mode\": \"linked\",\n
This behaves like the unique
mode, except specified tabs can be \"linked\" together, such that those specific tabs will always show together. These linked tabs can be specified with blockquotes.folderTab.linkedTabs
.
TODO image
"},{"location":"blockquotes/#show-multiple-tabs-at-once","title":"Show multiple tabs at once","text":"By default, multiple tabs cannot be shown at the same time. If you have any blockquotes.open.*
runtime options set, then you may see a warning saying:
TODO\n
In order to see multiple blockquotes at the same time, you will need to set the folder tab mode to either multiple
or linked
.
Warning
None of the blockquotes.openOnNew
options will work on mobile:
- Unfortunately, there is currently no way to determine whether a card is new on mobile or not, as it requires an Anki-Connect call not supported by AnkiConnectAndroid.
- Additionally, the AnkiDroid JS API
ankiGetCardType()
doesn't seem to behave correctly either.
Likewise, there is no way to change the folder tab mode or linked tabs depending on whether the card is new,
"},{"location":"blockquotes/#do-not-hide-tabs-when-empty","title":"Do not hide tabs when empty","text":"On mobile, the tabs will be hidden when empty. This runtime option allows them to be shown (but replaced with a small dot) when empty.
\"blockquotes.folderTab.showDotWhenEmpty\": true,\n
Dot replacing empty tabs (true
)Hidden tabs (false
, default) TODO
TODO
"},{"location":"building/","title":"Building","text":""},{"location":"building/#technical-summary","title":"Technical Summary","text":"The Anki card template is generated through jinja
templates, which is a popular templating engine for Python
. All of these templates are located under the (root)/src
folder.
The Anki templates are generated through a combination of sass
(for CSS), jinja
(for HTML generation), and npm
(Webpack + TypeScript) for JavaScript generation. All of this is managed through the tools/make.py
script.
You must build the note to use any compile options.
Additionally, if you want to use bleeding edge features (the absolute latest features, which maybe riddled with bugs), you must build and install the note from the dev
branch. More info about this is shown later.
Note
The instructions listed below will be primarily Linux based. Notes for other operating systems may be shown, but are not guaranteed.
It is also assumed that you have knowledge of basic command line.
"},{"location":"building/#building","title":"Building","text":""},{"location":"building/#prerequisites","title":"Prerequisites","text":" - Python 3.10.6 or higher
- I recommend pyenv to upgrade your python version if you're running Linux.
- git
- npm
- Anki-Connect
- Anki 2.1.54+ or higher
"},{"location":"building/#initialization-git","title":"Initialization (git)","text":"First, you must clone the repository onto your drive.
# on fresh installs\ngit clone https://github.com/arbyste/jp-mining-note.git\ncd jp-mining-note\n\n# alternatively, if you already have the repository on your system:\ngit pull origin master\n
The master
branch is the stable version of the note.
If you want to build the pre-release version of the note, use the dev
branch. For example, do the following:
git fetch\ngit checkout dev\n
"},{"location":"building/#initialization-venv","title":"Initialization (venv)","text":"The following creates a custom python environment with venv
, so that packages aren't installed into your global python environment.
# assuming you are under the root folder, usu. jp-mining-note\n# You may have to use `python` instead of `python3`, and `pip` instead of `pip3`.\npython3 -m venv .venv\n\n# The following is for POSIX (bash/zsh) only.\n# See how to activate venv on your system in the official documentation:\n# https://docs.python.org/3/library/venv.html\nsource ./.venv/bin/activate\n\npip3 install -r tools/requirements.txt\n
Some additional options with venv
are shown below.
Disabling the venv deactivate\n
Resetting the venv # run this only if you're already in a venv\ndeactivate\n\nrm -r ./venv\npython3 -m venv .venv\nsource ./.venv/bin/activate\npip3 install -r tools/requirements.txt\n
Don't want to use venv? It is highly recommended that you use venv, or something else that isolates the python environment.
However, in case you don't want to use venv
, you can manually install the dependencies (including dependencies for building documentation):
pip3 install \\\npyjson5 jinja2 black pytest \\\nmkdocs mkdocs-video mkdocs-material mkdocs-macros-plugin mkdocs-redirects \\\nmkdocs-git-revision-date-localized-plugin\n
"},{"location":"building/#initialization-npm","title":"Initialization (npm)","text":"The following installs all the required dependencies for generating the note's JavaScript.
# installs a clean state of the dependencies\nnpm ci\n
"},{"location":"building/#building-and-installing","title":"Building and Installing","text":"After setting up venv
and npm
, you are ready to build and install the note.
# Builds the note into the (root)/build folder, and installs.\n# WARNING: completely overrides current note that is installed!\n# Please make a backup of your collection before doing this!\npython3 tools/main.py\n
Note
If you are attempting to (build and) install the bleeding edge version of the note on an Anki profile that does NOT already have the note installed, you have to run the installation script twice. For example:
python3 tools/main.py\npython3 tools/main.py\n
Additional things you can do with the project are shown below.
"},{"location":"building/#running-tests","title":"Running Tests","text":"cd tools\npython3 -m pytest ./tests\n
"},{"location":"building/#building-the-documentation","title":"Building the Documentation","text":"To \"build\" the documentation, all you have to do is the following:
cd docs\n\n# you should now be in (root)/docs, where the mkdocs.yml is.\nmkdocs serve\n
This will allow you to preview the website (usually at http://127.0.0.1:8000/jp-mining-note/
).
If you are looking to edit the documentation, all related files should be found under this docs
folder. The important markdown files are found under:
(root)\n L docs\n L docs\n L index.md # the home page\n L preface.md\n L setup.md\n L ...\n L mkdocs.yml\n
"},{"location":"building/#common-errors","title":"Common Errors","text":"(TODO) Fill this out as people start working with this note
"},{"location":"cardtypes/","title":"Card Types","text":""},{"location":"cardtypes/#preface","title":"Preface","text":"Previously, this note type only had vocab and sentence cards. Although I was originally fine with this, I started to realize some issues with only having these two card types:
- Vocab cards that require context have to be turned into sentence cards, and
- Sentence cards take a very long time to review, and can create context-based memories.
I found that many vocab cards had to be turned into sentence cards, since either the context was fundamental to understanding the definition, or there were other parts of the sentence that I wanted to test. This lead to many sentence cards, which naturally meant that Anki sessions lasted longer.
I attempted to tackle these exact issues by introducing new card types outside of the fundamental vocab and sentence cards.
"},{"location":"cardtypes/#changing-card-type","title":"Changing Card Type","text":"The rest of this page will document all card types that this note can create, and will use certain terminology such as \"filling a field\". If you do not know what this means, see the quickstart page on just that.
"},{"location":"cardtypes/#vocab-card","title":"Vocab Card","text":"A vocab card simply shows the target word at the front. You test yourself on the reading and definition of the word.
How to create: This is the default card type. Nothing has to be done for the card to be a vocab card.
"},{"location":"cardtypes/#sentence-card","title":"Sentence Card","text":"A sentence card simply shows the entire sentence at the front. You test yourself on the reading and meaning of the entire sentence.
How to create: Fill the IsSentenceCard
field.
"},{"location":"cardtypes/#targeted-sentence-card","title":"Targeted Sentence Card (TSC)","text":"A targeted sentence card is a special case of the sentence card. The sentence is shown at the front, but only the highlighted content (only the word by default) is tested. This allows you to have all the information and context of the sentence, but you don't have to waste your time testing other parts of the sentence.
This card type was originally defined here.
How to create: Fill the IsTargetedSentenceCard
field.
"},{"location":"cardtypes/#audio-cards","title":"Audio Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO new image)
Audio cards allows you to create cards that tests word or sentence audio.
Indicator: The sentence contains [...]
How to test:
- The audio should be automatically played on the front side of the card. With this audio, test yourself on the meaning and reading of the unknown section.
How to create: Fill the IsAudioCard
field. The word(s) that are hidden are exactly the words that are bolded in the Sentence
(or the AltDisplaySentence
) field.
Note
Before version 0.12.0.0
, these were misnamed as \"Cloze Deletion Cards, and the field was misnamed as IsClozeDeletionCard
\".
"},{"location":"cardtypes/#sentence-audio-cards","title":"Sentence Audio Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
This is simply a regular audio card, but the entire sentence is tested.
Indicator: The displayed text is exactly \u300c\uff1f\u300d
How to test:
- The audio should be automatically played on the front side of the card. With this audio, test yourself on the meaning and reading of the entire sentence.
How to create: Fill the IsAudioCard
and IsSentenceCard
field.
"},{"location":"cardtypes/#reveal-cards","title":"Reveal Cards","text":"Reveal cards (previously known as hybrid cards) are a group of card types that have the distinct feature that the word is shown at the front, while the sentence is hidden but can be shown through some natural means. Additionally, all reveal cards have some form of underline beneath the tested word, to differentiate it between a vocab card.
The primary reason why this exists is to prevent context-based memories. For example, in a TSC or sentence card, you may only remember the tested word due to its surrounding context.
Notes
-
For all forms of reveal cards, you can press n
to toggle whether the sentence is shown or not.
-
The \"How to test\" sections are simply recommended ways of testing, and are by no means the required way of testing yourself. Feel free to test yourself differently depending on whatever you think works the best.
"},{"location":"cardtypes/#hover-vocab-card","title":"Hover Vocab Card","text":"A hover vocab word shows the tested word at the front. When you hover over the word, you can see the full sentence, with the tested word highlighted.
This acts similarly to a vocab card. However, you are given the option to see the full sentence without failing the card.
This is also known as the fallback card.
Indicator: Grey & dotted underline under the word.
How to test:
- Attempt to guess the reading and definition of the word without hovering over the word.
- If you are able to guess both the reading and definition of the word, flip the card.
- Otherwise, hover over the word and guess the reading and definition of the word with the entire sentence.
How to create: Fill the IsHoverCard
field.
"},{"location":"cardtypes/#click-vocab-card","title":"Click Vocab Card","text":"A click vocab word shows the tested word at the front. When you click on the word, you can see the full sentence, with the tested word highlighted.
This card acts as an intermediary between the hover vocab card and the vocab card itself. You must guess the reading BEFORE revealing the sentence, but you can use the sentence to guess the definition.
Indicator: Grey & dashed underline under the word.
How to test:
- Attempt to guess the reading of the word without hovering over the word. If you are unable to guess the reading of the word before revealing the entire sentence, then the card must be marked as a fail.
- After guessing the reading of the word, you can optionally click on the word to reveal the entire sentence to guess the definition.
- In other words, if you can only guess the definition by reading the sentence, then the card should still be passed.
How to create: Fill the IsClickCard
field.
"},{"location":"cardtypes/#hover-sentence-card","title":"Hover Sentence Card","text":"This acts similarly to the hover vocab card. However, the tested content is the entire sentence, so you must hover over the word to test the entire sentence.
Indicator: Colored word & dotted underline under the word.
How to test:
- Attempt to guess the reading and definition of the word without hovering over the word.
- Regardless of whether you are able to guess the reading and definition of the word, hover over the word and test yourself on the sentence (as if it was a sentence card).
How to create: Fill the IsHoverCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#click-sentence-card","title":"Click Sentence Card","text":"This acts similar to the click vocab card. However, similarly to the hover sentence card, the tested content is the entire display, so you must click the word to test the entire display
Indicator: Colored word & dashed underline under the word.
How to test:
- Attempt to guess the reading of the word without hovering over the word. If you are unable to guess the reading of the word before revealing the entire sentence, then the card must be marked as a fail.
- After guessing the reading of the word, click on the word to reveal the entire sentence, and test yourself on the sentence (as if it was a sentence card).
How to create: Fill the IsClickCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#reveal-tsc","title":"Reveal TSC","text":"Similarly to the normal TSC, if you want to use the hover sentence card or click sentence card to only test a specific portion of the sentence, you can bold the desired selection of the sentence and fill IsTargetedSentenceCard
.
The above example is a Hover TSC, with the last sentence bolded.
"},{"location":"cardtypes/#reveal-hint-card","title":"Reveal Hint Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Hover HintClick Hint TODO image
TODO image
Similarly to a normal hint card, filling the IsHintCard
allows the reveal card type to reveal the sentence below the word (instead of replacing the word). You would test this like any normal reveal card, because this is simply a change in the style of how the information is displayed.
"},{"location":"cardtypes/#hint-cards","title":"Hint Cards","text":"Hint cards are a group of card types that display the sentence below the word. This acts as a better alternative compared to manually adding the sentence in the Hint
(or HintNotHidden
) field.
"},{"location":"cardtypes/#hint-vocab-card","title":"Hint Vocab Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
A hint vocab card is simply a vocab card that shows the sentence below the word. The tested content is the word itself, so you would test yourself as if it were a TSC or Hover Vocab card.
How to create: Fill the IsHintCard
field.
"},{"location":"cardtypes/#hint-vocab-card-highlighted","title":"Hint Vocab Card (highlighted)","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
This is exactly the same as the Hint Vocab Card, except the word within the sentence is automatically highlighted. This is tested the exact same as the Hint Vocab Card.
The reason why a highlighted word is not the default is because I found that I was focusing too heavily on the highlighted word instead of the word itself. To guarantee that you do not see the sentence unless you actually want to, see reveal cards.
How to create: Fill the IsHintCard
and IsTargetedSentenceCard
fields.
"},{"location":"cardtypes/#hint-sentence-card","title":"Hint Sentence Card","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO img
A hint sentence card is very similar to a Hint Vocab card, except the tested content is the entire sentence. This is indicated by the fact that the word is colored.
This is tested exactly like a Hover Sentence Card.
How to create: Fill the IsHintCard
and IsSentenceCard
fields.
"},{"location":"cardtypes/#hint-tscs","title":"Hint TSCs","text":"TODO img
Similarily to the normal TSC, this can be used to only test yourself on a specific portion of the sentence. This is tested exactly like a Hover TSC.
How to create: Fill the IsHintCard
, IsSentenceCard
and IsTargetedSentenceCard
fields.
Note
For all other card types, only IsTargetedSentenceCard
has to be filled to create a TSC. However, for hint cards, both IsSentenceCard
and IsTargetedSentenceCard
must be filled out.
"},{"location":"cardtypes/#sentence-first-cards","title":"Sentence-First Cards","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
Sentence-first cards are a group of cards that show the sentence first, and then show the tested word below. For these cards, you must read the entire sentence, but you only test yourself on the tested word. This differs from TSCs, because with TSCs, you do not need to read the entire sentence.
How to create: Fill the IsSentenceFirstCard
field.
"},{"location":"cardtypes/#sentence-first-tscs","title":"Sentence-First TSCs","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
(TODO image)
Just like a TSC, if you only want to read one specific portion of the sentence, you can highlight that specific portion.
It is expected that you use the AltDisplaySentence
field to set the custom highlight. There is no reason to use this with the default highlighted word (because you would then test it exactly the same as a normal TSC).
How to create: Fill the IsSentenceFirstCard
and IsTargetedSentenceCard
fields.
"},{"location":"cardtypes/#sentence-first-cards-hiding-the-word","title":"Sentence-First Cards: Hiding the word","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Hide until hoverHide until click TODO image
TODO image
If you do not wish to see the word accidentally before reading the entire sentence, one can use the IsHoverCard
or IsClickCard
to hide the word until you hover over or click on the sentence, respectively.
You would test yourself on these just like any other sentence-first card.
"},{"location":"cardtypes/#card-creation-summary","title":"Card Creation Summary","text":"The top row contains shorthands for the actual field names used:
- Sent:
IsSentenceCard
- TSC:
IsTargetedSentenceCard
- Click:
IsClickCard
- Hover:
IsHoverCard
- Audio:
IsAudioCard
- Hint:
IsHintCard
- Sent-First:
IsSentenceFirstCard
Card Creation Summary (Common Cards)
Sent TSC Click Hover Audio Result (Card Type) Vocab Card \ud83d\uddf8 Sentence Card \ud83d\uddf8 TSC \ud83d\uddf8 Click Vocab \ud83d\uddf8 \ud83d\uddf8 Click Sentence \ud83d\uddf8 \ud83d\uddf8 Click TSC \ud83d\uddf8 Hover Vocab \ud83d\uddf8 \ud83d\uddf8 Hover Sentence \ud83d\uddf8 \ud83d\uddf8 Hover TSC \ud83d\uddf8 Audio Card \ud83d\uddf8 \ud83d\uddf8 Sentence Audio Card Card Creation Summary (Hint Cards)
This table assumes you have IsHintCard
filled.
Hint Sent TSC Click Hover Result (Card Type) \ud83d\uddf8 Hint Vocab Card \ud83d\uddf8 \ud83d\uddf8 Hint Vocab Card (highlighted) \ud83d\uddf8 \ud83d\uddf8 Hint Sentence Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hint TSC \ud83d\uddf8 \ud83d\uddf8 Click Hint Vocab \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Hint Sentence \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Hint TSC \ud83d\uddf8 \ud83d\uddf8 Hover Hint Vocab \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Hint Sentence \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Hint TSC Card Creation Summary (Sentence-First Cards)
This table assumes you have IsSentenceFirst
filled.
Sent-First TSC Click Hover Result (Card Type) \ud83d\uddf8 Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 Sentence-First TSC \ud83d\uddf8 \ud83d\uddf8 Click Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Click Sentence-First TSC \ud83d\uddf8 \ud83d\uddf8 Hover Sentence-First Card \ud83d\uddf8 \ud83d\uddf8 \ud83d\uddf8 Hover Sentence-First TSC"},{"location":"cardtypes2/","title":"More on Card Types (TODO)","text":""},{"location":"cardtypes2/#hints","title":"Hints","text":"You can include a customized hint to show at the front of any card, by using the Hint
field. This will show as a collapsible field at the front of card.
If you do not want the hint to be hidden by default, you can use the HintNotHidden
field instead.
HintHintNotHidden "},{"location":"cardtypes2/#testing-pitch-accent","title":"Testing Pitch Accent","text":"TODO UPDATE IMAGES!!
No particular card type specifies how you should test pitch accent. This is because customizing how you should test pitch accent is a common feature of all card types.
By default, no special indicator is shown on whether pitch accent is tested or not, so you are free to choose either to test the pitch accent on all cards, or no cards.
To test for pitch accent, fill the PAShowInfo
field. You should see a circle to the left of the word or sentence.
"},{"location":"cardtypes2/#pitch-accent-indicator","title":"Pitch Accent Indicator","text":"This circle you see is called the \"Pitch Accent Indicator\", or \"PA Indicator\" for short. How this card indicates what pitch accent is tested is by the PA indicator's color.
Here are what the colors represent:
- Green: The entire sentence is tested.
- Blue: Only the word is tested.
- Red: Pitch accent should not be tested in any way.
If you ever forget what the colors mean, you can hover your mouse over the circle to get a description of what is being tested.
Alternatively, you can look at the top right of the screen and look at the value after the /
.
Note
If the tested content is a sentence (card), but you want to only test for word pitch accent, you would not be able to see the word normally. To see the word that is tested, there is a button to toggle whether the word is highlighted or not. The content that is highlighted is exactly what is bolded in the Sentence
(or AltDisplay
/ AltDisplayPASentenceCard
) field, which is the added word by default.
Note
If your card is a vocab card, then full sentence is shown as a collapsed field by default. This is only here to check your hearing with your guessed pitch accent, when used in conjunction with the sentence play button.
"},{"location":"cardtypes2/#selecting-the-pitch-accent","title":"Selecting the Pitch Accent","text":"The following shows how to fill in the proper fields to test pitch accent:
Filled fields PA Indicator Separated Cards (None, default) (Doesn't exist) PAShowInfo
Green (sentence) or blue (word), depending on the tested content PAShowInfo
& PADoNotTest
Red (not tested) PAShowInfo
& PATestOnlyWord
Blue (word) PAShowInfo
& PASeparateWordCard
Red (not tested) Word PAShowInfo
& PASeparateSentenceCard
Blue (word) Sentence PAShowInfo
& PASeparateWordCard
& PASeparateSentenceCard
Red (not tested) Word & Sentence To clarify some of the above:
- By default, if only
PAShowInfo
is filled, then the entire display is tested - For vocab cards, targeted sentence cards, and reveal vocab cards, only the word PA is tested (PA indicator: blue).
- For sentence cards and reveal sentence cards, the entire sentence PA is tested (PA indicator: green).
- To test just the word pitch accent, fill the
PATestOnlyWord
field. - To create completely separate cards to just test pitch accent on, use the fields
PASeparateSentenceCard
and/or PASeparateWordCard
. - If a PA word card is created, then the default card does not test pitch accent. Similarly, if a PA sentence card is created, then the default card only tests the word pitch accent.
"},{"location":"changingcardtype/","title":"Changing Card Type (TODO)","text":""},{"location":"changingcardtype/#individually-change-card-type","title":"Individually Change Card Type","text":"TODO copy/paste from quickstart
- can determine which fields are \"binary fields\" or not by the Fields page
"},{"location":"changingcardtype/#default-card-type","title":"Default Card Type","text":"TODO video
If you want to change the card type for all new cards, you can simply fill the field in Yomichan's Anki Card Format.
For example, if you want to set the default card type to be a sentence card:
- Navigate to Yomichan settings, and then to
Anki
\u2192 Configure Anki card format...
. - Set
IsSentenceCard
to 1
.
This will set all new cards to be a sentence card by default.
However, what if you don't want ALL new cards to be sentence cards? With the power of Yomichan handlebars, it is possible to selectively fill fields depending on select properties of the target word.
"},{"location":"changingcardtype/#is-hiragana","title":"Is Hiragana","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Helpers: {jpmn-filled-if-word-is-hiragana}
\u30fb{jpmn-filled-if-word-is-not-hiragana}
If the word is purely comprised of hiragana, you can create different card types by default using these helpers.
For example, let's say you want the default card to be a vocab card, but want hiragana terms to be TSCs. To do exactly that, do the following:
- Navigate to Yomichan settings, and then to
Anki
\u2192 Configure Anki card format...
. - Set
IsTargetedSentenceCard
to {jpmn-filled-if-word-is-hiragana}
.
Example behavior (click here) Example word {jpmn-filled-if-word-is-hiragana}
{jpmn-filled-if-word-is-not-hiragana}
\u3075\u3089\u3063\u3068 1 \u30c8\u30a4\u30ec 1 \u6210\u308a\u7acb\u3064 1 \u3076\u3064\u3076\u3064 1 \u30d6\u30c4\u30d6\u30c4 1 Note
This was inspired by Marv's hint sentence for kana cards.
"},{"location":"changingcardtype/#is-grammar-point","title":"Is Grammar point","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Helpers: {jpmn-filled-if-grammar-point}
\u30fb{jpmn-filled-if-not-grammar-point}
These helpers check if the word exists in a grammar dictionary. Of course, this can only work if you have a grammar dictionary installed in the first place.
The exact list of grammar dictionaries can be customized with the opt-grammar-override-dict-regex
option.
"},{"location":"changingcardtype/#is-onomatopoeia","title":"Is Onomatopoeia","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Helpers: {jpmn-filled-if-on-mim}
\u30fb{jpmn-filled-if-on-mim}
These helpers check if a dictionary entry is an Onomatopoeia word. It does this specifically by checking if the on-mim
tag exists on any dictionary entry. This design is unique to JMdict, so you must have a JMdict dictionary installed in order for this helper to function.
"},{"location":"changingcardtype/#batch-change-card-type","title":"Batch Change Card Type","text":"You may want to change the card type of many existing cards all at once. For example, you may have cards imported into JPMN, or cards that were simply not created by Yomichan in the first place.
Warning
As always, before mass editing your collection, please backup your Anki data.
There are three ways of batch changing the card type:
Batch CommandAnki's Search & ReplaceBatch Editing Addon You can use the fill_field
and empty_field
batch commands. For example, the following batch commands fill and empty the IsSentenceCard
field, respectively:
fill_field IsSentenceCard\nempty_field IsSentenceCard\n
More info about these batch commands can be found here. TODO
You can use a Batch Editing Addon to do the changes.
"},{"location":"changingcardtype/#batch-change-is-hiragana","title":"Batch Change: Is Hiragana","text":"If you used to have Marv's \"Automatic Hint Sentence for Kana Cards\" setup, you might be interested in replicating that for old cards. In order to do so, the fill_field_if_hiragana
batch command is provided to fill the provided field of all cards that have hiragana-only terms.
For example, the following batch command fills the IsHintCard
, which turns all cards with hiragana-only terms into Hint Cards, meaning a hint sentence is shown below the word.
fill_field_if_hiragana IsHintCard\n
If you want to have this be the default for all new cards, see here.
"},{"location":"compiletimeoptions/","title":"Compile Options (TODO)","text":"Just like runtime options, compile options are also options that are applied globally to each JPMN card.
The difference between runtime options and compile options is that compile options require you to build the note on your machine to use. Runtime options can be accessed and changed without having to build the note.
"},{"location":"compiletimeoptions/#accessing-editing","title":"Accessing & Editing","text":"To access the compile options, build the note.
After building the note, a new file config/config.py
should appear. The compile options can be found in this file.
To use these compile options, edit the config.py
file, and then re-build the note.
Warning
Do not edit the config/example_config.py
file. The example config file can be updated at any time, so if you update the example config through git, it may result in unnecessary merge conflicts.
"},{"location":"compiletimeoptions/#always-filled-never-filled-fields","title":"Always filled & Never filled fields","text":"Using compile options, one can set a field to act as if it has always been filled, or it has never been filled, using the always-filled-fields
and never-filled-fields
options. This will remove the conditional Anki templates ({{#FIELD}}
and {{^FIELD}}
markers) for the specified fields.
Example If your compile-options
is:
\"compile-options\": {\n ...\n \"always-filled-fields\": [\"A\"],\n \"never-filled-fields\": [\"B\"],\n ...\n}\n
and your card template is:
{{#A}} A is filled {{/A}}\n{{^A}} A is not filled {{/A}}\n{{#B}} B is filled {{/B}}\n{{^B}} B is not filled {{/B}}\n{{#C}} C is filled {{/C}}\n{{^C}} C is not filled {{/C}}\n
then upon card build, the resulting card template will be:
A is filled\nB is not filled\n{{#C}} C is filled {{/C}}\n{{^C}} C is not filled {{/C}}\n
This usually renders the actual field value useless. In other words, filling the field for a note will have no effect on the cards.
Warning
Do not delete the field from the fields list! See here for more details.
"},{"location":"compiletimeoptions/#optimized-vocab-card-example","title":"Optimized Vocab Card Example","text":"An example set of compile options to create a more optimized vocab card is shown below.
Vocab card compile options example
\"compile-options\": {\n\"keybinds-enabled\": False,\n\"hardcoded-runtime-options\": True,\n\"always-filled-fields\": [],\n\"never-filled-fields\": [\n\"PAShowInfo\", \"PATestOnlyWord\", \"PADoNotTest\",\n\"PASeparateWordCard\", \"PASeparateSentenceCard\", \"AltDisplayPASentenceCard\",\n\"SeparateClozeDeletionCard\",\n\"IsClickCard\", \"IsHoverCard\", \"IsSentenceCard\", \"IsTargetedSentenceCard\",\n],\n\"enabled-modules\": [\n# HIGHLY RECOMMENDED to have this enabled if you want a nice looking card\n# (unless you are not using images in your cards of course)\n\"img-utils-minimal\",\n],\n}\n
"},{"location":"customcss/","title":"Custom CSS (TODO)","text":"TODO introduction
- CSS: styles for the note
- can change font size, colors, hide elements, reposition certain elements, etc.
"},{"location":"customcss/#how-to-add-custom-css","title":"How To Add Custom CSS","text":"There are two options to add custom CSS:
-
Edit the styles directly.
This is the recommended way for most people to modify the CSS.
-
Add SCSS files.
These SCSS files are built with the note to extend the current CSS.
This is recommended way for people who build the note.
Option 1: Edit the styles directly (click here) TODO video
-
Navigate to the following:
(Main window) \u2192 Browse
\u2192 Cards...
(middle of the screen) \u2192 Styling
(top left)
-
Scroll all the way to the bottom, and add any CSS to the bottom of the styles.
Option 2: Add SCSS Files (click here) -
Build the note if you haven't already, and ensure everything works.
-
Create the following folder structure: (project root)/overrides/scss/extra
. The project root is usually jp-mining-note
.
-
Add the folder to the end of css-folders
list in config.py
. For example:
\"css-folders\": [\"base\", \"responsive\", \"dictionaries\", \"extra\"],\n
TODO update the exact folders
-
Under the extra
folder, use the following files to override the correct CSS:
style.scss
: The main CSS for the card templates. This is likely the file you want to edit, when adding custom CSS. field.scss
: The CSS used by CSS injector to customize individual fields. editor.scss
: The CSS used by CSS injector to customize the editor around the fields.
All of the files are optional. This means you do not need to create all three files for the folder to be valid.
The resulting folder should be of the format:
(project root)\n L overrides\n L scss\n L extra\n L field.scss\n L editor.scss\n L style.scss\n
-
Rebuild and reinstall the template. The CSS should be automatically applied to the note.
"},{"location":"definitions/","title":"Definitions (TODO)","text":"This page is dedicated to showcasing how definitions can be easily chosen, overwritten and customized overall.
"},{"location":"definitions/#dictionary-placement","title":"Dictionary Placement","text":"Dictionaries from Yomichan are sorted into the following fields:
Field Description PrimaryDefinition The highest priority monolingual or bilingual dictionary (depending on the value of opt-first-definition-type
). If you want to manually select a different dictionary, see here SecondaryDefinition All bilingual dictionaries outside of the one selected in the primary definition. ExtraDefinition All monolingual dictionaries outside of the one selected in the primary definition. UtilityDictionaries All dictionaries that fall outside the category of bilingual or monolingual. For example, JMnedict or JMdict Forms. The way that the dictionaries are sorted into the appropriate fields is by assigning a category to each individual dictionary.
"},{"location":"definitions/#verifying-categories","title":"Verifying Categories","text":"You can check that your dictionaries are correctly categorized with the {jpmn-test-dict-type}
helper. Under the Anki Templates code, replace Card field
with {jpmn-test-dict-type}
and press Test
.
An example output of the above (on the word \u7d50\u69cb) is the following:
\u300c\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248\u300d: monolingual\n\u300c\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248\u300d: monolingual\n\u300c\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797\u300d: monolingual\n\u300c\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248\u300d: monolingual\n\u300c\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9\u300d: monolingual\n\u300cNHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\u300d: utility\n\u300cJMDict Surface Forms\u300d: utility\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300cJMdict (English)\u300d: bilingual\n\u300c\u65b0\u548c\u82f1\u300d: bilingual\n
If a dictionary is miscategorized, you will have to edit bilingual-dict-regex
or utility-dict-regex
at the top of the template code. Monolingual dictionaries are considered to be dictionaries that aren't either of the two above, so no handlebars code has to be changed if one were to use more monolingual dictionaries.
To see how to edit the regex, go to this section.
"},{"location":"definitions/#ignoring-a-dictionary","title":"Ignoring a Dictionary","text":"If you want to see the dictionary on Yomichan but not have it show on Anki, you can use the ignored-dict-regex
option.
To see how to edit the option, see the section below.
Conversely, if you want to not see the dictionary on Yomichan but want it to show up on Anki, see here.
"},{"location":"definitions/#editing-the-dictionary-regex","title":"Editing the dictionary regex","text":"To modify a regex string:
-
Determine the exact tag your dictionary has. To see this, take a word that has a definition in the desired dictionary, and test {jpmn-test-dict-type}
like above. The string inside the quotes \u300c\u300d is exactly the tag of the dictionary.
-
Add the dictionary tag to the string, by replacing ADD_x_DICTIONARIES_HERE
. For example, if your bilingual dictionary tag is Amazing Dictionary
, change ADD_BILINGUAL_DICTIONARIES_HERE
to Amazing Dictionary
.
If you want to add more than one dictionary, they have to be joined with the |
character. For example, if you want to add the bilingual dictionaries Amazing Dictionary
and Amazing-Dictionary-2
, change ADD_BILINGUAL_DICTIONARIES_HERE
to Amazing Dictionary|Amazing-Dictionary-2
.
"},{"location":"definitions/#primary-definition-selection","title":"Primary Definition Selection","text":"The primary definition can either be selected automatically, or manually via highlighting the dictionary name or a section of the definition.
"},{"location":"definitions/#primary-definition-selection-automatic","title":"Primary Definition Selection: Automatic","text":"The dictionary for the primary definition is the first bilingual dictionary (that appears on Yomichan) by default.
This can be changed to the first monolingual dictionary by changing the following Yomichan template option to monolingual
:
{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n
TODO re-record with only automatic
"},{"location":"definitions/#primary-definition-selection-manual","title":"Primary Definition Selection: Manual","text":"TODO re-record with only manual
Sometimes, you may want to override the primary definition, or highlight the definition that makes sense with the context.
This is enabled by default. In case you want to disable this behavior, set opt-selection-text-enabled
to false
.
This manual selection behavior does the following:
-
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.
To disable this, set opt-selection-text-dictionary
to false
.
-
If a section of text is selected, then that dictionary will replace the first definition. Additionally, that section of text will be highlighted (bolded).
To disable this, set opt-selection-text-glossary
to false
.
Additionally, if you do not want to use the entire dictionary, and prefer that only the selected text is shown in the first definition, then set opt-selection-text-glossary-attempt-bold
to false
.
"},{"location":"definitions/#when-manual-selection-fails","title":"When Manual Selection Fails","text":"In an ideal world, we would have access to exactly what dictionary was selected from the handlebars. For example, a handlebars function could tell us if the n'th dictionary was highlighted. Unfortunately, we do not live in this ideal world, so we must get this information manually.
The handlebars algorithm runs thusly:
- If the selected text exactly matches any dictionary in the exported definition, then the dictionary entry is selected as the primary definition.
- Otherwise, we do the same search as the above, except we search through every dictionary's HTML (in Yomichan's order) for the selected text.
- If the selected text was found in some dictionary, then that dictionary is chosen. Otherwise, we fallback to the selected text itself.
Due to us having to find the information ourselves, there are many edge-cases where this algorithm fails.
-
Selecting formatted text
If you select formatted parts of text then automatic bolding will fail. An incomplete list of of formatted sections is shown below:
Line breaks Line breaks cannot be properly captured by the selected text.
IncorrectCorrect
Furigana Just like line breaks, furigana cannot be properly captured by the selected text.
IncorrectCorrect
List Items (common with JMdict) Avoid highlighting multiple items in a list if you want automatic bolding to work.
IncorrectCorrect
-
Same selected text appearing in multiple dictionaries
Manual selection may occasionally select the wrong dictionary, but this only happens if the selected text also appears in a dictionary above the selected text.
For example, suppose you have two bilingual dictionaries. and for the word \u86f8, you highlight the word \"octopus\" and create the card. Both bilingual dictionaries will list \"octopus\", so even if you highlight the word \"octopus\" in the second bilingual dictionary, only the first bilingual dictionary will be chosen.
Example: \u86f8
This is usually not a problem even if the same text appears in a dictionary above, because you'll be seeing the same definition regardless. However, if you still want a specific dictionary, highlight the dictionary tag as shown above.
-
Selected text in HTML markup
There are very rare edge cases when the highlighted text can be found in the internal HTML markup, leading to invalid HTML and (almost certainly) the incorrect definition.
Example: \u57a3\u6839 On the word \u57a3\u6839, if you have the \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 dictionary before JMdict in Yomichan and you highlight border
, then \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 will be incorrectly selected as the primary definition.
This is due to a perfect storm of events:
- Due to Yomichan's implementation details, definitions with images contain a
border
property in an internal style attribute. - \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 indeed has images for the word \u57a3\u6839.
- \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 is ordered before JMdict in Yomichan
With all these three combined, \u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9 is prioritized over JMdict, leading to an incorrect dictionary selected and invalid HTML.
"},{"location":"definitions/#usage-on-yomichans-search-page-clipboard-page","title":"Usage on Yomichan's Search Page / Clipboard Page","text":"On Yomichan's Search Page or Clipboard Page, the word is usually highlighted within the example sentence when searching for the word. For example, the word \u300c\u4eba\u91cc\u96e2\u308c\u305f\u300d is highlighted in the following image:
This highlighted word interferes with the definition selector used by the handlebars, and may cause unexpected definitions to be selected as the primary definition instead.
In order to fix this, you have a few different options:
- Simply don't use the search page or clipboard page. Instead, you can use a texthooker setup.
- Create a new Yomichan profile that matches the desired page(s), and disable
Selected matching text
within your new profile in the Yomichan settings. If you must use the search page or clipboard page, this is the recommended way to deal with the issue, as it has minimal impact on the rest of your workflow. - Ensure you always manually select something in the definition.
- Simply disable the
opt-selection-text-glossary
handlebars option completely.
Explanation (click here) Under normal circumstances, i.e. within an embedded popup, the selected text in a sentence does not interfere with the handlebars, because the selected text is not within the popup itself. However, within the search page / clipboard page, the sentence and its selected text is found directly within the page itself.
Internally, the handlebars to get the selected text cannot distinguish between whether the text is selected within a definition or somewhere else. As mentioned before, the handlebars has no way of actually knowing which dictionary entry or dictionary is selected, and must use this algorithm to search for the correct entry. With these two combined, the selected text within the sentence is used to search the definition. This may be especially confusing to see for people who remove the first line of monolingual dictionaries, because it is usually the first line of monolingual dictionaries that is matched and bolded.
"},{"location":"definitions/#simplifying-the-definition","title":"Simplifying the Definition","text":"If you use a monolingual dictionary, there is usually a bunch of extra information in the first line. Additionally, there is usually only one dictionary entry, making the list number redundant. Both of these can be automatically hidden with the following runtime option:
\"blockquotes.simplifyDefinitions.enabled\": true,\n
SimpleDefault "},{"location":"definitions/#simpifying-the-definition-per-blockquote","title":"Simpifying the definition per blockquote","text":"By default, if the above option is enabled, all definitions within the Primary Definition, Secondary Definition and Extra Definitions blockquotes are simplified. One can grant finer control to only simplify definitions within these particular blockquotes:
// Remember to enable this so the options can be used!\n\"blockquotes.simplifyDefinitions.enabled\": true,\n// The following controls precisely whether the simplifying definition is enabled\n// or not for each block.\n\"blockquotes.simplifyDefinitions.primaryDefinition.enabled\": true,\n\"blockquotes.simplifyDefinitions.secondaryDefinition.enabled\": true,\n\"blockquotes.simplifyDefinitions.extraDefinitions.enabled\": true,\n
"},{"location":"definitions/#removing-the-first-line-algorithms-discussion","title":"Removing the first line: Algorithms Discussion","text":"There are plenty of ways to remove the first line within the definition. In order to better understand how these handlebars work as well as its pitfalls, pretty much all possible options are listed below.
-
Remove the first line completely, using Handlebars.
Advantanges:
- The biggest advantage this has is the exported definition is as clean and minimalistic it can possibly be.
Disadvantages:
- This can lead to invalid HTML, because Handlebars does not expose a HTML parser. Additionally, removing the first line completely will remove info from the export.
-
Use JavaScript within the note template to remove the first line.
Advantages:
- No special handlebars are particularly required in order for this method to work, i.e. default handlebars can usually do the trick.
- All info is present / not lost.
- Anki's card reviewer is based off a web browser, so the JavaScript has access to a html parser. In other words, html should remain valid.
- This approach should theoretically work on previously exported cards.
Disadvantages:
- The JavaScript algorithm must assume the definition is of a particular HTML structure, i.e. all
<ol>
elements contain a list of definitions. This is problematic if the user edits the field, as they can change it to pretty much whatever they want. - Javascript must be ran, which will slow down card loads.
- This is not immediately portable between note types, because the JS must be copied/pasted for each note type.
- If the user decides that they want to include the first line, it will likely be non-trivial to do so. Editing the raw HTML may be required to simply specify whether the first line should be removed or not.
-
Wrap the first line with some HTML, using Handlebars.
Advantages:
- This does not require JS to be run at all; Only special CSS has to be used. Note that internally, some extra JS is actually run in order to further filter between dictionaries (
blockquotes.simplifyDefinitions.dictsOverride.hideFirstLineMode
). However, this JS is faster than the above option, because the JS only adds CSS classes to particular elements, and does not do any string or HTML parsing. - All info is present / not lost.
- This algorithm is relatively simple to implement.
- Including the first line is slightly more intuitive compared to the 2nd option: Delete the
<li>
node and create a fresh node.
Disadvantages:
- Just like the first option, this can lead to invalid HTML.
- This is technically not immediately portable, because the CSS must be copied/pasted for each note type.
- This solution will not work on older cards exported with different handlebars, i.e. handlebars that do not wrap the first line.
This is currently the chosen method for this note, primarily due to speed, no info loss and simplicity. The second option may be implemented in the future as a fallback, or for special case handling for specific dictionaries.
"},{"location":"definitions/#when-html-can-break","title":"When HTML can break","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
As mentioned in the algorithms discussion, the method used by this note can lead to invalid HTML. This is because the resulting HTML is parsed with regex in order to match that first line. In computer science, it is recommended that you should not parse HTML with regex, because it is mathematically impossible to fully describe and parse HTML with regex. Unfortunately, Yomichan's handlebars does not expose any HTML parser, so we are left with using regex to parse our HTML. Due to this, an unexpected dictionary format may cause the resulting export to be invalid HTML.
If you do not plan on using this feature, you should set opt-wrap-first-line-spans
to false
to remove the possibility of invalid HTML.
"},{"location":"definitions/#hide-the-first-line-for-select-dictionaries","title":"Hide the first line for select dictionaries","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The following two options are useful if you want to ignore certain problematic dictionaries, that do not play well with the regex above.
{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv)$ {{~/set~}}\n
opt-first-line-dicts-regex
specifies the list of dictionaries that should be ignored or kept. Whether the dictionaries are ignored or kept is defined in opt-first-line-regex-mode
(except
means that the specified dictionaries are ignored, and only
means that only the specified dictionaries can have their first lines removed.)
"},{"location":"definitions/#exporting-only-one-dictionary-entry","title":"Exporting only one dictionary entry","text":"A \"dictionary entry\" in this context is the single section of text corresponding to a number indicated by Yomichan, to the very far left.
In the following example, \u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248 and \u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248 each have one single entry, corresponding to 1
and 2
respectively. JMdict (English)
has two entries, corresponding to 3
and 4
.
As you may have noticed, it is almost never the case that monolingual dictionaries has multiple dictionary entries. Instead, most monolingual dictionaries store the definition as one gigantic entry.
By default, all dictionary entries are exported in the primary definition. However, if opt-primary-def-one-dict-entry-only
is set to true
, then only the first (or manually selected) dictionary entry will be imported into the primary definition.
Export all entries (default)Export one entry "},{"location":"definitions/#legacy-jmdict-support","title":"Legacy JMdict Support","text":"By default, JMdict is exported in a list format, which allows the note's CSS to re-compact the list. This is required over plaintext, because JMdict Extra cannot compact export a compact definition normally. This is a known issue with Yomichan's default handlebars.
If you prefer using a legacy version of JMdict and prefer a full line of plaintext instead of a CSS list, you can set opt-jmdict-list-format
to false
.
"},{"location":"externallinks/","title":"External Links (TODO)","text":"External links are usually found under the Extra Info
section of the note, to the top right corner.
TODO image
Naturally, these can be customized to your liking.
"},{"location":"externallinks/#customize-external-links","title":"Customize external links","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
Custom external links can be specified under the externalLinks
section in the compile options.
Creating external links is is explained in the config file, and there are plenty of commented-out examples that should work.
"},{"location":"externallinks/#removing-all-external-links","title":"Removing all external links","text":"If you want to remove all external links, set externalLinks
to {}
in the compile options.
For example:
\"externalLinks\": {},\n
"},{"location":"externallinks/#icons-with-multiple-text-characters","title":"Icons with multiple text characters","text":"When using text instead of a picture, it is recommended that you use single characters (e.g. one kanji) to represent the icon.
However, in the cases where you want to use more characters, the default CSS rules causes the icon will use the minimum amount of space, which may mis-aligned the surrounding icons.
Fixing this with SCSS (click here) Using the custom SCSS, you can specify the amount of space it takes (in terms of number of icons):
@use \"../base/common\" as common;\n.glossary__external-links a[data-details=\"DICTIONARY_ID\"] { // (1)!\nwidth: common.maxWidthForXIcons(2);\n}\n
- The DICTIONARY_ID are the key values of
external-links
. For example, the id of the jpdb.io
entry below is exactly jpdb.io
. \"jpdb.io\": {\n\"icon-type\": \"image\",\n\"icon-image-light\": \"_icon_jpdb_lightmode.png\",\n\"icon-image-dark\": \"_icon_jpdb_darkmode.png\",\n\"url\": \"https://jpdb.io/search?q={{text:Word}}\"\n}\n
Warning
This SCSS code is NOT CSS. This cannot be added directly to the template's style sheet in Anki. Please see the link above to see how to use custom SCSS.
An example of this can be found in src/scss/dictionaries/style.scss
"},{"location":"externallinks/#external-links-in-primary-definition","title":"External links in primary definition","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
External links usually appear in the \"Extra Info\" section. If you wish to have the external links to be on the primary definition section, set externalLinksPosition
to \"Primary Definition\"
in the compile options.
"},{"location":"faq/","title":"FAQ & Troubleshooting","text":""},{"location":"faq/#errors-warnings","title":"Errors & Warnings","text":"This section documents frequent errors that may show up on the info circle at the top right.
"},{"location":"faq/#error-ankiconnect-failed-to-issue-request","title":"(Error) AnkiConnect failed to issue request.","text":"This is an indication that Anki-Connect is failing. There are two main reasons that Anki-Connect can fail:
-
Ensure that Anki-Connect is installed. If it is installed, be sure to restart Anki to ensure the add-on is actually running.
-
If you are using an older version of Anki (2.1.49 and below), see the note in the Anki-Connect setup section here.
"},{"location":"faq/#warning-jpmnopts-was-not-defined-in-the-options-file-was-there-an-error","title":"(Warning) JPMNOpts was not defined in the options file. Was there an error?","text":"There are two reasons why you would be getting this warning:
-
You updated your note from a version before 0.12.0.0
, to 0.12.0.0
or higher. In this case, you will have to update your config file.
-
You are using Anki version 2.1.49 or below.
Please check your Anki version to confirm this:
Main Window \u2192 Help
\u2192 About...
How to fix (click here) If your Anki version is indeed 2.1.49 or below, then this should only appear on the front side of your first card of the session. To check, try flipping the card and back. This warning should dissappear once you do.
The only side effect of this is that the user-defined runtime options will not be used for the front side of the first card, and the defaults will be used instead.
There are two ways to fix this:
- Update Anki to a higher version. (highly recommended)
- Compile the card with hard-coded defaults.
Why this happens (click here) The <script ... src=\"_jpmn-options.js\">
tag seems to runs asynchronously on 2.1.49 and below, meaning that the order of when this is ran is not constant compared to the main javascript block. With that being said, the exact tag seems to run synchronously on 2.1.50 and above, so it is guaranteed to run before the main javascript block on these versions.
With my current knowledge, the only way to guarantee the order of this import is asynchronous functions, or some other asynchronous features. For example, a simple await import(...)
should work. However, asynchronous features have been avoided throughout the development of this, as it currently seems to behave unpredictably within Anki.
"},{"location":"faq/#warning-cannot-find-own-card","title":"(Warning) Cannot find own card","text":"This warning usually only appears if you renamed the note from JP Mining Note
to something else. If you rename the note, certain features will no longer function as expected, such as:
- Kanji Hover
- Word Indicators
- Most batch commands
- Automatic duplicate
Key
field checks
To remedy this, it is recommended that you change the note name back to JP Mining Note
.
"},{"location":"faq/#my-error-isnt-listed-or-the-steps-above-do-not-work","title":"My error isn't listed, or the steps above do not work","text":"If none of the above worked, follow the general troubleshooting steps.
"},{"location":"faq/#troubleshooting","title":"Troubleshooting","text":""},{"location":"faq/#the-font-on-the-card-template-is-incorrect","title":"The font on the card template is incorrect","text":"TODO bullet pt to sentences
TODO example picture of the wrong font
- if everything is correct, then fonts should actually be japanese (see: \u76f4\u3059)
- easy way to check for correct fonts: look at bolded serif font
- should look good (example picture)
-
if not, wrong fonts are likely being used
-
steps
- ensure fonts are downloaded and in the correct folder (media folder)
- show screenshot of this!
- ensure fonts are valid (could be corrupted)
- show gif of opening in windows
- restart your entire computer
- sometimes, restarting Anki isn't enough
"},{"location":"faq/#the-font-on-the-card-editor-is-incorrect","title":"The font on the card editor is incorrect","text":" - TODO link to setupanki.md
"},{"location":"faq/#the-sentencereading-field-is-not-updated-is-different-from-the-sentence-field","title":"The SentenceReading
field is not updated / is different from the Sentence
field","text":"This happens because programs such as mpvacious and asbplayer update the sentence manually. For example, assume the subtitles are the following:
- \u3060\u3063\u3066\u3001\u9ebb\u8863\u3055\u3093\u306f\u9045\u523b\u3057\u3066\u304d\u305f\u7537\u3092\u3001\u5065\u6c17\u306b\u4e00\u6642\u9593\u4e09\u5341\u516b\u5206\u3082
- \u5f85\u3063\u3066\u3044\u308b\u3088\u3046\u306a\u53ef\u611b\u3052\u306e\u3042\u308b\u5973\u3058\u3083\u306a\u3044\uff01\u3055\u3066\u306f\u507d\u7269\u3060\u306a\uff01
If you make a card from the highlighted \u507d\u7269, the Sentence
and SentenceReading
field will only contain the text from the 2nd subtitle. If you then use mpvacious or asbplayer to grab both subtitles, the Sentence
field will be updated, but the SentenceReading
field will not be updated.
Partial solutions
Sometimes, the problem appears because one subtitle can span multiple lines. These partial solutions work to solve that problem. However, these do not work for when lines span multiple subtitles.
-
For mpvacious, use a texthooker that can remove all whitespace (i.e. Renji's Texthooker).
-
For asbplayer, you can remove the line breaks in the subtitle file itself (i.e. with SubtitleEdit)
The only full solution I know to this is to disabling automatic furigana generation on card add. If you still want furigana on your cards, bulk generate it after each session.
"},{"location":"faq/#the-word-is-incorrectly-highlighted-not-highlighted-at-all","title":"The word is incorrectly highlighted / not highlighted at all.","text":"The word is usually highlighted by default, but the word may not be highlighted for the following reasons:
- The sentence field got updated by an external program.
- The card was imported from an older deck that did not highlight the tested word.
As of version 0.12.0.0
, the card will automatically attempt to highlight the word if the word was not highlighted in the first place. However, this highlight may yield incorrect results. This is expected behavior, and you are expected to manually bold the sentence if the highlight is incorrect.
See here for more info.
"},{"location":"faq/#the-tools-check-media-interface-removes-the-font-files","title":"The Tools
\u2192 Check Media
interface removes the font files.","text":"This is a known bug, and unfortunately, this bug will not be fixed by default. 1
If you accidentally removed the fonts, redownload the fonts and re-add them into the media folder of your profile. Alternatively, updating the note with JPMN manager should automatically re-install the required font files.
It is possible to fix this by using the following workaround:
- Within the media folder, rename all the font files such that they all have
_
at the beginning. For example, NotoSerifJP-Regular.otf
should be renamed to _NotoSerifJP-Regular.otf
. -
Add the following custom CSS to the very bottom (do not modify the existing CSS!):
@font-face {\n font-family: notoserif;\n src: url(\"_NotoSerifJP-Regular.otf\");\n}\n@font-face {\n font-family: notoserif;\n src: url(\"_NotoSerifJP-Bold.otf\");\n font-weight: bold;\n}\n@font-face {\n font-family: notosans;\n src: url(\"_NotoSansJP-Regular.otf\");\n}\n@font-face {\n font-family: notosans;\n src: url(\"_NotoSansJP-Bold.otf\");\n font-weight: bold;\n}\n
"},{"location":"faq/#the-showhide-button-doesnt-do-anything","title":"The Show/Hide button doesn't do anything.","text":"The show/hide button requires that the displayed sentence has a bolded element. For example, this means if the currently displayed sentence comes from the AltDisplay
field and nothing in that field is bolded, then the show/hide button will do nothing.
"},{"location":"faq/#the-replay-audio-button-plays-the-sentence-word-and-then-sentence","title":"The replay audio button plays the sentence, word, and then sentence.","text":"This is playing the audio from the front of the card, and then the back of the card, in sequence. To fix it so you only hear the audio displayed in the back of the card, go to:
Decks
(main anki browser) \u2192 Deck settings (the gear beside your deck) \u2192 Options
\u2192 Audio
section \u2192 Toggle Skip question when replaying answer
"},{"location":"faq/#general-troubleshooting","title":"General Troubleshooting","text":"The following will be some general troubleshooting tips that can help you figure out what is causing the issue:
-
Disable all of your add-ons.
To do this, start Anki while holding Shift. Note that it is expected that you will get an Anki-Connect error (since Anki-Connect will be disabled).
If the issue was fixed after this step, please let me know which add-on(s) conflicts with this note type! To do this, re-enable the add-ons one-by-one (remembering to restart Anki each time!).
-
Upgrade Anki to the latest version.
After doing this, try disabling all of your add-ons again and see if the issue persists.
-
If you manually added any custom CSS and/or runtime / compile options, make a backup of your collection and then remove all of those options. If it works after this, try re-adding those one-by-one until you find the issue.
If you can't manage to fix it, please let me know!
"},{"location":"faq/#card-editing","title":"Card Editing","text":""},{"location":"faq/#how-do-i-disable-furigana-on-card-generation","title":"How do I disable furigana on card generation?","text":" -
In Yomichan's Anki Card Format, ensure that the SentenceReading
field is empty.
-
If you are using the AJT Furigana addon, navigate to:
AJT
\u2192 Japanese Options
\u2192 Furigana
\u2192 Select profile: Add furigana for sentence
\u2192 Triggered by
\u2192 Uncheck Note Added
.
You likely want to bulk-generate the furigana if you are disabling furigana on card generation. See the question below to do just that.
"},{"location":"faq/#how-do-i-bulk-generate-furigana-and-pitch-accents","title":"How do I bulk generate furigana and pitch accents?","text":" -
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select all notes without furigana, with the following search:
\"note:JP Mining Note\" SentenceReading:\n
-
Head over to:
Edit
(top left corner) \u2192 AJT: Bulk-generate
.
Note
Bulk generating pitch accents will only batch generate the AJTWordPitch
field. Pitch accent graphs and positions cannot be automatically generated. This is important to note if you are using colored pitch accent. If PAPositions
is not filled, then the card cannot be automatically colored.
In version 0.12.0.0
, this no longer matters, because the pitch accent info is properly parsed from AJTWordPitch.
Note
There may be some cards that still have an empty AJTWordPitch
field. This is simply because the add-on did not contain the pitch data for those words.
"},{"location":"faq/#how-do-i-remove-an-empty-card-without-deleting-the-entire-note","title":"How do I remove an empty card without deleting the entire note?","text":"Quote
To remove the empty cards, go to Tools
\u2192 Empty Cards
in the main window. You will be shown a list of empty cards and be given the option to delete them.
Taken directly from Anki's official documentation.
"},{"location":"faq/#how-do-i-edit-the-fields-raw-html","title":"How do I edit the field's raw HTML?","text":"Within the card browser, select a field to edit, and then type Ctrl+Shift+X.
Alternatively, on newer versions of Anki, you can click on the top-right corner on the code button.
"},{"location":"faq/#how-do-i-use-this-note-type-as-an-anime-card","title":"How do I use this note type as an Anime Card?","text":"An anime card is a vocab card with a picture and (native) sentence audio, which is the default setup for this card.
If you want to add hints that aren't collapsed by default, use the HintNotHidden
field.
"},{"location":"faq/#other-questions","title":"Other Questions","text":""},{"location":"faq/#where-is-the-x-folder-in-anki","title":"Where is the (X) folder in Anki?","text":"You must first locate the Anki2
folder. The location of this folder is different for each operating system.
Quote
WindowsMacLinux On Windows, the latest Anki versions store your Anki files in your appdata folder. You can access it by opening the file manager, and typing %APPDATA%\\Anki2
in the location field. Older versions of Anki stored your Anki files in a folder called Anki
in your Documents
folder.
On Mac computers, recent Anki versions store all their files in the ~/Library/Application Support/Anki2
folder. The Library folder is hidden by default, but can be revealed in Finder by holding down the option key while clicking on the Go menu. If you're on an older Anki version, your Anki files will be in your Documents/Anki
folder.
On Linux, recent Anki versions store your data in ~/.local/share/Anki2
, or $XDG_DATA_HOME/Anki2
if you have set a custom data path. Older versions of Anki stored your files in ~/Documents/Anki
or ~/Anki
.
Taken directly from Anki's official documentation.
- Your profile folder is under
Anki2/PROFILE_NAME
. - Your media folder is under
Anki2/PROFILE_NAME/collections.media
. - Your addons folder is under
Anki2/addons21
.
"},{"location":"faq/#how-do-i-backup-my-anki-data","title":"How do I backup my Anki data?","text":"The following makes a complete backup of your collection, including media:
Main Window \u2192 File
(top left corner) \u2192 Export...
\u2192 Anki Collection Package
The following makes a temporary backup of your collection, not including media:
Main Window \u2192 File
(top left corner) \u2192 Create Backup
See Anki's official documentation for more info.
"},{"location":"faq/#how-do-i-backup-yomichan-settings","title":"How do I backup Yomichan settings?","text":" - Navigate to Yomichan Settings.
- Go to the
Backup
section - Select
Export Settings
"},{"location":"faq/#how-do-i-export-notes","title":"How do I export notes?","text":" -
Navigate to the Card Browser, by doing the following:
Main Window \u2192 Browse
-
Select a note. Hold down Ctrl to select multiple individual notes.
-
Right click the selected notes, and navigate to:
Notes
\u2192 Export Notes...
"},{"location":"faq/#how-do-i-see-the-version-of-jp-mining-note","title":"How do I see the version of jp-mining-note?","text":"Preview any card. The version should be displayed at the top left corner.
For mobile, the version is shown in the info circle. Note that the version is only displayed on mobile for versions 0.12.0.0
and above.
TODO redo image for mobile
"},{"location":"faq/#how-do-i-see-the-version-of-anki","title":"How do I see the version of Anki?","text":"Navigate to:
Help
\u2192 About
"},{"location":"faq/#what-card-type-should-i-use","title":"What card type should I use?","text":"The short answer is: whichever one you want. :)
The long answer is: whichever one you want, because everyone has their own preferences on what card types they like. I recommend being open about it and experiment with them, to see which one you like.
"},{"location":"faq/#what-is-the-point-of-the-pasilence-field","title":"What is the point of the PASilence
field?","text":"This is a hack to not play the sentence audio on the front side, even if you set-up your Anki client to do so. With this field filled correctly, the play sentence audio button will appear at the front, and will not be autoplayed.
Leaving this field empty will affect cards where you test pitch accent, i.e. with PAShowInfo
filled. In particular, this will cause Anki to autoplay the sentence audio on the front side of cards that test pitch accent, which is undesirable.
"},{"location":"faq/#do-you-plan-on-supporting-any-other-language-other-than-japanese","title":"Do you plan on supporting any other language other than Japanese?","text":"Unfortunately, other languages outside of Japanese will not be supported.
The reason for this decision is best explained in the \"When are you going to add support for $MYLANGUAGE?\" question within Yomichan's README
Quote
Developing Yomichan requires a decent understanding of Japanese sentence structure and grammar, and other languages are likely to have their own unique set of rules for syntax, grammar, inflection, and so on. Supporting additional languages would not only require many additional changes to the codebase, it would also incur significant maintenance overhead and knowledge demands for the developers. Therefore, suggestions and contributions for supporting new languages will be declined, allowing Yomichan's focus to remain Japanese-centric.
"},{"location":"faq/#how-was-this-documentation-made","title":"How was this documentation made?","text":"Through Material for MkDocs. This site generator is what many other popular sites use, including TheMoeWay and AnimeCards.
"},{"location":"faq/#contact-info","title":"Contact Info","text":" -
Discord
- Username:
aquafina_water_bottle
(user id: 244677612272746496
) - Servers:
- TheMoeWay (I recommend using the jp-mining-note thread in the
#resources-sharing
channel) - Refold (JP) server (I recommend using the jp-mining-note thread in the
#sentence-mining-workflows
channel)
-
Github
- If you don't want to use Discord, please shoot your message here.
-
This will not be fixed by default because to make debugging easier for the developer. When a user is asked to export a card, the exported file will not contain the font files, meaning that the result .apkg
file will be about 1MB instead of some 20MB, allowing it to be shared easily on a place like Discord.\u00a0\u21a9
"},{"location":"fieldref/","title":"Fieldref","text":"This page is dedicated showing how to edit the note fields to change the card to your liking.
Note
If you want to edit the user interface for all cards, see the UI Customization page.
"},{"location":"fieldref/#definitions","title":"Definitions","text":"Binary Field: A field that checks whether it is filled or not with any value, say 1
. The default is implied by the name of the field, and a value of \"true\" means that the field is filled. For example, the IsSentenceCard
field will turn the card into a sentence card if filled. If it is not filled, then the card will be a word card. To fill a field automatically, see here.
PA: Short for \"Pitch Accent\".
"},{"location":"fieldref/#quick-jump","title":"Quick Jump","text":"The table below provides quick links to most of the fields found with the card, as well as some general info on each field. Fields without links are assumed to be either obvious (and do not require documentation), or not meant to be edited.
Click here to reveal the field list Note
Auto-filled
represents fields that should be automatically filled out from Yomichan and Anki add-ons.
Field Auto-Filled Binary Field Notes Key Word WordReading PAOverride PAOverrideText AJTWordPitch PrimaryDefinition PrimaryDefinitionPicture Sentence SentenceReading AltDisplayWord AltDisplaySentence Originally AltDisplay
before 0.12.0.0
AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard Originally SeparateClozeDeletionCard
before 0.12.0.0
SeparateSentenceAudioCard Currently doesn't do anything Picture WordAudio SentenceAudio PAGraphs PAPositions FrequenciesStylized FrequencySort PASilence WordReadingHiragana YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment"},{"location":"fieldref/#modifying-the-front-side-tested-content","title":"Modifying the Front Side (Tested Content)","text":"The front side is exactly the content that we want to test ourselves on. Naturally, since we can test ourselves on many aspects of the word, there are many ways to change this tested content.
"},{"location":"fieldref/#card-types","title":"Card types","text":"Main Page: Card Types
The default card type is a vocab card, where the tested content is simply the word.
To change the card to a sentence card, fill the IsSentenceCard
binary field.
Vocab cardSentence card "},{"location":"fieldref/#altdisplay-changing-the-displayed-content","title":"AltDisplay: Changing the Displayed Content","text":"Vocab cards show the Word
field and sentence cards show the Sentence
fields by default. However, you can modify what is exactly shown in the front by using the AltDisplay
field.
NewlineLast sentence only The previous sentence card looks a little ugly, because the sentence splits off at a strange point. To fix this, we add a newline at a sensible place (after the period) in the AltDisplay
field.
Alternatively, we can simply test the last sentence, by removing the first sentence.
"},{"location":"fieldref/#altdisplay-furigana","title":"AltDisplay: Furigana","text":"One nice feature is that the AltDisplay
has hoverable furigana text enabled by default. In other words, you can use furigana in the field. I personally use this to insert furigana for certain names, since I'm usually not testing myself on how to read a name.
For example, the card below has the following HTML:
\u4e0a\u6761[\u304b\u307f\u3058\u3087\u3046] \u606d\u4ecb[\u304d\u3087\u3046\u3059\u3051]\u541b\u306e\u3053\u3068\u304a<b>\u6155\u3044</b>\u3057\u3066\u307e\u3057\u305f\u306e\n
"},{"location":"fieldref/#altdisplay-final-notes","title":"AltDisplay: Final Notes","text":" -
The example with adding a newline to AltDisplay
is somewhat contrived. More realistically, you would want to add the newline to the Sentence
field.
If you are using AJT Furigana, I recommend deleting the text within the SentenceReading
field before editing the Sentence
field, so the furigana can be automatically generated with the newly formatted Sentence
field.
-
If you are using a vocab card, you can use AltDisplay
to show something that differs from the Word
field.
-
On Hybrid Card types, the AltDisplay
field only affects the sentence, and not the front displayed word.
"},{"location":"fieldref/#modifying-the-back-side","title":"Modifying the Back Side","text":"The main two fields that one can add text to is PrimaryDefinition
and AdditionalNotes
. Bolding anything in these sections will highlight the word in a light yellow (or blue in light mode) tint, to make the bolded text stand out more.
"},{"location":"fieldref/#primarydefinition-field","title":"PrimaryDefinition
field","text":"The PrimaryDefinition
field contains the main content, and should be the main field to edit if one wants to put down more notes about the card.
"},{"location":"fieldref/#additionalnotes-field","title":"AdditionalNotes
field","text":"The AdditionalNotes
field is useful if you want to write down even more notes, but keep it in a collapsible field to reduce vertical space.
Here are some suggestions on how you can use this field:
- Recording the source where the scene came from
- Adding custom notes on the scene's context
- Recording the sentences surrounding the mined sentence
In general, this field should be used for any info that is not crucial to understanding the tested content.
"},{"location":"fieldref/#modifying-images-pitch-accent","title":"Modifying Images & Pitch Accent","text":"As there are plenty of ways to modify images and pitch accent, they are discussed in their respective pages:
- Images (
Picture
and PrimaryDefinitionPicture
) - Pitch Accent (
PAOverride
and PAOverrideText
)
"},{"location":"fieldref/#modifying-pitch-accent-sentence-cards","title":"Modifying Pitch Accent Sentence Cards","text":"The field AltDisplayPASentenceCard
exists to customize the display of the PA sentence card, if it exists. It works similarly to AltDisplay
, and takes priority over AltDisplay
in the PA sentence card.
"},{"location":"fieldref/#other-fields","title":"Other Fields","text":""},{"location":"fieldref/#key-field","title":"Key
field","text":"This contains the tested word. In other words, this contains the exact same content as the field below, but this field is specifically not used in the card template. This is to allow the user to modify the key if duplicates arise, while still being able to test the word.
For example, if I were to test different usages of \u4e0a, I can change this key value to \u4e0a (preposition)
, \u4e0a (grammar)
, etc. and add a new card.
It is expected that this Key
field is unique; a warning will appear on cards that have a duplicate key.
"},{"location":"fieldref/#comment-field","title":"Comment
field","text":"Similarly to the Key
field, this field will not be used in any card template. In other words, this is a place where you can write down notes without affecting the card itself.
"},{"location":"fieldref/#frequencysort-field","title":"FrequencySort
field","text":"By default, this note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in this guide. Visit the aformentioned link (and scroll down to Usage
) to see how to sort and review your cards by frequency.
Note
I personally use this field by re-ordering only some of the most common words in my deck, and then separating it with a step of 1. This ensures that every card in the deck will eventually be reached.
"},{"location":"fields/","title":"Fields (TODO)","text":"This page contains a table with some specific information on the fields used by this note type. If you are instead looking for what a particular field does, try using the search bar instead.
"},{"location":"fields/#fields-table","title":"Fields Table","text":"Fields Font Size Collapsed Binary Notes Key 40
Word 20
WordReading 20
PAOverride 20
PAOverrideText 20
New in v0.11.0.0
AJTWordPitch 20
PrimaryDefinition 20
PrimaryDefinitionPicture 20
New in v0.11.0.0
Sentence 20
SentenceReading 20
AltDisplayWord 20
New in v0.12.0.0
AltDisplaySentence 20
Originally AltDisplay
before 0.12.0.0
AltDisplayPASentenceCard 20
New in v0.12.0.0
AltDisplayAudioCard 20
New in v0.12.0.0
AdditionalNotes 20
Hint 15
HintNotHidden 15
IsSentenceCard 10
IsTargetedSentenceCard 10
IsClickCard 10
IsHoverCard 10
IsHintCard 10
New in v0.12.0.0
IsSentenceFirstCard 10
New in v0.12.0.0
IsAudioCard 10
New in v0.12.0.0
PAShowInfo 10
PATestOnlyWord 10
PADoNotTest 10
PASeparateWordCard 10
PASeparateSentenceCard 10
SeparateAudioCard 10
Originally SeparateClozeDeletionCard
before 0.12.0.0
SeparateSentenceAudioCard 10
Currently doesn't do anything Picture 20
WordAudio 15
SentenceAudio 15
PAGraphs 15
PAPositions 15
FrequenciesStylized 15
FrequencySort 10
PASilence 10
WordReadingHiragana 10
New in v0.11.0.0
YomichanWordTags 10
New in v0.12.0.0
SecondaryDefinition 15
ExtraDefinitions 15
UtilityDictionaries 15
CardCache 20
Comment 20
"},{"location":"fields/#definitions","title":"Definitions","text":" -
Binary Field: A field that checks whether it is filled or not with any value, say 1
. The default is implied by the name of the field, and a value of \"true\" means that the field is filled. For example, the IsSentenceCard
field will turn the card into a sentence card if filled. If it is not filled, then the card will be a word card. To fill a field automatically, see here.
-
PA: Short for \"Pitch Accent\".
"},{"location":"frequencies/","title":"Frequencies (TODO)","text":"The frequencies of a card can be found on the back side of the card, at the top right corner.
By default, the shown frequency is the value in FrequencySort
. All other frequencies can be viewed by hovering over the dropdown arrow.
(TODO gif)
"},{"location":"frequencies/#sorting-by-frequency","title":"Sorting by Frequency","text":"This note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in this guide.
To summarize how FrequencySort
is generated: all frequencies (filtering out the useless ones) are averaged using a harmonic mean, which can be thought of as a mean that heavily leans towards the minimum.
However, some exceptions apply:
- If the word exists in a downloaded grammar dictionary, then the frequency value is set to 0, because we make the assumption that grammar points should be studied as soon as possible.
- If there are no frequencies, then it is set to
9999999
.
By default, nothing is done to re-order your cards according to this value. You will need to manually re-order your cards, or use an add-on to automatically do so. Visit the aformentioned link (and scroll down to Usage
) to see exactly that.
"},{"location":"frequencies/#list-mode","title":"List Mode","text":"Older versions of the note displayed the frequencies similarly to Yomichan: as a list of existing frequencies. If you wish to do this, set the following runtime option to list
:
\"freqUtils.displayMode\": \"list\",\n
(TODO GIF with dropdown)
"},{"location":"frequencies/#list-mode-maximum","title":"List Mode Maximum","text":"The list mode defaults to showing a total of 4 frequencies by default, before overflowing into the dropdown. This limit can be changed with the following runtime option:
\"freqUtils.list.max\": 4,\n
(TODO IMAGE with dropdown and >= 5 frequencies)
If you never want to limit the number of frequencies shown, set this to -1
.
(TODO IMAGE without dropdown and >= 5 frequencies)
"},{"location":"frequencies/#unknown-frequency","title":"Unknown Frequency","text":"When no frequency can be found for a particular word, \"unknown\" is instead shown.
TODO image of unknown
Note
If you see \"unknown\" for all your cards, you likely don't have any Yomichan frequency dictionaries installed.
If you have many cards like this, I recommend backfilling existing cards.
"},{"location":"frequencies/#hiding-unknown-frequency-marker","title":"Hiding Unknown Frequency Marker","text":"If you don't want to see this \"unknown\", you can remove it with the following CSS:
.frequencies [data-is-unknown] {\ndisplay: none;\n}\n
"},{"location":"images/","title":"Images","text":"This page is dedicated to showcasing how images can be displayed and interacted with.
"},{"location":"images/#main-image","title":"Main Image","text":"The main image (shown to the right of the word box) is exactly the contents of the Picture
field. As you likely already know, this image can be clicked to zoom in.
(TODO gif)
This display of the picture automatically adjusts for any aspect ratio. For the best looking cards, it is recommended that you use images with aspect ratios between 16:9 (landscape) to 1:1 (square).
(TODO screenshots)
Note
Instead of a picture, it is possible to use text within the Picture
field. This is useful if you forgot to add the picture (or didn't want to add it in the first place), and would like to describe the scene in words.
Do not use more than one picture, or combine pictures and text within the Picture
field. If you have an image and would like to add text, add the text in the PrimaryDefinition
or AdditionalNotes
field. If you want to add more than one image, add the remaining images under PrimaryDefinitionPicture
or PrimaryDefinition
.
"},{"location":"images/#automatically-add-images-using-tags","title":"Automatically Add Images Using Tags","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
One can automatically add a specific image if a card contains a specific tag.
This is particularily useful for cards made from written media, such as books. One can save an image of the cover (in the media folder), and add the appropriate tag to all of the cards to automatically set the image to the cover of the book.
This is specified under the runtime options:
\"imgStylizer.setMainImageFromTags\": [],\n
Example:
\"imgStylizer.setMainImageFromTags\": [\n{\n\"tag\": \"\u9752\u6625\u30d6\u30bf\u91ce\u90ce\u30fbLN1\",\n\"fileName\": \"_\u9752\u6625\u30d6\u30bf\u91ce\u90ce-LN1.png\"\n}\n],\n
TODO example gif
"},{"location":"images/#collapsed-images","title":"Collapsed Images","text":"Any images that are added to a definition by Yomitan are shown by default. If you add a custom image to a definiton however, it will be converted to text which you have to hover over to reveal. Of course, this image can also be clicked on to zoom. See the video demo below to see exactly what happens.
"},{"location":"images/#how-to-collapse-yomitan-images","title":"How to Collapse Yomitan Images","text":"If you want images from Yomitan to be collapsed by default, add the following to your runtime options:
```json\n\"imgStylizer.glossary.primaryDef.mode.yomichan\": \"collapse\",\n```\n
"},{"location":"images/#how-to-disable-collapsed-user-images","title":"How to Disable Collapsed User Images","text":"There are several ways of disabling collapsed user images.
-
Place your images in the PrimaryDefinitionPicture
field, as shown in the section below.
-
Disable it globally in the runtime options:
// alternatively, try \"none\" instead of \"float\".\n\"imgStylizer.glossary.primaryDef.mode.user\": \"float\",\n
-
Disable it per card, by adding the following tag: img-user-float
. Alternatively, try adding img-user-no-styling
.
-
To disable this for only specific images, edit the HTML of the desired field, and add data-do-not-convert=\"true\"
.
For example:
<img src=\"your_image.png\" data-do-not-convert=\"true\">\n
"},{"location":"images/#the-primarydefinitionpicture-field","title":"The PrimaryDefinitionPicture
Field","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
This field can be used to place images in the Primary Definition section without collapsing the image. Large images are automatically resized to fit the area.
This is useful if one wants to put images in place of, or to suppliment definitions. For example, using images for words such as \"frog\" or \"chair\" is much easier to understand compared to using the monolingual definition.
Right of the definition (Default)No DefinitionBelow the definitionAbove the definition (\u7a81\u3063\u4f0f\u3059) Usually, the image is placed to the right (like on Wikipedia).
(\u96d1\u5dfe) Naturally, the picture appears to the left if there is no definition. As of version 0.12.0.0
, the size of the picture will also be slightly increased.
(\u96d1\u5dfe) The image is below the definition if the appropriate options are set.
(\u96d1\u5dfe) The image is above the definition if the appropriate options are set.
Note
Although not recommended, the PrimaryDefinitionPicture
does not need to contain pictures. For example, one can add text, tables, or links to the field.
"},{"location":"images/#changing-automatic-positioning-behavior","title":"Changing Automatic Positioning Behavior","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The following runtime option can be used to change how the primary definition picture is positioned:
// Valid options (case sensitive): \"auto\", \"bottom\", \"right\", \"top\"\n\"imgStylizer.glossary.floatImg.position\": \"auto\",\n
The options bottom
, right
, and top
force the image to always be placed below, to the right, and above the definition, respectively. auto
is the default behavior, and will automatically position the picture to the left if there is no text. Otherwise, the image is placed to the right.
"},{"location":"images/#force-positioning","title":"Force Positioning","text":"The automatic repositioning as described above may not be perfect. Fortunately, there are ways to force the position of this image, by adding any of the following tags to the card:
img-right
forces the image to be to the right. img-bottom
forces the image to be below the text. img-top
forces the image to be above the text.
"},{"location":"images/#image-blur","title":"Image Blur","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
Images on cards can be automatically blurred by marking it with a NSFW tag. To mark a card as NSFW, add any of the following tags to the card:
nsfw
\u30fbNSFW
\u30fb-NSFW
This behavior is disabled by default. In other words, you will not be able to blur images unless the following setting is explicitly enabled in the runtime options:
\"imgStylizer.mainImage.blur.enabled\": true, // (1)!\n
- The
imgStylizer
module must be enabled to use the image blur feature. For example: \"imgStylizer.enabled\": true,\n
This is enabled by default, so you likely don't need to manually enable this module.
Note
Recall that you can use custom text in the Picture
field instead of having an actual picture. This is useful if you simply don't want to save a particular image.
"},{"location":"images/#change-review-session-state","title":"Change Review Session State","text":"The above demo shows how you can un-blur an image temporarily. This means that if you see that card again during the same review session, the image will be blurred again.
This state can be changed for a review session. To toggle between review-session states, hover over the info circle, and click on the eyeball to the top left. This state will be maintained for the entire review session, but will be lost on the next session.
The tabs below show the available states. By default, states cycle from left to right.
Only Blur if NSFWAlways BlurredAlways Revealed Not Marked Marked (with NSFW
tag) Not Marked Marked (with NSFW
tag) Not Marked Marked (with NSFW
tag) Demos (click here) Regular, unmarked cardCard marked as NSFW Note
Both examples have the info circle toggled (clicked), so the tooltip persists.
"},{"location":"images/#mobile-usage","title":"Mobile Usage","text":" - TODO the eye to the top right of the image is not shown to prevent fat finger unblurs
- if you want to unblur, you must change review session state via the info circle as shown above
"},{"location":"images/#additional-details","title":"Additional Details","text":" - The eyeball to toggle the blur between an image will not be shown unless the card is marked as NSFW (or the review session state is \"Always Blurred\").
- Clicking on the blurred image will do nothing; you must click on the eye to un-blur the image. Forcing the user to click in a smaller area makes accidental unblurs less common.
- After revealing the image, you can click on the image to zoom, as normal. You cannot click on a blurred image to zoom.
- Most things can be changed in the runtime options, including what tags can be used, the default initial state on PC/mobile, etc.
- This was heavily inspired by Marv's implementation of the same feature.
"},{"location":"importing/","title":"Transfer Existing Notes","text":""},{"location":"importing/#overview","title":"Overview","text":"This section is dedicated to explaining how you can change other Anki cards into this note format.
Note
If you are simply importing old JPMN notes, updating JPMN will properly update all the notes in place. See this section instead.
"},{"location":"importing/#introduction","title":"Introduction","text":"Unfortunately, there are so many card formats out there that it would be impossible to cover how to import from every format with detailed rigor. Instead, this section will give you some general tips on operations that will likely be common across most or all formats, as well as present a small example for Anime Cards.
Additionally, although you maybe able to import most of the card, it is unlikely that you will have complete 100% full functionality after importing the notes.
"},{"location":"importing/#prerequisites","title":"Prerequisites","text":"Before doing anything that affects your Anki collection in a major way (for example, basically everything on this page), please make a complete backup of your collection.
Note
Transferring your previous notes shouldn't change your media files at all. However I recommend exporting with media just in case, so long as you have the disk space for it.
"},{"location":"importing/#anki","title":"Anki","text":"Anki provides a feature to switch between note types, without affecting scheduling information. To do this, follow the proceeding steps:
-
Head to the Card Browser window:
Main Window \u2192 Browse
-
Select all the cards that you want to switch.
Tip
Ctrl+A selects all cards in the browser.
-
Right click the selection \u2192 Notes
\u2192 Change Note Type...
"},{"location":"importing/#mapping-fields","title":"Mapping Fields","text":"Here is where I can't give specific advice, as every note is different. However, here are a few tips:
-
Map Word
to Key
and Word
.
Your card likely doesn't have a separate Key
and Word
field, and instead only contains one Word
field. To import this correctly into JPMN, make sure JPMN's Key
and Word
field are exactly your old card's Word
field.
-
The WordReading
field should ideally be a simplified furigana format. For example, if the word is \u6210\u308a\u7acb\u3064, this field should be \u300c\u6210[\u306a]\u308a \u7acb[\u305f]\u3064\u300d. If you do not have any field that resembles this, use the kana reading (\u306a\u308a\u305f\u3064) or true furigana (\u6210\u306a\u308a\u7acb\u305f\u3064), and continue with the steps below.
-
Leave AJTWordPitch
and SentenceReading
empty.
These fields can be empty as AJT Japanese can batch generate both word pitches and sentence furigana.
-
You may have some word pitch fields already in your card. Pitch accent graphs should be mapped to PAGraphs
, and pitch accent positions should be mapped to PAPositions
.
-
FrequencySort
maps to the frequency value used to sort by frequency, which works exactly the same as Marv's Frequency
field as documented in Marv's Resources page.
-
If you have a field that stores the source of the media, I recommend mapping that to AdditionalNotes
or Comment
.
-
I recommend not setting FrequenciesStylized
to anything, even if you have a field for frequency lists1.
-
When in doubt, look at the format in the example notes.
An example with Anime cards is shown below.
Example for Anime Cards (click here) jp-mining-note fields Anime Cards Fields Key front Word front WordReading Reading PAOverride PAOverrideText AJTWordPitch PrimaryDefinition Glossary PrimaryDefinitionPicture Sentence Sentence SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden Hint IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture Picture WordAudio Audio SentenceAudio SentenceAudio PAGraphs Graph PAPositions FrequenciesStylized FrequencySort PASilence WordReadingHiragana YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment Note
Anything not specified should be set to (Nothing)
"},{"location":"importing/#batch-editing","title":"Batch Editing","text":"After switching your notes, you will have to do the following few steps:
"},{"location":"importing/#correctly-formatting-sentence-field","title":"1. Correctly Formatting Sentence
Field","text":"If your sentence fields have been highlighted in a way that isn't using <b>
, then it will be incompatable with JPMN by default.
To see what the formatting of the sentence is, view the raw HTML of the Sentence
field.
Sentences are usually formatted in one of three ways, as shown below:
(1) Highlighted with <b>
(2) Nothing is highlighted(3) Highlighted, but not with <b>
If the tested content is highlighted with <b>
, then it is already formatted correctly. You can skip this step.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<b>\u7206\u7761</b>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
The note comes with a feature to automatically highlight the word within the sentence. However, this is an imperfect solution, and there is currently no easy way to add accurate highlighting to existing sentences.
As there is nothing to do, you can skip this step.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c\u7206\u7761\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
If the tested content is highlighted with something that isn't <b>
, then continue with the following instructions to change it.
Example:
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<span style=\"color: #ffc2c7\">\u7206\u7761</span>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
Instructions to port formatted sentences (click here) Note
You may want to make another backup before doing the following, just in case.
-
Determine how the sentence is formatted.
We will be using the above for this example. This example highlights the word using a <span>
with a custom color.
\u4eca\u65e5\u3082\u3001\u306a\u3093\u304b\u3001\u663c<span style=\"color: #ffc2c7\">\u7206\u7761</span>\u3057\u3066\u3057\u307e\u3063\u305f\u3093\u306e\u3067\u2026\n
The above is created from the following Yomichan fields:
{cloze-prefix}<span style=\"color: #ffc2c7\">{cloze-body}</span>{cloze-suffix}\n
-
Testing the Conversion.
In the Anki card viewer, select only one of your old notes.
Afterwards, right click the selection, and head over to:
Notes
\u2192 Find and Replace...
-
Setting the fields.
Set the Find
field to something that can find your highlighted content. We will use the above as an example.
It is extremely likely that you will have to change the Find
field according to your note's sentence format.
Field name Value Find: <span style=\"color: #ffc2c7\">(?P<t>.*?)</span>
Replace With: <b>$t</b>
In: Sentence
Selected notes only Checked () Ignore case Unchecked () Treat input as aregular expression Checked () Example image (click here)
-
Verify.
Press Ok, and then preview the card.
If the highlight is yellow (or blue on light mode), then it it was successful! Repeat steps 2 and 3, except select all of the affected notes instead of just one.
If it was not successful, you likely have to adjust the Find
field. See here to see Anki's official documentation on regex.
"},{"location":"importing/#cleanup-other-fields","title":"2. Cleanup Other Fields","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Run the following batch command:
cleanup\n
Expected this batch command to take quite a bit of time, especially on collections containing many thousands of cards. This is because the batch command does quite a bit behind the scenes:
- Corrects
WordReading
if it is ruby text or regular text. - Backfills
WordReadingHiragana
. - Backfills
PASilence
. - Moves extra pictures in the
Picture
field into the PrimaryDefinitionPicture
field. - Note that this requires
beautifulsoup4
installed (pip install beautifulsoup4
). This is installed by default on Anki, so this will be properly ran if the batch command was ran with JPMN Manager.
- Moves extra audio in the
WordAudio
field into the SentenceAudio
field.
"},{"location":"importing/#batch-generate-pitch-accents-and-sentence-furigana","title":"3. Batch Generate Pitch Accents and Sentence Furigana (optional)","text":"This step requires the AJT Japanese
addon to be correctly setup. Although this step is technically optional, pitch accents likely won't show for imported cards if you had nothing to import into PAPositions
. In that case, this step is highly recommended.
See here on how to backfill pitch accents and sentence furigana.
"},{"location":"importing/#backfill-the-frequencysort-field","title":"4. Backfill the FrequencySort
Field (optional)","text":"See here if you want to backfill the FrequencySort
field.
"},{"location":"importing/#conclusion","title":"Conclusion","text":"If everything went smoothly, then you have successfully transferred your notes to the JPMN template. Enjoy reviewing your old cards with a new template!
"},{"location":"importing/#legacy-instructions","title":"Legacy Instructions","text":"Most steps have now been combined all into the one cleanup
batch command. The legacy instructions for dealing with those steps individually are recorded below just in case.
Legacy instructions: Batch Set PASilence
Field This will ensure all PASilence
are filled correctly. See here to understand what this field does. This can be done with a batch command, or manually within Anki itself.
Batch CommandWithin Anki set_pasilence_field\n
- Head to the Card Browser window.
-
Right click a card, and then head to:
Notes
\u2192 Find and Replace...
-
Set the fields to the following:
Field name Value Find: .*
Replace With: [sound:_silence.wav]
In: PASilence
(IMPORTANT! Do not forget this field!) Selected notes only Unchecked () Ignore case Unchecked () Treat input as aregular expression Checked () ??? example \"Example image <small>(click here)</small>\"\n <figure markdown>\n [![The above table in Anki](assets/importing/bulk_add_silencewav.png)](assets/importing/bulk_add_silencewav.png)\n </figure>\n
Legacy instructions: Correctly Formatting WordReading
Field Your WordReading
field is likely formatted in one of three ways:
Furigana (plain)FuriganaKana only This is generated with the {furigana-plain}
helper.
Example: \u6210[\u306a]\u308a \u7acb[\u305f]\u3064
If your WordReading
field is formatted this way, then the WordReading
field is already formatted correctly. You can skip this step.
This is generated with the {furigana}
helper.
Example: \u6210\u306a\u308a\u7acb\u305f\u3064 (HTML: <ruby>\u6210<rt>\u306a</rt></ruby>\u308a<ruby>\u7acb<rt>\u305f</rt></ruby>\u3064
)
If your WordReading
field is formatted this way, it would be ideal to convert this into plain furigana so the note can properly parse the field.
Instructions for converting furigana into plain furigana (click here) - Head to the Card Browser window.
-
Right click a card, and then head to:
Notes
\u2192 Find and Replace...
-
Set the fields to the following:
Field name Value Find: <ruby>(<rb>)?(?P<kanji>.*?)(</rb>)?<rt>(?P<furigana>.*?)</rt></ruby>
Replace With: \u00a0$kanji[$furigana]
(Keep the whitespace at the beginning!) In: WordReading
Selected notes only Unchecked () Ignore case Unchecked () Treat input as aregular expression Checked () This is generated with the {reading}
helper.
Example: \u306a\u308a\u305f\u3064
This means that your old cards only have a kana reading. It would be ideal to have the WordReading
as the kanji word with furigana. You likely want the kanji word with the furigana, so the kanjis actually show in the proper places. Some examples include the kanji hover tooltip as well as to the left of the picture field.
Instructions for converting kana readings into (plain) furigana (click here) The solution provided below is imperfect, but passable. This will format all of the WordReading
fields to be Word[WordReading]
, which means kana will repeated. For example, a card with Word
as \u6210\u308a\u7acb\u3064, and WordReading
as \u306a\u308a\u305f\u3064, will turn into: \u6210\u308a\u7acb\u3064\u306a\u308a\u305f\u3064
To do this, run the following batch command:
quick_fix_convert_kana_only_reading_all_notes\n
The above will affect ALL notes. If you instead want to affect certain notes, add the kanaonlyreading
tag to all affected notes, and then run the following batch command:
quick_fix_convert_kana_only_reading_with_tag\n
Legacy instructions: Batch set WordReadingHiragana
Field The following automatically fills out the WordReadingHiragana
field.
Filling out the WordReadingHiragana
field is optional but highly recommended. This will enable the usage of Word Indicators on existing cards.
To do this, run the following batch command:
fill_word_reading_hiragana_field\n
-
FrequenciesStylized
uses a custom set of handlebars to store the frequency info in a way that css styles can be easily applied without javascript. This differs heavily from the {frequencies}
helper provided by Yomichan. Mapping an existing field that stores frequencies using {frequencies}
to FrequenciesStylized
will result in incorrect display of data.
There is currently no convenience function to convert it to the proper format.
Additionally, auto-generating frequency info (with the correct css, html, etc.) from arbitrary frequency lists does not seem trivial, and I currently provide no way of doing that (primarily because I'm not sure how to do it in the first place). If you know of a way or would like to help me out with doing this, please let me know!\u00a0\u21a9
"},{"location":"infocircle/","title":"Info Circle (TODO)","text":"hello world
"},{"location":"infocircle/#interface","title":"Interface","text":"DefaultDefault (back)ErrorWarningLeech On hover, the info circle on the top left corner just shows some basic info, However, it also serves as a notification system to the user, when it has a color.
(TODO IMAGE) By default, the info circle shows the tags at the back side of the card only. These tags can be clicked on (to search for the tag).
This should only appear when some javascript code fails. In other words, this should not appear under normal circumstances. If you get this without modifying the note in any way, please see this section for basic troubleshooting.
This serves to warn the user about something. It can appear without completely breaking the functionality of the card. In other words, you can choose to ignore it.
When the card is a leech, the circle is highlighted yellow (or blue in light mode) to indicate that it is a leech. This is only shown on the back side of the card.
"},{"location":"infocircle/#locking-the-info-circle","title":"Locking the Info Circle","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
You can toggle (click on) the info circle to lock the tooltip in place. This may be useful for copying/pasting errors and other debugging purposes.
"},{"location":"infocircle/#buttons","title":"Buttons","text":" - Image Blur Toggle Button
- toggles global status of image blur for the session (link)
- Refresh Button
- refreshes kanji hover and word indicators (link)
"},{"location":"jpmnhandlebars/","title":"JPMN Handlebars Package","text":"This section documents how to use the jp-mining-note handlebars for Yomichan on any template that is not jp-mining-note. If you are using jp-mining-note, please see the Definitions page instead.
"},{"location":"jpmnhandlebars/#features","title":"Features","text":"This handlebars package provides all of the features that comes with the standard jp-mining-note installation:
- A primary dictionary selector that automatically chooses the first bilingual or monolingual dictionary (depending on your settings)
- Ability to manually select a dictionary or highlight a definition, to override the primary dictionary selector
- Automatic separation of auxiliary dictionaries into monolingual and bilingual dictionaries
- Option to hide the first line of monolingual dictionaries
- Compatibility with other portable handlebars
The main difference between these handlebars and the handlebars used by jp-mining-note is that some default settings have been manually changed, so that definitions are exported in a minimalistic HTML format. This minimal format (almost) completely conforms with the default Yomichan handlebars, so it should work for any note type.
"},{"location":"jpmnhandlebars/#setup-handlebars","title":"Setup Handlebars","text":"Before doing anything, please make a backup of your Yomichan settings.
Video demo (click here) - Navigate to Yomichan 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 Yomichan template code:
Click here to show the template code to copy. {{~! ~}}\n{{~! ==================== jp-mining-note handlebars ===================== ~}}\n{{~! v1.0.12 ~}}\n{{~! ~}}\n{{~! https://arbyste.github.io/jp-mining-note/ ~}}\n{{~! ------------------------------------------------------- ~}}\n{{~! ================ Dictionary Categorization Options ================= ~}}\n{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n{{~!\nA bunch of JP and CN bilingual dictionaries covered by default,\nincluding: JMdict, \u65b0\u548c\u82f1, CEDICT, etc\n~}}\n{{~#set \"bilingual-dict-regex\"~}} ^(([Jj][Mm][Dd]ict)(.*)|(.*)\u65b0\u548c\u82f1(.*)|\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|KireiCake|NEW\u658e\u85e4\u548c\u82f1\u5927\u8f9e\u5178|CEDICT|CC-CEDICT|CantoDict|Canto CEDICT|Words\\.hk C-E FS|CE Wiktionary|CC-Canto|Jitendex(.*)|ADD_BILINGUAL_DICTIONARIES_HERE)$ {{~/set~}}\n{{~#set \"utility-dict-regex\"~}} ^(NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178|\u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003|[Jj][Mm][Dd]ict( Surface)? Forms|JMedict)$ {{~/set~}}\n{{~#set \"ignored-dict-regex\"~}} ^(ADD_IGNORED_DICTIONARIES_HERE)$ {{~/set~}}\n{{~! ====================== Selected Text Options ======================= ~}}\n{{set \"opt-selection-text-enabled\" true}}\n{{set \"opt-selection-text-dictionary\" true}}\n{{set \"opt-selection-text-glossary\" true}}\n{{set \"opt-selection-text-glossary-attempt-bold\" true}}\n{{~! ==================== Frequency Sorting Options ===================== ~}}\n{{~! See here for the official documentation on how these options work:\nhttps://github.com/MarvNC/JP-Resources#freq-settings ~}}\n{{~#set \"opt-ignored-freq-dict-regex\"~}} ^(JLPT.*)|(HSK.*)$ {{~/set~}}\n{{~#set \"opt-ignored-freq-value-regex\"~}} \u274c {{~/set~}}\n{{~#set \"opt-keep-freqs-past-first-regex\"~}} ^()$ {{~/set~}}\n{{~set \"opt-no-freq-default-value\" 9999999 ~}}\n{{~set \"opt-freq-sorting-method\" \"harmonic\" ~}} {{~! \"min\", \"first\", \"avg\", \"harmonic\" ~}}\n{{~set \"opt-grammar-override\" true ~}}\n{{~set \"opt-grammar-override-value\" 0 ~}}\n{{~#set \"opt-grammar-override-dict-regex\"~}} ^(\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b|JLPT\u6587\u6cd5\u89e3\u8aac\u307e\u3068\u3081|\u3069\u3093\u306a\u3068\u304d\u3069\u3046\u4f7f\u3046 \u65e5\u672c\u8a9e\u8868\u73fe\u6587\u578b\u8f9e\u5178|\u7d75\u3067\u308f\u304b\u308b\u65e5\u672c\u8a9e)$ {{~/set~}}\n{{~! ============== Dictionary First Line Removal Options =============== ~}}\n{{~set \"opt-wrap-first-line-spans\" true ~}}\n{{~! valid values: \"except\", \"only\" ~}}\n{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~!\nJMdict and jitenbot dictionaries from stephenmk are ignored\n(the latter because the handlebars cannot properly detect the first line.)\nIn particular, removing the first line from jitenbot dictionaries with handlebars alone\nis not trivial, so that feature will not be supported.\n~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv|\u6545\u4e8b\u30fb\u3053\u3068\u308f\u3056\u30fb\u6163\u7528\u53e5\u30aa\u30f3\u30e9\u30a4\u30f3|\u56db\u5b57\u719f\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u56fd\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u5927\u8f9e\u6797\u3000\u7b2c\u56db\u7248|\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u516b\u7248)$ {{~/set~}}\n{{~! ========================== Other Options =========================== ~}}\n{{~set \"opt-primary-def-one-dict-entry-only\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt-jmdict-list-format\" false ~}} {{~! jpmn default: true ~}}\n{{~! ======================== Plaintext Options ========================= ~}}\n{{~!\nWARNING: I recommend not changing these options if you are using the\njp-mining-note template. These options will change the general layout\nof the HTML, which will prevent certain features or stylizations\nfrom properly working. (If you aren't using jp-mining-note, please feel\nfree to change these options!)\nInstead of using these options, see here:\nhttps://aquafina-water-bottle.github.io/jp-mining-note/definitions/\nThese hide specific elements using CSS instead of modifying the raw HTML\nstructure behind it.\n~}}\n{{~set \"opt__plaintext__enabled\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__one-dict-entry-only-no-list\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__remove-dictionary-tag\" true ~}} {{~! jpmn default: false ~}}\n{{~set \"opt__plaintext__remove-first-line-enabled\" true ~}} {{~! jpmn default: false ~}}\n{{~! ============== ORIGINAL YOMITAN TEMPLATE CODE BELOW ============== ~}}\n
-
Copy and paste the code below to the bottom of the default Yomichan template code:
Click here to show the template code to copy. {{~! ============== ORIGINAL YOMITAN TEMPLATE CODE ABOVE =============== ~}}\n{{~! v1.0.12 ~}}\n{{~!\n==================\nhelper functions\n==================\n~}}\n{{#*inline \"s\"}}{{/inline}}\n{{~! categorizes into 4 types: \"ignored\", \"bilingual\", \"utility\", or \"monolingual\" ~}}\n{{~#*inline \"jpmn-get-dict-type\"~}}\n{{~#scope~}}\n{{~#set \"rx-match-ignored\" ~}}\n{{~#regexMatch (get \"ignored-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-utility\" ~}}\n{{~#regexMatch (get \"utility-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-bilingual\" ~}}\n{{~#regexMatch (get \"bilingual-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if (op \"!==\" (get \"rx-match-ignored\") \"\")~}}\n ignored\n {{~else if (op \"!==\" (get \"rx-match-utility\") \"\")~}}\n utility\n {{~else if (op \"!==\" (get \"rx-match-bilingual\") \"\")~}}\n bilingual\n {{~else~}}\n {{~! assumed that anything else is a monolingual dictionary ~}}\n monolingual\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! returns \"\" if selection text is disabled, or if none existed in the first place ~}}\n{{~#*inline \"_jpmn-selection-text\"~}}\n {{~! text-mode != \"\" and text-mode > 0 ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-enabled\") true)~}}\n {{~! removes leading and trailing whitespace ~}}\n {{~#regexReplace \"^\\s+|\\s+$\" \"\" \"g\"~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n {{~/regexReplace~}}\n {{~/if~}}\n{{~/inline~}}\n{{~! checks that the selection text is indeed a dictionary (returns the text if true, nothing if false) ~}}\n{{~#*inline \"_jpmn-check-dictionary\"~}}\n {{~#scope~}}\n {{~#set \"selection-is-dictionary\" false}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" (get \"selection\") dictionary)~}}\n {{~#set \"selection-is-dictionary\" true ~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"===\" (get \"selection-is-dictionary\") true)~}}\n {{~get \"selection\"~}}\n {{~else~}}\n {{~! null ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n Gives the raw glossary as the search string\n (for searching to see if the selected text is a part of a dictionary)\n Remember: we should NOT use _jpmn-glossary-single because it preprocesses the text!\n If the selected text was on the first line and the first line is removed,\n then using _jpmn-glossary-single will fail to find the selected text!\n~}}\n{{#*inline \"_jpmn-glossary-single-search\"}}\n {{~#scope~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/scope~}}\n{{/inline}}\n{{~! escape a regex string: https://stackoverflow.com/a/6969486~}}\n{{~! /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' ~}}\n{{~! escapes the `regexString` regex to allow it to be used like a normal search in a string ~}}\n{{#*inline \"_jpmn-escape-regex\"}}\n {{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~regexString~}}{{~/regexReplace~}}\n{{/inline}}\n{{~#*inline \"_jpmn-get-dict-if-glossary-selected\"~}}\n {{~#scope~}}\n {{~#set \"result-dictionary\" null}}{{/set~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"search-def\"}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{/set~}}\n {{~#set \"search-regex-match\"}}\n {{~#regexMatch (get \"search-selection\") \"gu\"}}{{~get \"search-def\"~}}{{/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"result-dictionary\") null)\n (op \"!==\" (get \"search-regex-match\") \"\")\n )~}}\n {{~#set \"result-dictionary\" dictionary}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"result-dictionary\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n searches dictionary, determined by `opt-first-definition-type`\n - (opt-first-definition-type === bilingual) -> bilingual dictionaries are searched first\n - (opt-first-definition-type === monolingual) -> monolingual dictionaries are searched first\n~}}\n{{~#*inline \"_jpmn-search-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~#if (op \"===\" (get \"opt-first-definition-type\") \"bilingual\")~}}\n {{~#set \"first-definition-search-type-1\" \"bilingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"monolingual\"}}{{/set~}}\n {{~else~}}\n {{~#set \"first-definition-search-type-1\" \"monolingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"bilingual\"}}{{/set~}}\n {{~/if~}}\n {{~! first-dictionary === null <=> no valid dictionary was found ~}}\n {{~#set \"first-dictionary\" null}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-1\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! uses other dictionary type, last resort ~}}\n {{~#if (op \"===\" (get \"first-dictionary\") null)~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-2\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~/if~}}\n {{~#get \"first-dictionary\"~}}{{~/get~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n return null\n~}}\n{{~#*inline \"_jpmn-check-dictionary-and-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if\n (op \"&&\" (op \"===\" (get \"result\") \"\")\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return null\n if (able to detect dictionary of which the selection-text is highlighting):\n return \"uses-glossary\"\n return null\n~}}\n{{~#*inline \"_jpmn-selection-uses-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text is a dictionary -> null ~}}\n {{~else if\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text dict found -> \"uses-glossary\" ~}}\n uses-glossary\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n if (selection-text-glossary is not enabled):\n return first-dictionary (determined by `opt-first-definition-type`)\n return null\n else:\n return first-dictionary (determined by `opt-first-definition-type`)\n~}}\n{{~#*inline \"_jpmn-get-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~! first checks selection text ~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"selection\") \"\")~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary-and-glossary . ~}}{{/set~}}\n {{~! doesn't return a dictionary if opt-selection-text-glossary is false b/c ~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"result\") \"\")\n (op \"===\" (get \"opt-selection-text-glossary\") false)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-search-primary-definition-dict . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~! no selection text ~}}\n {{~else~}}\n {{~> _jpmn-search-primary-definition-dict . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n get number of primary dictionary entries\n~}}\n{{~#*inline \"_jpmn-primary-dict-entry-count\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~set \"dict-entry-count\" 0 ~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\")) ~}}\n {{~! dict-entry-count += 1 ~}}\n {{~set \"dict-entry-count\" (op \"+\"\n (get \"dict-entry-count\") 1\n )\n ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"dict-entry-count\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-is-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n dictionaryName: dictionary id\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~set \"valid-dict\" null ~}}\n {{~#set \"test-dict-type\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionaryName ~}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"test-dict-type\") validDictType)\n (op \"||\"\n (op \"!==\" (get \"primary-dictionary\") dictionaryName)\n (op \"===\" (get \"use-primary-dictionary\") true)\n )\n ) ~}}\n {{~set \"valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~get \"valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-has-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~!\n without this set statement, the parameters\n magically disappears within the bottom 'each' loop...\n ~}}\n {{~ set \"valid-dict-type\" validDictType ~}}\n {{~ set \"entry-count\" entryCount ~}}\n {{~set \"has-valid-dict\" null ~}}\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=(get \"valid-dict-type\") entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n {{~set \"has-valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"has-valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~#*inline \"_jpmn-get-primary-definition-value\"~}}\n {{~!\n ASSUMPTION: \"primary-dictionary\" and \"search-selection\" is available to us from previous functions\n ~}}\n {{~#scope~}}\n {{~#if\n (op \"&&\"\n (op \"!==\" (get \"search-selection\") \"\")\n (get \"opt-primary-def-one-dict-entry-only\")\n )\n ~}}\n {{~! text was highlighted -> use primary dictionary entry with highlighted text ~}}\n {{~set \"found-dict-entry\" false ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-dict-entry\" ~}}\n {{~#regexMatch (get \"search-selection\") \"gu\"~}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"found-dict-entry\") false)\n (op \"&&\"\n (op \"!==\" (get \"rx-match-dict-entry\") \"\")\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else if (get \"opt-primary-def-one-dict-entry-only\") ~}}\n{{~! use first primary dictionary entry ~}}\n{{~set \"found-dict-entry\" false ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n{{~/if~}}\n{{~#each definition.definitions~}}\n{{~#if\n(op \"&&\"\n(op \"===\" (get \"found-dict-entry\") false)\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else~}}\n{{~! use all primary dictionary entries ~}}\n{{~#if (get \"opt__plaintext__one-dict-entry-only-no-list\") ~}}\n{{~! must manually calculate number of primary-dictionary entries... ~}}\n{{~set \"t\" 0 ~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <ol> {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <li data-details=\"{{~dictionary~}}\"> {{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \">=\" (get \"t\") 2)~}} </li> {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} </ol> {{~/if~}}\n {{~else~}}\n <ol> {{~s~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol> {{~s~}}\n{{~/if~}}\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\nif (mode === \"except\" and (regex doesn't match) or mode === \"only\" and (regex matches)):\n return true\n return null\n~}}\n{{#*inline \"_jpmn-check-first-line-dict\"}}\n {{~#scope~}}\n {{~#set \"rx-match-first-line-dict\" ~}}\n {{~#regexMatch (get \"opt-first-line-dicts-regex\") \"u\"~}}{{dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"||\"\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"except\")\n (op \"===\" (get \"rx-match-first-line-dict\") \"\")\n )\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"only\")\n (op \"!==\" (get \"rx-match-first-line-dict\") \"\")\n )\n )\n ~}}\n true\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! custom glossary-single function for additional regex parsing per dictionary ~}}\n{{~! OVERRIDES brief and noDictionaryTag ~}}\n{{#*inline \"_jpmn-glossary-single\"}}\n {{~#scope~}}\n {{~#if (op \"===\" dictionary \"NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\")~}}\n {{~#regexReplace \"<br></span> \u30fb\" \"<br></span>\" \"g\"~}}\n {{~#regexReplace \"<br> \u30fb\" \"<br>\" \"g\"~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/regexReplace~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! custom glossary-single function to add custom html around the dictionary and tags ~}}\n{{#*inline \"_jpmn-glossary-single2\"}}\n {{~#scope~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__tag-list\"> {{~s~}}\n {{~#each definitionTags~}}\n <span class=\"dict-group__tag dict-group__tag--name\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~name~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~/each~}}\n <span class=\"dict-group__tag dict-group__tag--dict\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~dictionary~}}\n </span> {{~s~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~else~}}\n {{~#scope~}}\n {{~#set \"any\" false}}{{/set~}}\n {{~#each definitionTags~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{name}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/each~}}\n {{~#if (op \"!\" (get \"opt__plaintext__remove-dictionary-tag\"))~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{dictionary}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/if~}}\n {{~#if (get \"any\")}}) {{/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__glossary\"> {{~s~}}\n {{~/if~}}\n {{~!\n option to not wrap with spans because it may break dictionaries\n (this is the hell that is parsing html with regex)\n ~}}\n {{~#if (op \"&&\"\n (get \"opt-wrap-first-line-spans\")\n (op \"!\" (get \"opt__plaintext__enabled\"))\n )\n }}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1<span class=\\\"dict-group__glossary--first-line\\\">$2</span><span class=\\\"dict-group__glossary--first-line-break\\\"><br></span>\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else if (get \"opt__plaintext__remove-first-line-enabled\")~}}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~! none match means the dictionary is not an exception, i.e. replace newline ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n </span> {{~s~}}\n {{~/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n{{/inline}}\n{{#*inline \"_jpmn-glossary-single3\"}}\n {{~#scope~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"opt-jmdict-list-format\") true)\n (op \"||\"\n (op \"===\" dictionary \"JMdict (English)\")\n (op \"||\"\n (op \"===\" dictionary \"JMdict Extra\")\n (op \"===\" dictionary \"JMdict\")\n )\n )\n )\n ~}}\n {{~#if (op \"<=\" glossary.length 1)~}}\n {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}\n {{~else~}}\n <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>\n {{~/if~}}\n {{~else~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n =============\n frequencies\n =============\n~}}\n{{#*inline \"jpmn-frequencies\"}}\n {{~#if (op \">\" definition.frequencies.length 0)~}}\n {{~#each definition.frequencies~}}\n <div class=\"frequencies__group\" data-details=\"{{~dictionary~}}\"> {{~s~}}\n <div class=\"frequencies__number\"> {{~s~}}\n <span class=\"frequencies__number-inner\"> {{~s~}}\n {{~! removes the \"X\" in JPDB's frequency and replaces it with a less assuming character\n(it interferes with the color of the card, since you see red\nat the top corner which is somewhat distracting) ~}}\n{{~#regexReplace \"\u274c\" \"\u2716\" \"g\"~}}\n{{~frequency~}}\n{{~/regexReplace~}}\n </span> {{~s~}}\n </div> {{~s~}}\n <div class=\"frequencies__dictionary\"> {{~s~}}\n <span class=\"frequencies__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </span> {{~s~}}\n </div> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~! base code taken from: https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency ~}}\n{{~! NOTE: THIS IS ONLY KEPT FOR LEGACY PURPOSES, and is now deprecated. Please use {jpmn-frequency-sort} instead. ~}}\n{{~#*inline \"jpmn-min-freq\"~}}\n{{~#scope~}}\n{{~#set \"min-freq\" 0~}}{{~/set~}}\n{{~#each definition.frequencies~}}\n{{~#set \"rx-match-ignored-freq\" ~}}\n{{~#regexMatch (get \"ignored-freq-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if\n(op \"&&\"\n(op \"||\"\n(op \"===\" (get \"min-freq\") 0)\n (op \">\" (op \"+\" (get \"min-freq\")) (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency)))\n )\n (op \"===\" (get \"rx-match-ignored-freq\") \"\")\n )\n ~}}\n {{~#set \"min-freq\" (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency))}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"min-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-frequency-sort\"}}\n {{~! Frequency sort handlebars: v24.01.06.1 ~}}\n {{~! The latest version can be found at https://github.com/MarvNC/JP-Resources#freq-handlebar ~}}\n {{~#scope~}}\n {{~! Do not change the code below unless you know what you are doing. ~}}\n {{~set \"result-freq\" -1 ~}} {{~! -1 is chosen because no frequency dictionaries should have an entry as -1 ~}}\n {{~set \"prev-freq-dict\" \"\" ~}}\n {{~set \"t\" 1 ~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#each definition.frequencies~}}\n {{~! rx-match-ignored-freq is not empty if ignored <=> rx-match-ignored-freq is empty if not ignored ~}}\n {{~#set \"rx-match-ignored-freq\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#set \"rx-match-ignored-value\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-value-regex\") \"u\"~}}{{this.frequency}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\" (op \"===\" (get \"rx-match-ignored-freq\") \"\") (op \"===\" (get \"rx-match-ignored-value\") \"\"))~}}\n {{~!\n only uses the 1st frequency of any dictionary.\n For example, if JPDB lists 440 and 26189\u32d5, only the first 440 will be used.\n ~}}\n {{~set \"read-freq\" false ~}}\n {{~#if (op \"!==\" (get \"prev-freq-dict\") this.dictionary ) ~}}\n {{~set \"read-freq\" true ~}}\n {{~set \"prev-freq-dict\" this.dictionary ~}}\n {{/if~}}\n {{~#if (op \"!\" (get \"read-freq\") ) ~}}\n {{~#set \"rx-match-keep-freqs\" ~}}\n {{~#regexMatch (get \"opt-keep-freqs-past-first-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-keep-freqs is not empty if keep freqs ~}}\n {{~#if (op \"!==\" (get \"rx-match-keep-freqs\") \"\") ~}}\n {{~set \"read-freq\" true ~}}\n {{/if~}}\n {{/if~}}\n {{~#if (get \"read-freq\") ~}}\n {{~#set \"numericFrequencyMatch\"}}{{~#regexMatch \"\\d+\" \"\"}}{{~this.frequency~}}{{/regexMatch~}}{{/set~}}\n {{~set \"f\" (op \"+\" (get \"numericFrequencyMatch\")) ~}}\n {{~#if (op \"===\" (get \"opt-freq-sorting-method\") \"min\") ~}}\n {{~#if\n (op \"||\"\n (op \"===\" (get \"result-freq\") -1)\n (op \">\" (get \"result-freq\") (get \"f\"))\n )\n ~}}\n {{~set \"result-freq\" (op \"+\" (get \"f\")) ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"first\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~else~}}\n {{~!\n iterative mean formula (to prevent floating point overflow):\n $S_{(t+1)} = S_t + \\frac{1}{t+1} (x - S_t)$\n - example java implementation: https://stackoverflow.com/a/1934266\n - proof: https://www.heikohoffmann.de/htmlthesis/node134.html\n ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\"\n (op \"-\"\n (get \"f\")\n (get \"result-freq\")\n )\n (get \"t\")\n )\n )\n }}\n {{~/if~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~#if (op \">\" (get \"f\") 0) ~}} {{~! ensures only positive numbers are used ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (op \"/\" 1 (get \"f\")) ~}}\n {{~else ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\" 1 (get \"f\"))\n )\n }}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"debug\") ~}}\n {{ this.dictionary }}: {{ this.frequency }} -> {{ get \"f\" }} <br>\n {{~else~}}\n (INVALID opt-freq-sorting-method value)\n {{~/if~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! (x) >> 0 apparently floors x: https://stackoverflow.com/a/4228528 ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"opt-no-freq-default-value\") ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~set \"result-freq\"\n (op \">>\" (get \"result-freq\") 0 )\n ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~set \"result-freq\"\n (op \">>\"\n (op \"*\"\n (op \"/\" 1 (get \"result-freq\"))\n (get \"t\")\n )\n 0\n )\n ~}}\n {{~/if~}}\n {{~! override final result if grammar dictionary ~}}\n {{~#if (\n op \"&&\"\n (op \"===\" (get \"found-grammar-dict\") true)\n (op \"===\" (get \"opt-grammar-override\") true)\n )\n ~}}\n {{~set \"result-freq\" (get \"opt-grammar-override-value\") ~}}\n {{/if}}\n {{~get \"result-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n ==============\n pitch accent\n ==============\n~}}\n{{#*inline \"jpmn-pitch-accent-graphs\"}}\n {{~#if (op \">\" pitchCount 0)~}}\n {{~#each pitches~}}\n <div class=\"pa-graphs__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-graphs__dictionary\"> {{~s~}}\n <div class=\"pa-graphs__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"graph\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-pitch-accent-positions\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#each pitches~}}\n <div class=\"pa-positions__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-positions__dictionary\"> {{~s~}}\n <div class=\"pa-positions__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"position\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~!\n==============\ndictionaries\n==============\n~}}\n{{~! primary def: first monolingual (or first bilingual if no monolingual dicts found) ~}}\n{{~! does the reverse if opt-first-definition-type is \"bilingual\" ~}}\n{{~#*inline \"jpmn-primary-definition\"~}}\n{{~#scope~}}\n{{~! output warning if no dictionaries are found ~}}\n{{~#if (op \"===\" definition.definitions.length undefined)~}}\nWARNING: JPMN Handlebars cannot find any definitions to export.\nThis is usually because your Yomichan settings has \"Result grouping mode\"\nset to \"No grouping\". Please set this to \"Group term-reading pairs\".\n {{~/if~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~#if (op \"===\" (get \"primary-dictionary\") \"\")~}}\n {{~> _jpmn-selection-text ~}}\n {{~else~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#set \"selection-uses-glossary\"~}}\n {{~> _jpmn-selection-uses-glossary . ~}}\n {{~/set~}}\n {{~! not \"\" <=> is a filled string, i.e. selection uses glossary ~}}\n {{~#if (op \"!==\" (get \"selection-uses-glossary\") \"\")~}}\n {{~! escape regex ~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#set \"search-selection-bold\"}}<b>{{~> _jpmn-selection-text ~}}</b>{{/set~}}\n {{~#regexReplace (get \"search-selection\") (get \"search-selection-bold\") \"g\"~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~#set \"search-selection\"}}{{/set~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! extra def: bilingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-secondary-definition\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~! looks to see if another dictionary exists ~}}\n {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n {{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n {{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n {{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! extra def: monolingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-extra-definitions\"~}}\n{{~#scope~}}\n{{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n{{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! pitch accent info: all pitch accent info dictionaries ~}}\n{{~#*inline \"jpmn-utility-dictionaries\"~}}\n{{~#scope~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! 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) ~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"utility\"~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") \"utility\")~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\n=======\nother\n=======\n~}}\n{{~#*inline \"jpmn-word-reading-hiragana\"~}}\n{{~#set \"word-reading\" ~}}{{> reading}}{{/set~}}\n{{~#if (op \"\" (get \"word-reading\")) ~}}\n{{~#set \"word-reading\" ~}}{{> expression}}{{/set~}}\n{{~/if~}}\n{{#hiragana (get \"word-reading\") keepProlongedSoundMarks=false}}{{/hiragana}}\n{{~/inline~}}\n{{~!\nthanks to:\n- https://github.com/FooSoft/yomichan/issues/1952#issuecomment-922671489 for the base code\n- DaNautics#8833 for finding the above + removing the span classes\n~}}\n{{#*inline \"jpmn-sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-hiragana\"}}\n{{~#scope~}}\n{{~#set \"expression\" ~}}{{> expression}}{{/set~}}\n{{~#set \"reading\" ~}}{{> reading}}{{/set~}}\n{{~#set \"expression-hiragana\" ~}}{{> jpmn-word-reading-hiragana}}{{/set~}}\n{{~#if (op \"&&\" (op \"===\" (get \"expression\") (get \"reading\")) (op \"===\" (get \"expression\") (get \"expression-hiragana\")))~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-not-hiragana\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-word-is-hiragana}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-grammar-point\"}}\n {{~#scope~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#if (get \"found-grammar-dict\") ~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-grammar-point\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-grammar-point}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-on-mim\"}}\n {{~#scope~}}\n {{~#set \"rx-match-on-mim\" ~}}\n {{~#regexMatch \"(, |^)on-mim(, |$)\" \"gu\"~}}{{> tags }}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"!==\" (get \"rx-match-on-mim\") \"\") ~}}\n 1\n {{/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-on-mim\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-not-on-mim}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! my personal settings:\n- sentence card if grammar point\n- otherwise, if it's on-mim, then hint card\n- otherwise, default\n~}}\n{{#*inline \"jpmn-is-sentence-card\"}}\n {{~> jpmn-filled-if-grammar-point ~}}\n{{/inline}}\n{{#*inline \"jpmn-is-hint-card\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n {{~> jpmn-filled-if-on-mim ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-is-click-card\"}}\n {{~#scope~}}\n {{~#set \"filled1\" ~}}{{> jpmn-is-hint-card}}{{/set~}}\n {{~#set \"filled2\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"filled1\") \"\")\n (op \"===\" (get \"filled2\") \"\")\n )~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! a test to check if your dictionaries are correctly classified. ~}}\n{{~! Only meant to be used for debugging purposes, not Anki. ~}}\n{{~#*inline \"jpmn-test-dict-type\"~}}\n{{~#scope~}}\n{{~#each definition.definitions~}}\n\u300c{{dictionary}}\u300d: {{> jpmn-get-dict-type . dictionaryName=dictionary}}\n{{/each~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"jpmnhandlebars/#monolingual-definitions","title":"Monolingual definitions","text":"By default, the handlebars exports bilingual cards. Set opt-first-definition-type
to monolingual
if you want monolingual Anki cards. See here for more info.
"},{"location":"jpmnhandlebars/#setup-fields","title":"Setup Fields","text":"Video demo TODO (click here) TODO video
- Navigate to Yomichan Settings.
- Go to the
Anki
section. - Select
Anki card format...
. - Under your definition field (
Glossary
, VocabDef
, etc.), type {jpmn-primary-definition}
into the input box. - If you have a field for bilingual definitions, set that field to
{jpmn-secondary-definition}
- If you have a field for all other definitions, set that field to
{jpmn-extra-definitions}
"},{"location":"jpmnhandlebars/#common-problems","title":"Common Problems","text":" -
If you transferred from the legacy Anime Cards handlebars (step 6 of this), then your pitch accent graphs might look a bit different. This is because the legacy Anime Cards handlebars removes a bunch of extra styling from the exported SVG, which is unfortunately non-standard.
Nonetheless, the easy way to fix this is by simply replacing the current pitch accent handlebars with Anime Card's modified pitch accent handlebars:
Legacy pitch accent handlebars (click here) {{! Pitch Accents }}\n{{#*inline \"pitch-accent-item\"}}\n{{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}\n{{/inline}}\n{{#*inline \"pitch-accent-item-disambiguation\"}}\n{{~#scope~}}\n{{~#set \"exclusive\" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}\n{{~#if (op \">\" (property (get \"exclusive\") \"length\") 0)~}}\n{{~#set \"separator\" \"\"~}}{{/set~}}\n <em>({{#each (get \"exclusive\")~}}\n{{~#get \"separator\"}}{{/get~}}{{{.}}}\n{{~/each}} only) </em>\n{{~/if~}}\n{{~/scope~}}\n{{/inline}}\n{{#*inline \"pitch-accent-list\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~#each pitches~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~/each~}}\n{{~/each~}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~else~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"pitch-accents\"}}\n{{~> pitch-accent-list format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs\"}}\n{{~> pitch-accent-list format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions\"}}\n{{#regexReplace \"<(.|\\n)*?>\" \"\"}}{{~> pitch-accent-list format='position'~}}{{/regexReplace}}\n{{/inline}}\n{{! End Pitch Accents }}\n
Alternatively, you can use these handlebars to get one pitch accent only. This does not modify existing handlebars.
"},{"location":"jpmnhandlebars/#introduced-handlebars","title":"Introduced Handlebars","text":""},{"location":"jpmnhandlebars/#definitions","title":"Definitions","text":"Main Page: Definitions: Dictionary Placement
The most important handlebars that this package introduces is {jpmn-primary-definition}
. This handlebars automatically selects the first monolingual or bilingual dictionary, depending on the opt-first-definition-type
option.
To summarize the introduced definition handlebars:
Handlebars Description {jpmn-primary-definition}
The highest priority monolingual or bilingual dictionary (depending on the value of opt-first-definition-type
). {jpmn-secondary-definition}
All bilingual dictionaries outside of the one selected in the primary definition. {jpmn-extra-definitions}
All monolingual dictionaries outside of the one selected in the primary definition. {jpmn-utility-dictionaries}
All dictionaries that fall outside the category of bilingual or monolingual. For example, JMnedict or JMdict Forms. If you want to select a different dictionary, highlight the dictionary, or a portion of the definition before importing. This will override the primary definition with the selected dictionary / definition.
"},{"location":"jpmnhandlebars/#frequency-sorting","title":"Frequency Sorting","text":"This package introduces {jpmn-frequency-sort}
, which behaves the exact same as Marv's {freq}
handlebars. The only difference is that the options are placed at the very top of the handlebars, instead of within the function.
In other words, feel free to use this in the exact same way as you would with {freq}
.
"},{"location":"jpmnhandlebars/#other-handlebars","title":"Other handlebars","text":" - TODO
jpmn-sentence-bolded-furigana-plain
- TODO binary field handlebars
- link to appropriate yomichan template section
"},{"location":"jpmnhandlebars/#plaintext-options","title":"Plaintext Options","text":"This section describes all the plaintext options, which are all prefixed with opt__plaintext__
.
-
If you are not using jp-mining-note, all these options should be set to true
by default. This means definitions are as minimal as possible in both internal HTML structure and in content.
-
If you are using jp-mining-note, then all of these should be set to false
by default.
If you are looking for information about the other options, please see the Definitions page.
"},{"location":"jpmnhandlebars/#opt__plaintext__stylize-glossary","title":"opt__plaintext__stylize-glossary
","text":"Setting this option to true
will no longer stylize the definition handlebars for jp-mining-note usage, and instead stylizes it to be virtually the same as Yomichan's default HTML structure.
Differences between default Yomichan format and JPMN plaintext (click here) There are a few minor differences between Yomichan's format and these non-stylized definitions:
- The dictionary and tags are not italicized. This is to avoid seeing italic kanjis/kana.
-
The div that left-aligns the text is not present. If this breaks your card, (for example, the definition gets centered), try surrounding your definition field. For example, if your field name is Definition
, then within your Anki card templates, surround {{ Definition }}
with the following:
<div style=\"text-align: left\"> {{Definition}} </div>\n
-
Dictionaries with only one entry is formatted as a list of one element by default. This is usually not desired. To disable this behavior and make the behavior more like Yomichan, set opt__plaintext__one-dict-entry-only-no-list
to true
.
-
The first line for most dictionaries are removed by default. This can be controlled with the following options:
opt__plaintext__remove-first-line-enabled
opt-first-line-dicts-regex
There are som dictionaries simply cannot have their first line be removed by the handlebars, due to its complicated internal structure. Those dictionaries are specified under opt-first-line-dicts-regex
by default.
"},{"location":"jpmnhandlebars/#opt__plaintext__one-dict-entry-only-no-list","title":"opt__plaintext__one-dict-entry-only-no-list
","text":"If this is true
, then a definition that only contains one dictionary entry will export without being in a list.
For the following examples, we take the definition of \u7d68\u6bef from the \u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248 dictionary.
true
(single definition has no list)false
(single definition exported in list) \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
- \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
Note
If there are multiple definitions, then it is exported in a list format by default. This is almost never present in monolingual dictionaries, but almost always present for JMdict. For example, \u5730\u96f7 (in the old JMdict dictionary) will always be exported as the following, regardless of the setting:
- (n, JMdict (English)) land mine
- (n, col, JMdict (English)) topic that sets someone off | sensitive topic | taboo topic | trigger
- (n, col, JMdict (English)) something that seems fine at first but turns out to be very bad (e.g. product, business) | booby trap | pitfall
"},{"location":"jpmnhandlebars/#opt__plaintext__remove-dictionary-tag","title":"opt__plaintext__remove-dictionary-tag
","text":"Whether the dictionary tag is exported or not.
true
(no dictionary tag)false
(keep dictionary tag) \u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
(\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248) \u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
"},{"location":"jpmnhandlebars/#opt__plaintext__remove-first-line-enabled","title":"opt__plaintext__remove-first-line-enabled
","text":"Whether the first line is exported or not.
true
(first line removed)false
(first line kept) \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
\u3058\u3085\u3046\u2010\u305f\u3093\u3010\u25b3\u7d68\u25b3\u6bef\u30fb\u25b3\u7d68\u25b3\u7dde\u3011 \u5e8a\u306e\u6577\u7269\u306b\u3059\u308b\u539a\u3044\u6bdb\u7e54\u7269\u3002\u30ab\u30fc\u30da\u30c3\u30c8\u3002\u300c\u5e8a\u306b\u2015\u3092\u6577\u304f\u300d \u300a\u5b63\u30fb\u51ac\u300b
This affects almost all dictionaries by default. If you want to ignore certain dictionaries, use the opt-first-line-dicts-regex
option as described here.
"},{"location":"jpmnhandlebars/#compatibility-with-other-handlebars","title":"Compatibility with other Handlebars","text":"These handlebars are fully compatable SO LONG AS your other handlebars are based off of the most recent set of default handlebars. A non-example is the classic animecard's {test}
. {test}
requires outdated handlebars in order to work, and is therefore incompatible with these handlebars.
There are two reasons why these handlebars are compatible with most other handlebars:
- Everything is prefixed with
jpmn
(or _jpmn
). These prefixes prevent the JPMN handlebars from overriding any other custom handlebars you may have defined. - These handlebars do not modify the default handlebars code. This is in order to preserve the original handlebars functionality, and so other handlebars can rely on the original handlebars to work properly.
"},{"location":"jpresources/","title":"JP Resources","text":"A collection of tips and tricks, primarily related to CSS, Yomichan templates, and ShareX. Other resources can be found to the left sidebar.
This page was inspired by Marv's resources page, which has a bunch of different but equally awesome resources. I highly recommend checking it out!
If you encounter any problems, have any questions, etc., feel free to contact me on discord aquafina_water_bottle
, or submit an issue. I exist on the TheMoeWay and Refold (Japanese) servers.
"},{"location":"jpresources/#master-project-list","title":"Master Project List","text":"This contains the list of all my current projects that relate to learning Japanese.
-
jp-mining-note
jp-mining-note is a highly customizable Anki card template for studying Japanese, designed to be visually appealing and simple to use without sacrificing functionality. Easily paired with most automatic card creation workflows, this aims to make your experience with Anki as smooth as possible.
-
JPMN Manager
JPMN Manager is a simple Anki add-on that makes it possible to seemlessly install and update jp-mining-note, and makes working with the note a little easier.
-
Local Audio Server for Yomichan
This Anki add-on runs a local server of which Yomichan can fetch audio files from, using a database containing over 200,000 unique expressions. With this setup, you are able to create Anki cards nearly instantaneously, and get word audio without a working internet connection.
-
JPMN Handlebars Package
Instructions on how to use the JPMN handlebars for any note type, not just jp-mining-note. Most notably, these handlebars make it very easy to select and export dictionaries into Anki.
-
All Anki note templates I can find
I catalogue all note templates I can possibly find (that isn't jp-mining-note, and made for learning Japanese) here.
-
JMdict (English) for Yomichan
This simply contains a Yomichan dictionary version of JMdict (English)
from the main website (from files JMdict_e
and JMdict_e_examp
), compiled using yomichan-import. (Disclaimer: I did not make any of these tools.)
This repository exists to simply give people a more up-to-date version of this dictionary, for people who don't want to compile the dictionary themselves. A more up-to-date version of JMdict usually provides better definitions and coverage compared to older versions, so I would recommend updating this dictionary every few months.
"},{"location":"jpresources/#css-yomichan","title":"CSS (Yomichan)","text":""},{"location":"jpresources/#how-to-add-custom-css-in-yomichan","title":"How-To: Add Custom CSS In Yomichan","text":"To add custom CSS in Yomichan, do the following:
- Head over to Yomichan settings (Yomichan extension marker -> cogwheel)
- Go to
Appearance
\u2192 Configure custom CSS...
- Add the CSS to the top section.
- Close the window.
Demo (click here) "},{"location":"jpresources/#not-selecting-or-copying-furigana","title":"Not selecting or copying furigana","text":"If you want to select / copy the main word within Yomichan without copying the furigana, you can use the following CSS:
.headword-term ruby rt {\nuser-select: none;\n}\n
Note
The above is actually general enough to use for Anki cards itself, say with the following CSS:
ruby rt {\nuser-select: none;\n}\n
"},{"location":"jpresources/#limiting-the-number-of-frequency-lists","title":"Limiting the number of frequency lists","text":"/* Only shows the first 2 frequency lists */\nspan.frequency-group-item:nth-child(n+3) {\ndisplay: none;\n}\n
(Thanks Marv#5144 for the CSS. Original message on TMW server) Demo (click here)"},{"location":"jpresources/#limiting-the-number-of-pitch-accent-dictionaries","title":"Limiting the number of pitch accent dictionaries","text":"The following CSS displays only the first 2 pitch accent dictionaries:
/* Only shows the first 2 pitch accent dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n
Make the pitch accent dictionary text a bit grey by default, and to make specifically the \"NHK\" and \"\u5927\u8f9e\u6cc9\" white (change these two to any dictionary you find to be of higher quality)
/* Greys out all pitch accent dictionary names */\n/* Sets NHK and \u5927\u8f9e\u6cc9 pitch accent dictionaries to a white name */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\n
Demo (click here) "},{"location":"jpresources/#hide-the-dictionary-but-allow-it-to-be-used-by-anki","title":"Hide the dictionary, but allow it to be used by Anki","text":"The default way to hide a dictionary is by disabling the dictionary under Yomichan's Dictionaries
section. However, if you disable the dictionary, you cannot export it into Anki, which is a problem if you are using a bilingual profile but you want to export monolingual definitions.
Steps:
- Ensure that the dictionary is enabled in your Yomichan profile.
- Add the following CSS for the desired dictionaries (this has to be done for each individual dictionary):
li.definition-item[data-dictionary='DICTIONARY'] {\ndisplay: none;\n}\n
Example CSS for JMdict (click here) li.definition-item[data-dictionary='JMdict (English)'] {\ndisplay: none;\n}\n
Demo (click here) "},{"location":"jpresources/#hide-bilingual-definitions-until-hover","title":"Hide bilingual definitions until hover","text":"Add the following CSS for the desired dictionaries (this has to be done for each individual dictionary):
li.definition-item[data-dictionary='DICTIONARY'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='DICTIONARY']:hover .gloss-list {\nopacity: 1;\n}\n
Example CSS for JMdict (click here) li.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\n
Demo (click here) "},{"location":"jpresources/#remove-the-add-reading-button","title":"Remove the \"Add Reading\" button","text":"This removes the small green button to add the reading.
button[title^=\"Add reading\"] {\ndisplay:none;\n}\n
Demo (click here) Left: without CSS. Right: with CSS.
"},{"location":"jpresources/#coloring-dictionaries","title":"Coloring Dictionaries","text":"Darius has some CSS here that uniquely colors popular dictionaries.
"},{"location":"jpresources/#css-other","title":"CSS (Other)","text":""},{"location":"jpresources/#ensuring-properly-quotes-the-text","title":"Ensuring \u300c\u300d properly quotes the text","text":"If your text contains quotes, the following CSS ensures that it is properly stylized:
.jp-quote-text {\ntext-indent: -1em;\npadding-left: 1em;\n}\n
On the example to the right, the first quote is the standard display without any custom CSS. The second quote is with the aforementioned CSS.
An example JSFiddle can be found here.
"},{"location":"jpresources/#changing-the-japanese-font-on-discord","title":"Changing the Japanese font on Discord","text":"Note
Discord's codebase is always subject to change, so this method may not work in the future.
- Get BetterDiscord so you can use custom CSS.
- In Discord Settings \u2192
Custom CSS
section, add the following: :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"YOUR-PREFERRED-FONT\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: var(--font-primary);\n}\n
Example CSS for Noto Sans (click here) :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"Noto Sans CJK JP\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: var(--font-primary);\n}\n
Discord's default CSS (click here) :lang(ja), :lang(ja-JP) {\n--font-primary: \"gg sans\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n--font-display: \"gg sans\",\"Hiragino Sans\",\"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\u30e1\u30a4\u30ea\u30aa,Meiryo,Osaka,\"MS PGothic\",\"Noto Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n}\n
Note
If you are using the browser version of Discord, you can also change the font with the Stylus extension. I personally don't use this, so I'll leave it to the user to figure out the settings. ;)
Changelog 22/12/01
: Changed Whitney
to gg sans
to match with Discord's new font 22/12/05
: Added --font-display
, added missing Noto Sans
to all the fonts
"},{"location":"jpresources/#yomichan-templates-handlebars","title":"Yomichan Templates / Handlebars","text":"Note
If you are using the jp-mining-note template, most things here will likely not be useful for you as the Yomichan templates that comes with the note already contains most of these features and more.
"},{"location":"jpresources/#how-to-edit-yomichan-fields","title":"How-To: Edit Yomichan Fields","text":" - Navigate to Yomichan Settings.
- Go to the
Anki
section. - Select
Anki card format...
.
Demo (click here) The above showcases option 2 of this example.
"},{"location":"jpresources/#how-to-edit-yomichan-templates-handlebars","title":"How-To: Edit Yomichan Templates (Handlebars)","text":" - Navigate to Yomichan Settings.
- Make sure that advanced settings are turned on (bottom left corner).
- Go to the
Anki
section - Select
Configure Anki card templates...
Demo (click here)"},{"location":"jpresources/#grab-only-the-first-pitch-accent-dictionary","title":"Grab only the first pitch accent dictionary","text":"Adds the following Yomichan Fields:
{pitch-accents-single-dict}
: Pitch accent in text (downstep) format {pitch-accent-graphs-single-dict}
: Pitch accent in svg graph format {pitch-accent-positions-single-dict}
: Pitch accent in positions (number) format
Template code (click here) {{#*inline \"pitch-accent-list-single-dict\"}}\n{{~#if (op \">\" pitchCount 1)~}}<ol>{{~/if~}}\n{{~#eachUpTo pitches 1~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}<li>{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}</li>{{~/if~}}\n{{~/each~}}\n{{~else~}}\n No pitch accent data\n{{~/eachUpTo~}}\n{{/inline}}\n{{#*inline \"pitch-accents-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='position'~}}\n{{/inline}}\n
Modified version of the above for Anime Cards (click here) {{#*inline \"pitch-accent-list-single-dict\"}}\n{{~#if (op \">\" pitchCount 1)~}}{{~/if~}}\n{{~#eachUpTo pitches 1~}}\n{{~#each pitches~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~> pitch-accent-item-disambiguation~}}\n{{~> pitch-accent-item format=../../format~}}\n{{~#if (op \">\" ../../pitchCount 1)~}}{{~/if~}}\n{{~/each~}}\n{{~else~}}\n{{~/eachUpTo~}}\n{{/inline}}\n{{#*inline \"pitch-accents-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='text'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-graphs-single-dict\"}}\n{{~> pitch-accent-list-single-dict format='graph'~}}\n{{/inline}}\n{{#*inline \"pitch-accent-positions-single-dict\"}}\n{{#regexReplace \"<(.|\\n)*?>\" \"\"}}{{~> pitch-accent-list-single-dict format='position'~}}{{/regexReplace}}\n{{/inline}}\n
(Thanks An#7416 for the template code. Original message on TMW server).
"},{"location":"jpresources/#export-only-the-selected-text-only-if-text-is-selected","title":"Export only the selected text (only if text is selected)","text":"Adds: {selection-text-or-glossary}
Tip
I recommend using {jpmn-primary-definition}
from the JPMN Handlebars Package instead of this handlebars, because the handlebars package can do this and much more.
Allows you to export only a section of a glossary by highlighting over it, and uses the glossary by default if you don't have anything highlighted.
Template code (click here) {{#*inline \"selection-text-or-glossary\"}}\n{{~#if (op \"!==\" (getMedia \"selectionText\") \"\")~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n{{~else~}}\n{{~> glossary ~}}\n{{/if~}}\n{{/inline}}\n
Note
Related Github issue.
"},{"location":"jpresources/#grab-only-the-first-dictionary","title":"Grab only the first dictionary","text":"Adds: {glossary-first}
Tip
I recommend using {jpmn-primary-definition}
from the JPMN Handlebars Package instead of this handlebars, because the handlebars package can do this and much more.
The following grabs the first dictionary (including every definition within said dictionary).
For further customization on how the first dictionary is selected (say, for automatic bilingual / monolingual separation), see the handlebars code used by jp-mining-note here.
Template code (click here) {{~#*inline \"glossary-first\"~}}\n{{~#scope~}}\n{{~#set \"first-dictionary\" null}}{{/set~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"!==\" null (get \"first-dictionary\"))~}}\n <div style=\"text-align: left;\"><ol>\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"first-dictionary\"))~}}\n <li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>\n{{~/if~}}\n{{~/each~}}\n </ol></div>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"jpresources/#automatically-highlight-the-tested-word-within-the-sentence-upon-card-creation","title":"Automatically highlight the tested word within the sentence upon card creation","text":"Option 1: Bold only {cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}\n
Option 2: Bold + Styling (recommended) Yomichan Fields:
{cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}\n
Anki Note CSS (the Styling
page under the editing card templates page):
b {\ncolor: #fffd9e; /* bright yellow */\n}\n
If your card template is formatted like <div class=\"sentence\">{{ Sentence }}</div>
:
.sentence b {\ncolor: #fffd9e; /* bright yellow */\n/* if you want to make the word not bolded, un-comment the following */\n/*font-weight: normal;*/\n}\n
Option 3: Custom div Yomichan Fields:
{cloze-prefix}<span class=\"word-highlight\">{cloze-body}</span>{cloze-suffix}\n
Anki Note CSS:
.word-highlight {\ncolor: #fffd9e;\n}\n
Note
I personally prefer using Option 2 (bold + styling) over a custom div because it makes editing the note easier. For example, if you want to edit the highlighted region, you only have to bold the desired region (say, with Ctrl+B) instead of having to edit the raw HTML of the field (say, with Ctrl+Shift+X).
See also: How to automatically highlight the targetted word within the sentence for already existing cards.
"},{"location":"jpresources/#plain-style-sentence-furigana","title":"Plain-Style Sentence Furigana","text":"Adds: {sentence-bolded-furigana-plain}
This does the following:
- Generates plain style furigana on the sentence (e.g. \u300c \u65e5\u672c\u8a9e[\u306b\u307b\u3093\u3054]\u300d
- Bolds the added word
To use this in Anki, add furigana:
in front of the field within the template code. For example, if your field is SentenceReading
, use {{furigana:SentenceReading}}
.
Template code (click here) {{#*inline \"sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n
Thanks to Skillesss: for the base code and DaNautics#8833 for finding the above + removing the span classes
Comparisons to alternatives (click here) -
AJT Furigana can auto-generate furigana on card add and can add furigana to any text within a field even after a card add. However, generating furigana cannot be done within this addon on Android, as this is a PC add-on.
Nonetheless, I recommend keeping AJT Furigana so furigana can be generated even after editing the sentence field.
-
The {furigana}
helper provided by default in Yomichan does not generate plain style furigana, which makes editing furigana more difficult in Anki.
"},{"location":"jpresources/#further-reading","title":"Further Reading","text":"Official documentation om Yomichan's templates:
- Yomichan template helper functions
- Yomichan template structure
Example template code can be found here:
-
Helpers for individual dictionaries: here
- This has certain extended capabilities over my template code, such as removing the first line.
-
Template code for this note: here and here
-
Old template code for this note (NO LONGER USED / MAINTAINED): here
"},{"location":"jpresourcesother/","title":"Other","text":""},{"location":"jpresourcesother/#settings-css-for-renjis-texthooker","title":"Settings / CSS for Renji's texthooker","text":"I use the following stylizations to remove unnecessary padding within the document, and to behave more similarly to Anacreon's texthooker.
Settings:
Setting Value Preserve Whitespace Remove Whitespace Custom CSS:
main > p {\npadding: 0rem !important;\n}\nmain {\npadding-left: min(5%, 5rem) !important;\npadding-right: min(5%, 5rem) !important;\n}\nbody > div > textarea {\nfont-size: 24px !important;\n}\n
Using a custom font (click here) I set the font to be Noto Sans, but this will likely not work without downloading and installing the font first (e.g. from here). Below is the actual full CSS that I use in conjuction with the installed font:
main > p {\npadding: 0rem !important;\n}\nmain {\npadding-left: min(5%, 5rem) !important;\npadding-right: min(5%, 5rem) !important;\nfont-family: \"Noto Sans CJK JP\" !important; /* <-- new! */\n}\nbody > div > textarea {\nfont-size: 24px !important;\n}\n
"},{"location":"jpresourcesother/#send-text-from-anki-to-your-texthooker","title":"Send text from Anki to your texthooker","text":"Warning
THIS CODE IS DEPRECATED in favor of AJT Autocopy. If you still wish to use a websocket setup to prevent clipboard flooding, I recommend writing an Anki Add-on instead of the code below.
This is a very quick hack to have text from Anki to appear on a websocket based texthooker.
Requires Python, written for Renji's texthooker.
Instructions (click here) -
Save as server.py
:
import asyncio\nimport websockets\nCONNECTIONS = set()\nasync def register(websocket):\nCONNECTIONS.add(websocket)\ntry:\nasync for message in websocket:\nprint(f\"server will now echo '{message}' to all other connections\")\nconnections = [c for c in CONNECTIONS if c != websocket]\nwebsockets.broadcast(connections, message)\nawait websocket.wait_closed()\nfinally:\nCONNECTIONS.remove(websocket)\nasync def main():\nasync with websockets.serve(register, \"localhost\", 6678):\nawait asyncio.Future() # run forever\nif __name__ == \"__main__\":\nasyncio.run(main())\n
-
Paste this on the back side of your Anki template:
<script>\n(() => {\nfunction sendText(id) {\nconst sentEle = document.getElementById(id);\nif (sentEle !== null) {\nconst sentence = sentEle.innerText.trim();\nif (sentence.length > 0) {\nsocket.send(sentence);\n}\n}\n}\nconst url = \"ws://localhost:6678\";\nconst socket = new WebSocket(url);\nsocket.onopen = (_e) => {\nsendText(\"full_sentence\");\nsendText(\"primary_definition_raw_text\");\n};\n})();\n</script>\n
-
Replace full_sentence
and primary_definition_raw_text
with whatever id.
- Install
websockets
with pip, i.e. pip3 install websockets
- Change the web port on the texthooker page to
6678
.
Whenever you want to connect Anki to the texthooker page:
- Run
server.py
, i.e. python3 server.py
- Ensure the web port is the same on the texthooker page, i.e.
6678
- Enable the websocket connection on the texthooker page.
"},{"location":"jpresourcesother/#mikagu-pitch-accent-alternatives","title":"Mikagu pitch accent alternatives","text":" - migaku updated
- Fork of migaku to be updated for anki version 2.1.50+
- anki-jrp
- Completely stand-alone plugin from migaku with a completely different codebase
- Only does one thing: adds pitch accent colors (along with furigana)
"},{"location":"kanjihover/","title":"Kanji Hover (TODO)","text":"Kanji Hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
Note that Kanji Hover does not search for words outside of your deck of \"JP Mining Note\" types. This means if you have notes of any other type, those notes will not be included in the resulting popup.
"},{"location":"kanjihover/#interface","title":"Interface","text":""},{"location":"kanjihover/#interface-new-cards","title":"Interface: New Cards","text":"You may have noticed that some results are greyed out. These represent words from cards that have not been reviewed yet. Conversely, as non-greyed out results come from cards that you have already reviewed, they should represent words that you already know.
(TODO image)
"},{"location":"kanjihover/#interface-pitch-accents","title":"Interface: Pitch Accents","text":"Pitch accents are shown when you hover over a particular word within the tooltip. You can change this to always be shown with RTO:tooltips.displayPitchAccent
.
(TODO image)
"},{"location":"kanjihover/#interface-sentence-search","title":"Interface: Sentence Search","text":"If there are not enough results to display, the kanji is searched within the sentences of existing cards.
(TODO image)
"},{"location":"kanjihover/#interface-open-card","title":"Interface: Open Card","text":"You can click on the word to open the specified card within Anki's card browser.
(TODO image)
"},{"location":"kanjihover/#refresh-button","title":"Refresh Button","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
TODO
- If editing
WordReading
field or some other card shown as the results, the changes will not show due to cache - pressing the refresh button on the info circle + hovering over the kanji again should work
"},{"location":"kanjihover/#related-programs","title":"Related Programs","text":"Warning
None of the above will work with jp-mining-note by default. In fact, it's almost guaranteed that Cade's Kanji Hover will conflict with this note's kanji hover ability, if placed directly in the word reading field.
"},{"location":"kanjihover/#cades-kanji-hover","title":"Cade's Kanji Hover","text":" - Hover over a kanji to see its readings, meanings (english), and other info.
- This does not show example words from other cards.
- My implmentation of kanji hover was heavily inspired by this.
"},{"location":"kanjihover/#hanzi-web-for-anki","title":"Hanzi Web for Anki","text":" - The end result of this is to JPMN's implementation of kanji hover, in the sense that it is used to see kanjis that have been used in other notes. However, it differs primarily in the fact that all the information must be mass-generated. This indeed has several advantages, such as being able to use the infomation on Android, where Anki-Connect isn't full supported.
"},{"location":"kanjihover/#kanjieaters-kanji-connections","title":"KanjiEater's Kanji Connections","text":" - Ability to show kanjis with heisig's RTK keywords, as well as related vocabulary.
- Has stylization options to show maturity and difficulty (number of possible readings) for each individual kanji.
"},{"location":"kanjihover/#kanjikeywordoverlay","title":"KanjiKeywordOverlay","text":" - Shows kanji hover on info, based off of existing cards. Works similarly to KanjiEater's Kanji Connections add-on.
"},{"location":"kanjihover/#anki-wanikani-hints","title":"Anki-WaniKani-Hints","text":" - Shows WaniKani information on kanji hover, which includes stories for radicals and pronunciations.
"},{"location":"kanjihover/#glutanimates-pop-up-dictionary","title":"Glutanimate's Pop-up Dictionary","text":" - An old add-on that searches highlighted text across all cards.
- Requires a download from file
- Also see p1000's version, which should work with jp-mining-note by default
"},{"location":"keybinds/","title":"Keybinds","text":"This note ships with some keybinds to do some common actions.
Keybind What it does P Play sentence audio W Play word audio N Reveals the sentence or word (for reveal cards) 8 Toggles Secondary Definition
field 9 Toggles Additional Notes
field 0 Toggles Extra Definitions
field [ Toggles Extra Info
field . Reveals and hides the hint TODO wtf is keybinds.toggleFrontFullSentenceDisplay
See the runtime options if you would like to edit / disable any keybind, and/or to view the full list of keybinds.
"},{"location":"modding/","title":"Modding Overview","text":""},{"location":"modding/#modding-the-obvious-way","title":"Modding (The Obvious Way)","text":"Throughout the documentation and within the templates alone, you will likely see warning messages to not edit the templates directly unless you are willing to lose your changes when you update the note.
The most obvious way to mod the note is directly in the pre-built template downloaded. If you are completely fine with losing your changes upon each update, and don't want to take advantages of certain tools that comes with this note (such as compile options), then you can simply edit the template and ignore the rest of this page.
"},{"location":"modding/#modding-the-recommended-way","title":"Modding (The Recommended Way)","text":"To ensure that your changes aren't lost, the recommended way to make changes to the existing templates is to add new files, rather than editing existing ones. This allows you to continuously update with the note, while having your custom files stay in place.
Warning
There is no guaranteed backwards compatability for anything mentioned here (especially while the note is still in beta). Although you won't lose your changes upon update, your changes might also not work on the next update. For example, if the file that you are overriding gets renamed, you will have to rename the file to match the newly renamed file.
I will try my best to keep things backwards compatable, but given the current state of the note (particularily the CSS), it might not be possible to do most of the time. When this note comes out of beta, backward-incompatable changes should be harshly reduced.
"},{"location":"modding/#prerequisites","title":"Prerequisites","text":"You must be able to successfully build the template in order to start modding the note.
Click here to see how to build the template!
"},{"location":"moddingtips/","title":"Tips & Tricks (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"moddingtips/#ankiwebview-inspector","title":"AnkiWebView Inspector","text":"TODO non-point-form
- addon: https://ankiweb.net/shared/info/31746032
- note has built-in support with this due to providing all the typescript
.map
files - one can view source typescript code and debug with breakpoints all in Anki
"},{"location":"moddingtips/#custom-runtime-options","title":"Custom Runtime Options","text":"The runtime options file (default: config/jpmn_opts.jsonc
) can be specified at build time.
If you are working with modding the note, it is recommended that you create your own runtime options file, so you can edit the options at build time, while ensuring your runtime options file is up to date.
Here is how you can create and use a custom runtime options file:
-
Create the local runtime options file (e.g. user_jpmn_opts.jsonc
)
cd config\ncp jpmn_opts.jsonc user_jpmn_opts.jsonc\n
-
Change opts-path
under config/config.py
:
\"opts-path\": \"user_jpmn_opts.jsonc\",\n
-
(optional) Make the runtime options hard-coded to remove the file dependency during runtime, by changing the following setting in config/config.py
:
\"compile-options\": {\n \"hardcoded-runtime-options\": True,\n}\n
-
Build and install the note as normal.
Note
If you are not using hard-coded runtime options and you have edited the contents of the local runtime options file, please run the installation script with --install-options
to replace the existing options file in Anki's media folder.
"},{"location":"moddingtips/#field-list-editing","title":"Field List Editing","text":"This section describes import PSAs on what you should you if you want to edit the fields of the note (i.e. adding, removing, renaming, and moving).
Fields editing in this context refers to the fields that you can edit in the Fields
(list) menu, found under (Main window) \u2192 Browse
\u2192 Fields...
.
Note
If you never plan on updating the note, you can safely modify the field list to your heart's content, and ignore the rest of this section.
"},{"location":"moddingtips/#installer-details","title":"Installer details","text":"The installer, when detecting a higher version, attempts to find and apply any changes to the field list when necessary. These changes are specified under tools/note_changes.py
.
By default, the installer expects the field list to be completely un-changed after installation, and does many checks to verify this before and after installation.
"},{"location":"moddingtips/#do-not-remove-fields","title":"Do not remove fields","text":"One of the checks that the installer does is to ensure that all fields are present. This is a design choice to remove as many assumptions as possible, so that it is easier for the installer to update the note.
Note
This design choice may be changed in the future, but will likely remain until the end of the beta release.
If you want to remove a field, the best alternative is to do the following:
- Move the field below the
Comment
field, so the field is out of your way. - Whenever you decide to update the note to a new version, run the installation script with the
--ignore-order
flag.
"},{"location":"moddingtips/#do-not-rename-fields","title":"Do not rename fields","text":"There is currently no way to let the installer know that you renamed a field. Therefore, you should not rename fields at all, as this will cause the initial field list check to fail.
If you are completely insistent on renaming a field, you must change all templates that uses the field to match your preferred field name.
Note
Similarily to the above, this may be changed in the future, but will likely remain until the end of the beta release.
"},{"location":"moddingtips/#how-to-add-reorder-fields","title":"How to add & reorder fields","text":"If you want to add a field while preserving the existing field order upon updates, add the field under the Comment
field. This is because the installer only checks the subset of fields above the Comment
field, when verifying correctness.
If you don't care about preserving field order, you can simply add the field anywhere you want, and then run the installation script with --ignore-order
whenever you want to update the note to a new version.
"},{"location":"moddingtips/#javascript-print-statements","title":"Javascript print statements","text":"Anki doesn't come with a way to use console.log()
normally, so I made one myself.
// global logger\nLOGGER.error(\"message\");\nLOGGER.warn(\"message\");\nLOGGER.info(\"message\");\nLOGGER.debug(\"message\");\n// module-specific logger\nconst logger = JPMNLogger(\"module-name\");\nlogger.error(\"message\");\nlogger.warn(\"message\");\nlogger.info(\"message\");\nlogger.debug(\"message\");\n
The above functions prints a message of the given log level to the info circle. To see the message, hover over the info circle.
To use the debug
function, make sure that the debug
option is set to true
in the javascript options.
"},{"location":"moddingtips/#avoid-asynchronous-javascript-features-in-anki","title":"Avoid asynchronous javascript features in Anki","text":"Example Asynchronous Javascript <script>\n// Example 1: normal asynchronous functions\nasync function runMeAsynchronously() {\n// ...\n}\n// Example 2: promises\nfunction giveMeAPromise() {\nreturn new Promise((resolve, reject) => {\nsetTimeout(() => {\nresolve(\"Success!\");\n}, 1000);\n});\n}\ngiveMeAPromise().then(() => {\nLOGGER.warn(\"The promise is complete!\", unique=false);\n});\n</script>\n<!-- Example 3: anything wrapped in type=\"module\" -->\n<script type=\"module\">\n// everything here is run asynchronously\n// ...\n</script>\n
TODO reason:
- functions can be executed multiple times
- reproducible way: use example 2 on both the front/back side of the card, and switch sides quickly
- should be two warnings
- but worst case is for cases which I don't know how to reproduce
- rarely, asynchronous functions run more than once
- it seems like anki randomly loads the page twice, causing all asynchronous functions to also run twice
- including the async functions defined currently in modules like
kanji-hover
- to cirumvent having their actions done twice, define the affected elements outside the asynchronous section
- the function still runs twice (so any side-effects of the function will still happen)
- however, other instances of the function should not work on the elements defined outside
-
additionally, many modules require things to be loaded before the card is shown
- Anki displays the page only when all of the synchronous javascript is ran
- If these become asynchronous, the user will be able to see split-second changes to the layout as the javascript is running
- Two solutions to this:
- (1) To only show the page when specific asynchronous functions are complete, the entire page must be hidden, with say, a
hidden
class on the <body>
element - Problem: if the main javascript fails, then you will get a blank page!
- making this approach very risky
- (2) Avoid asynchronous functions alltogether
-
avoiding asynchronous features makes things more predictable within anki
Example (safer) asynchronous javascript let ele = document.getElementById(\"example\");\nasync function runMeAsynchronously() {\n// ...\nele.innerText += \"this should only appear once!\";\n}\n
"},{"location":"modules/","title":"Custom JS (Modules) (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"modules/#overview","title":"Overview","text":"Modules (not to be confused with regular javascript modules) is a hybrid template/javascript system that allows code separation at the file level, but allows the javascript to be compiled into each template, rather than separate files.
The biggest advantage of this over a monolithic system is that individual modules can be enabled, disabled, created, and modified at ease, all without editing the source files.
"},{"location":"modules/#example-hello-world","title":"Example (Hello World)","text":"The following will enable a the hello world module, which prints a \"Hello world!\" at the front of any card (as a warning on the info circle).
-
Under config/config.py
, add \"example\"
to enabled-modules
.
\"compile-options\": {\n \"allow-user-defined-modules\": True,\n\n \"enabled-modules\": [\n ...\n \"customize-open-fields\", # Make sure a comma is here!\n \"example\"\n ]\n},\n
-
Under config/jpmn_opts.jsonc
(or more preferably, your own options file specified under opts-path
in config.py
), add the following:
\"modules\": {\n \"customize-open-fields\": {\n ...\n }, // Make sure there is a comma here!\n\n \"example\": {\n \"enabled\": true\n }\n}\n
-
Rebuild the note, and preview any card. The front side of any card should have a \"Hello world!\" warning, while the back side should remain normal.
"},{"location":"modules/#quickstart","title":"Quickstart","text":"If you want to get to inserting your own javascript as soon as possible, do the following:
- Follow the steps of the example above, and make sure the example module is working.
-
Copy the example
module into overrides/modules
.
This should result in the following file structure:
overrides\n L modules\n L example\n L main.html\n L main.js\n
From here, all you have to do is edit the main.js
and main.html
to your liking.
Note
The js
module is of type JavascriptContainer
, which is defined under tools/make.py
. This interface allows you to define javascript within certain parts of a card, and restrict it to a certain subset of templates (sides and card types). Please see the aformentioned file to view the existing interface. Likewise, see the base javascript file (src/jp-mining-note/base.js
) to view how the interface is used.
If you want more detailed explanations on what has been happening up until this point, continue reading below.
"},{"location":"modules/#enabling-disabling-modules","title":"Enabling & Disabling Modules","text":"Modules can be easily enabled and disabled by modifying the enabled-modules
option under config/config.py
. Comment out any existing module, or add any modules you want to the list.
Additionally, if you are using modules outside the default modules that come enabled with the note (including the example
module), the allow-user-defined-modules
option should be set to True
.
"},{"location":"modules/#modding-existing-modules","title":"Modding Existing Modules","text":"Modules can be defined in the same style as the template overrides above. This means that if you want to edit a module, you can simply override the module files themselves by copying the module folder into overrides/modules
folder.
For example, if you want to override the auto-pitch-accent
module, copy the auto-pitch-accent
folder into overrides/module/auto-pitch-accent
.
Note
In the quickstart, we did exactly this with the example
module. Since the example module is completely overwritten by the user, the previous example module code is completely ignored.
"},{"location":"modules/#creating-more-modules","title":"Creating More Modules","text":"The easiest way to create a new module is by copying the example
folder, and renaming it to something different. This folder should be placed under overrides/modules
under most cases. However, if you are looking to contribute to the project, place this under src/modules
instead.
Certain parts of the code should be renamed as well to avoid conflicts with the existing example
module, including the MOD.id
, import path, JPMNLogger
constructor, and runtime option call (utils.opt
).
Of course, make sure all the renames are consistent. For example, all of the following should be the same:
MOD.id
- module folder name
JPMNLogger
constructor argument
Afterwards, make sure to add the module id to enabled-modules
, and ensure that allow-user-defined-modules
is set to True
.
If everything is done correctly, the note should include your custom module after the next build!
"},{"location":"modules/#why-not-just-separate-the-code-with-files","title":"Why not just separate the code with files?","text":"Short answer: In an attempt to keep the card as stable as possible between versions.
Long answer: Anki specifically states this in its official documentation:
Quote
Javascript functionality is provided without any support or warranty.
Many javascript-related things seem to behave strangely in Anki, which prevents the ability to separate files easily. Here have been the solutions I have tried before moving to this approach:
Link an external script with the <script>
tag There are two main problems with this approach:
-
On older Anki versions (2.1.49 and below), all <script>
tags loads asynchronously compared to each other.
This means if any file must be ran before a file is loaded, then the script would fail.
On versions 2.1.50 and above, it appears that Anki loads <script>
tags synchronously. However, there is no guarantee that this will be the case for the future.
-
Certain javascript in the main template has to be ran before loading in any file.
This requirement exists for this note type due to the runtime-options file exists. The global JPMNOpts
has to exist for any external files that uses runtime options to work.
This can be fixed by importing the options separately for each file, but that naturally leads us to the examples shown in the following section.
Regular imports within Javascript All other examples of importing without a separate <script src=\"...\">
requires asynchronous javascript features, which should be avoided as much as possible.
Examples:
<script>\n// https://forums.ankiweb.net/t/linking-to-external-javascript/1713\nvar injectScript = (src) => {\nreturn new Promise((resolve, reject) => { // a Promise is an asynchronous feature!\nconst script = document.createElement('script');\nscript.src = src;\nscript.async = true;\nscript.onload = resolve;\nscript.onerror = reject;\ndocument.head.appendChild(script);\n});\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import\n// this import function is an asynchronous function!\n(async () => {\nawait import(\"/modules/my-module.js\");\n// ...\n})();\n</script>\n<!-- type=\"module\" forces this entire script to run asynchronously! -->\n<script type=\"module\">\n// for the `import` statement to work, the script must be of type=\"module\"\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import\nimport { export1 } from \"module-name\";\n</script>\n
In conclusion, this is a design decision made after lots of trial and error when attempting to work with Anki's Javascript parser.
I believe this is the best way to ensure that the note stays resilient across Anki updates, as the javascript itself has very few hacks to get it to behave well.
"},{"location":"other/","title":"Other (TODO)","text":""},{"location":"other/#design-decisions","title":"Design Decisions","text":""},{"location":"other/#pc-template-design-decisions","title":"PC Template Design Decisions","text":" - everything should be available to the user even for words with very long definitions
- the definitions are below everything specifically due to that
- potential issue: people who speed through cards
- potential solution: use theme
- front side has no guarantee to be consistent
- thus, for vocab cards, the word is repeated again below the line
- similarly, for sentence cards, the sentence is repeated again
- also see: cardtypes.md
- word and pitch accent are on separate lines
- because both can expand very far to the left/right
- minimize vertical space taken from word info / image
- if certain elements are removed, can result in an uneven shape
- however, this is preferable over an even shape because it minimizes vertical space
- TODO option to have a consistent shape?
"},{"location":"other/#mobile-template-design-decisions","title":"Mobile Template Design Decisions","text":" -
make definition show up ASAP, i.e. by the first quarter of the screen
-
this means elements that were previously above the definition on the PC version, like the audio buttons, image, and sentence, is now below the definition
-
unfortunately, putting the sentence above the definition can easily take up a lot of room
- the limited space for mobile users makes placing the definition above the sentence actually more important, otherwise the sentence can easily push down the bulk of the definition (and thus you must scroll to see the definition)
- comes at the cost of potentially not being able to see the sentence without scrolling
-
the image is small by design
- otherwise, will take up too much room or will require scrolling to see
- goal is to always be able to immediately see the image on card flip
-
replace collapsible sections with tabs for easier mobile navigation, and to prevent unnecessary scrolling
"},{"location":"other/#comment-field","title":"Comment
field","text":"Similarly to the Key
field, this field will not be used in any card template. In other words, this is a place where you can write down notes without affecting the card itself. I personally like using this field to test handlebars from Yomichan.
This is named Comment
in reference to comments in code (comments do not change the execution of the code).
"},{"location":"other/#remove-the-na-on-cards-with-no-pitch-accents","title":"Remove the \"(N/A)\" on cards with no pitch accents","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
If the word has no pitch accent, the pitch accent is usually displayed as (N/A)
. This indicator can be removed with the following CSS:
.dh-left__word-pitch-text:empty:before {\ncontent: \"\"\n}\n
"},{"location":"other/#removing-the-furigana-on-the-word-reading","title":"Removing the furigana on the word reading","text":"TODO image
The following CSS removes the furigana on the word reading, while keeping the furigana on the kanjis within hover.
.dh-left__reading > ruby > rt {\ndisplay: none;\n}\n
"},{"location":"other/#changing-colors","title":"Changing colors","text":"Most color changes can be done by simply overriding a CSS variable. These variables are shown at the very top of the main CSS sheet. For example, --accent
is the variable that specifies the main accent color of the card, as well as the color of the text when bolded. To override this variable, place this at the end of the styles sheet:
:root {\n--accent: #ff1fd1; /* hot pink */\n}\n.night_mode {\n--accent: #ff7777; /* light red */\n}\n
Warning
To change any variable color for dark mode, you cannot use :root
, even if you are only setting the color for night mode. You must use .night_mode
.
For example, doing the following will NOT change the accent for night mode:
:root {\n/* only changes light mode accent, and will NOT change dark mode accent! */\n--accent: #ff7777;\n}\n
You must do this instead:
/* changes the color for both light and dark mode */\n:root {\n--accent: #ff7777;\n}\n.night_mode {\n--accent: #ff7777;\n}\n
"},{"location":"other/#removing-the-word-sentence-at-the-top-of-the-back-side","title":"Removing the word / sentence at the top of the back side","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Hidden tested contentShown tested content (default) TODO image
TODO image
For users who are only using one card type (e.g. only vocab cards with no sentence cards, TSCs, or anything else), it might be better to remove the tested content and the line below it.
The tested content is shown at the back by default to allow the user to differentiate between card types on both sides of the card. However, this take up extra vertical space which is unnecessary if you are only using one card type. This can be hidden with the following CSS:
.jpmn--back > .card-main .expression-wrapper {\ndisplay: none;\n}\n.jpmn--back > .card-main .answer-border {\ndisplay: none;\n}\n
"},{"location":"other/#mobile-unbolded-text","title":"Mobile Unbolded Text","text":"By default, most text that would be bolded on desktop is unbolded in mobile. This is because the bolded text makes the kanji feel much more squished together, especially on Android where the custom bold font cannot be used. Additionally, the bolded text is still highlighted in the accent color of the note, so the text still stands out compared to other text.
If you want to bold the text again, use the following CSS:
(TODO link to extra/style.scss and all)
@media (max-width: 620px) {\n :root {\n --bold-font-weight: bold;\n }\n}\n
"},{"location":"overrides/","title":"Custom HTML (Overrides) (TODO)","text":"Warning
This entire section will be completely overhauled in version 0.12.0.0, meaning that this information will be completely changed when that version releases. See the dev
branch on Github if you want to see the work in progress.
"},{"location":"overrides/#overview","title":"Overview","text":"An easy way to override and extend parts of the card templates is by using an overrides
folder. This folder (specified under config.py
under the templates-override-folder
option) allows you to override any file under the src
folder (outside of scss
files).
Primarily, this allows you to override sections of template code found under src/jp-mining-note
, such as src/jp-mining-note/partials/hint.html
.
The structure of the overrides
folder must match the structure in the src
folder. For example, if you want to override the hint file (src/jp-mining-note/partials/hint.html
), the new file must be created under overrides/jp-mining-note/partials/hint.html
"},{"location":"overrides/#example-add-external-links","title":"Example (Add external links)","text":"Warning
The following is deprecated starting from Version 0.10.3.0. Version 0.10.3.0 allows the user to customize external links in the compile options (config.py
).
This is only here to serve as a placeholder example (while I try to think of other practical examples people would use). Let me know if you have any ideas!
Let's say we want to rewrite the Extra Info
section to have external links that search for the tested word.
-
Look for the partial within the src
folder. This leads us to the src/jp-mining-note/partials/extra_info.html
file.
-
Override the partial. Now that we know the location of the partial, we create the same file in overrides
. This new file should be of the path overrides/jp-mining-note/partials/extra_info.html
.
-
Write the code. Using the partial under src
as an example, the following code is a modified version of the original HTML where we removed the dependency on the PAGraphs
and UtilityDictionaries
fields. Additionally, at the very bottom, a link to Jisho and Yourei is provided.
Copy and paste the code below to your newly created file (overrides/jp-mining-note/partials/extra_info.html
).
Extra Info with External Links <details class=\"glossary-details glossary-details--small\" id=\"extra_info_details\">\n<summary>Extra Info</summary>\n<blockquote class=\"glossary-blockquote glossary-blockquote--small highlight-bold\">\n<div class=\"glossary-text glossary-text--extra-info\">\n{% call IF(\"PAGraphs\") %}\n<div class=\"pa-graphs\">\n{{ T(\"PAGraphs\") }}\n</div>\n{% endcall %}\n{% call IF(\"UtilityDictionaries\") %}\n<div class=\"utility-dicts\">\n{{ T(\"UtilityDictionaries\") }}\n</div>\n{% endcall %}\n<a href=\"https://jisho.org/search/{{ T('Word') }}\">\u8f9e\u66f8</a\n>\u30fb<a href=\"http://yourei.jp/{{ T('Word') }}\">\u7528\u4f8b</a>\n</div>\n</blockquote>\n</details>\n
-
Rebuild and reinstall the template. After rebuilding and reinstalling, your Extra Info
section should now have two links at the bottom.
"},{"location":"personalsetup/","title":"Personalsetup","text":"Welcome to my (hidden) personal setup page! This section is very likely outdated and is not very easy to go through.
If you want to use this note type, I recommend looking at other pages of the wiki.
"},{"location":"personalsetup/#texthooker-css-renji","title":"Texthooker CSS (Renji)","text":"main > p {\n padding: 0rem !important;\n}\n\nmain {\n padding-left: min(5%, 5rem) !important;\n padding-right: min(5%, 5rem) !important;\n font-family: \"Noto Sans CJK JP\" !important;\n}\n
"},{"location":"personalsetup/#anki","title":"Anki","text":"plugins:
1344485230 1225470483 2055492159 580654285
- ajt furigana / ajt pitch accent / ankiconnect / local forvo
- config under normal setup page
- custom audio sources:
http://localhost:8770/?expression={expression}&reading={reading}
- local audio plugin w/ sqlite
- get audio zips from existing computer / backup
.\n\u251c\u2500\u2500 jpod_alternate_files\n\u2502 \u2514\u2500\u2500 \u3088\u3080 - \u8aad\u3080.mp3\n\u2502 \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 jpod_files\n\u2502 \u2514\u2500\u2500 \u3088\u3080 - \u8aad\u3080.mp3\n\u2502 \u2514\u2500\u2500 ...\n\u2514\u2500\u2500 nhk16_files\n \u251c\u2500\u2500 audio\n \u2502 \u2514\u2500\u2500 20170616125910.aac\n \u2502 \u2514\u2500\u2500 ...\n \u2514\u2500\u2500 entries.json\n
- forvo plugin
"},{"location":"personalsetup/#yomichan","title":"Yomichan","text":" - import settings from an existing computer / backup drive
- TMW dicts
- Yomichan settings \u2192 \"Popup Appearance\":
- \"Compact glossaries\": on
- \"Compact tags\": off,
monolingual:
- hold shift: bilingual (at any level)
- mouseover: monolingual
monolingual shift:
- hold shift:
- access monolingual at first level
- bilingual at all other levels
- mouseover to access monolingual at other levels
bilingual:
- mouseover: bilingual
pa:
- hold shift: pitch accent and utilities
{{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n{{~#set \"ignored-dict-regex\"~}} ^(\u65b0\u548c\u82f1)$ {{~/set~}}\n{{~set \"opt-jmdict-list-format\" false ~}} {{~! still using regular jmdict ~}}\n
"},{"location":"personalsetup/#monolingual-profile","title":"monolingual profile","text":" - scale: 110%
- condition: modifier keys are shift
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\nli.definition-item[data-dictionary='NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)']:hover .gloss-list {\nopacity: 1;\n}\n
"},{"location":"personalsetup/#other-monolingual-profiles","title":"other monolingual profiles","text":"URL - Matches Domain - doc.rust-jp.rs\n - tag: rust\n - scale: 90%\n
"},{"location":"personalsetup/#bilingual-profile","title":"bilingual profile","text":" - scale: 100%
- NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178 and \u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003 should have lower priority compared to bilingual dicts
- condition: modifier keys are ctrl
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\nli.definition-item[data-dictionary='\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6f22\u5b57\u6e90'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b9f\u7528\u65e5\u672c\u8a9e\u8868\u73fe\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b66\u7814 \u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u4e09\u7701\u5802\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u4fd7\u8a9e\u8f9e\u66f8'] {\ndisplay: none;\n}\n
"},{"location":"personalsetup/#pa-and-grammar-profile","title":"PA and grammar profile","text":" - scale: 100%
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\nli.definition-item[data-dictionary='\u65fa\u6587\u793e\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u5341\u4e00\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u660e\u93e1\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e8c\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u65b0\u8f9e\u6797'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178 \u7b2c\u4e94\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u30c7\u30b8\u30bf\u30eb\u5927\u8f9e\u6cc9'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6f22\u5b57\u6e90'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b9f\u7528\u65e5\u672c\u8a9e\u8868\u73fe\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5b66\u7814 \u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56db\u5b57\u719f\u8a9e\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u4e09\u7701\u5802\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u4e03\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='surasura \u64ec\u58f0\u8a9e'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u5927\u8f9e\u6797 \u7b2c\u4e09\u7248'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u4fd7\u8a9e\u8f9e\u66f8'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='\u65b0\u548c\u82f1'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='Nico/Pixiv'] {\ndisplay: none;\n}\n
"},{"location":"personalsetup/#phone-profile","title":"Phone profile","text":" - \u65b0\u548c\u82f1 is not installed on the phone
/*\n * ========\n * global\n * ========\n */\nbutton[title^=\"Add reading\"] {\ndisplay:none;\n}\n[data-sc-ortho=\"table\"] td {\ntext-align: center;\n}\n.headword-term ruby rt {\nuser-select: none\n}\n/* Taken from: https://github.com/MarvNC/yomichan-dictionaries/#yomichan-css-for-kanji-dictionaries */\n/* remove misc dict classifications/codepoints/stats */\n.kanji-glyph-data {\nwidth: 100%\n}\n.kanji-glyph-data > tbody > tr:nth-child(n + 3) {\ndisplay: none;\n}\n/* remove stroke diagram, freq, header for next entries */\ndiv.entry[data-type='kanji']:nth-child(n + 2) .kanji-glyph-container,\ndiv.entry[data-type='kanji']:nth-child(n + 2) [data-section-type='frequencies'],\ndiv.entry[data-type='kanji']:nth-child(n + 2) table.kanji-glyph-data > tbody > tr:first-child {\ndisplay: none;\n}\n/* remove 'No data found' */\n.kanji-info-table-item-value-empty {\ndisplay: none;\n}\n/* remove horizontal lines */\n.entry + .entry[data-type='kanji'],\ndiv#dictionary-entries > div.entry:nth-child(n + 2) .kanji-glyph-data > tbody > tr > * {\nborder-top: none !important;\n}\n/* Only shows the first 4 frequency lists */\nspan.frequency-group-item:nth-child(n+5) {\ndisplay: none;\n}\n/*\n * ============\n * global end\n * ============\n */\n/* only shows the first 2 pitch dictionaries */\nli.pronunciation-group:nth-child(n+3) {\ndisplay: none;\n}\n/* makes \u5927\u8f9e\u6cc9 and NHK have white text, and all other pitch dictionaries have grey text */\n.tag[data-category=\"pronunciation-dictionary\"] {\n--tag-text-color: #c8bfdb;\n}\n.tag[data-details=\"\u5927\u8f9e\u6cc9\"], .tag[data-details=\"NHK\"] {\n--tag-text-color: #FFFFFF;\n}\n/* Only shows the first freq list */\nspan.frequency-group-item:nth-child(n+2) {\ndisplay: none;\n}\nli.definition-item[data-dictionary='NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178'] {\ndisplay: none;\n}\nli.definition-item[data-dictionary='JMdict (English)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='JMdict (English)']:hover .gloss-list {\nopacity: 1;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)'] .gloss-list {\nopacity: 0;\n}\nli.definition-item[data-dictionary='\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178(\u5168\u96c6)']:hover .gloss-list {\nopacity: 1;\n}\n
"},{"location":"personalsetup/#yomichan-fields","title":"Yomichan Fields","text":"Example Anki Fields Yomichan Format Key {expression} Word {expression} WordReading {furigana-plain} PAOverride PAOverrideText AJTWordPitch PrimaryDefinition {jpmn-primary-definition} PrimaryDefinitionPicture Sentence {cloze-prefix}{cloze-body}{cloze-suffix} SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden IsSentenceCard {jpmn-is-sentence-card} IsTargetedSentenceCard IsClickCard {jpmn-is-click-card} IsHoverCard IsHintCard {jpmn-is-hint-card} IsSentenceFirstCard IsAudioCard PAShowInfo 1 PATestOnlyWord 1 PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture WordAudio {audio} SentenceAudio PAGraphs {jpmn-pitch-accent-graphs} PAPositions {jpmn-pitch-accent-positions} FrequenciesStylized {jpmn-frequencies} FrequencySort {jpmn-frequency-sort} PASilence [sound:_silence.wav] WordReadingHiragana {jpmn-word-reading-hiragana} YomichanWordTags {tags} SecondaryDefinition {jpmn-secondary-definition} ExtraDefinitions {jpmn-extra-definitions} UtilityDictionaries {jpmn-utility-dictionaries} CardCache Comment DICTIONARY:\u300c{_jpmn-get-primary-definition-dict}\u300dSELECTION:\u300c{_jpmn-selection-text}\u300d"},{"location":"personalsetup/#discord","title":"Discord","text":""},{"location":"personalsetup/#custom-css","title":"Custom CSS","text":":lang(ja), :lang(ja-JP) {\n--font-primary: Whitney, \"Noto Sans CJK JP\", \"Hiragino Sans\", \"\u30d2\u30e9\u30ae\u30ce\u89d2\u30b4 ProN W3\",\"Hiragino Kaku Gothic ProN\",\"\u30e1\u30a4\u30ea\u30aa\",Meiryo,Osaka,\"MS PGothic\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n}\ncode {\nfont-family: Ubuntu Mono, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, Consolas,Andale Mono WT,Andale Mono,Lucida Console,Lucida Sans Typewriter,DejaVu Sans Mono,Bitstream Vera Sans Mono,Liberation Mono,Nimbus Mono L,Monaco,Courier New,Courier,monospace !important;\n}\n
"},{"location":"personalsetup/#mobile-changes","title":"Mobile Changes","text":" - the following are notes of what to change for mobile support
- nothing is set in stone, etc. etc. things are likely not even implemented yet
"},{"location":"personalsetup/#other","title":"Other","text":" - TMW github source since I keep losing this link
"},{"location":"preface/","title":"Preface","text":"Before committing and going through the setup process, it would be best to make sure that the note aligns with exactly what you want.
"},{"location":"preface/#why-you-would-not-want-to-use-jp-mining-note","title":"Why you would NOT want to use jp-mining-note","text":" - You have an existing setup and are happy with it.
- You want to study only from pre-made decks (or are not willing to spend the time to import notes into this template).
- You want to use this template to study something outside of Japanese.
- You want an extremely minimal template, with little/no javascript.
- You do not like its overall layout, and are not willing to customize the note to suit your needs.1
- You are not comfortable with bearing a slightly higher maintenance cost than most other setups.2
"},{"location":"preface/#why-you-would-want-to-use-jp-mining-note","title":"Why you would want to use jp-mining-note","text":" - You agree with jp-mining-note's philosophy.
"},{"location":"preface/#alternatives","title":"Alternatives","text":"There are many, many Anki templates out there in the wild. This page is my attempt to assemble together some of the the popular and/or interesting card templates.
If you are not satisfied with this template, or are not interested in using this template, feel free to refer to the above list of alternatives. Of course, you can always create one from scratch, or modify any of these notes to your heart's content.
"},{"location":"preface/#supported-systems","title":"Supported Systems","text":"The most important step is to see if jp-mining-note (JPMN) works on your device.
"},{"location":"preface/#card-creation-yomichan","title":"Card Creation (Yomichan)","text":"The card creation process requires a working instance of Yomichan, Anki-Connect, and Anki.
By default, this works on PC (Windows, Mac, Linux), and the instructions shown will be for PC. However, with the proper setup, one can also create cards on the following platforms:
- Android (including Android based e-readers such as ONYX BOOX)
- Kindle (export a list of sentences to the PC to manually create)
I'm not aware of a workflow for iOS that works with Yomichan.
Note
JPMN currently requires Yomichan to create the Anki cards. As common as Yomichan is, this dependency to Yomichan can be considered a weakness (especially now that Yomichan is no longer getting updates).
There are many popular setups out there that do not use Yomichan and instead have their own card exporter, such as JL and jidoujisho.
It is almost guaranteed that one can create JPMN cards with these card exporters. However, it is also almost guaranteed that various minor features will likely be missing.
In the future, more workarounds will be developed to work with alternative card exporters.
"},{"location":"preface/#anki-desktop","title":"Anki Desktop","text":"This note supports Anki versions 2.1.50 and above, with primary support given to the latest stable Anki versions (23.10.1+ & Qt6).
It is important to note that this note is no longer supported for Anki versions 2.1.49 or older. There are certain features that are known to break on these versions.
"},{"location":"preface/#mobile-ankidroid-and-ankimobile","title":"Mobile (AnkiDroid and AnkiMobile)","text":"JPMN finally supports AnkiDroid and AnkiMobile, and comes with a new interface specifically designed for mobile devices.
However, there are some limitations on mobile. Mainly, anything requiring Anki-Connect within the note (kanji hover and word indicators) will not work. The current workaround is to cache the tooltip results.
"},{"location":"preface/#ankiweb","title":"AnkiWeb","text":"JPMN is not tested on AnkiWeb, and there are currently no plans to support AnkiWeb.
"},{"location":"preface/#themes","title":"Themes","text":"Both light mode and dark mode are supported. The note's theme changes accordingly with your Anki theme.
"},{"location":"preface/#updating","title":"Updating","text":"If you ever wish to update the note, this can only be done on PC, and cannot be done on mobile. The note does not auto-update; it must be done manually.
"},{"location":"preface/#setup","title":"Setup","text":"Excited to take this note on a whirl?
Click here to set it up!
-
Most minor things, such as colors, font size, etc. can be customized fairly easily with custom CSS. However, customizing the overall layout (i.e. customizing where the image is placed relative to the word), requires a lot more technical skill. Alternatively, if plan on using a custom theme within the themes
folder, these require you to build the note, which at least requires basic knowlwedge of command line.\u00a0\u21a9
-
In general, this template is a little more fragile than other templates due to its heavy usage of JavaScript. This is combined with updates to Anki and external add-ons. These updates have been known to break a bit more compared to other setups, and usually require some user intervention to deal with (whether it is updating the note, or manually changing some settings outside the note). If something breaks and a fix is released, they will usually be recorded under Setup Changes.
Note that updating the template itself has been smoothlined as much as possible, due to JPMN Manager.\u00a0\u21a9
"},{"location":"principles/","title":"Philosophy","text":""},{"location":"principles/#made-for-japanese-learning","title":"Made for Japanese Learning","text":"The absolute fundamental goal of this note type is to make learning Japanese easier. Every feature you see is to simply make this learning process easier and smoother.
"},{"location":"principles/#minimalistic-design","title":"Minimalistic Design","text":"This note is visually designed to be minimalistic because the fundamental goal is to learn Japanese, not to have eye catching graphics. The main focus is on the content, not the fluff.
"},{"location":"principles/#minimal-dependencies","title":"Minimal Dependencies","text":"The only fundamental dependencies are Yomichan
(to create the note) and the Anki-Connect
add-on (to export the note from Yomichan
, update the note, and for certain features to work within the note). Absolutely nothing else is required. This helps with maintaining stability across various Anki versions.
"},{"location":"principles/#modularized-customizable-extendable","title":"Modularized, Customizable & Extendable","text":"This project ships with built-in tools to easily disable/enable features, or even completely remove them from the base template via compile options. Additionally, there are many built-in ways to extend the note to suit your exact needs.
"},{"location":"principles/#documentation-first","title":"Documentation First","text":"What's the point of having a powerful tool if you don't know how to use it? Lots of time has been spent in order to make sure that this note type is well documented and updated so you can use it to the best of your ability.
"},{"location":"principles/#free-open-source","title":"Free & Open Source","text":"Everything here, including the documentation itself, is completely free and open source, licensed under MIT. Rest easy knowing you will keep full ownership of your note, forever.
"},{"location":"quickstart/","title":"Quick Start (TODO)","text":"Welcome to jp-mining-note's quick start page! This page summarizes the main features that jp-mining-note has to offer, as well as common changes that people may want to make with the note.
"},{"location":"quickstart/#ui-summary","title":"UI Summary","text":""},{"location":"quickstart/#ui-summary-front","title":"UI Summary: Front","text":"(TODO image front)
The front side of the card was designed to be as minimal as possible. Information such as tags, source, frequency, reading, audio, etc. are not shown here, by design.
Tested contentCard typeInfo Circle This can be a sentence, word, etc. depending on the card type.
This simply describes exactly what the card type is.
Hovering over the info circle displays a tooltip that contains general infomation about the note type. When the info circle is not grey, this acts as a notifications window to the user. (TODO link)
You may notice some buttons to the top left. These are explained here TODO.
"},{"location":"quickstart/#ui-summary-back","title":"UI Summary: Back","text":"(TODO image back)
Compared to the front side of the card, the back side was designed to contain as much as information as possible. However, only the important information is shown by default, while all the auxilary information is hidden behind various tooltips and dropdowns.
Tested contentFrequencyWord boxMain imagePrimary DefinitionBlockquotes The tested content is repeated on the back side of the card, and is separated by a line.
Contains the value in the FrequencySort
field. Hovering over the dropdown to the right should show all other frequencies, found in the FrequenciesStylized
field.
Contains the word, its reading, its pitch accent, and the word/sentence audio, in that order.
This is where the image from the Picture
field appears. If there is no picture, then the word box takes up the entire space.
This is where the text in PrimaryDefinition
, and optionally, the picture(s) in PrimaryDefinitionPicture
appears.
In general, this contains all the other information and dictionaries from Yomichan. See here for more info.
"},{"location":"quickstart/#ui-summary-mobile","title":"UI Summary: Mobile","text":"(TODO image, mark w/ numbers)
The interface for mobile should be mostly the same as the desktop. However, there are a few important differences to note:
- Collapsing sections, are replaced with tabs.
- The sentence appears below the definition instead of above.
- The audio buttons appear at the bottom left of the card, instead of right below the pitch accent.
See here TODO to see the reasons why these design decisions were made.
"},{"location":"quickstart/#changing-the-card-type","title":"Changing the Card Type","text":"Main Page: Changing Card Type
For the purposes of this documentation, the \"card type\" of a card refers to how the content is displayed and tested. For example, vocab cards and sentence cards are two different \"card types\".
In order to change the card type of any card:
(TODO video)
- Select any JPMN card within Anki's Card browser
- Within the card editor, fill in any binary field. For example, fill
IsSentenceCard
with 1
. - Preview the card. You should now see that the card is a sentence card!
As you can tell, this only changes the card type for one individual card. Of course, this does not mean you must manually edit each individual card to change its card type!
- If you want to change the default card type (i.e. change the card type for all new/future cards), see here.
- If you want to change the card type for all currently existing cards, see here.
- A comprehensive list of all possible card types can be found here.
"},{"location":"quickstart/#selecting-definitions","title":"Selecting Definitions","text":"Main Page: Definitions: Primary Definition Selection (Manual)
If you don't want to use the first bilingual/monolingual definition, you can select the dictionary or text that you want to use.
Here is exactly what's happening:
- 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.
"},{"location":"quickstart/#simplify-definitions","title":"Simplify Definitions","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
If you want to remove the list numbers, as well as the first line of most definitions, set the following runtime option:
\"blockquotes.simplifyDefinitions.enabled\": true,\n
SimpleDefault "},{"location":"quickstart/#kanji-hover","title":"Kanji Hover","text":"Main Page: Kanji Hover
Kanji hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
Note
Kanji hover does not show words outside of your collection.
"},{"location":"quickstart/#word-indicators","title":"Word Indicators","text":"Main Page: Word Indicators
New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found.
\u540c (\u540c\u3058)\u8aad (\u8aad\u307f\u65b9)\u5b57 (\u6f22\u5b57) (TODO image)
This indicates the card is a duplicate.
(TODO update image)
This shows cards with the same reading, ignoring pitch accent (also known as \u540c\u97f3\u7570\u7fa9\u8a9e.) For example, the word \u81ea\u8eab is still shown, despite having a different pitch accent to \u5730\u9707.
(TODO image)
This indicates that there are other card(s) with the same kanji, but different reading.
"},{"location":"quickstart/#images-in-the-primary-definition","title":"Images in the Primary Definition","text":"Main Page: Images: Primary Definition Image TODO
DefaultPrimaryDefinitionPictureChanging the Default (TODO gif)
Images in the PrimaryDefinition
field are collapsed by default.
(TODO gif)
The main way to have images not be collapsed is by pasting the desired images in the PrimaryDefinitionPicture
field.
(TODO gif)
However, you may want existing images in PrimaryDefinition
to not be collapsed. To do this, there are two runtime options that you can set:
\"imgStylizer.glossary.primaryDef.mode.yomichan\": \"none\",\n\"imgStylizer.glossary.primaryDef.mode.user\": \"none\",\n
"},{"location":"quickstart/#image-blur","title":"Image Blur","text":"Main Page: Images: Image Blur
The main image can be blurred on specific cards, if desired.
This behavior is disabled by default, and must be manually enabled by setting the following runtime option to true
:
\"imgStylizer.mainImage.blur.enabled\": true,\n
After setting the runtime option, you can blur the image of any card by marking as NSFW. To mark a card as NSFW, add any of the following tags to the card:
nsfw
\u30fbNSFW
\u30fb-NSFW
"},{"location":"quickstart/#pitch-accent","title":"Pitch Accent","text":"Main Page: Pitch Accent
This note template displays pitch accent using binary pitch over katakana by default. If you don't know what pitch accent is, see here.
"},{"location":"quickstart/#pitch-accent-modification","title":"Pitch Accent Modification","text":"The displayed pitch accent is usually the first position found in PAPositions
. However, you can override this automatically chosen position using the PAOverride
field.
TODO update video with interface
"},{"location":"quickstart/#pitch-accent-coloring","title":"Pitch Accent Coloring","text":"Main Page: Pitch Accent
The card can be colored according to the pitch accent of the word, if desired.
This behavior is disabled by default, and must be manually enabled by setting the following runtime option to true
:
\"autoPitchAccent.coloredPitchAccent.enabled\": true,\n
TODO update video with new colors + interface
"},{"location":"quickstart/#other-common-changes","title":"Other Common Changes","text":""},{"location":"quickstart/#adjusting-zoom","title":"Adjusting Zoom","text":"You can increase (or decrease) the size of the card, (without affecting any of Anki's GUI) with custom CSS.
:root {\n/* Times 1.1 of the original size.\n * If you want to make the note smaller, use a value below 1, like 0.9.\n */\n--zoom: 1.1;\n}\n
"},{"location":"quickstart/#adjusting-font-size","title":"Adjusting Font Size","text":"In case overall zoom isn't enough, you can adjust the font sizes for individual sections of the card.
TODO list CSS variables
"},{"location":"quickstart/#changing-the-display-language","title":"Changing the display Language","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, the display language is in English. Currently, Japanese and English are supported as display languages.
To change the display language (say, to Japanese), use the following compile option:
\"display-languages\": [\"jp\", \"en\"],\n
Note
Currently, only some text is supported. This means that various tooltips on hover, warning messages, etc. will still be in English.
"},{"location":"quickstart/#sorting-by-frequency","title":"Sorting by Frequency","text":"Main Page: Frequencies: Sorting by Frequency
This note type comes with a FrequencySort
field, which is the equivalent of Marv's Frequency
field in his guide.
This note does not sort via frequency by default. It simply contains the frequency data so you can sort by frequency if you choose to do so. Visit Marv's guide (and scroll down to Usage
) to see how to sort and review your cards by frequency.
"},{"location":"quickstart/#key-field","title":"Key Field","text":"This field contains the tested word. In other words, this contains the exact same content as the Word
. However, this field is purposefully not displayed anywhere in the card template. This is so you can modify the key if duplicates arise, while still being able to test the word.
For example, if you want to test different usages of \u4e0a, you can change this key value to \u4e0a (preposition)
, \u4e0a (grammar)
, etc. and add a new card.
It is expected that this Key
field is unique for internal purposes; a warning will appear on cards that have a duplicate key.
"},{"location":"quickstart/#conclusion","title":"Conclusion","text":"Congratulations, you have reached the end of the Quick Start page, and are ready to use jp-mining-note to its fullest! If you did not find what you want within this page, feel free to look through the other pages on the left sidebar.
"},{"location":"runtimeoptions/","title":"Runtime Options (TODO)","text":"Runtime options are card options that are applied globally to all JPMN cards. This differs from binary fields, as binary fields are options that only affects the one card.
"},{"location":"runtimeoptions/#accessing-editing","title":"Accessing & Editing","text":"Video demo (click here) To access the runtime options, navigate to your profile's media folder, and open the _jpmn-options.js
file with your favorite text editor.
The contents of the file should look something like the following:
window.JPMNOptions = {\n// Add your runtime options here.\n// ...\n}\n
"},{"location":"runtimeoptions/#adding-options","title":"Adding Options","text":"You can add a runtime option anywhere between the two outer-most curly brackets. For example:
window.JPMNOptions = {\n// Add your runtime options here.\n\"autoPitchAccent.coloredPitchAccent.enabled\": true,\n// ...\n}\n
Note
You should only add options that you want to override. This is to allow the default options to change, which usually only happens if the old option is no longer valid due to implementation details. In the rare occasion that default options do change, they will be recorded in the changelog (TODO link changelog).
"},{"location":"runtimeoptions/#available-options","title":"Available options","text":"All available options can be found in the runtime_opts.json5 file. (TODO not dev branch!)
You can safely copy/paste anything there into your runtime options file.
Warning
This json5
file is, strictly speaking, NOT an example configuration file. There are a few differences between the runtime_opts.json5
file and the actual _jpmn-opts.js
configuration file:
runtime_opts.json5
does not have the window.JPMNOptions
variable set at the very top. -
runtime_opts.json5
has an additional overrides
key at the very bottom. This overrides
key is an implementation detail, and should NOT be used anywhere in the true configuration file.
The overrides
key contains a dictionary that overrides the true value of the original key/value pair defined. For example,
\"kanjiHover.enabled\": true,\n\"overrides\": {\n \"kanjiHover.enabled\": false,\n}\n
renders in the built card as:
\"kanjiHover.enabled\": false,\n
- TODO this info is outdated, refer to
rto_overrides.json5
"},{"location":"runtimeoptions/#override-options","title":"Override Options","text":"TODO link to tooltipresults? or visa versa?
There are a few option groups that can be used to override other options:
tooltips.overrideOptions.sentenceParser
tooltips.overrideOptions.autoPitchAccent
kanjiHover.overrideOptions.tooltips
wordIndicators.overrideOptions.tooltips
The tooltips internally use an instance of the sentence parser and auto pitch accent modules to display the content. However, one may want to display content differently in tooltips than in the regular card. If that is desired, these override options can be used to exactly define what options are used by the internal sentence parser, auto pitch accent and/or tooltips modules.
"},{"location":"runtimeoptions/#option-branch-values","title":"Option Branch Values","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
All runtime options are formatted as a key/value pair. A simple example is the following:
\"kanjiHover.enabled\": true,\n
In the above example, the key is kanjiHover.enabled
, whereas the value is true
.
All runtime options can take special values (known as \"option branch values\"), which are always formatted as the following:
{\n\"type\": \"IDENTIFIER_STRING\",\n// potentially extra arguments in \"args\": { ... }\n\"resultTrue\": VALUE,\n\"resultFalse\": VALUE,\n},\n
For example, we can change the above kanjiHover.enabled
to use this branch value, with type type of isMobile
:
This can be changed to:
\"kanjiHover.enabled\": {\n\"type\": \"isPC\",\n\"resultTrue\": true, // kanji hover is enabled on PC\n\"resultFalse\": false, // kanji hover is not enabled on non-PC devices, i.e. mobile\n},\n
A full list of option branch values is shown below. The source code for these can be found under src/ts/options.ts. (TODO not dev branch)
"},{"location":"runtimeoptions/#ismobile-and-ispc","title":"isMobile
and isPC
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The isMobile
and isPC
type allows you to specify different values depending if you are using Anki on a mobile device, or PC (non-mobile).
\"key\": {\n\"type\": \"isMobile\",\n\"resultTrue\": VALUE_IF_MOBILE,\n\"resultFalse\": VALUE_IF_PC,\n},\n
isPC
is the exact opposite of isMobile
, and be used similarly.
\"key\": {\n\"type\": \"isPC\",\n\"resultTrue\": VALUE_IF_PC,\n\"resultFalse\": VALUE_IF_MOBILE,\n},\n
"},{"location":"runtimeoptions/#isiphoneipad","title":"isiPhoneiPad
","text":"TODO
"},{"location":"runtimeoptions/#viewportwidth","title":"viewportWidth
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
The viewportWidth
type allows you to specify different values depending on the screen width. Note that the viewport width is read for each card flip. This means that viewport width changes after resizing a window will not be detected, and will only be updated when you flip the side or go to a new card.
This is formatted as the following:
\"key\": {\n\"type\": \"viewportWidth\",\n\"args\": {\n\"op\": MATH_OP,\n\"value\": WIDTH,\n},\n\"resultTrue\": ...,\n\"resultFalse\": ...,\n},\n
TODO MATH_OP
and WIDTH
"},{"location":"runtimeoptions/#viewportwidthbreakpoint","title":"viewportWidthBreakpoint
","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
\"key\": {\n\"type\": \"viewportWidthBreakpoint\",\n\"args\": {\n\"op\": MATH_OP,\n\"value\": BREAKPOINT_VAR,\n},\n\"resultTrue\": ...,\n\"resultFalse\": ...,\n},\n
BREAKPOINT_VAR
can be one of:
displaySentenceShrink
displaySentenceRemoveNewlines
maxWidthBackside
(tablet) combinePicture
(mobile)
"},{"location":"runtimeoptions/#cardtype","title":"cardType
","text":"TODO
"},{"location":"runtimeoptions/#cardside","title":"cardSide
","text":"TODO
"},{"location":"runtimeoptions/#fieldsallempty","title":"fieldsAllEmpty
","text":"TODO
"},{"location":"runtimeoptions/#fieldsallfilled","title":"fieldsAllFilled
","text":"TODO
"},{"location":"runtimeoptions/#fieldsanyfilled","title":"fieldsAnyFilled
","text":"TODO
"},{"location":"runtimeoptions/#troubleshooting","title":"Troubleshooting","text":"TODO record specific errors
If you have any error, or an option is simply not working, please check the following:
- If a runtime option is not working, or you get an error saying that an option doesn't exist, you may have an outdated option. Please check that your option is indeed recorded in the available options.
"},{"location":"scripts/","title":"Anki Hotkeys (TODO)","text":"This page serves as a collection of small Anki-related scripts primarily for the usage automating repetitive tasks with hotkeys.
It is separated into two main sections:
- ShareX Hotkeys: Hotkeys meant to be specifically used with media files generated from ShareX.
- Anki Hotkeys: General purpose hotkeys that act on the most recent card(s). Does not require media files to operate.
TODO demo
Note
The ShareX hotkeys are originally based off of Stegatxins0's Mining Setup. That was itself originally based off of AnimeCard's ShareX Setup.
"},{"location":"scripts/#sharex-hotkeys","title":"ShareX Hotkeys","text":"Windows users can use ShareX as a general purpose tool to automatically add images and audio to your most recently created card. There are two main hotkeys that this setup introduces:
- A screenshot hotkey
- An audio hotkey
Note
If you are using Linux, I recommend using ames instead of ShareX. Unfortunately, I'm not aware of a good solution for macOS users.
"},{"location":"scripts/#feature-summary","title":"Feature Summary","text":" - Audio is automatically normalized, and attempts to remove silence at the beginning of the audio.
- Images are saved as webp, to save disk space.
- The screenshot hotkey automatically adds the Window name as a tag to the card.
- Work with any note type, given that the correct flags are provided. By default, these work with jp-mining-note and AnimeCards.
- Instead of using PowerShell, this setup uses Python. Unfortunately, this is a little bit more difficult to setup for the average user, but using Python makes it much easier to develop and maintain the underlying scripts. Most people, including myself, know Python much more than PowerShell. Additionally, Python is generally cross platform and easy enough to setup on all operating systems.
"},{"location":"scripts/#sharex-hotkeys-prerequisites","title":"ShareX Hotkeys Prerequisites","text":"To use these hotkeys with ShareX, you must have the following installed:
- ShareX
- Python (Python 3.10 or above should work)
- Anki-Connect (You probably have this installed already if you're using Yomichan or jp-mining-note).
hotkey.py
(see below)
The hotkey.py
file can be downloaded in any of the following ways:
Option 1: JPMN Manager (click here) If you have JPMN Manager installed, then this script is already available to you! It is located under the Anki folder:
Anki2/addons21/301910299/tools/hotkey.py\n
Option 2: With git
(click here) For git
users, simply clone the JPMN repository in somewhere you'll remember:
git clone https://github.com/arbyste/jp-mining-note.git\n
The hotkey.py file will be found under (repo root)/tools/hotkey.py
. Option 3: Manually (click here) If none of the above works / you don't know what git
is:
- Navigate to a folder you'll remember.
- Right click on some blank space, and then create a new text file (
New
-> Text Document
). Name this text file hotkey.py
. - Copy the script text into the new text file, and save (
Ctrl+S
). TODO gif!
"},{"location":"scripts/#sharex-screenshot-hotkey","title":"ShareX Screenshot Hotkey","text":" -
Create the hotkey:
- Open ShareX, if you haven't already.
- On the sidebar to the left, click on
Hotkey settings...
. (TODO image) - Within the Hotkey Settings window, click
Add
. (TODO image) - Set the task to be
Screen capture
-> Capture region
. - Set the hotkey value to whatever you want. For example,
F6
.
(TODO gif)
-
Change the hotkey settings:
-
Click on the gear of your new Capture Region
hotkey. (TODO image)
-
Navigate to the Task
tab.
- Check
Override after capture settings
() - Navigate to the capture tasks dropdown, and only have the following two items selected:
- Save image to file
- Perform actions (TODO image)
- Check
Override screenshots folder
() - Click
Browse
and select your Anki collection media location. Your media location can be found under: C:\\Users\\YOUR_USER_NAME\\AppData\\Roaming\\Anki2\\YOUR_ANKI_PROFILE_NAME\\collection.media\n
Tip: An easy way to navigate to this is by entering %APPDATA%
in the path of the file browser. - To make it easier for you to remember what this hotkey does, set the
Description
to anki-screenshot
. Your Task
tab should now look something like this: (TODO image)
-
Navigate to the General
tab.
- Check
Override general settings
() (TODO image)
-
Navigate to the General
-> Notifications
tab.
- Uncheck
Play sound after capture is made
() - Uncheck
Play sound after task is completed
() The sound on screenshot is removed so one can take a screenshot while recording the audio, without having the screenshot sound affect the recording. (TODO image)
-
Add the ffmpeg-to-webp
action:
Explanation: This action saves the image as a webp image, to reduce file space while retaining the same quality. Unfortunately, as of writing this, ShareX does not support webp natively, so this action must be explicitly defined to save the image as a webp.
- Navigate to the
Actions
tab. - Check
Override actions
() - Click
Add...
. -
A new window should pop up. Under this new window, fill out the following values:
ffmpeg-to-webp action (click here) - Name:
ffmpeg-to-webp
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-i \"$input\" -quality 95 \"$output\"\n
- Output file name extension:
webp\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Add the card-add-image
action:
Explanation: This adds the image to the Anki card itself, using Anki-Connect and Python.
- Under the
Actions
tab, click Add...
. -
A new window should pop up. Under this new window, fill out the following values:
card-add-image action (click here) - Name:
card-add-image
- File path: (change the path to your exact path to
python.exe
) C:\\PATH\\TO\\YOUR\\PYTHON\\EXECUTABLE\\python.exe\n
- Your
python.exe
file is usually under C:\\PythonXX\\python.exe
, where XX
is the version number. If you can't find it, you can always search for python.exe
on the search bar, and then copying the full path of the file.
- Argument: (change the path to your exact path to
hotkey.py
) C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\"\n
- This is the
hotkey.py
file from the prerequisites step.
- Check
Hidden window
()
(TODO image)
Picture field
The expected name of the picture field is exactly Picture
. If your card uses a different field name, say Image
, then the --field-name
flag must be used (change Image
to whatever your field name is):
C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\" --field-name Image\n
TODO gif
-
Test the hotkey: TODO
"},{"location":"scripts/#sharex-screenshot-hotkey-nsfw","title":"ShareX Screenshot Hotkey (NSFW)","text":"For people using jp-mining-note or using Marv's Anki Card Blur, you might want to setup a different hotkey to specifically tag the card as NSFW when adding the image.
The following hotkey does the same as the above, while also adding the -NSFW
tag to the card.
- Duplicate the screenshot hotkey above, and set the hotkey to something else (i.e. Shift+F6)
- Navigate to the
Actions
tab. - Select
card-add-image
action. - Change the
Argument
to the following: C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_picture \"$input\" --nsfw True\n
TODO gif
"},{"location":"scripts/#sharex-audio-hotkey","title":"ShareX Audio Hotkey","text":" -
Create the hotkey:
- Open ShareX, if you haven't already.
- On the sidebar to the left, click on
Hotkey settings...
. (TODO image) - Within the Hotkey Settings window, click
Add
. - Set the task to be
Screen record
-> Start/Stop screen recording using pre configured region
. - Set the hotkey value to whatever you want. For example,
F7
.
(TODO gif)
-
Change the hotkey settings:
-
Click on the gear of your new Start/Stop screen recording ...
hotkey. (TODO image)
-
Navigate to the Task
tab.
- Check
Override after capture settings
() - Navigate to the capture tasks dropdown, and only have the following two items selected:
- Save image to file
- Perform actions
- Check
Override screenshots folder
() - Click
Browse
and select your Anki collection media location. Your media location can be found under: C:\\Users\\YOUR_USER_NAME\\AppData\\Roaming\\Anki2\\YOUR_ANKI_PROFILE_NAME\\collection.media\n
This should be the exact same folder as the anki-screenshot
hotkey. - To make it easier for you to remember what this hotkey does, set the
Description
to anki-audio
.
Your Task
tab should now look something like this: (TODO image)
-
Navigate to the Capture
tab.
- Check
Override capture settings
() - Click
Select region
, and select anywhere on the screen. This region would preferably not overlap with whatever you want to capture. If it does and you attempt to screenshot while using the audio hotkey, then the dotted region marked by ShareX will be captured as well. (TODO image)
-
Navigate to the Capture
-> Screen recorder
tab. Within this, tab, click on the Screen recording options...
button to open a new window.
- Press the
Install recorder devices
button - Set
Video source
to None
- Set
Audio source
to virtual-audio-capturer
- Set
Audio codec
to Opus
(This will be configurable later) - Click on the
Opus
tab right underneath Audio codec
, and ensure the quality is set to 128k
. - Close this new window.
-
Add the process audio action(s):
Explanation: This adds a ffmpeg call to normalize the audio and remove the beginning silence. Ideally, we would put these audio filters in the Screen recording options
custom commands box. Unfortunately, if placed there, the flags to normalize the audio ends up cutting off the audio. Therefore, this action is required to accurately run the desired audio filters.
You have two options:
- Store as Opus. The Opus audio codec provides much better quality at lower bitrates (which saves a lot of space and makes syncing large collections faster). However, Opus is NOT compatible with AnkiMobile (iOS), Android 4, and AnkiWeb. If you use any of these, please use the 2nd option (MP3 audio) below.
- Store as MP3. Older and less efficient codec, but needed for compatibility with pretty much all devices.
Option 1. Opus (click here) Explanation: ShareX does not natively support storing audio as .wav or .flac files. ShareX does not provide a simply way to copy a file. FFmpeg does not allow us to read and write to the exact same file. Finally, ShareX cannot run the audio filters in the Screen recording options
custom commands box, as mentioned above. With all these limitations, the only way to store it as opus while running the audio filters is to first convert the file to something else (we use .wav), and then re-convert it back to opus again while applying the audio filters.
- Navigate to the
Actions
tab. - Check
Override actions
() -
Create the first action, by clicking Add...
. A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-wav action (click here) - Name:
ffmpeg-process-audio-wav
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -i \"$input\" \"$output\"\n
- Output file name extension:
wav\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Close the above ffmpeg-process-audio-wav
action window.
-
Create the second action, by clicking Add...
. A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-opus action (click here) - Name:
ffmpeg-process-audio-opus
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -c:a opus -i \"$input\" -af \"silenceremove=1:0:-50dB, loudnorm=I=-16:TP=-6.2:LRA=11:dual_mono=true\" -b:a 64k \"$output\"\n
- Output file name extension:
opus\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
Option 2. MP3 (click here) - Navigate to the
Actions
tab. - Check
Override actions
() - Click
Add...
. -
A new window should pop up. Under this new window, fill out the following values:
ffmpeg-process-audio-mp3 action (click here) - Name:
ffmpeg-process-audio-mp3
- File path:
C:\\Program Files\\ShareX\\ffmpeg.exe\n
- Argument:
-y -i \"$input\" -af \"silenceremove=1:0:-50dB, loudnorm=I=-16:TP=-6.2:LRA=11:dual_mono=true\" -q:a 3 \"$output\"\n
- Output file name extension:
mp3\n
- Check
Hidden window
() - Check
Delete input file
()
(TODO image)
-
Add the card-add-audio
action:
This adds the image to the Anki card itself.
- Under the
Actions
tab, click Add...
. -
A new window should pop up. Under this new window, fill out the following values:
card-add-audio action (click here) - Name:
card-add-audio
- File path: (change the path to your exact path to
python.exe
) C:\\PATH\\TO\\YOUR\\PYTHON\\EXECUTABLE\\python.exe\n
- Argument: (change the path to your exact path to
hotkey.py
) C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py set_audio \"$input\"\n
- These paths should be the exact same as the
card-add-audio
action within the anki-screenshot
hotkey.
- Check
Hidden window
()
(TODO image)
Sentence Audio field
The expected name of the sentence audio field is exactly SentenceAudio
. If your card uses a different field name, say SentAudio
, then the --field-name
flag must be used (change SentAudio
to whatever your field name is):
\"$input\" set_audio --field-name SentAudio\n
TODO gif
"},{"location":"scripts/#troubleshooting","title":"Troubleshooting","text":" -
Do NOT view the card in the card browser when running any script, because if you do, the affected fields may not update. Close the card browser before running the scripts.
However, you do not need to worry about this if you are running the python script with the --enable-gui-browse
flag.
"},{"location":"scripts/#other-hotkeys","title":"Other Hotkeys","text":"These are a set of scripts that may help you to prevent doing repetitive actions when adding notes.
Unlike the above, these scripts are not meant to be used with audio or picture files. Rather, they are stand-alone scripts that modify the most recent cards added.
These scripts are written in two formats: one that works automatically with your usual ShareX
setup, and one in Python for cross-platform portability.
"},{"location":"scripts/#how-to-running-with-sharex","title":"How-To: Running with ShareX","text":"As shown above, ShareX has the ability to run custom user scripts. However, for ShareX to only run the script and do nothing else, the hotkey must be configured with steps shown below.
"},{"location":"scripts/#steps","title":"Steps","text":"(TODO video)
- Under the main window, go to
Hotkey Settings
, and add a new hotkey. - Click on the settings icon (of the newly added hotkey).
- In the
Task
tab (to the left): - Set:
Task
to Screen capture
\u2192 Capture active window
- Check
Override After Capture Tasks
() - Under
After Capture
, un-check everything, and check the following: Save Image to File
Perform Actions
Delete Locally
- In the
Actions
tab (to the left): - Check
Override Actions
() - Uncheck all existing actions.
- Add a new action by clicking on
Add
. - Set the following values of the action:
- File Path:
C:\\PATH\\TO\\python.exe
- Argument:
C:\\PATH\\TO\\YOUR\\HOTKEY\\FILE\\hotkey.py FUNCTION_NAME
Note
If you are adding multiple scripts with ShareX, instead of re-doing all of the steps above, you can instead duplicate the keybind, and simply set the Argument
of the action to a different function name.
Explanation of the setup (click here) The reason that the After Capture
settings include Save Image to File
and Delete Locally
is because without those settings, the Perform Actions
section doesn't appear to run. Fortunately, the combination of Save Image to File
and Delete Locally
means the hotkey does the following:
- Saves the image file
- Runs the custom script
- Deletes the image file
In other words, the image file is only temporarily created, and then deleted immediately after running the script. This effectively means that ShareX is only running the script whenever the keybind is used.
"},{"location":"scripts/#how-to-running-with-command-line","title":"How-To: Running with Command Line","text":"If you don't want to use ShareX, or you are not using Windows, you can simply run a python script with command line.
# Your python version should be 3.9 or higher.\n# It may work for lower python versions, but I make no guarantee.\npython3 /path/to/jp-mining-note/tools/hotkey.py FUNCTION_NAME\n
Examples (click here) # default\npython3 /path/to/jp-mining-note/tools/hotkey.py update_sentence\n\n# opens card browser automatically\npython3 /path/to/jp-mining-note/tools/hotkey.py update_sentence --enable-gui-browse\n
If you want to use these as keybinds, I will leave it up to you to determine how to do that (as there are too many different setups and programs that people can use to create keybinds). However, some tips for ShareX and AutoKey are given below.
"},{"location":"scripts/#how-to-running-with-autokey","title":"How-To: Running with AutoKey (Not AutoHotKey)","text":"If you are using AutoKey for Linux, it should be possible to do the following instead:
-
Go to: Settings
\u2192 Configure AutoKey
\u2192 Script Engine
\u2192 User Module file
\u2192 (add the jp-mining-note/tools
directory)
-
Create a script
type hotkey,
-
Within the script, run any function thusly:
import hotkey\nhotkey.FUNCTION_NAME()\n
Example:
import hotkey\nhotkey.update_sentence()\n
Example with GUI:
import hotkey\nhotkey._browse_anki(\"nid:1\")\nnote_id = hotkey.update_sentence()\nhotkey._browse_anki(f\"nid:{note_id}\")\n
"},{"location":"scripts/#update-sentence-with-clipboard","title":"Update Sentence with Clipboard","text":"Function Name: update_sentence
This script updates the sentence with the current clipboard (while preserving the bolded word), and removes the SentenceReading
field (of the newest note added).
This script is useful when Yomichan's parsed sentence does not match the recorded audio. This is also useful for when Yomichan's word parser doesn't match the word itself (steps shown below).
Note
After running this script, you must manually generate the SentenceReading
field if you want the furigana reading. Of course, this can be done in bulk at any point, as shown here.
How-To: Fix incorrectly-bolded words (click here) As an example, The target word \u5e0c\u671b in the sentence \u300c\u5165\u90e8\u5e0c\u671b\u306a\u3093\u3067\u3059\u3051\u3069\u2026\u300d will be parsed by Yomichan as the following:
\u5165\u90e8<b>\u5e0c\u671b\u306a</b>\u3093\u3067\u3059\u3051\u3069\u2026\n
Within the original popup, you can add two versions of the word by default:
- The one with JMdict only. Adding this word will add the sentence with incorrect bolding.
- The one with everything else other than JMdict. Adding this word will have the correct bold, but will be missing some definitions.
To add the above sentence that solves both problems (no weird bold, and contains all definitions), do NOT add the word within the sentence. Instead, do the following:
-
Highlight over the header word itself (or the word in the orthographic forms dictionary), and add that word instead.
Demo (click here) -
Copy the desired sentence.
-
Run this script.
Note
It is assumed that you have multiple popups enabled.
How the bolded word is preserved (click here) The bolded word is preserved if the exact content within the bolded word is found within the clipboard, which should be almost always the case.
For example, assume the added sentence is the following:
\u3055\u3066\u306f<b>\u507d\u8005</b>\u3060\u306a\uff01\n
As long as the clipboard contains the word \u300c\u507d\u8005\u300d, then the bold is preserved. For example, the following clipboard contents will preserve the bold:
\u304b\u308f\u3044\u3052\u306e\u3042\u308b\u5973\u3058\u3083\u306a\u3044\u3002\u3055\u3066\u306f\u507d\u8005\u3060\u306a\uff01\n
TODO sharex_display(sharex.update_sentence)
"},{"location":"scripts/#update-additionalnotes-with-clipboard","title":"Update AdditionalNotes with Clipboard","text":"Function Name: update_additional_notes
This script does the exact same thing as the above script, but with AdditionalNotes
instead of Sentence
. The tested word, if found, is also automatically highlighted.
This is useful to copy/paste context for the sentence (the surrounding lines around the sentence).
TODO sharex_display(sharex.update_additional_notes)
"},{"location":"scripts/#copy-from-previous-card","title":"Copy from Previous Card","text":"Function Name: copy_from_previous
This script does the following:
- Set the
AdditionalNotes
and Picture
field of the newest card to the previous (second-newest) card's fields. - Copies all the tags of the previous card.
This is useful for when you are adding more than one sentence with the same text box of a visual novel, as it prevents you from having to run the screenshot hotkey.
"},{"location":"scripts/#how-to-use","title":"How to use","text":" - Create a card from the first unknown word in the text box.
- Create a card from the second unknown word in the text box.
- Run this script.
TODO sharex_display(sharex.copy_from_previous)
"},{"location":"scripts/#orthographic-variants-fix-sentence-and-frequency","title":"Orthographic Variants: Fix Sentence and Frequency","text":"Function Name: fix_sent_and_freq
This script does the following:
- Sets the previous note's fields to the newest note's fields:
FrequencyStylized
Sentence
SentenceReading
- Deletes the newest note
This is useful for when you want to add the the word within the Orthographic Variants dictionary. The Orthographics Variants dictionary is extremely useful for monolingual definitions, where dictionaries only contain entries for more kanjified words.
In practice, I've personally found numerous examples of this in everyday media, so this has helped me immensely.
Examples (to test the dictionary on) \u300c\u30b9\u30da\u30eb\u30c9\u65cf\u3078\u306e\u6050\u6016\u306f\u6050\u3089\u304f\u3053\u306e\u4e16\u754c\u306b\u6839\u3065\u3044\u3066\u3044\u308b\u3093\u3060\u308d\u3046\u300d
\u300c\u30eb\u30fc\u306f\u305f\u304f\u3055\u3093\u3042\u308b\u306e\u3067\u3001\u4eca\u304a\u4ee3\u308f\u308a\u3092\u304a\u6301\u3061\u3057\u307e\u3059\u306d\u300d
\u300c\u305f\u3060\u3001\u4e00\u3064\u3060\u3051\u91d8\u3092\u3055\u3055\u305b\u3066\u3082\u3089\u3046\u3051\u3069\u2026\u8cb4\u65b9\u304c\u3053\u308c\u304b\u3089\u4f55\u3092\u3059\u308b\u306b\u3057\u3066\u3082\u3001\u4ed5\u4e8b\u306f\u4eca\u307e\u3067\u901a\u308a\u3053\u306a\u3057\u3066\u3082\u3089\u3046\u308f\u3088\uff1f\u300d
It is assumed that you have multiple popups enabled for monolingual definitions, so you can easily look up the word in the Orthographic Forms dictionary.
"},{"location":"scripts/#how-to-use_1","title":"How to use","text":" - Create a card from the word in the Orthographic Variants dictionary.
- Create a card from the word in original sentence.
- Run this script.
"},{"location":"scripts/#deprecated-scripts","title":"Deprecated Scripts","text":"These contain powershell code for some scripts above. This powershell code has been replaced with Python scripts for easier maintainability
Screenshot and Clipboard Hotkey Follow the steps for setting up the screenshot hotkey, and use this script in place of step 8's argument
.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne \\\"\\\"}) -join \\\"<br>\\\"; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_clipboard = $clipboard; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_clipboard = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = \\\"<img data-editor-shrink=`\\\"true`\\\" src=`\\\"$media_name`\\\">\\\"; AdditionalNotes = $result_clipboard; } } } }; if ($media_name -match '(?<tag>.+)_.*') { $tag = $matches['tag']; } Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne \"\"}) -join \"<br>\";\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n# attempts to bold the found word within the clipboard\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_clipboard = $clipboard;\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_clipboard = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n};\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = \"<img data-editor-shrink=`\"true`\" src=`\"$media_name`\">\";\nAdditionalNotes = $result_clipboard;\n}\n}\n}\n};\nif ($media_name -match '(?<tag>.+)_.*') {\n$tag = $matches['tag'];\n}\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n};\n
Screenshot (only) Hotkey This is the same as the above, but without setting the AdditionalNotes
field to the current clipboard.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = \\\"<img data-editor-shrink=`\\\"true`\\\" src=`\\\"$media_name`\\\">\\\"; } } } }; if ($media_name -match '(?<tag>.+)_.*') { $tag = $matches['tag'] } Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = \"<img data-editor-shrink=`\"true`\" src=`\"$media_name`\">\";\n}\n}\n}\n};\nif ($media_name -match '(?<tag>.+)_.*') {\n$tag = $matches['tag']\n}\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n};\n
Audio Hotkey This script works exactly the same as stegatxins0's version, except rewritten in a more readable format. If you already have the audio hotkey setup, there is no reason to change the old script.
To use this, follow the steps for setting up the audio hotkey, and use this script in place of step 14's Argument
.
ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $media_name = '$input' | Split-Path -leaf; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ SentenceAudio = \\\"[sound:$media_name]\\\"; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n# gets only the file name\n$media_name = '$input' | Split-Path -leaf;\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nSentenceAudio = \"[sound:$media_name]\";\n}\n}\n}\n};\n
Update Sentence with Clipboard ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne ''}) -join ''; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_sent = ''; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_sent = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); } else { $result_sent = $clipboard; }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Sentence = $result_sent; SentenceReading = ''; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne ''}) -join '';\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_sent = '';\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_sent = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n} else {\n# default\n$result_sent = $clipboard;\n};\n# updates current card with result_sent\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nSentence = $result_sent;\nSentenceReading = '';\n}\n}\n}\n};\n
Update AdditionalNotes with Clipboard ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $clipboard = (Get-Clipboard | where{$_ -ne \\\"\\\"}) -join \\\"<br>\\\"; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; $curr_note_sent = $curr_note_data.result.fields.Sentence.value; $result_sent = ''; if ($curr_note_sent -match '<b>(?<bolded>.+)</b>') { $bolded = $matches['bolded']; $result_sent = $clipboard.replace($bolded, \\\"<b>$bolded</b>\\\"); } else { $result_sent = $clipboard; }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ AdditionalNotes = $result_sent; } } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$clipboard = (Get-Clipboard | where{$_ -ne \"\"}) -join \"<br>\";\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n$curr_note_sent = $curr_note_data.result.fields.Sentence.value;\n$result_sent = '';\nif ($curr_note_sent -match '<b>(?<bolded>.+)</b>') {\n$bolded = $matches['bolded'];\n# may not replace anything\n$result_sent = $clipboard.replace($bolded, \"<b>$bolded</b>\");\n} else {\n# default\n$result_sent = $clipboard;\n};\n# updates current card with result_sent\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nAdditionalNotes = $result_sent;\n}\n}\n}\n};\n
Copy from Previous Card ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $prev_note_id = $sorted_list[1]; $curr_note_id = $sorted_list[0]; $prev_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($prev_note_id); } }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $curr_note_id; fields = @{ Picture = $prev_note_data.result.fields.Picture.value; AdditionalNotes = $prev_note_data.result.fields.AdditionalNotes.value; } } } }; foreach ($tag in $prev_note_data.result.tags) { Run-Json @{ action = 'addTags'; version = 6; params = @{ notes = @($curr_note_id); tags = $tag; } } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$prev_note_id = $sorted_list[1];\n$curr_note_id = $sorted_list[0];\n$prev_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($prev_note_id);\n}\n};\n# copies picture & additional notes to current note\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $curr_note_id;\nfields = @{\nPicture = $prev_note_data.result.fields.Picture.value;\nAdditionalNotes = $prev_note_data.result.fields.AdditionalNotes.value;\n}\n}\n}\n};\n# copies tags\nforeach ($tag in $prev_note_data.result.tags) {\nRun-Json @{\naction = 'addTags';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\ntags = $tag;\n}\n}\n};\n
Orthographic Variants: Fix Sentence and Frequency ShareX Script
-NoProfile -Command \"function Run-Json { param( $json_map ); $json = $json_map | ConvertTo-Json -Depth 5; $data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType 'application/json; charset=UTF-8' -Body $json; return $data; }; $added_notes = Run-Json @{ action = 'findNotes'; version = 6; params = @{ query = 'added:1'; } }; $sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_}; $prev_note_id = $sorted_list[1]; $curr_note_id = $sorted_list[0]; $curr_note_data = Run-Json @{ action = 'notesInfo'; version = 6; params = @{ notes = @($curr_note_id); } }; Run-Json @{ action = 'updateNoteFields'; version = 6; params = @{ note = @{ id = $prev_note_id; fields = @{ FrequenciesStylized = $curr_note_data.result.fields.FrequenciesStylized.value; Sentence = $curr_note_data.result.fields.Sentence.value; SentenceReading = $curr_note_data.result.fields.SentenceReading.value; } } } }; Run-Json @{ action = 'deleteNotes'; version = 6; params = @{ notes = @($curr_note_id); } };\"\n
Original ShareX Code (click here) # (common begin)\nfunction Run-Json {\nparam( $json_map );\n$json = $json_map | ConvertTo-Json -Depth 5;\n$data = Invoke-RestMethod -Uri http://127.0.0.1:8765 -Method Post -ContentType `\n'application/json; charset=UTF-8' -Body $json;\nreturn $data;\n};\n# (common end)\n$added_notes = Run-Json @{\naction = 'findNotes';\nversion = 6;\nparams = @{\nquery = 'added:1';\n}\n};\n$sorted_list = $added_notes.result | Sort-Object -Descending {[Long]$_};\n$prev_note_id = $sorted_list[1];\n$curr_note_id = $sorted_list[0];\n$curr_note_data = Run-Json @{\naction = 'notesInfo';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n# copies frequency, sentence, sentence reading to previous note\nRun-Json @{\naction = 'updateNoteFields';\nversion = 6;\nparams = @{\nnote = @{\nid = $prev_note_id;\nfields = @{\nFrequenciesStylized = $curr_note_data.result.fields.FrequenciesStylized.value;\nSentence = $curr_note_data.result.fields.Sentence.value;\nSentenceReading = $curr_note_data.result.fields.SentenceReading.value;\n}\n}\n}\n};\n# removes current note\nRun-Json @{\naction = 'deleteNotes';\nversion = 6;\nparams = @{\nnotes = @($curr_note_id);\n}\n};\n
"},{"location":"sentences/","title":"Sentences (TODO)","text":""},{"location":"sentences/#display-sentence-vs-full-sentence","title":"Display sentence vs Full sentence","text":"We will use the following terms to differentiate between the different sentences present in this note:
- Display sentence refers to the sentence(s) shown at the front side of the card. Most topics on this page will be relating to the display sentence.
- Full sentence to refers to the sentence(s) shown at the back with furigana. This is called the \"full sentence\" as this is usually just the
Sentence
(or SentenceReading
) field with minimal styling.
TODO image
"},{"location":"sentences/#sentence-cards","title":"Sentence cards","text":"If you are looking on how to make sentence cards or targeted sentence cards (sentence cards where the tested word is bolded), see Card Types: Sentence Card and Card Types: Targeted Sentence Card respectively.
"},{"location":"sentences/#customize-the-display-sentence","title":"Customize the display sentence","text":"You can use the AltDisplaySentence
field you ever wish to customize the display sentence without modifying the full sentence (Sentence
field),
Last sentence onlyFuriganaKanjifying the word For example, we can use AltDisplaySentence
to only test the last sentence.
One nice feature is that AltDisplaySentence
has hoverable furigana text enabled by default. In other words, you can write furigana within the field. I personally use this to insert furigana for certain names, since I'm usually not testing myself on how to read a name.
For example, the card below has the following HTML:
\u4e0a\u6761[\u304b\u307f\u3058\u3087\u3046] \u606d\u4ecb[\u304d\u3087\u3046\u3059\u3051]\u541b\u306e\u3053\u3068\u304a<b>\u6155\u3044</b>\u3057\u3066\u307e\u3057\u305f\u306e\n
TODO image
It is not uncommon for words to be written in kana, but have a kanji variant. Instead of modifying the Sentence
field, you can copy the Sentence
field into the AltDisplaySentence
field, and then manually replace the kana with its kanji variant. This may be useful for any card type that isn't a vocab or audio card.
"},{"location":"sentences/#adding-line-breaks","title":"Adding line breaks","text":"TODO this is basically the only time I ever edit the Sentence
field
- if you have furigana, make sure you refresh the
SentenceReading
field, i.e. with the AJT Japanese
plugin
"},{"location":"sentences/#sentence-max-width-indicator","title":"Sentence Max Width Indicator","text":"TODO sentence-max-width
under cssFolders
- warning: experimental, may have weird bugs
"},{"location":"sentences/#automatic-word-highlighting","title":"Automatic word highlighting","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Usually, the word within the sentence is already bolded by Yomichan. However, there are some cases where the word within the sentence may not be bold, such as when external programs update the Sentence
field, or if you are using imported cards.
By default, the note attempts to highlight the word within the sentence.
With that being said, it is not uncommon that the automatic highlighting fails to highlight the full word. For example, verb and i-adj. conjugations are not highlighted whatsoever. In order to keep the javascript lightweight, any improper highlighting is considered as expected behavior, and will not be changed or fixed. I recommend manually bolding the word if the word is incorrectly highlighted.
Examples (click here) Any text in red is not highlighted automatically. They are considered as examples of when automatic highlighting doesn't work.
WordReading Sentence Result \u6295\u7a3f\u3068\u3046\u3053\u3046 \u300c\u3042\u306e\u6642\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u4e0a\u3067\u8272\u3093\u306a\u8cea\u554f\u304c\u3067\u304d\u308b\u30b5\u30a4\u30c8\u306b\u6295\u7a3f\u3057\u305f\u3089\u3001\u89aa\u5207\u306a\u4eba\u304c\u5546\u54c1\u540d\u3068\u58f2\u3063\u3066\u3044\u308b\u5834\u6240\u3092\u6559\u3048\u3066\u304f\u308c\u305f\u3093\u3067\u3059\u300d \u4e00\u5148\u3072\u3068\u307e\u305a \u300c\u3075\u30fc\u2026\u3053\u308c\u3067\u3072\u3068\u307e\u305a\u306f\u5927\u4e08\u592b\u305d\u3046\u306d\u2026\u300d \u7363\u3051\u3060\u3082\u306e \u300c\u305d\u306e\u5834\u5408\u2026\u300e\u5acc\u3063\uff01\u3053\u306e\u30b1\u30c0\u30e2\u30ce\uff01\u300f\u3068\u66b4\u308c\u305f\u65b9\u304c\u3001\u98a8\u898b\u3055\u3093\u306f\u304a\u597d\u307f\u3067\u3057\u3087\u3046\u304b\uff1f\u300d \u7532\u6590\u7532\u6590\u304b\u3044\u304c\u3044\u3057\u3044 \u300c\u306a\u306b\u3088\u3045\u2026\u7532\u6590\u7532\u6590\u3057\u304f\u4f1a\u3044\u306b\u6765\u305f\u5973\u306b\u5bfe\u3057\u3066\u3001\u6700\u521d\u306b\u8a00\u3046\u30bb\u30ea\u30d5\u304c\u305d\u308c\uff1f\u300d \u5c71\u3084\u307e\u3054\u3082\u308a \u300c\u3067\u306f\u3001\u308f\u305f\u3057\u3082\u4eca\u304b\u3089\u5c71\u3054\u3082\u308a\u306e\u4fee\u884c\u3092\u59cb\u3081\u307e\u3059\u300d \u5c71\u7c60\u3084\u307e\u3054\u3082\u308a \u300c\u3067\u306f\u3001\u308f\u305f\u3057\u3082\u4eca\u304b\u3089\u5c71\u3054\u3082\u308a\u306e\u4fee\u884c\u3092\u59cb\u3081\u307e\u3059\u300d \u629c\u306c\u304d\u3093\u51fa\u306c\u308b \u300c\u201c\u3059\u3054\u3044\u201d\u3067\u3059\u304b\u3089\u3001\u826f\u304f\u3082\u60aa\u304f\u3082\u3001\u629c\u304d\u3093\u51fa\u3066\u3044\u308b\u3068\u3044\u3046\u610f\u5473\u306b\u306f\u306a\u308b\u3068\u601d\u3044\u307e\u3059\u300d Note
Much of the base code was taken from Marv's implementation of the same thing.
"},{"location":"sentences/#removing-sentence-periods","title":"Removing sentence periods","text":"The display sentence will have the period at the end of the sentence removed by default. If you want to keep the period, you can set the desired runtime options to false
:
\"sentenceParser.removeFinalPeriod.fullSent.quoted\": true, // (1)!\n\"sentenceParser.removeFinalPeriod.fullSent.unquoted\": false,\n\"sentenceParser.removeFinalPeriod.display.quoted\": true,\n\"sentenceParser.removeFinalPeriod.display.unquoted\": false,\n\"sentenceParser.removeFinalPeriod.altDisplay.quoted\": false,\n\"sentenceParser.removeFinalPeriod.altDisplay.unquoted\": false,\n
- For example,
\"sentenceParser.removeFinalPeriod.fullSent.quoted\": true,
means that the final period is removed from the full sentence if it is quoted. The other options follow similarly.
TODO image
"},{"location":"sentences/#adding-or-removing-quotes","title":"Adding or removing quotes","text":"The sentence display has quotes surrounding the sentence by default, to provide a simple indicator to differentiate between a sentence and vocab card.
If you do not want quotes around the sentence, you can set the following runtime options to remove
:
\"sentenceParser.fullSent.quotes.processMode\": \"remove\",\n\"sentenceParser.display.quotes.processMode\": \"add\",\n\"sentenceParser.altDisplay.quotes.processMode\": \"as-is\",\n
All available process modes are explained within the example config file.
If you want to add or remove quotes on a card-by-card basis, add the quote-add
tag or quote-remove
tag to the card, respectively.
TODO image????
"},{"location":"sentences/#sentencereading-furigana-options","title":"SentenceReading
Furigana Options","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, the furigana for the full sentence (on the back side of the card) is shown on hover, given that this SentenceReading
field is filled out. If SentenceReading
is not filled out, then the sentence will show as usual (without furigana).
The following options change how the furigana is displayed within the full sentence, if any exists.
Note
These options do NOT affect furigana elsewhere, such as any in the displayed sentence.
"},{"location":"sentences/#furigana-simple-css-options","title":"Furigana: Simple CSS options","text":"Most problems that people face with ruby is that there is added spacing within the furigana. The following are some simple CSS-only solutions that solves this main problem.
Shown on sentence hoverShown on word hover .full-sentence ruby rt {\nvisibility: visible !important;\nfont-size: 0%;\ntransition: 0.2s;\n}\n.full-sentence:hover ruby rt {\nfont-size: 50%;\ntransition: 0.2s;\n}\n
.full-sentence ruby rt {\nvisibility: visible !important;\nfont-size: 0%;\ntransition: 0.2s;\n}\n.full-sentence ruby:hover rt {\nfont-size: 50%;\ntransition: 0.2s;\n}\n
If you want more control over the furigana, more options are shown below. However, note that the options below require you to compile the note.
"},{"location":"sentences/#furigana-when-to-show","title":"Furigana: When to show","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, furigana is shown on hover. This can be changed to only be shown on click, or always/never shown.
On clickOn hover (default)On hover and clickAlways revealedNever revealed TODO gif: show on click
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"click\",\n
This is commonly paired with the hide furigana spacing option, so furigana does not impede with the sentence whatsoever until toggled.
TODO gif: show on hover
This is the default behavior.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"hover\",\n
TODO gif: show on hover and click
This allows furigana to be shown on hover, and toggled on click.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"both\",\n
TODO gif: static with mouseover
This is not recommended, because you should not be relying on furigana to understand Japanese.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"always\",\n
TODO gif: static with mouseover
If you are looking to not see furigana at all, feel free to use this option. However, I personally recommend toggling on click instead of removing furigana completely.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.displayMode\": \"never\",\n
"},{"location":"sentences/#furigana-hide-spacing","title":"Furigana: Hide spacing","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Furigana that extends past the length of the kanji will add additional spacing around the kanjis, which may be unpleasant to look at.
One solution to this is to simply hide the spacing until hover or click. This has the unintentional consequence where kanjis can potentionally change position, or overflow into the next line. There is also a possibility that the entire sentence shifts over a bit to the left due to (what I think is a) chromium based bug1.
Hide SpacingHide spacing with no transitionKeep spacing (default) TODO img
Instructions (click here) Change the following compile options:
\"fullSentenceRuby.fillMode\": \"font-size\",\n\"fullSentenceRuby.fillModeFontSizeTransition\": true,\n
TODO img
Instructions (click here) Change the following compile options:
\"fullSentenceRuby.fillMode\": \"font-size\",\n\"fullSentenceRuby.fillModeFontSizeTransition\": false,\n
TODO img
This is the default behavior.
Instructions (click here) Change the following compile option:
\"fullSentenceRuby.fillMode\": \"opacity\",\n
Note
All of the examples above are shown with furigana on hover. They will also work with furigana on click.
"},{"location":"sentences/#generating-sentence-furigana","title":"Generating Sentence Furigana","text":"TODO AJT Japanese and {jpmn-sentence-bolded-furigana-plain}
"},{"location":"sentences/#furigana-generation-ajt-japanese","title":"Furigana Generation: AJT Japanese","text":"TODO
"},{"location":"sentences/#furigana-generation-yomichan-helper","title":"Furigana Generation: Yomichan Helper","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
helper: {jpmn-sentence-bolded-furigana-plain}
TODO add details on how to even use this
This automatically uses Yomichan's internal furigana generator to add furigana to your sentence. Use this under SentenceReading
.
This is useful if:
- You are not using AJT Japanese, or
- You are using a device that doesn't have AJT Japanese installed (say, a phone), and you do not want to bulk generate furigana after each session.
"},{"location":"sentences/#keeping-and-removing-newlines-within-the-display-sentence","title":"Keeping and removing newlines within the display sentence","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
You can add newlines to the Sentence
field to make the full sentence field have cleaner line breaks. If you do this, you will need to regenerate the SentenceReading
field if you are using furigana.
However, these newlines are automatically removed from the display sentence if the width of the screen is determined to be too small. To override this option, you can use the following custom CSS:
Instructions (click here) Keep all newlinesRemove all newlinesRemove all newlines when AltDisplay is not used .expression .expression-inner br {\ndisplay: inline !important;\n}\n
.expression .expression-inner br {\ndisplay: none !important;\n}\n
This only removes newlines when the AltDisplay
(or AltDisplayPASentenceCard
) field is not being used as the display sentence.
.expression .expression-inner br {\ndisplay: inline !important;\n}\n.expression .expression-inner:not(.expression-inner--altdisplay) br {\ndisplay: none !important;\n}\n
"},{"location":"sentences/#multiple-sentences","title":"Multiple Sentences","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
- TODO
- summary: split with multiple newlines, i.e.
<br><br>
- TODO pictures
-
See #4 in the minor visual bugs list.\u00a0\u21a9
"},{"location":"setup/","title":"Setup: Installing","text":""},{"location":"setup/#overview","title":"Overview","text":"A full sentence mining workflow requires two main parts:
- Text to make the cards from.
- The card exporter, to create cards from the text.
- And optionally, the image and sentence audio from the media (if the media has either).
These next few sections (Installing, Anki and Yomichan) are all dedicated to providing the minimal setup to setup the card exporter to create cards with this note type.
Getting the text (the first part) and getting the image and sentence audio (the optional part of part two) are not heavily focused on within this site, but can be found under Setup: Text & Media page.
Note
There's quite a few things to setup to use this note. If you ever get lost, remember that this site has a search bar!
"},{"location":"setup/#installing-anki","title":"Installing Anki","text":"Download and install Anki from the official website if you haven't already. I recommend downloading the latest version, to avoid having to do extra steps during the setup.
"},{"location":"setup/#installing-jp-mining-note","title":"Installing jp-mining-note","text":"There are three ways of installing the note:
- Via JPMN Manager, a small Anki add-on that can install and update jp-mining-note, as well as notify you when updates are available. If you don't know which method to choose, choose this one.
- Via command line. This method is recommended for people who are familiar with
git
and python
, and don't want to download another Anki add-on. - Manually, using Anki. This tends to be more error-prone due to having many more potential points of failure. Therefore, I wouldn't recommend installing the note this way. It should only be used if the first two options didn't work.
Option 1: JPMN Manager (click here) Note
If you have previously installed Aquafina's old version of the JPMN add-on, then you must remove it before installing the new version below. The old and new versions will conflict with each other if they are both installed. In your list of Anki add-ons, you should only see JPMN Manager with prereleases New Version
. If you see JPMN Manager with prereleases
then please remove it and restart Anki before proceeding.
-
To install any Anki add-on, navigate to:
(Main Window) \u2192 Tools
\u2192 Add-ons
\u2192 Get Add-ons...
From here, you can install JPMN Manager and Anki-Connect by using the following add-on codes:
301910299 2055492159\n
-
Restart Anki, to load the new add-ons.
-
Within Anki, navigate to the following:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Install jp-mining-note
This will install latest version of the note, as well as the fonts required for the note to work. Note: Installing jp-mining-note might take a while, and Anki may appear frozen.
-->
Option 2: Command Line (click here) WindowsmacOS & Linux git clone \"https://github.com/arbyste/jp-mining-note.git\"\n:: TODO change this to master branch\ncd jp-mining-note\ngit checkout dev\n\n:: Ensure you have Anki open, and with Anki-Connect running\n:: Also ensure that you have python 3.9+ installed.\n:: It *MAY* work with lower versions of python, but I make no such guarantee. ;)\npython tools\\install.py\n
git clone \"https://github.com/arbyste/jp-mining-note.git\"\n:: TODO change this to master branch\ncd jp-mining-note\ngit checkout dev\n\n# Ensure you have Anki open, and with Anki-Connect running\n# Also ensure that you have python 3.9+ installed.\n# It *MAY* work with lower versions of python, but I make no such guarantee. ;)\n# You may have to use `python3` instead of `python`.\npython tools/install.py\n
install.py
will install latest stable version of the note, as well as the fonts required for the note to work.
Option 3: Manually (click here) - Go to the releases page and download the cards from the latest release. You should download the
{version}-jpmn_example_cards.apkg
file. -
After you download the cards, import them by navigating to Anki by doing the following:
File
(top left corner) \u2192 Import...
-
By default, the custom fonts do not come with the .apkg
file. To install these fonts, head over to this repository's media folder and download the 4 .otf
files.
- Move the
.otf
files into the media folder of your profile (Anki2/PROFILENAME/collections.media
).
"},{"location":"setup/#verifying-the-note-works","title":"Verifying the Note Works","text":"You should see a deck JPMN-Examples
in your collection. View one of the cards and make sure the card looks similar to the one below:
Dark ThemeLight Theme Please check the following in particular:
-
The fonts should match with the above example.
If the fonts don't match, try restarting Anki and/or your computer. If the fonts still don't match, the note was likely installed manually. Please verify you manually installed the fonts and placed them in the correct folder (see steps 3 and 4).
-
Notice how at the top left corner, the info circle (the \"i\" encased within the circle) is the default grey color.
If this circle is red or orange, there may be something wrong with the template. Please see this section for basic troubleshooting.
-
Clicking on the image to zoom should work out of the box.
Kanji hover may not work yet. If it doesn't work, continue reading to the Anki-Connect setup instructions on the next page.
If the image suddenly appears without a zoom animation, then you must enable animations on Anki.
"},{"location":"setup/#anki-setup","title":"Anki Setup","text":"This note requires some additional setup to Anki. In particular, some add-ons are required for the note to work.
Click here see how to setup Anki!
"},{"location":"setupandroid/","title":"Extra: Android","text":""},{"location":"setupandroid/#summary","title":"Summary","text":"On Android, it is possible to review and create JPMN cards similarly to desktop. It is expected that you have setup Anki and Yomichan properly on your desktop machine before continuing with this page.
"},{"location":"setupandroid/#reviewing","title":"Reviewing","text":"To review Anki cards on Android, use AnkiDroid.
In order to review the same cards on desktop, you must sync your collection with AnkiWeb. More tech savy users can sync their collections using a self-hosted server.
Note
If your collection on AnkiWeb is large, your initial sync to AnkiWeb will likely take a very long time. After your first sync, your collection may not actually be fully synced even if AnkiDroid says so. Keep pressing the sync button until you are sure that everything is indeed synced.
"},{"location":"setupandroid/#ankidroid-usage-tips","title":"AnkiDroid Usage Tips","text":" - Set the night theme to \"Dark\" if you want a similar dark theme to Anki's desktop client.
- Under the card browser, the default settings show the
Question
and Answer
as columns, which likely looks very strange. I recommend changing the columns to Sort field
and Due
respectively. -
If you are using pass/fail, you can remove the bottom bar by doing the following:
Settings
\u2192 Appearance
\u2192 Answer buttons position
\u2192 Select None
In replacement of the bottom bar, you can use custom gestures. I personally use:
- Show answer: Swipe up
- Answer button 1: Swipe right
- Answer recommended: Swipe left
- If you are using custom gestures, I recommend disabling most (if not all) tap gestures. This is because you will likely have to tap on various parts of the screen when reviewing, to reveal various parts of the card.
"},{"location":"setupandroid/#creating-cards","title":"Creating Cards","text":"There are two main ways of creating cards on Android. Both require AnkiDroid to be installed.
-
AnkiconnectAndroid (recommended)
AnkiconnectAndroid is an implementation of Anki-Connect, on Android. Combined with Kiwi browser, you can use Yomichan directly on your Android device, and have the exact same setup as you would on desktop. To do this, follow the instructions on the AnkiconnectAndroid's README page.
It might help to export a copy of Yomichan settings from your PC and import said settings on Android, instead of re-doing all of the steps on Android.
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, which is mostly useful for novels. See here for more info.
-
jidoujisho
This is a all-in-one solution app that allows you to immerse in various ways. However, jidoujisho provides a more limited interface when exporting the note, meaning that some features will be not be supported. See here for basic instructions on how to use the app to export JPMN cards.
"},{"location":"setupanki/","title":"Setup: Anki","text":""},{"location":"setupanki/#new-to-anki","title":"New to Anki?","text":"If you have never used Anki before, I recommend using fsrs4anki to get more optimized settings than the default settings.
That article showcases only one way of setting up Anki's settings for language learning. Feel free to view some other examples here.
"},{"location":"setupanki/#updating-anki","title":"Updating Anki","text":"It is highly recommended that you are using the latest (stable) Anki version (or as close as you can get to the latest Anki version). This includes using the Qt6 version instead of Qt5 if possible.
Using the latest version of Anki is recommended for the following reasons:
- The note is primarily tested and maintained on the latest versions of Anki.
- There are a few minor but known bugs that this note type has with older Anki versions. These bugs do not exist in newer Anki versions.
Worst case scenario, if any essential add-ons no longer work, you can always downgrade back to a previous version.
If you aren't upgrading Anki from an older version, you can skip the rest of this section.
Tips on Updating Anki (click here) Official Documentation:
-
The official documentation on how to install and upgrade Anki is shown below:
Windows\u30fbmacOS\u30fbLinux
Note that for all three, there are additional sections in the table of contents to the left that could be helpful.
Add-ons Breaking:
-
If an add-on (that worked in a previous version of Anki) no longer works, you have a few options you can try:
- As a sanity check, click the
Check for Updates
button on Anki's Addons
window. -
Check that the add-on supports the current version of Anki in the official AnkiWeb page. If the page says that the current Anki version is supported, try reinstalling it again from AnkiWeb.
Occasionally, the Check for Updates
button doesn't properly work, so this method ensures that your addon is actually updated.
"},{"location":"setupanki/#enable-animations-2161-2163","title":"Enable Animations (2.1.61 - 2.1.63)","text":"If you are using Anki versions 2.1.61, 2.1.62 or 2.1.63, animations are disabled by default. The note works best with animations enabled. To enable animations, head over to:
Tools
\u2192 Preferences
\u2192 Appearance
\u2192 Reduce Motion
\u2192 (unchecked)
Note
Starting Anki 2.1.64, Reduce Motion
no longer affects animations within templates. 1
"},{"location":"setupanki/#fixing-your-editor-fonts","title":"Fixing your Editor Fonts","text":"By default, your editor fonts may be showing Japanese characters using a Chinese font. To determine this, compare the \u76f4 character in the \u53e9\u304d\u76f4\u3059 example card with the following pictures:
Japanese (correct)Chinese (incorrect!)
If you are using a Chinese font, you likely want to switch to using a Japanese font.
How to fix Chinese Fonts within Anki Card Editor (click here) - Within Anki's card browser, select any JPMN card. You may have to select a deck on the left sidebar.
- Click on the
Fields
tab within the card editor. -
Change the Editing Font
to a Japanese font.
If you don't know what Japanese fonts exist, try searching for any of the following (courtesy of TMW):
- IPAexGothic
- Meiryo
- MS Gothic
- Yu Gothic
- Hiragino Kaku Gothic Pro
- Noto Sans CJK JP Regular
If you cannot find any of these, you may have to install a Japanese font.
-
After finding a correct font, you will have to set all other fields to this same font. This can be done manually, or with the following batch command:
set_fonts_to_key_font\n
The above batch command sets the font of all fields to the font in the Key
field.
More info on how to change the font everywhere else can be found here.
"},{"location":"setupanki/#dark-mode","title":"Dark Mode","text":"Both light mode and dark mode are supported by this note.
The note automatically adjusts according to Anki's theme. To change Anki's theme, head over to:
Tools
\u2192 Preferences
\u2192 Basic
\u2192 Theme (dropdown)
Note
The note's theme currently cannot be forced to be a particular theme without changing Anki's settings.
"},{"location":"setupanki/#anki-add-ons","title":"Anki Add-ons","text":"There are certain add-ons that must be installed for this note type to work.
"},{"location":"setupanki/#downloading-add-ons","title":"Downloading Add-ons","text":"To download an add-on, copy the add-on's code, and navigate to the following to paste the code:
Tools
\u2192 Add-ons
\u2192 Get Add-ons...
"},{"location":"setupanki/#required-add-ons","title":"Required Add-ons","text":""},{"location":"setupanki/#anki-connect","title":"Anki-Connect","text":"Code: 2055492159
Required for Yomichan and most other Anki-related automated tasks to work. I use the default config that comes with the add-on.
If you installed JPMN Manager, you likely already have this installed.
Note for Anki versions 2.1.49 and below (click here) This is left for legacy purposes, because jp-mining-note no longer officially supports versions 2.1.49 or below.
Anki versions 2.1.49 and below require a hack to the Anki-Connect config for certain features within the card to work. In particular, Anki-Connect is used for the \"Kanji Hover\" feature and the \"Open Fields on New Card\" feature.
To make those features work, add \"null\"
to the webCorsOriginList
list in the Anki-Connect config file. An example of how the config should look is shown below:
\"webCorsOriginList\": [\n \"http://localhost\",\n \"null\"\n]\n
Of course, this isn't very safe and it is highly recommended that you upgrade Anki to avoid this problem.
If you aren't interested in those features, you can skip this step and disable them in the runtime options.
"},{"location":"setupanki/#optional-add-ons","title":"Optional Add-ons","text":"These are a set of optional, but useful add-ons that can easily work with the card. If this is your first time here, I recommend skimming through the descriptions and choosing the add-ons that seem appealing for you.
Note
Make sure to head over to the final steps section afterwards!
"},{"location":"setupanki/#css-injector","title":"CSS Injector","text":"Code: 181103283
I strongly recommend using this, because if you don't use this, the fields within the Anki field editor won't have certain stylizations that makes the field actually interpretable.
There are two ways of using css injector with this note type:
Option 1: Automatically updates with the card (recommended) WindowsmacOSLinux As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
:: be sure to change USERNAME to your computer username!\ndel \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\field.css\"\ndel \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\editor.css\"\n
Afterwards, open command prompt with elevated permissions.
Note
Be sure to open command prompt, and not PowerShell. If you've never used command prompt before, see this.
With command prompt opened, run the following command:
:: be sure to change USERNAME to your computer username and PROFILENAME to your Anki profile.\n:: There are **two** USERNAME's to replace, and **one** PROFILENAME to replace\n:: in the commands below.\n:: Make sure to replace all the fields!\nmklink \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\field.css\" \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\PROFILENAME\\collection.media\\_field.css\"\nmklink \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\addons21\\181103283\\user_files\\editor.css\" \"C:\\Users\\USERNAME\\AppData\\Roaming\\Anki2\\PROFILENAME\\collection.media\\_editor.css\"\n
As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
rm \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/field.css\"\nrm \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/editor.css\"\n
Afterwards, run the following command:
# be sure to change `PROFILENAME` to your Anki profile\nln -s \"$HOME/Library/Application Support/Anki2/PROFILENAME/collection.media/_field.css\" \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/field.css\"\nln -s \"$HOME/Library/Application Support/Anki2/PROFILENAME/collection.media/_editor.css\" \"$HOME/Library/Application Support/Anki2/addons21/181103283/user_files/editor.css\"\n
As a preliminary step, you will have to remove the empty field.css
and editor.css
files that comes with the add-on. That can be done through command line (below), or you can simply navigate to the Anki2/addons21/181103283/user_files
folder (within the addons folder) and delete both css
files.
rm \"$HOME/.local/share/Anki2/addons21/181103283/user_files/field.css\"\nrm \"$HOME/.local/share/Anki2/addons21/181103283/user_files/editor.css\"\n
Afterwards, run the following command:
# be sure to change `PROFILENAME` to your Anki profile\nln -s \"$HOME/.local/share/Anki2/PROFILENAME/collection.media/_field.css\" \"$HOME/.local/share/Anki2/addons21/181103283/user_files/field.css\"\nln -s \"$HOME/.local/share/Anki2/PROFILENAME/collection.media/_editor.css\" \"$HOME/.local/share/Anki2/addons21/181103283/user_files/editor.css\"\n
Option 2: Manually without respecting updates - Navigate to css injector addon folder (
Anki2/addons21/181103283/user_files
) - Remove the existing
field.css
and editor.css
files - Copy the
_field.css
file and _editor.css
file (found under your profile's media folder) into the css injector add-on directory. - Rename
_field.css
to field.css
. - Rename
_editor.css
to editor.css
.
Note
If either of the two css files ever update, you will have to manually copy and rename the file again.
"},{"location":"setupanki/#ajt-japanese","title":"AJT Japanese","text":"Code: 200813220
JP Mining Note uses a slightly modified version of AJT Japanese that has been pre-configured to work with this note type.
Warning
As of writing this (2023/04/28), AJT Japanese is only guaranteed to work on Anki versions 2.1.60 and above, because it is no longer maintained on previous versions. If you are using an older version of Anki and you want to use this add-on, please update Anki to 2.1.60 or above.
This is an add-on that automatically adds furigana and pitch accents to cards upon Yomichan card creation. Previously known as AJT Furigana
, and now comes packaged with AJT Pitch Accent
.
If this add-on is not used, then the following features will be missing:
- Automatically generated furigana
- Devoiced and nasal information to pitch accents
- Less coverage on pitch accents
- If your Yomichan pitch accent dictionaries did not contain any pitch accent info for the word but the add-on does, then it will use the add-on data. This will likely happen for expressions containing more than one word. Fortunately, AJT Japanese can usually detect the existence of multiple words, and add the pitch accent for each individual word.
The version of AJT Japanese that is linked above has already been configured to work with JP Mining Note, so there is no need to modify the configuration. After installation, you can move on to Final Steps.
"},{"location":"setupanki/#additional-info","title":"Additional Info","text":"Furigana generation is occasionally incorrect, so if you plan on using furigana regularly, you should double-check the readings to make sure they are correct.
JapaneseSupport v.s. AJT Japanese (Furigana) If you use JapaneseSupport, bolded words and other styles within a field are not transferred over from the original field to the reading field. Additionally, JapaneseSupport does not have an option to automatically add the reading upon card creation. AJT Japanese supports both of those of those features.
"},{"location":"setupanki/#config-changes","title":"Config Changes","text":"If you want to manually modify the configuration of AJT Japanese, this section might be useful. It details the changes that have been made to the default AJT Japanese configuration file. Documentation for configuring AJT Japanese can be found from the page for the original version of the add on.
To view the config of any Anki add-on, head over to:
Tools
\u2192 Add-ons
\u2192 (select the add-on) \u2192 Config
.
Below is an annotated copy of the config file that JP Mining Note uses:
Click here to see the full AJT Japanese config The important changes to the config are:
fields
profiles
pitch_accent.reading_separator
pitch_accent.word_separator
pitch_accent.maximum_results
pitch_accent.style
{\n\"cache_lookups\": 1024,\n\"last_file_save_location\": \"\",\n\"profiles\": [ // (2)!\n{\n\"name\": \"Add furigana for sentence\",\n\"note_type\": \"JP Mining Note\",\n\"source\": \"Sentence\",\n\"destination\": \"SentenceReading\",\n\"mode\": \"furigana\",\n\"split_morphemes\": true,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add furigana for word -- UNUSED BY jp-mining-note\",\n\"note_type\": \"AJT_JAPANESE_IGNORE_PROFILE\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabFurigana\",\n\"mode\": \"furigana\",\n\"split_morphemes\": false,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add pitch accent for word\",\n\"note_type\": \"JP Mining Note\",\n\"source\": \"Word\",\n\"destination\": \"AJTWordPitch\",\n\"mode\": \"pitch\",\n\"split_morphemes\": false,\n\"output_format\": \"html\",\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n},\n{\n\"name\": \"Add audio for word -- UNUSED BY jp-mining-note\",\n\"note_type\": \"AJT_JAPANESE_IGNORE_PROFILE\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabAudio\",\n\"mode\": \"audio\",\n\"split_morphemes\": false,\n\"triggered_by\": \"focus_lost,toolbar_button,note_added,bulk_add\",\n\"overwrite_destination\": false\n}\n],\n\"pitch_accent\": {\n\"lookup_shortcut\": \"Ctrl+8\",\n\"output_hiragana\": false,\n\"kana_lookups\": true,\n\"skip_numbers\": true,\n\"reading_separator\": \"\u30fb\", // (3)!\n\"word_separator\": \"\u3001\",\n\"blocklisted_words\": \"\u3053\u3068,\u3078,\u304b,\u3088,\u3093,\u3060,\u3073,\u306e,\u3084,\u306d,\u3070,\u3066,\u3068,\u305f,\u304c,\u306b,\u306a,\u306f,\u3082,\u307e\u3059,\u304b\u3089,\u3044\u308b,\u305f\u3061,\u3066\u308b,\u3046,\u307e\u3057\u3087,\u305f\u3044,\u3059\u308b,\u3067\u3059,\u306a\u3044\",\n\"maximum_results\": 100, // (4)!\n\"discard_mode\": \"discard_extra\",\n\"style\": \"none\" // (1)!\n},\n\"furigana\": {\n\"skip_numbers\": true,\n\"prefer_literal_pronunciation\": false,\n\"reading_separator\": \", \",\n\"blocklisted_words\": \"\u4eba\",\n\"mecab_only\": \"\u5f7c,\u732b,\u9996,\u6bcd,\u9854,\u6728,\u982d,\u79c1,\u5f1f,\u7a7a,\u4f53,\u884c\u304f\",\n\"maximum_results\": 1, // (5)!\n\"discard_mode\": \"discard_extra\"\n},\n\"context_menu\": {\n\"generate_furigana\": true,\n\"to_katakana\": true,\n\"to_hiragana\": true,\n\"literal_pronunciation\": true,\n\"look_up_word\": true\n},\n\"toolbar\": { // (6)!\n\"generate_all_button\": {\n\"enabled\": false,\n\"shortcut\": \"Alt+P\",\n\"text\": \"\u5165\"\n},\n\"regenerate_all_button\": {\n\"enabled\": false,\n\"shortcut\": \"Alt+;\",\n\"text\": \"\u518d\"\n},\n\"furigana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u632f\"\n},\n\"hiragana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u5e73\"\n},\n\"clean_furigana_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u524a\"\n},\n\"audio_search_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u691c\"\n},\n\"add_definition_button\": {\n\"enabled\": false,\n\"shortcut\": \"\",\n\"text\": \"\u610f\"\n}\n},\n\"audio_sources\": [\n{\n\"enabled\": false, // (7)!\n\"name\": \"NHK-2016\",\n\"url\": \"https://github.com/Ajatt-Tools/nhk_2016_pronunciations_index/releases/download/v1.2/NHK_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"NHK-1998\",\n\"url\": \"https://github.com/Ajatt-Tools/nhk_1998_pronunciations_index/releases/download/v1.1/NHK_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"Shinmeikai-8\",\n\"url\": \"https://github.com/Ajatt-Tools/shinmeikai_8_pronunciations_index/releases/download/v1.5/Shinmeikai-8_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"Daijisen\",\n\"url\": \"https://github.com/Ajatt-Tools/daijisen_pronunciations_index/releases/download/v1.0/Daijisen_main.zip\"\n},\n{\n\"enabled\": false,\n\"name\": \"TAAS\",\n\"url\": \"https://github.com/Ajatt-Tools/taas_pronunciations_index/releases/download/v1.0/TAAS_main.zip\"\n}\n],\n\"audio_settings\": {\n\"dictionary_download_timeout\": 30,\n\"audio_download_timeout\": 6,\n\"attempts\": 4,\n\"maximum_results\": 99,\n\"ignore_inflections\": false,\n\"stop_if_one_source_has_results\": false,\n\"search_dialog_field_name\": \"VocabAudio\",\n\"tag_separator\": \"<br>\"\n},\n\"definitions\": {\n\"timeout\": 10,\n\"remove_marks\": true,\n\"dict_name\": \"meikyou\",\n\"search_type\": \"exact\",\n\"source\": \"VocabKanji\",\n\"destination\": \"VocabDef\",\n\"behavior\": \"append\"\n}\n}\n
-
\"style\": \"none\"
formats the pitch accent data using a simple html span structure, which makes it easy to control how pronunciation information is displayed. Without this, pitch accent information in the AJTWordPitch field will not render correctly.
-
The Add audio for word
and Add furigana for word
profiles are not used. In order to disable them, the note type is set to AJT_JAPANESE_IGNORE_PROFILE
, which only matches note types containing the string AJT_JAPANESE_IGNORE_PROFILE
. It is very unlikely that your Anki notes will unintentionally contain this string.
-
This makes the separators behave like the old version, and has to be changed to this for the default config of jp-mining-note to work.
-
This is set to a high number in order for many pitch accents to be displayed for long expressions. This is fine because the pitch accent display is usually overwritten by the PAPositions
field, so it's rare to see the AJTWordPitch
field results anyways. Additionally, a higher number increases the sample size for the internal auto-pitch-accent module, to better search for devoiced and nasal markers.
-
(Optional) This is to restrict the generated furigana to only show one reading. Feel free to leave this as the default (3
).
-
(Optional) I personally have the buttons removed because I don't want it to clutter up the editor toolbar. Feel free to have these enabled.
-
(Optional) These are disabled because it slows down Anki's startup time. Additionally, the note does not use this feature. If you want to use this feature, feel free to enable these.
"},{"location":"setupanki/#final-steps-after-installing-add-ons","title":"Final Steps: After Installing Add-ons","text":"After the above setup, make sure to restart Anki for the add-ons and config changes to take effect. If the css injector add-on is installed correctly, your Anki field editor should now have color!
Additionally, now that Anki-Connect is installed, kanji hover should also be functioning. Hover over a kanji within the word reading to make sure that a popup appears. In particular, the \u8005 kanji in the example \u507d\u8005 and \u4e0d\u5be9\u8005 cards should point to each other.
Note
Hovering over the other kanjis will display a Kanji not found.
message, because the template only searches for kanjis within existing jp-mining-note cards.
If you wish to see usages of the kanji within words outside of your deck, I highly recommend using Marv's JPDB Kanji Yomichan Dictionary.
"},{"location":"setupanki/#transfer-existing-notes","title":"Transfer Existing Notes","text":"If you wish to transfer existing cards into this note type (say, to make kanji hover work on existing cards), please see this page.
"},{"location":"setupanki/#updating-the-note","title":"Updating the Note","text":"If you wish to update the note, follow the steps in this page.
This note does not auto-update. This should keep your setup stable, as long as you do not update Anki.
When updating Anki, don't forget to check if there is a new version of this note available, because this note should update along with Anki.
"},{"location":"setupanki/#setting-up-yomichan","title":"Setting up Yomichan","text":"Of course, you can have an Anki template, but what's the point of it if you can't make cards with it?
We will use Yomichan to create these cards.
Click here see how to setup Yomichan!
-
https://github.com/ankitects/anki/commit/c54b897b4f456124f0b1956a05deb8f12e98f23c \u21a9
"},{"location":"setupasbplayer/","title":"asbplayer","text":"asbplayer is a browser-based media player and Chrome extension, used for subtitle sentence mining and video playing. asbplayer works on both video streaming sites and downloaded videos. However, codec support for downloaded videos is limited, and is purely dependent on the browser used.
If you are looking to create cards using downloaded videos, I recommend mpvacious.
"},{"location":"setupasbplayer/#existing-guides","title":"Existing Guides","text":"There are a bunch of existing guides out there for asbplayer. A few are listed below.
- mikumino's mining workflow (asbplayer + jp-mining-note)
- asbplayer's list of community guides
- Shiki's mining workflow (asbplayer)
- Contact info:
boundary-of-emptiness#3065
on the Refold (JP) Discord server
- Tigy01's mining workflow (asbplayer)
- Contact info:
Tigy01#1231
on the Refold (JP) Discord server
- Brian's \"Sentence mining from Netflix and YouTube with asbplayer\"
"},{"location":"setupasbplayer/#installation","title":"Installation","text":"Install the extension from asbplayer's releases page.
"},{"location":"setupasbplayer/#configuration","title":"Configuration","text":"asbplayer's settings can be found here.
I recommend filling out the following fields as follows:
asbplayer field JPMN field Sentence Field Sentence
Definition Field Word Field Audio Field SentenceAudio
Image Field Picture
Source Field AdditionalNotes
URL Field AdditionalNotes
"},{"location":"setupasbplayer/#card-creation","title":"Card Creation","text":"To create JPMN cards with asbplayer:
- Attach asbplayer to the desired video, or drag/drop a downloaded video into the asbplayer site.
- Create the card with Yomichan
- Capture the audio (TODO specific instructions! What default keybinds?)
- Update the last card (TODO is this the exact text?)
"},{"location":"setupasbplayer/#other","title":"Other","text":" -
A common issue with asbplayer is that the SentenceReading
field may differ from the Sentence
field. See the FAQ on how to fix it.
-
You have to export the audio as mp3
if you plan on using AnkiMobile (iOS), or AnkiWeb.
"},{"location":"setupchanges/","title":"Setup Changes","text":"This page documents any changes to the setup as recorded in previous pages, as well as any important handlebars and JPMN updates. Most importantly, this documents the existance of breaking changes from external programs and if there are fixes or workarounds for them.
If something breaks, and you suspect it's due to an external program updating, please check here first! If you can't find any solution, please let me know!
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13","title":"2023/10/08 (JPMN 0.12.0.0-prerelease-13)","text":"This version of jp-mining-note fixes a bug that was introduced with a recent AJT Japanese update. This bug resulted in an Unexpected flattened.childNode
error on new cards, and prevented pitch accent information from being displayed correctly. See the Updating page on how to update the note. Afterwards, see below for the other necessary changes that must be made to properly update the note.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-ajt-config","title":"AJT Japanese Config Update","text":"This update requires you to update your AJT Japanese config settings. To do so, go to the AJT Japanese setup instructions and follow the instructions. The main changes are the removal of the \"styles\"
key, and the addition of the \"style\"
key under the \"pitch_accent\"
settings.
Note
After updating the AJT Japanese config, make sure you restart Anki. Do this before moving on to the next step.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-ajt-regen","title":"Regenerating the AJTWordPitch field","text":"After updating your AJT Japanese config settings, you will need to regenerate the AJTWordPitch field for all your cards.
Warning
This procedure will delete data from all your cards, however, under normal use, the AJTWordPitch field should only contain autogenerated content, so this shouldn't be a problem. If, for some reason, you have manually edited the AJTWordPitch field for any cards, those edits should be recorded somewhere before running this procedure.
- Run the following batch command:
empty_field AJTWordPitch\n
- Regenerate the AJT Japanese data for all of your notes.
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-reformat-paoverride","title":"Reformat any entries in the PAOverrideText field","text":"Since the HTML format for displaying pronunciation data has changed, any pronunciation data that has been manually entered into the PAOverrideText field will need to be rewritten. The new format is described here.
A simple way to find all cards that contain manually edited data in the PAOverrideText field is to run the following query in the Anki browser:
PAOverrideText:_*\n
"},{"location":"setupchanges/#v0-12-0-0-prerelease-13-final-steps","title":"Final Steps","text":"After changing everything, don't forget to test that the card works! If you reached this point, then congratulations! You are finally done with updating the note! Pitch accent and pronunciation data should now be displayed correctly on all cards.
If your cards still don't display properly, then it's possible you forgot to restart Anki after updating the AJT Japanese configuration. Restart Anki to confirm the config change, and then go back and regenerate the AJTWordPitch field again.
"},{"location":"setupchanges/#v0-12-0-0","title":"2023/??/?? (JPMN 0.12.0.0)","text":"This version of jp-mining-note comes with many changes, including an entire backend javascript rework. See the Updating page on how to update the note. Afterwards, see below for the other necessary changes that must be made to properly update the note.
"},{"location":"setupchanges/#v0-12-0-0-config-rework","title":"Config Rework","text":"The _jpmn-options.js
runtime options file has been completely reworked, meaning your previous config will no longer work. With this update, the file has been replaced automatically, so the note can work for future versions.
If you have changed any runtime options before, you will need change them again. Common runtime-options (pitch accent coloring and image blur) are included as examples; remove the comment to re-enable them. To see all available runtime options, see Runtime Options: Available Options.
A backup of your previous runtime options should be made. The location of the backup is different depending on the updating method used:
JPMN ManagerCommand Line Anki2/addons21/1732829476/user_files/backup\n
(repo root)/backup\n
Note
For people using pitch accent coloring, the entire card is now highlighted with the pitch accent group. To restore the previous behavior, use these runtime options:
\"autoPitchAccent.coloredPitchAccent.color.fullSentence\": false,\n\"autoPitchAccent.coloredPitchAccent.color.definitions\": false,\n
"},{"location":"setupchanges/#v0-12-0-0-multiple-devices","title":"Updating Multiple Devices","text":"A common issue with updating multiple devices (for example, updating your phone) is that the new runtime options file may not be synced properly. In the case that the file is not synced properly, you will get the following warning:
JPMNOptions was not defined in the options file. Was there an error?\n
The official documentation says that adding or removing a media file should fix this issue. However, I received various reports from people saying this does not work. A fool-proof workaround that is guaranteed to work is documented below.
Batch CommandsManually - Make sure all devices are synced.
-
Run the following batch command:
move_runtime_options_file_to_temp\n
-
Sync to AnkiWeb (from the computer).
-
Run the following batch command:
move_runtime_options_file_to_original\n
-
Sync to AnkiWeb (from the computer).
- On all other devices, sync from AnkiWeb.
- Make sure all devices are synced.
- Rename the
_jpmn-options.js
file to something different manually, i.e. _jpmn-options-TEMP.js
. - Sync to AnkiWeb (from the computer).
- Rename the temporary file (in the example above:
_jpmn-options-TEMP.js
) to the original name (_jpmn-options.js
). - Sync to AnkiWeb (from the computer).
- On all other devices, sync from AnkiWeb.
"},{"location":"setupchanges/#v0-12-0-0-handlebars","title":"Yomichan Handlebars","text":"Yomichan's Handlebars has been updated, with some new helpers and features being added.
- To update Yomichan's Anki Card Format, see here.
- To update your handlebars templates, see here.
After updating the templates, the following fields must be changed:
FrequencySort
: {jpmn-min-freq}
\u2192 {jpmn-frequency-sort}
- Newer users might already have this set correctly. In that case, you don't have to change anything.
YomichanWordTags
: (empty)
\u2192 {tags}
- See here for instructions on how to update Anki Card Format.
Note
Remember that these settings must be updated on every device that you use Yomichan on! This includes Android (if you use AnkiConnectAndroid), and all active Yomichan profiles.
"},{"location":"setupchanges/#v0-12-0-0-frequency-display","title":"Frequency Display","text":"The frequency at the top right now defaults to using the FrequencySort value. This is because it is usually more useful to see a summary of the values, instead of all the literal values itself.
- If you prefer the list display, see Frequencies: List Mode. Also see Frequencies: List Mode Maximum.
- If you prefer the frequency sort display but you don't have a frequency sort value, backfill the frequencies.
- If you prefer the frequency sort display but your frequency sort is somehow invalid:
- Clear out your
FrequencySort
field entirely through the following batch command: clear_field \"FrequencySort\"\n
- Backfill the frequencies.
"},{"location":"setupchanges/#v0-12-0-0-automatic-field-collapsing","title":"Automatic Field Collapsing","text":"For newer versions of Anki, you can set a field to be collapsed by default by heading over to:
(Note editor) \u2192 Fields...
\u2192 Collapse by default
Feel free to automatially collapse any fields you don't use, or very rarely use. The fields that are collapsed by default can be found here.
"},{"location":"setupchanges/#v0-12-0-0-custom-scss","title":"Custom SCSS","text":"For people who are using custom SCSS (usually through src/scss/extra
, when building the note), it is now recommended that the extra
folder is moved to the overrides/scss
folder. This is purely a stylistic change, to better separate user-defined changes and source code.
"},{"location":"setupchanges/#font-size-changes","title":"Font Size Changes","text":"The default font sizes of certain sections have been changed to be a bit bigger, in order to make kanji more readable. If you prefer the original smaller font sizes, the following CSS will revert the changes:
.hover-tooltip__word-div {\nfont-size: 1em;\n}\n.hover-tooltip__word-div b {\nfont-weight: var(--bold-font-weight);\n}\n.hover-tooltip__card--sentence-only .hover-tooltip__sent-div b {\nfont-weight: var(--bold-font-weight);\n}\n:root {\n--glossary-font-size: 1.125rem;\n}\n@media (max-width: 850px), (max-height: 700px) {\n:root {\n--glossary-font-size: 0.9375rem;\n}\n}\n
"},{"location":"setupchanges/#v0-12-0-0-final-steps","title":"Final Steps","text":"After changing everything, don't forget to test that the card works! If you reached this point, then congratulations! You are finally done with updating the note! Enjoy 0.12.x.x
and all its new features!
"},{"location":"setupchanges/#20230407-ajt-japanese-update","title":"2023/04/07 (AJT Japanese Update)","text":"AJT Japanese got updated to include automatic audio file downloading. The example config was updated to disable this by default, because having it enabled increased Anki startup time. Feel free to re-enable this if you plan on using this feature.
"},{"location":"setupchanges/#20230401-anki-2161","title":"2023/04/01 (Anki 2.1.61)","text":"Anki 2.1.61 sets Reduce motion
to be enabled by default. This breaks all animations in templates. To re-enable animations in templates, please turn this option off.
Note that this is a temporary change on Anki's side, and should be fixed at some point in the future.
"},{"location":"setupchanges/#20230318-handlebars-101","title":"2023/03/18 (Handlebars 1.0.1)","text":"The handlebars got an update to support other note types other than jp-mining-note. Documentation has still not been released on the new options, so this update has not been officially announced yet.
- See the full changelog here.
- See how to update your handlebars here.
"},{"location":"setupchanges/#20230307-ajt-anki-add-ons-update","title":"2023/03/07 (AJT Anki Add-ons Update)","text":"AJT Furigana and AJT Pitch Accent got combined into one add-on: AJT Japanese. AJT Japanese takes the place of AJT Furigana, and should've be automatically updated.
To use this new add-on, the config must be updated. This new config can be found here.
Additionally, please disable or remove the \"AJT Pitch Accent\" add-on, as it is now redundant and may interfere with \"AJT Japanese\".
"},{"location":"setupchanges/#20230222-css-injector-update","title":"2023/02/22 (CSS Injector Update)","text":"The CSS Injector was updated by the author, to support Anki versions 2.1.55 and above. Any local version of CSS Injector should be removed, and the AnkiWeb version should be used instead. If you are already using the AnkiWeb version, nothing has to be done.
See the setup instructions here.
"},{"location":"setupchanges/#v0-11-0-0","title":"2022/11/19 (JPMN 0.11.0.0)","text":" - Yomichan's handlebars was updated. See how to update your handlebars here.
- Yomichan's 'Anki Card Format' section was updated, and the following fields must be changed:
WordReadingHiragana
: (empty)
\u2192 {jpmn-word-reading-hiragana}
- See here for instructions on how to update Anki Card Format.
- If you are using the nsfw-toggle function, the option name was changed from
nsfw-toggle
to image-blur
. Please change it in your runtime options to continue using it. Example config - The way keybinds are specified has been changed (to allow keys to still function as expected even with CapsLock enabled.) Keybinds will no longer work until you update the runtime options values. For example, update
n
to KeyN
. Example config
"},{"location":"setupchanges/#everything-before","title":"Everything before","text":"Lower versions of JPMN are not recorded here. Full details of the changes can be found in the main changelog instead.
"},{"location":"setupereaders/","title":"Extra: eReaders","text":""},{"location":"setupereaders/#summary","title":"Summary","text":"I do not own any eReader, so I cannot personally test or verify any of these methods. However, there are a few ways of creating Anki Cards with various eReaders.
"},{"location":"setupereaders/#kindle","title":"Kindle","text":"One can use something like ann2html to export a Yomichan-able HTML file based on the Kindle's vocabulary builder. This allows you to add the cards through Yomichan on the PC.
"},{"location":"setupereaders/#onyx-boox","title":"ONYX BOOX","text":"ONYX BOOX internally uses Android. You should be able to follow the steps under the Android setup page in order to get this eReader working.
Also see:
- Use Boox Side Buttons to Navigate ttu Reader
"},{"location":"setupextraanki/","title":"Extra: Anki","text":""},{"location":"setupextraanki/#various-anki-resources","title":"Various Anki Resources","text":"This documentation is primarily focused on how to use this note, rather than Anki itself, so little will be written about the details of Anki here.
Instead, here is a small list of resources on setting up and using Anki itself:
- Cade's blog: Optimizing Anki for Language Learning
- Tatsumoto's blog: Setting up Anki
- Lazy Guide: Anki
- Showcases an example note type, addons used and tips
- Refold's Recommended Anki Setup
- FSRS4Anki
- Twenty Rules
- These are general rules for learning (with an SRS), written for SuperMemo. Some rules are not applicable for specifically language learning, but I believe the first 4 rules are very important.
- Awesome Anki
- \"A curated list of awesome Anki add-ons, decks and resources.\"
Note that every website here has different recommendations. You will likely have to play with the settings and actually use Anki for an extended period of time to find the most optimal setup for yourself.
"},{"location":"setupextraanki/#other-anki-add-ons","title":"Other Anki Add-ons","text":"If you're interested in copying my setup, I provide the list of addons I personally use here. I also provide a small list of other popular add-ons that I don't use, but may be useful for you.
List of Add-ons I use (click here) Documented above (I use all required and optional addons for the note type):
- Anki-Connect
- CSS Injector
- AJT Japanese
Algorithm Changing:
- FSRS4Anki Helper
Stats:
- Learning Step and Review Interval Retention
- True Retention by Card Maturity Simplfied
- Kanji Grid
Usability:
- Adjust Sound Volume
- Used to normalize volume automatically (so adjusting the volume of recorded files is not necessary)
- Advanced Browser
- Used for sorting notes by frequency
- AJT Flexible Grading
- I use this to change Anki to pass/fail
- If you are using Anki dark mode, I recommend these colors (change in the config):
\"again\": \"#ff8c74\"
\"good\": \"#9cff98\"
- Paste Images As WebP
Other:
- AnkiWebView Inspector
- Local Audio Server for Yomichan
- Yomichan Forvo Server
Useful Add-ons that I don't use (click here) - AJT Mortician
- Edit Field During Review Cloze
- Generate Batch Audio
- Review Heatmap
- Straight Reward
"},{"location":"setupextraanki/#minimalist-mode","title":"Minimalist Mode","text":"Did you know that Anki comes with a theme that makes the display a lot simpler?
If you like this look, then it can be enabled by heading over to:
Tools
\u2192 Preferences
\u2192 Distractions
\u2192 Minimalist mode
"},{"location":"setupextrayomichan/","title":"Extra: Yomichan","text":""},{"location":"setupextrayomichan/#summary","title":"Summary","text":"This page contains a bunch of completely optional tips for making the best use of Yomichan. It is expected that you have setup Yomichan properly before continuing with this page.
"},{"location":"setupextrayomichan/#yomichan-appearance","title":"Yomichan Appearance","text":"If you want to follow my exact Yomichan popup appearance:
- Go to (Yomichan settings) \u2192
Popup Appearance
. - Set
Compact glossaries
to ON. - Set
Compact tags
to OFF.
There are also plenty of CSS customizations for Yomichan listed out in the JP Resources page. Some popular customizations within that page include:
- Setting the max number of frequency lists or pitch accent dictionaries shown
- Hiding bilingual dictionaries by default, until hovered over
"},{"location":"setupextrayomichan/#yomichan-themes","title":"Yomichan Themes","text":"I personally haven't changed the theme / color scheme of Yomichan. However, many others have. Here's a small list of some popular custom themes:
- Rudnam's Dark Mode
- Nord Theme
- Tutorial on editing Yomichan's color scheme
"},{"location":"setupextrayomichan/#jmdict","title":"JMdict","text":"If you are planning on using the JMdict dictionary, the ones provided from most sources (TMW's google drive - The \"JMdict Extra\" version is fine, Matt's video on Yomichan, and Yomichan's main github page) are all somewhat outdated, which usually means less accurate definitions and less coverage.
To get the most recent version of JMdict, download it from the official site (download JMdict_e_examp.gz
) and use yomichan-import to get the latest JMdict version available.
If you don't want to compile it from source, I provide a download link here, which should only be a few months stale at most.
"},{"location":"setupextrayomichan/#other-dictionaries","title":"Other dictionaries","text":" -
JMdict Forms
This is a dictionary placed in the UtilityDictionaries
field by default. Although I don't use it when studying Anki, it helps to use this when creating Anki notes for monolingual definitions.
-
I highly recommend getting some pitch accent dictionaries and frequency lists if you have not already, as these will be shown and used in the note type. See TheMoeWay's folder to browse through some examples.
I personally recommend NHK, \u5927\u8f9e\u6cc9, and \u30a2\u30af\u30bb\u30f3\u30c8\u8f9e\u5178.
-
JPDB frequency list
I personally recommend using the JPDB frequency list as one of your frequency lists, because it has high word coverage, and seems very high quality (particularly for fiction content).
-
JPDB Kanji dictionary
This dictionary is extremely useful to see the most popular words where a particular kanji is used. I like using this to see how rare a kanji is at a glance.
This synergizes well with kanji frequency dictionaries.
"},{"location":"setupextrayomichan/#local-audio-server-for-yomichan","title":"Local Audio Server for Yomichan","text":"See here if you want to be able to create Anki cards nearly instanteously, and fetch audio without a working internet connection.
I personally recommend using this setup if you can.
"},{"location":"setupgoldendict/","title":"goldendict (TODO)","text":"TODO
WordReading
must be filled with AJT Japanese WordReadingHiragana
cannot be backfilled with AJT Japanese currently, since there's no option to only generate the kana reading Key
cannot be autofilled? probably the biggest problem with this setup
"},{"location":"setupios/","title":"Extra: iOS","text":""},{"location":"setupios/#summary","title":"Summary","text":"On iOS (iPhone and iPad), it is possible to review JPMN cards. However, I am not currently aware of a setup that can create cards with iOS. If you do know of a setup that can create cards on iOS, please let me know!
It is expected that you have setup Anki and Yomichan properly on your desktop machine before continuing with this page.
"},{"location":"setupios/#reviewing","title":"Reviewing","text":"To review Anki cards on iOS, use AnkiMobile.
You'll probably notice that AnkiMobile costs a bit of money. If you don't want to pay for whatever reason, the best free alternative is to simply use AnkiWeb.
Warning
Other \"Anki\"-like apps on the App Store are not officially supported by Anki, and will almost certainly not work with this note. Please only use AnkiMobile or AnkiWeb if you are on iOS. More info can be found from the official Anki documentation here.
Warning
This note does not officially support AnkiWeb as of writing this (2023/06/21). However, the main features of the note will almost likely still work.
In order to review the same cards on desktop, you must sync your collection with AnkiWeb. More tech savy users can sync their collections using a self-hosted server.
"},{"location":"setupios/#tap-gestures","title":"Tap Gestures","text":"You will likely tap on various parts of the screen when reviewing, to reveal various parts of the card. However, AnkiMobile has tap gestures are enabled by default, which will interfere with using the note.
Tap gestures can be customized under:
(settings gear) \u2192 Review
\u2192 Taps
I recommend using the following tap gesture settings:
Side Position Action When question shown Bottom Left Show Answer When question shown Bottom Center Show Answer When question shown Bottom Right Show Answer When answer shown Bottom left Replay Audio (Everything else) None To explain what the above does:
-
There is no other way to show the answer outside of gestures. There is usually nothing on the bottom third of the screen when the question is shown, so it is safe to use that to show the answer. This is compared to the top third of the screen, where various parts of the card can be interacted with, such as the info circle and click cards.
-
You may have noticed that audio buttons do not show on AnkiMobile. This is due to an AnkiMobile bug. In order to emulate the intended experience (where the audio buttons are shown on the bottom left), I recommend setting the \"Bottom Left\" tap gesture to \"Replay Audio\".
"},{"location":"setupjidoujisho/","title":"jidoujisho (TODO)","text":"TODO actually test this app out, and update the fields / limitations as necessary
"},{"location":"setupjidoujisho/#limitations","title":"Limitations","text":""},{"location":"setupjidoujisho/#major","title":"Major","text":"None that I am aware of.
"},{"location":"setupjidoujisho/#minor","title":"Minor","text":" Sentence
: The tested word won't be automatically bolded on export (TODO: will be possible if/when handlebars is implemented) PrimaryDefinition
field is a bit limited, cannot stylize the definition output as much as Yomichan, such as: - The first line / dictionary name cannot be removed
- Lists cannot be collapsed into a compact list
- Pitch accent display is generated from AJT Japanese, and there is no control on card export.
- Note that pitch accent can still be overwritten per card when necessary.
- Also note that you should be able to see the exported pitch accent within
PAGraphs
. This can be used as a reference if you want to override the pitch accent.
"},{"location":"setupjidoujisho/#extremely-minor","title":"Extremely Minor","text":" SentenceReading
and AJTWordPitch
: cannot be automatically generated on card export. These must be batch filled later, on PC. FrequenciesStylized
: List of frequencies cannot be exported, only the sort value can WordReadingHiragana
can contain katakana. This should ideally be 100% hiragana, but this is a very minor issue (TODO explanation: the field is only used for word indicator queries, not pre-processed in order to optimize for speed, so must be processed when card is added. katakana can interfere with the process, but it is very unlikely to have a katakana-reading word to have the same reading as a hiragana-reading word)
"},{"location":"setupjidoujisho/#setup","title":"Setup","text":"jp-mining-note fields jidoujisho's creator fields Key Term Word Term WordReading Furigana PAOverride PAOverrideText AJTWordPitch PrimaryDefinition Meaning PrimaryDefinitionPicture Sentence Sentence SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Notes Hint HintNotHidden IsSentenceCard IsTargetedSentenceCard IsClickCard IsHoverCard IsHintCard IsSentenceFirstCard IsAudioCard PAShowInfo PATestOnlyWord PADoNotTest PASeparateWordCard PASeparateSentenceCard SeparateAudioCard SeparateSentenceAudioCard Picture Image WordAudio Term Audio SentenceAudio Sentence Audio PAGraphs Pitch Accent PAPositions FrequenciesStylized FrequencySort Frequency PASilence WordReadingHiragana Reading YomichanWordTags SecondaryDefinition ExtraDefinitions UtilityDictionaries CardCache Comment Context - additionally, highly recommend using a
jidoujisho
tag to all cards generated from jidoujisho (under the Tags
creator field?) - currently does nothing, but may be useful for future compatability purposes
"},{"location":"setupjidoujisho/#notes","title":"Notes","text":" - Binary fields can use any arbitrary field, like
Term
. The content of the field doesn't matter, what matters is that the field is filled.
"},{"location":"setupjl/","title":"JL (TODO)","text":"TODO
- are readings in plain furigana form?
- if not, might have to auto generate with AJT Japanese
- can the PrimarySpelling JLField be set to multiple Anki fields?
- can an Anki field be set to multiple JLFields?
- how do frequencies look? Can be used properly?
"},{"location":"setupmpvacious/","title":"mpvacious","text":"mpvacious is a user script made for of mpv, a cross platform media player. mpv itself can be used on pretty much anything, including streamed videos. However, mpvacious
was designed for downloaded videos, and almost certainly does not work on streamed videos.
If you are looking to create cards using streamed videos, I recommend asbplayer.
"},{"location":"setupmpvacious/#installation","title":"Installation","text":"Installation steps for mpvacious can be found here.
You must install this under your mpv scripts folder. This scripts
folder does not exist by default; it must be created manually.
Expected file structure (click here) WindowsmacOS and Linux C:/Users/USERNAME/AppData/Roaming\n\u2514\u2500 mpv\n \u2514\u2500 scripts\n \u2514\u2500 mpvacious\n \u251c\u2500 ankiconnect.lua\n \u251c\u2500 main.lua\n \u251c\u2500 subs2srs.lua\n \u2514\u2500 ...\n
~/.config\n\u2514\u2500 mpv\n \u2514\u2500 scripts\n \u2514\u2500 mpvacious\n \u251c\u2500 ankiconnect.lua\n \u251c\u2500 main.lua\n \u251c\u2500 subs2srs.lua\n \u2514\u2500 ...\n
"},{"location":"setupmpvacious/#configuration","title":"Configuration","text":"You will have to change mpvacious's configuration in order for mpvacious to work with JPMN.
Note
In case nothing works, always make sure to check the official documentation, as it is guaranteed to have the latest instructions if they ever change.
WindowsMac / Linux (Terminal) - Navigate to
%APPDATA%\\Roaming
You can access this by opening the file manager, and typing %APPDATA%\\Roaming
in the location field. - Create the
mpv
folder if it doesn't exist, and open the folder. - Create the
script-opts
folder if it doesn't exist, and open the folder. By now, you should be under: %APPDATA%\\Roaming\\mpv\\script-opts\n
- Create a text file with your favorite text editor. If you do not have any custom text editor downloaded, notepad should work. TODO exact steps on creating the text file
-
Copy/paste the following, and save as subs2srs.conf
:
Example config file (click here) # A full example config file can always be found in the mpvacious repository:\n# - https://github.com/Ajatt-Tools/mpvacious#configuration\n# - https://github.com/Ajatt-Tools/mpvacious/blob/master/.github/RELEASE/subs2srs.conf\n# ================= #\n# REQUIRED SETTINGS #\n# ================= #\n# These settings are required in order to be usable by JPMN.\n# Model names are listed in `Tools -> Manage note types` menu in Anki.\nmodel_name=JP Mining Note\n# Field names as they appear in the selected note type.\n# If you set `audio_field` or `image_field` empty,\n# the corresponding media file will not be created.\nsentence_field=Sentence\n#secondary_field=SentEng # Not used by the note. This is ignored entirely.\naudio_field=SentenceAudio\nimage_field=Picture\n# ========================= #\n# COMMONLY CHANGED SETTINGS #\n# ========================= #\n# Uncomment to disable native language subs entirely.\n#secondary_sub_visibility=auto\n# If you do not want the Anki browser to appear every time you add a card,\n# uncomment the following:\n#disable_gui_browse=yes\n# ====================== #\n# MEDIA QUALITY SETTINGS #\n# ====================== #\n# The following settings provide saner defaults to audio and image quality,\n# when using opus and webp. Feel free to play around with these as you see fit.\n# Sane values are 16k-32k for opus, 64k-128k for mp3.\naudio_bitrate=32k\n# Quality of produced image files. 0 = lowest, 100=highest.\n#snapshot_quality=15\nsnapshot_quality=50\n# Image dimensions\n# If either (but not both) of the width or height parameters is -2,\n# the value will be calculated preserving the aspect-ratio.\n#snapshot_width=-2\n#snapshot_height=200\nsnapshot_width=800\nsnapshot_height=-2\n
Ensure that your file is indeed a .conf file when saved. If your file browser says that it is a text file, then the file was likely incorrectly saved as subs2srs.conf.txt
. TODO exact instructions on renaming
Expected file structure (click here) C:/Users/Username/AppData/Roaming\n\u2514\u2500 mpv\n \u2514\u2500 script-opts\n \u2514\u2500 subs2srs.conf\n
The following installs the correct configuration, along with all the recommended settings stated below.
mkdir -p ~/.config/mpv/script-opts\n# TODO change this to the master branch eventually\ncurl https://raw.githubusercontent.com/arbyste/jp-mining-note/dev/docs/docs/assets/setupmpvacious/subs2srs.conf > ~/.config/mpv/script-opts/subs2srs.conf\n
Be sure to restart mpv after changing the config to make sure your configuration is applied.
The example configuration includes plenty of commonly changed settings by default. In general, I recommend looking through the example configuration to see if there are other options that you may want to change.
"},{"location":"setupmpvacious/#card-creation","title":"Card Creation","text":"To create JPMN cards with mpvacious:
- Create a card from Yomichan. The text is usually gotten via a texthooker.
- Within mpv, navigate to the desired subtitle, and then press Ctrl+M.
- If you instead want to add audio from multiple subtitles at a time:
- Navigate to the beginning subtitle.
- Press A+C
- Navigate to the ending subtitle.
- Press M.
- Much more can be found under mpvacious's usage section.
"},{"location":"setupmpvacious/#other","title":"Other","text":" -
A common issue with mpvacious is that the SentenceReading
field may differ from the Sentence
field, say, if you export multiple subtitles into one card. See the FAQ on how to fix it.
-
You have to export the audio as mp3
if you plan on using AnkiMobile (iOS), or AnkiWeb.
"},{"location":"setuptextmedia/","title":"Setup: Text & Media","text":""},{"location":"setuptextmedia/#overview","title":"Overview","text":"This page is dedicated to providing resources on how to do the following:
- Getting the actual text to use Yomichan on.
- Getting the pictures and/or sentence audio from the media.
There are plenty of well established resources out there on how to do just that, ranging from software to written & video guides. Instead of repeating what others have already said, those programs and guides will be linked.
If you are looking to setup jp-mining-note, see this page instead.
Note
If you already have a sentence mining workflow, you can likely skip to this section. TODO update link!
"},{"location":"setuptextmedia/#troubleshooting-support","title":"Troubleshooting & Support","text":"If you are having troubles with any of the guides or programs below, I unfortunately will not be able to provide very detailed support.
Instead, I would recommend that you contact the creators of the guides / programs, or the communities surrounding said guides / programs.
Additionally, the guides listed here usually do not use JPMN, and instead link to other note types. This shouldn't be an issue as long as you change the appropriate the field names.
"},{"location":"setuptextmedia/#getting-the-text-to-create-the-cards","title":"Getting the Text to Create the Cards","text":"I use a texthooker setup, which is able to extract subtitles or text into the browser. Once the text is on the browser, you can use Yomichan to select the word and create the Anki card (by clicking on the green plus button).
The standard texthooker setup works for most games, and any show with subtitle files.
"},{"location":"setuptextmedia/#texthooker-websocket-based","title":"Texthooker: Websocket based","text":"These pages display the hooked content, where the hooked content is communicated via Websockets. Websocket based texthookers are better than the classic clipboard-based texthookers in almost every aspect:
- They are generally faster and more reliable.
- They do not flood your clipboard.
- They do not require an extension that constantly polls the clipboard.
However, it requires more specialized coordination between programs. Fortunately, most standard workflows support websockets nowadays.
Resources (click here) -
Renji's Texthooker Page (recommended)
- Open source and more featureful alternative to the more popular Anacreon's texthooker page.
- This texthooker page comes with built in support for both websockets and clipboard inserter plugins.
- I use these settings to make the text more compressed.
-
exSTATic (recommended for stats lovers)
- Its primary use is for automatic stats collection and visualizing said statistics.
- Integrates seamlessly with many workflows, including non-texthooker related workflows.
- Uses a custom texthooker page, which connects with Textractor with its own custom extension.
- A video installation guide is available on the project's README page.
Supported Workflows:
- Textractor with textractor-websocket or TextractorSender
- mpv with mpv_websocket
Legacy Resources (click here) These resources are considered legacy, and I highly recommend using the standard resources above in favor of these.
-
Marv's Websocket Userscript
- A more featureful version of the patch below.
- Written for Anacreon's texthooker page.
-
Zetta's Custom Patch
- Patch Instructions for existing clipboard-based texthookers.
- This patch is intended to be used in conjunction with this Textractor extension.
- This patch was written for Anacreon's texthooker page. However, it will likely work for most other texthooker pages.
Instructions to use the patch (click here) Warning
This is a monkey patch, even according to the author. Now that better alternatives have came out (see above), I recommend to use said alternatives.
- Download your favorite texthooker page into a raw html file.
- Copy/paste the code below to the very end of the raw html file.
- If you are currently viewing the page, refresh.
<script>\nlet socket = null;\nlet wsStatusElem = null;\nconst createStatusElem = () => {\nwsStatusElem = document.createElement(\"span\")\nlet node = document.getElementById('menu').firstChild\nwsStatusElem.setAttribute(\"class\", \"menuitem\")\nwsStatusElem.addEventListener('click', (e) => {\nif(wsStatusElem.innerText == \"Reconnect\") {\nconnect()\n}\n})\nnode.insertBefore(wsStatusElem, node.firstChild)\n}\nconst updateStatus = (connected) => {\nif(wsStatusElem === null) { createStatusElem() }\nwsStatusElem.innerText = connected ? \"Connected\" : \"Reconnect\"\nwsStatusElem.style.cssText = \"margin-right: 1.5em; display: inline-block;\"\nwsStatusElem.style.cssText += connected ? \"color:rgb(24, 255, 24);\" : \"color:rgb(255, 24, 24);\"\n}\nconst connect = () => {\nsocket = new WebSocket(\"ws://localhost:6677/\")\nsocket.onopen = (e) => { updateStatus(true) }\nsocket.onclose = (e) => { updateStatus(false) }\nsocket.onerror = (e) => { updateStatus(false); console.log(`[error] ${e.message}`) }\nsocket.onmessage = (e) => {\nlet container = document.getElementById('textlog')\nlet textNode = document.createElement(\"p\")\ntextNode.innerText = e.data\ndocument.body.insertBefore(textNode, null)\n}\n}\nconnect()\n</script>\n
(Original discord message, on TMW server. Thanks Zetta#3033 for the code.)
"},{"location":"setuptextmedia/#texthooker-clipboard-based","title":"Texthooker: Clipboard based","text":"These pages display the hooked content, where the hooked content is communicated via automated clipboard (copy/paste) tools. Most classic setups documented are for clipboard based texthooker pages. If possible, I highly recommend trying out a websocket based texthooker approach instead.
Resources (click here) - Clipboard Inserter Redux (Extension)
- Updated version of the original Clipboard Inserter extension
- Still using manifest v2, so this extension will be deprecated in the future unless updated
- Lap Clipboard Inserter (Extension) (Firefox)
- Rewritten version of the original Clipboard Inserter extension, to use manifest v3
- Works on Firefox, but Chrome is currently not supported. Use Clipboard Inserter Redux if you are using a chromium based browser.
- Renji's Texthooker Page (recommended)
- Open source and more featureful alternative to the more popular Anacreon's texthooker page.
- I use these settings to make the text more compressed.
Guides (click here) - TMW: Texthooker & Visual Novels
- Lazy Guide: Texthooker
- stegatxins0's mining guide: Texthooker
- Anime Cards: Texthooker & Visual Novels
Legacy Resources (click here) These resources are considered legacy, and I highly recommend using the standard resources above in favor of these.
- Original Clipboard Inserter (Extension) (WARNING: NO LONGER MAINTAINED!)
- WARNING: No longer works on Firefox as of Firefox version 107.0. Use either extensions above if you are using Firefox.
- Anacreon's Texthooker Page
- TMW's Texthooker Page
"},{"location":"setuptextmedia/#game-like-content-getting-text","title":"Game-Like Content: Getting Text","text":"The following are primarily for text-heavy games, such as visual novels.
Resources (click here) - Textractor (recommended)
- agent
- This is a good fallback for when Textractor doesn't work
Guides (click here) - TMW: Installing Visual Novels
- TMW: Texthooker & Visual Novels
- Anime Cards: Texthooker & Visual Novels (slightly outdated compared to others)
- Lazy Guide: Playing Visual Novels on Mobile
- Playing Emulated DS, 3DS, PSP and Gameboy Advanced games on Android devices
- Contact info:
OrangeLightX#2907
on the Refold (JP) Discord server or TMW server
- See this section to get sentence audio and images
"},{"location":"setuptextmedia/#video-content-getting-text-sentence-audio-picture","title":"Video Content: Getting Text, Sentence Audio, Picture","text":"Video content includes streamed content (Youtube, Netflix, etc.) and locally downloaded files.
Resources (click here) - mpvacious (recommended for downloaded videos / if you are using mpv)
- Add-on for mpv, a cross platform media player. Personally tested.
- Basically universal codec support since it uses mpv.
- This addon has capabilities to extract the video clip itself as the form of a gif (autoplayable webp).
- See here for basic setup instructions.
- asbplayer (recommended for streamed sites)
- Cross platform (chromium) browser video player. Personally tested.
- Works on video streaming sites, as well as downloaded videos.
- Does not require a texthooker page: subtitles are displayed on the site itself.
- Codec support is limited, and depends on the browser used.
- See here for basic setup instructions.
- Animebook
- Cross platform (chromium) browser video player.
- Does not require a texthooker page: subtitles are displayed on the site itself.
- Codec support is limited, and depends on the browser used.
- See Cade's sentence mining guide for basic setup instructions. Note that the aformentioned guide is not using JPMN.
- Contact info:
eminent#8189
on Perdition's server or TMW server)
- All of the above require subtitle files to function. See here and/or here for some websites where you can get subtitles from.
- One challenge for video content is that subtitles are usually not aligned properly if the subtitles are downloaded separately from the video. I've always used a combination of mkvextract (to extract the subtitle file from the
.mkv
file) and alass (to align the native subtitles with reference subtitles, usually in a different language) to get the job done. If you want more options, see this page.
Other:
- jidoujisho
- Android e-book reader and media player. Advertises itself as an all-in-one app.
- Immersive
- Add-on for MPV. Alternative to mpvacious.
- WARNING: This is potentially outdated and/or abandoned. The most recent commit as of writing (2022/10/19) was done in 2022/01/27. This is listed here for completeness only.
"},{"location":"setuptextmedia/#manga-getting-text","title":"Manga: Getting Text","text":"mokuro (recommended) mokuro pre-processes manga, so you don't have to run any OCR program afterwards.
Guides:
- Lazy guide (recommended)
- (For Windows users) Make sure to check the \"Add Python to Path\" on install.
- If you are using online processing (google colab), be sure that you are using the gpu to speed up the process.
- Josuke's mokuro setup guide
- Contact info:
Josuke#7212
on the Refold (JP) Discord server - This doesn't include instructions on how to process online (whereas the Lazy guide does)
Other Resources:
- If you are on Android, this can be paired with Anki Connect for Android to create Anki cards.
- WeebAlt's RemoteMokuro setup
- This includes setup instructions on using Mokuro remotely (from google drive, i.e. no disk storage)
- leermangamokureado is a site with various manga ran through mokuro.
If any error occurs, check the following:
-
Check your Python version (python --version
, or python3 --version
). Python 3.10 is not supported yet.
If your Python version is too old, I recommend using pyenv (for Linux users). Linux users can use the automatic installer. For Windows users, it should be sufficient to uninstall mokuro
, install a newer version of Python, and then re-install mokuro with the newer version.
-
Make sure your directory is a string and not a number. For example, mokuro ./01
on unix, and mokuro .\\01
on Windows.
Manga OCR Manga OCR allows you to automatically OCR any image. As the name suggests, this works best on manga.
Guides:
- Lazy guide (Windows)
"},{"location":"setuptextmedia/#books-epubs-htmlz-pdf","title":"Books (EPUBs, HTMLZ, PDF)","text":"As long as you're not using a scan (image-based), the text should already be available. Below will list a few ways to view these files in a browser to Yomichan.
Resources (click here) - \u30c3\u30c4 Ebook Reader (EPUBs, HTMLZ) (recommended)
- Mozilla's PDF Viewer (PDF)
Other:
- jidoujisho
- Android e-book reader and media player. Advertises itself as an all-in-one app.
- Uses \u30c3\u30c4 Ebook Reader as its backend.
Guides (click here) - Like with Mokuro, if you are on Android, this can be paired with Anki Connect for Android to create Anki cards.
"},{"location":"setuptextmedia/#audiovideo-with-no-subtitles","title":"Audio/Video with No Subtitles","text":"KanjiEater's AudiobookTextSync is a relatively new set of tools that generates subtitles using machine learned models.
"},{"location":"setuptextmedia/#getting-images-sentence-audio-manually","title":"Getting Images & Sentence Audio Manually","text":"Sometimes, there is no easy way to get the image and sentence audio other than with a screen recorder. The primary example for this is game-like content.
Here are the two popular approaches to automatically adding the image and sentence audio:
ShareX (Windows) ShareX
- Windows media recorder which can both take screenshots and record audio. Personally tested.
Guides:
- stegatxins0's mining guide: ShareX (recommended)
- The scripts written here works by default with this note. These scripts are meant used with stegatxins0's setup.
- Xeliu's mining guide: ShareX
- ShareX setup is based off of stegatxins0's setup
- Anime Cards: Handling Media
- Not recommended: introduces additional steps compared to the above two guides
ames (Linux) ames
- ShareX alternative for Linux. Personally tested.
- Primarily used to automate audio and picture extraction to the most recently added Anki card.
"},{"location":"setuptextmedia/#resource-lists","title":"Resource Lists","text":"Other websites have significantly larger resource lists that may prove useful for you.
Resource Lists (click here) - TheMoeWay
- Tatsumoto
- itazuraneko
- kuzuri
- Refold (JP) (Old Google doc) (Mirror)
- Refold (General) (Mirror)
- IgrecL/japanese
- donkuri/learn-japanese
"},{"location":"setupyomichan/","title":"Setup: Yomichan","text":""},{"location":"setupyomichan/#overview","title":"Overview","text":"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.
"},{"location":"setupyomichan/#preliminary-steps","title":"Preliminary Steps","text":" -
If you have used Yomitan before, please make a backup of your settings (just in case).
-
On top of the standard dictionaries, I highly recommend installing some frequency and pitch accent dictionaries, as that information is used by jp-mining-note. Many of these dictionaries can be found within TheMoeWay's drive. These dictionaries are installed in the exact same way as the standard Yomitan dictionaries.
In particular, I recommend the JPDB frequency list.
"},{"location":"setupyomichan/#yomichan-fields","title":"Yomichan Fields","text":"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
, and \"Deck\" to whatever your Anki deck is. - Copy and paste the following values into the fields (the custom helpers won't be available in the dropdown arrow):
Click here to see the fields to copy and paste. Anki Fields Yomichan Format Key {expression}
Word {expression}
WordReading {furigana-plain}
PAOverride PAOverrideText AJTWordPitch PrimaryDefinition {jpmn-primary-definition}
PrimaryDefinitionPicture Sentence {cloze-prefix}<b>{cloze-body}</b>{cloze-suffix}
SentenceReading AltDisplayWord AltDisplaySentence AltDisplayPASentenceCard AltDisplayAudioCard AdditionalNotes Hint HintNotHidden *IsSentenceCard *IsTargetedSentenceCard *IsClickCard *IsHoverCard *IsHintCard *IsSentenceFirstCard *IsAudioCard *PAShowInfo *PATestOnlyWord *PADoNotTest *PASeparateWordCard *PASeparateSentenceCard *SeparateAudioCard *SeparateSentenceAudioCard Picture WordAudio {audio}
SentenceAudio PAGraphs {jpmn-pitch-accent-graphs}
PAPositions {jpmn-pitch-accent-positions}
FrequenciesStylized {jpmn-frequencies}
FrequencySort {jpmn-frequency-sort}
PASilence [sound:_silence.wav]
WordReadingHiragana {jpmn-word-reading-hiragana}
YomichanWordTags {tags}
SecondaryDefinition {jpmn-secondary-definition}
ExtraDefinitions {jpmn-extra-definitions}
UtilityDictionaries {jpmn-utility-dictionaries}
CardCache 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 fields used to determine the resulting card type, 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 with anything, e.g. 1
.
See the Changing Card Type page for more info.
The custom helpers like {jpmn-primary-definition}
is not provided by Yomitan by default. See the section below to make these helpers usable.
"},{"location":"setupyomichan/#yomichan-templates","title":"Yomichan Templates","text":"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 helpers 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. {{~! ~}}\n{{~! ==================== jp-mining-note handlebars ===================== ~}}\n{{~! v1.0.12 ~}}\n{{~! ~}}\n{{~! https://arbyste.github.io/jp-mining-note/ ~}}\n{{~! ------------------------------------------------------- ~}}\n{{~! ================ Dictionary Categorization Options ================= ~}}\n{{~! valid values: \"bilingual\", \"monolingual\" ~}}\n{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n{{~!\nA bunch of JP and CN bilingual dictionaries covered by default,\nincluding: JMdict, \u65b0\u548c\u82f1, CEDICT, etc\n~}}\n{{~#set \"bilingual-dict-regex\"~}} ^(([Jj][Mm][Dd]ict)(.*)|(.*)\u65b0\u548c\u82f1(.*)|\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|KireiCake|NEW\u658e\u85e4\u548c\u82f1\u5927\u8f9e\u5178|CEDICT|CC-CEDICT|CantoDict|Canto CEDICT|Words\\.hk C-E FS|CE Wiktionary|CC-Canto|Jitendex(.*)|ADD_BILINGUAL_DICTIONARIES_HERE)$ {{~/set~}}\n{{~#set \"utility-dict-regex\"~}} ^(NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178|\u30b7\u30f3\u30fb\u6f22\u5b57\u9063\u3044\u53c2\u8003|[Jj][Mm][Dd]ict( Surface)? Forms|JMedict)$ {{~/set~}}\n{{~#set \"ignored-dict-regex\"~}} ^(ADD_IGNORED_DICTIONARIES_HERE)$ {{~/set~}}\n{{~! ====================== Selected Text Options ======================= ~}}\n{{set \"opt-selection-text-enabled\" true}}\n{{set \"opt-selection-text-dictionary\" true}}\n{{set \"opt-selection-text-glossary\" true}}\n{{set \"opt-selection-text-glossary-attempt-bold\" true}}\n{{~! ==================== Frequency Sorting Options ===================== ~}}\n{{~! See here for the official documentation on how these options work:\nhttps://github.com/MarvNC/JP-Resources#freq-settings ~}}\n{{~#set \"opt-ignored-freq-dict-regex\"~}} ^(JLPT.*)|(HSK.*)$ {{~/set~}}\n{{~#set \"opt-ignored-freq-value-regex\"~}} \u274c {{~/set~}}\n{{~#set \"opt-keep-freqs-past-first-regex\"~}} ^()$ {{~/set~}}\n{{~set \"opt-no-freq-default-value\" 9999999 ~}}\n{{~set \"opt-freq-sorting-method\" \"harmonic\" ~}} {{~! \"min\", \"first\", \"avg\", \"harmonic\" ~}}\n{{~set \"opt-grammar-override\" true ~}}\n{{~set \"opt-grammar-override-value\" 0 ~}}\n{{~#set \"opt-grammar-override-dict-regex\"~}} ^(\u65e5\u672c\u8a9e\u6587\u6cd5\u8f9e\u5178\\(\u5168\u96c6\\)|\u6bce\u65e5\u306e\u3093\u3073\u308a\u65e5\u672c\u8a9e\u6559\u5e2b|JLPT\u6587\u6cd5\u89e3\u8aac\u307e\u3068\u3081|\u3069\u3093\u306a\u3068\u304d\u3069\u3046\u4f7f\u3046 \u65e5\u672c\u8a9e\u8868\u73fe\u6587\u578b\u8f9e\u5178|\u7d75\u3067\u308f\u304b\u308b\u65e5\u672c\u8a9e)$ {{~/set~}}\n{{~! ============== Dictionary First Line Removal Options =============== ~}}\n{{~set \"opt-wrap-first-line-spans\" true ~}}\n{{~! valid values: \"except\", \"only\" ~}}\n{{~set \"opt-first-line-regex-mode\" \"except\"~}}\n{{~!\nJMdict and jitenbot dictionaries from stephenmk are ignored\n(the latter because the handlebars cannot properly detect the first line.)\nIn particular, removing the first line from jitenbot dictionaries with handlebars alone\nis not trivial, so that feature will not be supported.\n~}}\n{{~#set \"opt-first-line-dicts-regex\"~}} ^(JMdict.*|Nico/Pixiv|\u6545\u4e8b\u30fb\u3053\u3068\u308f\u3056\u30fb\u6163\u7528\u53e5\u30aa\u30f3\u30e9\u30a4\u30f3|\u56db\u5b57\u719f\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u56fd\u8a9e\u8f9e\u5178\u30aa\u30f3\u30e9\u30a4\u30f3|\u5927\u8f9e\u6797\u3000\u7b2c\u56db\u7248|\u65b0\u660e\u89e3\u56fd\u8a9e\u8f9e\u5178\u3000\u7b2c\u516b\u7248)$ {{~/set~}}\n{{~! ========================== Other Options =========================== ~}}\n{{~set \"opt-primary-def-one-dict-entry-only\" false ~}}\n{{~set \"opt-jmdict-list-format\" true ~}}\n{{~! ======================== Plaintext Options ========================= ~}}\n{{~!\nWARNING: I recommend not changing these options if you are using the\njp-mining-note template. These options will change the general layout\nof the HTML, which will prevent certain features or stylizations\nfrom properly working. (If you aren't using jp-mining-note, please feel\nfree to change these options!)\nInstead of using these options, see here:\nhttps://aquafina-water-bottle.github.io/jp-mining-note/definitions/\nThese hide specific elements using CSS instead of modifying the raw HTML\nstructure behind it.\n~}}\n{{~set \"opt__plaintext__enabled\" false ~}}\n{{~set \"opt__plaintext__one-dict-entry-only-no-list\" false ~}}\n{{~set \"opt__plaintext__remove-dictionary-tag\" false ~}}\n{{~set \"opt__plaintext__remove-first-line-enabled\" false ~}}\n{{~! ============== ORIGINAL YOMITAN TEMPLATE CODE BELOW ============== ~}}\n
-
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 YOMITAN TEMPLATE CODE ABOVE =============== ~}}\n{{~! v1.0.12 ~}}\n{{~!\n==================\nhelper functions\n==================\n~}}\n{{#*inline \"s\"}}{{/inline}}\n{{~! categorizes into 4 types: \"ignored\", \"bilingual\", \"utility\", or \"monolingual\" ~}}\n{{~#*inline \"jpmn-get-dict-type\"~}}\n{{~#scope~}}\n{{~#set \"rx-match-ignored\" ~}}\n{{~#regexMatch (get \"ignored-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-utility\" ~}}\n{{~#regexMatch (get \"utility-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#set \"rx-match-bilingual\" ~}}\n{{~#regexMatch (get \"bilingual-dict-regex\") \"gu\"~}}{{dictionaryName}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if (op \"!==\" (get \"rx-match-ignored\") \"\")~}}\n ignored\n {{~else if (op \"!==\" (get \"rx-match-utility\") \"\")~}}\n utility\n {{~else if (op \"!==\" (get \"rx-match-bilingual\") \"\")~}}\n bilingual\n {{~else~}}\n {{~! assumed that anything else is a monolingual dictionary ~}}\n monolingual\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! returns \"\" if selection text is disabled, or if none existed in the first place ~}}\n{{~#*inline \"_jpmn-selection-text\"~}}\n {{~! text-mode != \"\" and text-mode > 0 ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-enabled\") true)~}}\n {{~! removes leading and trailing whitespace ~}}\n {{~#regexReplace \"^\\s+|\\s+$\" \"\" \"g\"~}}\n {{~#getMedia \"selectionText\"}}{{/getMedia~}}\n {{~/regexReplace~}}\n {{~/if~}}\n{{~/inline~}}\n{{~! checks that the selection text is indeed a dictionary (returns the text if true, nothing if false) ~}}\n{{~#*inline \"_jpmn-check-dictionary\"~}}\n {{~#scope~}}\n {{~#set \"selection-is-dictionary\" false}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" (get \"selection\") dictionary)~}}\n {{~#set \"selection-is-dictionary\" true ~}}{{~/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \"===\" (get \"selection-is-dictionary\") true)~}}\n {{~get \"selection\"~}}\n {{~else~}}\n {{~! null ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n Gives the raw glossary as the search string\n (for searching to see if the selected text is a part of a dictionary)\n Remember: we should NOT use _jpmn-glossary-single because it preprocesses the text!\n If the selected text was on the first line and the first line is removed,\n then using _jpmn-glossary-single will fail to find the selected text!\n~}}\n{{#*inline \"_jpmn-glossary-single-search\"}}\n {{~#scope~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/scope~}}\n{{/inline}}\n{{~! escape a regex string: https://stackoverflow.com/a/6969486~}}\n{{~! /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' ~}}\n{{~! escapes the `regexString` regex to allow it to be used like a normal search in a string ~}}\n{{#*inline \"_jpmn-escape-regex\"}}\n {{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~regexString~}}{{~/regexReplace~}}\n{{/inline}}\n{{~#*inline \"_jpmn-get-dict-if-glossary-selected\"~}}\n {{~#scope~}}\n {{~#set \"result-dictionary\" null}}{{/set~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"search-def\"}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{/set~}}\n {{~#set \"search-regex-match\"}}\n {{~#regexMatch (get \"search-selection\") \"gu\"}}{{~get \"search-def\"~}}{{/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"result-dictionary\") null)\n (op \"!==\" (get \"search-regex-match\") \"\")\n )~}}\n {{~#set \"result-dictionary\" dictionary}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"result-dictionary\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n searches dictionary, determined by `opt-first-definition-type`\n - (opt-first-definition-type === bilingual) -> bilingual dictionaries are searched first\n - (opt-first-definition-type === monolingual) -> monolingual dictionaries are searched first\n~}}\n{{~#*inline \"_jpmn-search-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~#if (op \"===\" (get \"opt-first-definition-type\") \"bilingual\")~}}\n {{~#set \"first-definition-search-type-1\" \"bilingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"monolingual\"}}{{/set~}}\n {{~else~}}\n {{~#set \"first-definition-search-type-1\" \"monolingual\"}}{{/set~}}\n {{~#set \"first-definition-search-type-2\" \"bilingual\"}}{{/set~}}\n {{~/if~}}\n {{~! first-dictionary === null <=> no valid dictionary was found ~}}\n {{~#set \"first-dictionary\" null}}{{/set~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-1\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! uses other dictionary type, last resort ~}}\n {{~#if (op \"===\" (get \"first-dictionary\") null)~}}\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") (get \"first-definition-search-type-2\"))~}}\n {{~#if (op \"===\" null (get \"first-dictionary\"))~}}\n {{~#set \"first-dictionary\" dictionary~}}{{~/set~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~/if~}}\n {{~#get \"first-dictionary\"~}}{{~/get~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n return null\n~}}\n{{~#*inline \"_jpmn-check-dictionary-and-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if\n (op \"&&\" (op \"===\" (get \"result\") \"\")\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return null\n if (able to detect dictionary of which the selection-text is highlighting):\n return \"uses-glossary\"\n return null\n~}}\n{{~#*inline \"_jpmn-selection-uses-glossary\"~}}\n {{~#scope~}}\n {{~#set \"result\" \"\"}}{{/set~}}\n {{~! checks if the selected text matches a dictionary ~}}\n {{~#if (op \"===\" (get \"opt-selection-text-dictionary\") true)~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary . ~}}{{/set~}}\n {{~/if~}}\n {{~! checks if the selected text matches a definition in a dictionary ~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text is a dictionary -> null ~}}\n {{~else if\n (op \"&&\"\n (op \"===\" (get \"opt-selection-text-glossary\") true)\n (op \"===\" (get \"opt-selection-text-glossary-attempt-bold\") true)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-get-dict-if-glossary-selected . ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"result\") \"\") ~}}\n {{~! selection-text dict found -> \"uses-glossary\" ~}}\n uses-glossary\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n if (selection-text exists):\n if (selection-text is exactly a dictionary):\n return dictionary\n if (able to detect dictionary of which the selection-text is highlighting):\n return dictionary\n if (selection-text-glossary is not enabled):\n return first-dictionary (determined by `opt-first-definition-type`)\n return null\n else:\n return first-dictionary (determined by `opt-first-definition-type`)\n~}}\n{{~#*inline \"_jpmn-get-primary-definition-dict\"~}}\n {{~#scope~}}\n {{~! first checks selection text ~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#if (op \"!==\" (get \"selection\") \"\")~}}\n {{~#set \"result\"}}{{~> _jpmn-check-dictionary-and-glossary . ~}}{{/set~}}\n {{~! doesn't return a dictionary if opt-selection-text-glossary is false b/c ~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"result\") \"\")\n (op \"===\" (get \"opt-selection-text-glossary\") false)\n )\n ~}}\n {{~#set \"result\"}}{{~> _jpmn-search-primary-definition-dict . ~}}{{/set~}}\n {{~/if~}}\n {{~get \"result\" ~}}\n {{~! no selection text ~}}\n {{~else~}}\n {{~> _jpmn-search-primary-definition-dict . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n get number of primary dictionary entries\n~}}\n{{~#*inline \"_jpmn-primary-dict-entry-count\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~set \"dict-entry-count\" 0 ~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\")) ~}}\n {{~! dict-entry-count += 1 ~}}\n {{~set \"dict-entry-count\" (op \"+\"\n (get \"dict-entry-count\") 1\n )\n ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"dict-entry-count\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-is-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n dictionaryName: dictionary id\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~set \"valid-dict\" null ~}}\n {{~#set \"test-dict-type\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionaryName ~}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"test-dict-type\") validDictType)\n (op \"||\"\n (op \"!==\" (get \"primary-dictionary\") dictionaryName)\n (op \"===\" (get \"use-primary-dictionary\") true)\n )\n ) ~}}\n {{~set \"valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~get \"valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~!\n returns \"true\" if valid dict, \"\" (null) otherwise\n~}}\n{{~#*inline \"_jpmn-non-primary-has-valid-dict\"~}}\n {{~!\n PARAMETERS:\n validDictType: \"monolingual\" or \"bilingual\" or \"utility\"\n entryCount: primary dictionary entry count\n ~}}\n {{~#scope~}}\n {{~set \"use-primary-dictionary\" (op \"&&\"\n (get \"opt-primary-def-one-dict-entry-only\")\n (op \"&&\" (op \"!==\" (op \"+\" entryCount) 0) (op \"!==\" (op \"+\" entryCount) 1))\n )\n ~}}\n {{~!\n without this set statement, the parameters\n magically disappears within the bottom 'each' loop...\n ~}}\n {{~ set \"valid-dict-type\" validDictType ~}}\n {{~ set \"entry-count\" entryCount ~}}\n {{~set \"has-valid-dict\" null ~}}\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=(get \"valid-dict-type\") entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n {{~set \"has-valid-dict\" \"true\" ~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"has-valid-dict\" ~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~#*inline \"_jpmn-get-primary-definition-value\"~}}\n {{~!\n ASSUMPTION: \"primary-dictionary\" and \"search-selection\" is available to us from previous functions\n ~}}\n {{~#scope~}}\n {{~#if\n (op \"&&\"\n (op \"!==\" (get \"search-selection\") \"\")\n (get \"opt-primary-def-one-dict-entry-only\")\n )\n ~}}\n {{~! text was highlighted -> use primary dictionary entry with highlighted text ~}}\n {{~set \"found-dict-entry\" false ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-dict-entry\" ~}}\n {{~#regexMatch (get \"search-selection\") \"gu\"~}}{{~> _jpmn-glossary-single-search . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if\n (op \"&&\"\n (op \"===\" (get \"found-dict-entry\") false)\n (op \"&&\"\n (op \"!==\" (get \"rx-match-dict-entry\") \"\")\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else if (get \"opt-primary-def-one-dict-entry-only\") ~}}\n{{~! use first primary dictionary entry ~}}\n{{~set \"found-dict-entry\" false ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <ol>\n{{~/if~}}\n{{~#each definition.definitions~}}\n{{~#if\n(op \"&&\"\n(op \"===\" (get \"found-dict-entry\") false)\n (op \"===\" dictionary (get \"primary-dictionary\"))\n )\n ~}}\n {{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </li>\n{{~/if~}}\n{{~set \"found-dict-entry\" true ~}}\n{{~/if~}}\n{{~/each~}}\n{{~#if (op \"!\" (get \"opt__plaintext__one-dict-entry-only-no-list\")) ~}}\n </ol>\n{{~/if~}}\n{{~else~}}\n{{~! use all primary dictionary entries ~}}\n{{~#if (get \"opt__plaintext__one-dict-entry-only-no-list\") ~}}\n{{~! must manually calculate number of primary-dictionary entries... ~}}\n{{~set \"t\" 0 ~}}\n{{~#each definition.definitions~}}\n{{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <ol> {{~/if~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} <li data-details=\"{{~dictionary~}}\"> {{~/if~}}\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n{{~#if (op \">=\" (get \"t\") 2)~}} </li> {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~#if (op \">=\" (get \"t\") 2)~}} </ol> {{~/if~}}\n {{~else~}}\n <ol> {{~s~}}\n {{~#each definition.definitions~}}\n {{~#if (op \"===\" dictionary (get \"primary-dictionary\"))~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol> {{~s~}}\n{{~/if~}}\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\nif (mode === \"except\" and (regex doesn't match) or mode === \"only\" and (regex matches)):\n return true\n return null\n~}}\n{{#*inline \"_jpmn-check-first-line-dict\"}}\n {{~#scope~}}\n {{~#set \"rx-match-first-line-dict\" ~}}\n {{~#regexMatch (get \"opt-first-line-dicts-regex\") \"u\"~}}{{dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"||\"\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"except\")\n (op \"===\" (get \"rx-match-first-line-dict\") \"\")\n )\n (op \"&&\"\n (op \"===\" (get \"opt-first-line-regex-mode\") \"only\")\n (op \"!==\" (get \"rx-match-first-line-dict\") \"\")\n )\n )\n ~}}\n true\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! custom glossary-single function for additional regex parsing per dictionary ~}}\n{{~! OVERRIDES brief and noDictionaryTag ~}}\n{{#*inline \"_jpmn-glossary-single\"}}\n {{~#scope~}}\n {{~#if (op \"===\" dictionary \"NHK\u65e5\u672c\u8a9e\u767a\u97f3\u30a2\u30af\u30bb\u30f3\u30c8\u65b0\u8f9e\u5178\")~}}\n {{~#regexReplace \"<br></span> \u30fb\" \"<br></span>\" \"g\"~}}\n {{~#regexReplace \"<br> \u30fb\" \"<br>\" \"g\"~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/regexReplace~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single2 . ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! custom glossary-single function to add custom html around the dictionary and tags ~}}\n{{#*inline \"_jpmn-glossary-single2\"}}\n {{~#scope~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__tag-list\"> {{~s~}}\n {{~#each definitionTags~}}\n <span class=\"dict-group__tag dict-group__tag--name\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~name~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~/each~}}\n <span class=\"dict-group__tag dict-group__tag--dict\"> {{~s~}}\n <span class=\"dict-group__tag-inner\"> {{~s~}}\n {{~dictionary~}}\n </span> {{~s~}}\n </span> {{~s~}}\n </span> {{~s~}}\n {{~else~}}\n {{~#scope~}}\n {{~#set \"any\" false}}{{/set~}}\n {{~#each definitionTags~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{name}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/each~}}\n {{~#if (op \"!\" (get \"opt__plaintext__remove-dictionary-tag\"))~}}\n {{~#if (get \"any\")}}, {{else}}({{/if~}}\n {{dictionary}}\n {{~#set \"any\" true}}{{/set~}}\n {{~/if~}}\n {{~#if (get \"any\")}}) {{/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n <span class=\"dict-group__glossary\"> {{~s~}}\n {{~/if~}}\n {{~!\n option to not wrap with spans because it may break dictionaries\n (this is the hell that is parsing html with regex)\n ~}}\n {{~#if (op \"&&\"\n (get \"opt-wrap-first-line-spans\")\n (op \"!\" (get \"opt__plaintext__enabled\"))\n )\n }}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1<span class=\\\"dict-group__glossary--first-line\\\">$2</span><span class=\\\"dict-group__glossary--first-line-break\\\"><br></span>\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else if (get \"opt__plaintext__remove-first-line-enabled\")~}}\n {{~#set \"modify-first-line\" ~}}{{> _jpmn-check-first-line-dict dictionary=dictionary }}{{~/set~}}\n {{~#if (get \"modify-first-line\") ~}}\n {{~! none match means the dictionary is not an exception, i.e. replace newline ~}}\n {{~#regexReplace\n \"^(<span lang=\\\"ja\\\">)?(.*?)<br>\"\n \"$1\"\n ~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~else~}}\n {{~> _jpmn-glossary-single3 . ~}}\n {{~/if~}}\n {{~#if (op \"!\" (get \"opt__plaintext__enabled\")) ~}}\n </span> {{~s~}}\n {{~/if~}}\n {{~/scope~}}\n {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}\n{{/inline}}\n{{#*inline \"_jpmn-glossary-single3\"}}\n {{~#scope~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"opt-jmdict-list-format\") true)\n (op \"||\"\n (op \"===\" dictionary \"JMdict (English)\")\n (op \"||\"\n (op \"===\" dictionary \"JMdict Extra\")\n (op \"===\" dictionary \"JMdict\")\n )\n )\n )\n ~}}\n {{~#if (op \"<=\" glossary.length 1)~}}\n {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}\n {{~else~}}\n <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>\n {{~/if~}}\n {{~else~}}\n {{~#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n =============\n frequencies\n =============\n~}}\n{{#*inline \"jpmn-frequencies\"}}\n {{~#if (op \">\" definition.frequencies.length 0)~}}\n {{~#each definition.frequencies~}}\n <div class=\"frequencies__group\" data-details=\"{{~dictionary~}}\"> {{~s~}}\n <div class=\"frequencies__number\"> {{~s~}}\n <span class=\"frequencies__number-inner\"> {{~s~}}\n {{~! removes the \"X\" in JPDB's frequency and replaces it with a less assuming character\n(it interferes with the color of the card, since you see red\nat the top corner which is somewhat distracting) ~}}\n{{~#regexReplace \"\u274c\" \"\u2716\" \"g\"~}}\n{{~frequency~}}\n{{~/regexReplace~}}\n </span> {{~s~}}\n </div> {{~s~}}\n <div class=\"frequencies__dictionary\"> {{~s~}}\n <span class=\"frequencies__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </span> {{~s~}}\n </div> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~! base code taken from: https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency ~}}\n{{~! NOTE: THIS IS ONLY KEPT FOR LEGACY PURPOSES, and is now deprecated. Please use {jpmn-frequency-sort} instead. ~}}\n{{~#*inline \"jpmn-min-freq\"~}}\n{{~#scope~}}\n{{~#set \"min-freq\" 0~}}{{~/set~}}\n{{~#each definition.frequencies~}}\n{{~#set \"rx-match-ignored-freq\" ~}}\n{{~#regexMatch (get \"ignored-freq-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n{{/set~}}\n{{~#if\n(op \"&&\"\n(op \"||\"\n(op \"===\" (get \"min-freq\") 0)\n (op \">\" (op \"+\" (get \"min-freq\")) (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency)))\n )\n (op \"===\" (get \"rx-match-ignored-freq\") \"\")\n )\n ~}}\n {{~#set \"min-freq\" (op \"+\" (regexMatch \"\\d\" \"g\" this.frequency))}}{{/set~}}\n {{~/if~}}\n {{~/each~}}\n {{~get \"min-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-frequency-sort\"}}\n {{~! Frequency sort handlebars: v24.01.06.1 ~}}\n {{~! The latest version can be found at https://github.com/MarvNC/JP-Resources#freq-handlebar ~}}\n {{~#scope~}}\n {{~! Do not change the code below unless you know what you are doing. ~}}\n {{~set \"result-freq\" -1 ~}} {{~! -1 is chosen because no frequency dictionaries should have an entry as -1 ~}}\n {{~set \"prev-freq-dict\" \"\" ~}}\n {{~set \"t\" 1 ~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"u\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#each definition.frequencies~}}\n {{~! rx-match-ignored-freq is not empty if ignored <=> rx-match-ignored-freq is empty if not ignored ~}}\n {{~#set \"rx-match-ignored-freq\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-dict-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~#set \"rx-match-ignored-value\" ~}}\n {{~#regexMatch (get \"opt-ignored-freq-value-regex\") \"u\"~}}{{this.frequency}}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"&&\" (op \"===\" (get \"rx-match-ignored-freq\") \"\") (op \"===\" (get \"rx-match-ignored-value\") \"\"))~}}\n {{~!\n only uses the 1st frequency of any dictionary.\n For example, if JPDB lists 440 and 26189\u32d5, only the first 440 will be used.\n ~}}\n {{~set \"read-freq\" false ~}}\n {{~#if (op \"!==\" (get \"prev-freq-dict\") this.dictionary ) ~}}\n {{~set \"read-freq\" true ~}}\n {{~set \"prev-freq-dict\" this.dictionary ~}}\n {{/if~}}\n {{~#if (op \"!\" (get \"read-freq\") ) ~}}\n {{~#set \"rx-match-keep-freqs\" ~}}\n {{~#regexMatch (get \"opt-keep-freqs-past-first-regex\") \"u\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-keep-freqs is not empty if keep freqs ~}}\n {{~#if (op \"!==\" (get \"rx-match-keep-freqs\") \"\") ~}}\n {{~set \"read-freq\" true ~}}\n {{/if~}}\n {{/if~}}\n {{~#if (get \"read-freq\") ~}}\n {{~#set \"numericFrequencyMatch\"}}{{~#regexMatch \"\\d+\" \"\"}}{{~this.frequency~}}{{/regexMatch~}}{{/set~}}\n {{~set \"f\" (op \"+\" (get \"numericFrequencyMatch\")) ~}}\n {{~#if (op \"===\" (get \"opt-freq-sorting-method\") \"min\") ~}}\n {{~#if\n (op \"||\"\n (op \"===\" (get \"result-freq\") -1)\n (op \">\" (get \"result-freq\") (get \"f\"))\n )\n ~}}\n {{~set \"result-freq\" (op \"+\" (get \"f\")) ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"first\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"f\") ~}}\n {{~else~}}\n {{~!\n iterative mean formula (to prevent floating point overflow):\n $S_{(t+1)} = S_t + \\frac{1}{t+1} (x - S_t)$\n - example java implementation: https://stackoverflow.com/a/1934266\n - proof: https://www.heikohoffmann.de/htmlthesis/node134.html\n ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\"\n (op \"-\"\n (get \"f\")\n (get \"result-freq\")\n )\n (get \"t\")\n )\n )\n }}\n {{~/if~}}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~#if (op \">\" (get \"f\") 0) ~}} {{~! ensures only positive numbers are used ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (op \"/\" 1 (get \"f\")) ~}}\n {{~else ~}}\n {{~set \"result-freq\"\n (op \"+\"\n (get \"result-freq\")\n (op \"/\" 1 (get \"f\"))\n )\n }}\n {{~set \"t\" (op \"+\" (get \"t\") 1) ~}}\n {{~/if~}}\n {{~/if~}}\n {{~else if (op \"===\" (get \"opt-freq-sorting-method\") \"debug\") ~}}\n {{ this.dictionary }}: {{ this.frequency }} -> {{ get \"f\" }} <br>\n {{~else~}}\n (INVALID opt-freq-sorting-method value)\n {{~/if~}}\n {{~/if~}}\n {{~/if~}}\n {{~/each~}}\n {{~! (x) >> 0 apparently floors x: https://stackoverflow.com/a/4228528 ~}}\n {{~#if (op \"===\" (get \"result-freq\") -1) ~}}\n {{~set \"result-freq\" (get \"opt-no-freq-default-value\") ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"avg\") ~}}\n {{~set \"result-freq\"\n (op \">>\" (get \"result-freq\") 0 )\n ~}}\n {{~ else if (op \"===\" (get \"opt-freq-sorting-method\") \"harmonic\") ~}}\n {{~set \"result-freq\"\n (op \">>\"\n (op \"*\"\n (op \"/\" 1 (get \"result-freq\"))\n (get \"t\")\n )\n 0\n )\n ~}}\n {{~/if~}}\n {{~! override final result if grammar dictionary ~}}\n {{~#if (\n op \"&&\"\n (op \"===\" (get \"found-grammar-dict\") true)\n (op \"===\" (get \"opt-grammar-override\") true)\n )\n ~}}\n {{~set \"result-freq\" (get \"opt-grammar-override-value\") ~}}\n {{/if}}\n {{~get \"result-freq\"~}}\n {{~/scope~}}\n{{/inline}}\n{{~!\n ==============\n pitch accent\n ==============\n~}}\n{{#*inline \"jpmn-pitch-accent-graphs\"}}\n {{~#if (op \">\" pitchCount 0)~}}\n {{~#each pitches~}}\n <div class=\"pa-graphs__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-graphs__dictionary\"> {{~s~}}\n <div class=\"pa-graphs__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"graph\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-pitch-accent-positions\"}}\n{{~#if (op \">\" pitchCount 0)~}}\n{{~#each pitches~}}\n <div class=\"pa-positions__group\" data-details=\"{{dictionary}}\"> {{~s~}}\n <div class=\"pa-positions__dictionary\"> {{~s~}}\n <div class=\"pa-positions__dictionary-inner\"> {{~s~}}\n{{~dictionary~}}\n </div> {{~s~}}\n </div> {{~s~}}\n <ol> {{~s~}}\n{{~#each pitches~}}\n <li>\n{{~> pitch-accent-item-disambiguation~}}\n{{~#scope~}}\n{{~#set \"any\" false}}{{/set~}}\n{{~#each tags~}}\n{{~#if (get \"any\")}}, {{else}}({{/if~}}\n{{name}}\n{{~#set \"any\" true}}{{/set~}}\n{{~/each~}}\n{{~#if (get \"any\")}}) {{/if~}}\n{{~/scope~}}\n{{~> pitch-accent-item format=\"position\"~}}\n </li>\n{{~/each~}}\n </ol> {{~s~}}\n </div>\n{{~/each~}}\n{{~/if~}}\n{{/inline}}\n{{~!\n==============\ndictionaries\n==============\n~}}\n{{~! primary def: first monolingual (or first bilingual if no monolingual dicts found) ~}}\n{{~! does the reverse if opt-first-definition-type is \"bilingual\" ~}}\n{{~#*inline \"jpmn-primary-definition\"~}}\n{{~#scope~}}\n{{~! output warning if no dictionaries are found ~}}\n{{~#if (op \"===\" definition.definitions.length undefined)~}}\nWARNING: JPMN Handlebars cannot find any definitions to export.\nThis is usually because your Yomichan settings has \"Result grouping mode\"\nset to \"No grouping\". Please set this to \"Group term-reading pairs\".\n {{~/if~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~#if (op \"===\" (get \"primary-dictionary\") \"\")~}}\n {{~> _jpmn-selection-text ~}}\n {{~else~}}\n {{~#set \"selection\"}}{{~> _jpmn-selection-text ~}}{{/set~}}\n {{~#set \"selection-uses-glossary\"~}}\n {{~> _jpmn-selection-uses-glossary . ~}}\n {{~/set~}}\n {{~! not \"\" <=> is a filled string, i.e. selection uses glossary ~}}\n {{~#if (op \"!==\" (get \"selection-uses-glossary\") \"\")~}}\n {{~! escape regex ~}}\n {{~#set \"search-selection\"}}{{~#regexReplace \"[.*+?^${}()|[\\]\\\\]\" \"\\$&\" \"g\"~}}{{~> _jpmn-selection-text ~}}{{~/regexReplace~}}{{/set~}}\n {{~#set \"search-selection-bold\"}}<b>{{~> _jpmn-selection-text ~}}</b>{{/set~}}\n {{~#regexReplace (get \"search-selection\") (get \"search-selection-bold\") \"g\"~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/regexReplace~}}\n {{~else~}}\n {{~#set \"search-selection\"}}{{/set~}}\n {{~> _jpmn-get-primary-definition-value . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n {{~/if~}}\n {{~/if~}}\n {{~/scope~}}\n{{~/inline~}}\n{{~! extra def: bilingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-secondary-definition\"~}}\n {{~#scope~}}\n {{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n {{~! looks to see if another dictionary exists ~}}\n {{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n {{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n {{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n {{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"bilingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! extra def: monolingual defs (excluding primary def) ~}}\n{{~#*inline \"jpmn-extra-definitions\"~}}\n{{~#scope~}}\n{{~#set \"primary-dictionary\"}}{{~> _jpmn-get-primary-definition-dict . ~}}{{/set~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! entry count must be gotten here in order to properly iterate through definition.definitions ~}}\n{{~#set \"entry-count\"}}{{~> _jpmn-primary-dict-entry-count . ~}}{{/set~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\")~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"is-valid-dict\"}}{{~> _jpmn-non-primary-is-valid-dict . validDictType=\"monolingual\" entryCount=(get \"entry-count\") dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"is-valid-dict\") \"true\") ~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~! pitch accent info: all pitch accent info dictionaries ~}}\n{{~#*inline \"jpmn-utility-dictionaries\"~}}\n{{~#scope~}}\n{{~! looks to see if another dictionary exists ~}}\n{{~! 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) ~}}\n{{~#set \"has-valid-dict\"}}{{~> _jpmn-non-primary-has-valid-dict . validDictType=\"utility\"~}}{{/set~}}\n{{~#if (op \"===\" (get \"has-valid-dict\") \"true\") ~}}\n <ol>\n {{~#each definition.definitions~}}\n {{~#set \"test-dict-name\"}}{{~> jpmn-get-dict-type . dictionaryName=dictionary ~}}{{/set~}}\n {{~#if (op \"===\" (get \"test-dict-name\") \"utility\")~}}\n <li data-details=\"{{~dictionary~}}\">\n{{~> _jpmn-glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}\n </li>\n{{~/if~}}\n{{~/each~}}\n </ol>\n{{~/if~}}\n{{~/scope~}}\n{{~/inline~}}\n{{~!\n=======\nother\n=======\n~}}\n{{~#*inline \"jpmn-word-reading-hiragana\"~}}\n{{~#set \"word-reading\" ~}}{{> reading}}{{/set~}}\n{{~#if (op \"\" (get \"word-reading\")) ~}}\n{{~#set \"word-reading\" ~}}{{> expression}}{{/set~}}\n{{~/if~}}\n{{#hiragana (get \"word-reading\") keepProlongedSoundMarks=false}}{{/hiragana}}\n{{~/inline~}}\n{{~!\nthanks to:\n- https://github.com/FooSoft/yomichan/issues/1952#issuecomment-922671489 for the base code\n- DaNautics#8833 for finding the above + removing the span classes\n~}}\n{{#*inline \"jpmn-sentence-bolded-furigana-plain\"}}\n{{~#if definition.cloze~}}\n{{~#regexReplace \"(<span class=\\\"term\\\">)|(</span>)\" \"\" \"g\"~}}\n{{~#regexReplace \"<ruby>(.+?)<rt>(.+?)</rt></ruby>\" \" $1[$2]\" \"g\"~}}\n{{~#if (hasMedia \"textFurigana\" definition.cloze.prefix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.prefix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.prefix~}}\n{{~/if~}}\n <b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.body)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.body escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.body~}}\n{{~/if~}}\n </b>\n{{~#if (hasMedia \"textFurigana\" definition.cloze.suffix)~}}\n{{~#getMedia \"textFurigana\" definition.cloze.suffix escape=false}}{{/getMedia~}}\n{{~else~}}\n{{~definition.cloze.suffix~}}\n{{~/if~}}\n{{~/regexReplace~}}\n{{~/regexReplace~}}\n{{~/if~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-hiragana\"}}\n{{~#scope~}}\n{{~#set \"expression\" ~}}{{> expression}}{{/set~}}\n{{~#set \"reading\" ~}}{{> reading}}{{/set~}}\n{{~#set \"expression-hiragana\" ~}}{{> jpmn-word-reading-hiragana}}{{/set~}}\n{{~#if (op \"&&\" (op \"===\" (get \"expression\") (get \"reading\")) (op \"===\" (get \"expression\") (get \"expression-hiragana\")))~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-word-is-not-hiragana\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-word-is-hiragana}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-grammar-point\"}}\n {{~#scope~}}\n {{~set \"found-grammar-dict\" false ~}}\n {{~! search for grammar dictionary ~}}\n {{~#each definition.definitions~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~/each~}}\n {{~! Additional case when \"Result grouping mode\" is set to \"No Grouping\"~}}\n {{~#set \"rx-match-grammar-dicts\" ~}}\n {{~#regexMatch (get \"opt-grammar-override-dict-regex\") \"gu\"~}}{{this.definition.dictionary}}{{~/regexMatch~}}\n {{/set~}}\n {{~! rx-match-grammar-dicts is not empty if a grammar dictionary was found ~}}\n {{~#if (op \"!==\" (get \"rx-match-grammar-dicts\") \"\") ~}}\n {{~set \"found-grammar-dict\" true ~}}\n {{/if~}}\n {{~#if (get \"found-grammar-dict\") ~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-grammar-point\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-grammar-point}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-on-mim\"}}\n {{~#scope~}}\n {{~#set \"rx-match-on-mim\" ~}}\n {{~#regexMatch \"(, |^)on-mim(, |$)\" \"gu\"~}}{{> tags }}{{~/regexMatch~}}\n {{/set~}}\n {{~#if (op \"!==\" (get \"rx-match-on-mim\") \"\") ~}}\n 1\n {{/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-filled-if-not-on-mim\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-filled-if-not-on-mim}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! my personal settings:\n- sentence card if grammar point\n- otherwise, if it's on-mim, then hint card\n- otherwise, default\n~}}\n{{#*inline \"jpmn-is-sentence-card\"}}\n {{~> jpmn-filled-if-grammar-point ~}}\n{{/inline}}\n{{#*inline \"jpmn-is-hint-card\"}}\n {{~#scope~}}\n {{~#set \"filled\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"===\" (get \"filled\") \"\")~}}\n {{~> jpmn-filled-if-on-mim ~}}\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{#*inline \"jpmn-is-click-card\"}}\n {{~#scope~}}\n {{~#set \"filled1\" ~}}{{> jpmn-is-hint-card}}{{/set~}}\n {{~#set \"filled2\" ~}}{{> jpmn-is-sentence-card}}{{/set~}}\n {{~#if (op \"&&\"\n (op \"===\" (get \"filled1\") \"\")\n (op \"===\" (get \"filled2\") \"\")\n )~}}\n 1\n {{~/if~}}\n {{~/scope~}}\n{{/inline}}\n{{~! a test to check if your dictionaries are correctly classified. ~}}\n{{~! Only meant to be used for debugging purposes, not Anki. ~}}\n{{~#*inline \"jpmn-test-dict-type\"~}}\n{{~#scope~}}\n{{~#each definition.definitions~}}\n\u300c{{dictionary}}\u300d: {{> jpmn-get-dict-type . dictionaryName=dictionary}}\n{{/each~}}\n{{~/scope~}}\n{{~/inline~}}\n
"},{"location":"setupyomichan/#make-an-example-card","title":"Make an example card!","text":"TODO re-record with renji's texthooker, and show result card
At this point, you should be able to make cards with Yomitan!
Click here to show some example Japanese sentences. \u300c\u3084\u3001\u3044\u3089\u3063\u3057\u3083\u3044\u3002\u307e\u3001\u6bd2\u3092\u98df\u3089\u308f\u3070\u76bf\u307e\u3067\u3063\u3066\u8a00\u3046\u3057\u306d\u3002\u3042\u3001\u9055\u3046\u304b\u3002\u4e57\u308a\u639b\u304b\u3063\u305f\u8239\uff1f\u300d
\u300c\u3042\u306e\u6642\u9003\u3052\u51fa\u3057\u305f\u79c1\u306e\u7f70\u2026\u3042\u306e\u6642\u306e\u6c5a\u8fb1\u306f\u4eca\u3053\u3053\u3067\u3001\u5168\u90e8\u305d\u305d\u3044\u3067\u3084\u308b\u3093\u3060\u2026\u300d
\u300c\u3068\u306b\u304b\u304f\u5229\u6575\u884c\u70ba\u3055\u3048\u3057\u306a\u3044\u3088\u3046\u306b\u3059\u308c\u3070\u57fa\u672c\u7684\u306b\u554f\u984c\u306f\u306a\u3044\u306f\u305a\u3067\u3059\u3057\u3001\u6c7a\u307e\u308a\u304d\u3063\u305f\u30e0\u30fc\u30d6\u3060\u3051\u3067\u7d76\u5bfe\u306b\u52dd\u3066\u308b\u3068\u3044\u3046\u308f\u3051\u3067\u3082\u7121\u3044\u306e\u3067\u3001\u305d\u306e\u6642\u3005\u306e\u72b6\u6cc1\u3092\u843d\u3061\u7740\u3044\u3066\u898b\u3066\u3001\u67d4\u8edf\u306b\u884c\u52d5\u3059\u308b\u3053\u3068\u304c\u5927\u5207\u3067\u3059\u300d
\u300c\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u306f\u3001IEEE-754\u898f\u683c\u306b\u5f93\u3063\u3066\u8868\u73fe\u3055\u308c\u3066\u3044\u307e\u3059\u3002f32
\u304c\u5358\u7cbe\u5ea6\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u3001 f64
\u304c\u500d\u7cbe\u5ea6\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u3067\u3059\u300d
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.
"},{"location":"setupyomichan/#monolingual-cards","title":"Monolingual Cards","text":"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:
{{~set \"opt-first-definition-type\" \"bilingual\" ~}}\n
to {{~set \"opt-first-definition-type\" \"monolingual\" ~}}\n
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.
"},{"location":"setupyomichan/#enjoy-your-new-one-click-cards","title":"Enjoy your new one-click cards!","text":"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 minimal 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: Text & Media 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, and have should be set to SentenceAudio
and Picture
respectively.
Finally, remember that up until now, this has been the minimum setup in order to use jp-mining-note. There are likely many ways you can improve this current setup. See the \"Extra Setup\" pages to the left sidebar for more information.
"},{"location":"themes/","title":"Themes (TODO)","text":"TODO
- defined under
(root)/themes
- overrides folder for partials is pointed directly at the theme folder, i.e. the two are equivalent:
(root)/overrides/jp-mining-note/partials/js/post.js\n(root)/themes/THEME/jp-mining-note/partials/js/post.js\n
"},{"location":"tooltipresults/","title":"Tooltip Results (TODO)","text":"TODO add intro
- for kanji hover and same reading indicator
- TODO generalize this page to not only be for kanji hover
"},{"location":"tooltipresults/#pitch-accent-display","title":"Pitch Accent Display","text":" - pitch accents should be exactly the same pitch accents as shown on the specified card
- pitch accents are stripped of extra information (nasal and devoiced)
- all the extra color was very distracting, and stole the attention away from the important part (the example words found)
"},{"location":"tooltipresults/#cache-tooltip-results","title":"Cache Tooltip Results","text":"TODO
- problem: mobile (and anki-web) does not have access to Anki-Connect
- yes, Android has AnkiConnect Android, but its implementation is incomplete
- even if it were complete, it is currently a lot slower than the standard desktop Anki-Connect
- kanji hover and word indicators fully depend on Anki-Connect in order to work!
- solution: cache results of kanji hover and word indicators, into the
CardCache
field - requires building the note!!!
- may be implemented as a separate note in the future (so you can run the script within Anki)
- also requires node (npx node)
"},{"location":"tooltipresults/#cache-script-warnings","title":"Cache Script Warnings","text":" - cannot use Anki while running the script (Anki-Connect blocks using Anki, and the script continuously makes calls to Anki-Connect during its lifetime)
- will take a long time to run!!! this is because Anki-Connect itself is a bit slow when doing mass operations like this
- 1000 cards took about 45 minutes for me
"},{"location":"tooltipresults/#prerequisites","title":"Prerequisites","text":" - Open Anki (so that Anki-Connect is running)
-
Build the note! You might have to refresh the npm dependencies npm ci
.
-
If using runtime options (i.e. colored pitch accent), Use the following CTO:
\"hardcodedRuntimeOptions\": true,\n
- required because runtime options currently cannot be read from Anki.
- must also use
runtime_options.json(5)
file if you want any runtime options
-
Close your card viewer, so you are not viewing any card when running the script.
"},{"location":"tooltipresults/#test-cache-script-single-card","title":"Test Cache Script - Single Card","text":" - Test the script out first, by running it on a single card (preferably one with visible word indicators) For example, take a note ID of any JPMN note (Card browser \u2192 Right click a note \u2192
Info...
), and use the following: node ./src/_js/jpmn_card_cache.js --custom-query=\"nid:1234567890\"\n
- Sync on both PC and mobile.
- Check that kanji hover and word indicators work!
"},{"location":"tooltipresults/#test-cache-script-show-card-list","title":"Test Cache Script - Show Card List","text":"TODO --print-notes-only
"},{"location":"tooltipresults/#run-cache-script","title":"Run Cache Script","text":" -
Run the following:
node ./src/_js/jpmn_card_cache.js\n
-
above caches for 8 days (expected that you run this, say, once every saturday)
- run with
--help
for list of all available flags - TODO: macOS cannot find Anki-Connect???
"},{"location":"tooltipresults/#ignore-cache-results","title":"Ignore Cache Results","text":" - TODO results are ignored by default on PC (TODO not currently the case as of writing)
- so PC always gets the most current results, at the cost of slight performance
- can be edited via runtime option
cardCache.enabled
"},{"location":"tooltipresults/#remove-cached-results","title":"Remove Cached Results","text":" - TODO can clear the
CacheField
field (make sure to edit HTML! TODO link FAQ) - can remove all results via
clear_field CardCache
batch command
"},{"location":"tooltipresults/#result-queries-categorization","title":"Result Queries & Categorization","text":"TODO add writeup on new.newest
The exact results shown through Kanji Hover is not completely trivial, so this process is explained below.
The words are searched and sorted into 3 categories:
- The two oldest, not new cards (already reviewed before, in order of add date)
- The two latest, not new cards (the most recent two cards that you have reviewed, in order of add date)
- The two oldest, new cards (the first 2 new cards that you will see with the kanji)
The last category (the new cards) are greyed out to show that you haven't reviewed the card yet (i.e. you may not know the word yet). Conversely, the first two categories (the non-new cards) represent words that you likely already know, so they are not greyed out.
The exact numbers shown in each category can be changed in the runtime option:
// maximum number of words per category\n\"tooltips.categoryMax.nonNew.oldest\": 2,\n\"tooltips.categoryMax.nonNew.newest\": 2,\n\"tooltips.categoryMax.new.oldest\": 2,\n\"tooltips.categoryMax.new.newest\": 0,\n
TODO: add this to each query to hide results from cards that are due today
-(prop:due=0 -rated:1)\n
"},{"location":"tooltipresults/#results-sorting","title":"Results Sorting","text":"The above makes the assumption that you are reviewing in order of creation date, rather than the time of first review, to save resources. In other words, if you re-ordered your cards to be different from the add-date, then the kanji hover will not be able to recognize that.
For people who review in order of frequency only, then the assumption above is completely broken.
Unfortunately, there is currently no way to order the results by anything other than by the creation date.
"},{"location":"tooltipresults/#suspended-cards","title":"Suspended Cards","text":"TODO make sure this is correct with hidden
now removed
Some assumptions are made about suspended cards. For example, suspended cards flagged as green
are counted in the \"non-new\" cards category (known words), and suspended cards flagged as red
are counted as words that you do not know AND will not study in the future (not shown in any category). This can be changed in the runtime options:
\"tooltips.query.nonNew.base\": \"-is:new OR (is:suspended is:new flag:3)\",\n\"tooltips.query.nonNew.removed\": \"is:suspended flag:1\",\n
"},{"location":"tooltipresults/#customizing-sentences-pitch-accent","title":"Customizing Sentences & Pitch Accent","text":"TODO link to runtime options? or visa versa?
Any runtime option under the sentParser
and autoPA
group can be set under tooltips.overrideOptions.sentenceParser
and tooltips.overrideOptions.autoPitchAccent
respectively. Additionally, the kanjiHover
and wordIndicators
category has their own overrideOptions
section that behaves the exact same as the above, except they only affect Kanji Hover and Word Indicators, respectively.
This allows for very fine grained control on how the sentences and pitch accent should be displayed.
Note
When the sentence is being parsed by the tooltip builder, it is considered a \"full sentence\" internally. Therefore, only the fullSent
group of options will affect the resulting sentence.
"},{"location":"tooltipresults/#highlight-the-word-within-the-tooltips","title":"Highlight the word within the tooltips","text":"New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Within the tooltips, the word within the sentence is not highlighted by default. This is to emphasize the importance of the kanji over the word. However, this comes at the cost of having to scan through the entire sentence to find the word.
The following runtime option re-enables the highlighted word:
\"tooltips.highlightWordInSentence\": true,\n
HighlightedNot Highlighted (default) TODO this is no longer bolded
"},{"location":"tooltipresults/#display-newlines-in-mobile-tooltip-sentences","title":"Display newlines in mobile tooltip sentences","text":"TODO wrap with custom css text
.mobile-popup .hover-tooltip__sent-div br {\ndisplay: inline;\n}\n
"},{"location":"ui/","title":"Ui","text":"This page is dedicated to showcasing various aspects of the common user interface.
"},{"location":"ui/#summary","title":"Summary","text":"Most of the user interface is already shown off in the GUI demo, and I would recommend watching it before continuing.
However, to dispell any mysteries, here is a fully annotated summary of the user interface.
Additional information on some parts of the UI is stated below.
"},{"location":"ui/#keybinds","title":"Keybinds","text":"This note ships with some keybinds to do basic actions.
Keybind What it does p
Play sentence audio w
Play word audio 8
Toggles Secondary Definition
field 9
Toggles Additional Notes
field 0
Toggles Extra Definitions
field [
Toggles Extra Info
field See the runtime options if you would like to edit / disable any keybind, and/or to view the full list of keybinds.
"},{"location":"ui/#info-circle","title":"Info Circle","text":"DefaultErrorWarningLeech On hover, the info circle on the top left corner just shows some basic info. However, it also serves as a notification system to the user, when it has a color.
This should only appear when some javascript code fails. In other words, this should not appear under normal circumstances. If you get this without modifying the note in any way, please see this section for basic troubleshooting.
This serves to warn the user about something. It can appear without completely breaking the functionality of the card. In other words, you can choose to ignore it.
When the card is a leech, the circle is highlighted yellow (or blue in light mode) to indicate that it is a leech. This is only shown on the back side of the card.
"},{"location":"ui/#locking-the-info-circle","title":"Locking the Info Circle","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
You can toggle (click on) the info circle to lock the tooltip in place. This may be useful for copying/pasting errors and other debugging purposes.
"},{"location":"ui/#kanji-hover","title":"Kanji Hover","text":"Kanji hover shows you if you have seen the kanji in previous cards or not. This is useful if you want to check whether you have seen the reading in a previous card, to differentiate between similar kanjis, etc.
By default, it searches for the kanji within the \"Word\" field, within \"JP Mining Note\" types.
Various Details:
-
You may have noticed that some results are greyed out. These represent words from cards that have not been reviewed yet. Conversely, as non-greyed out results come from cards that you have already reviewed, they should represent words that you already know.
-
Pitch accents are shown when you hover over a particular word within the tooltip. You can change this to always be shown in the runtime options.
-
You can click on the word to open the specified card within Anki's card browser.
See here for information on how the examples are chosen, and how to customize it.
Related Programs (click here) Cade's Kanji Hover
- Hover over a kanji to see its readings, meanings (english), and other info.
- This does not show example words from other cards.
- My implmentation of kanji hover was heavily inspired by this.
Hanzi Web for Anki
- The end result of this is to this note's implementation of kanji-hover, in the sense that it is used to see kanjis that have been used in other notes. However, it differs primarily in the fact that all the information must be mass-generated. This indeed has several advantages, such as being able to use the infomation on Android, where Anki-Connect isn't full supported.
KanjiEater's Kanji Connections
- Ability to show kanjis with heisig's RTK keywords, as well as related vocabulary. Similar to Hanzi Web for Anki.
Warning
None of the above will work with jp-mining-note by default. In fact, it's almost guaranteed that Cade's Kanji Hover will conflict with this note's kanji hover ability.
"},{"location":"ui/#word-indicators","title":"Word Indicators","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found. The indicators are as follows:
- \u540c (short for \u540c\u3058) indicates that the card is a duplicate.
- \u8aad (short for \u8aad\u307f\u65b9) indicates that there are other card(s) with the same reading (ignoring pitch accent). In Japanese, these words are \u540c\u97f3\u7570\u7fa9\u8a9e. I consider this the most useful of the three.
- \u6f22 (short for \u6f22\u5b57) indicates that there are other card(s) with the same kanji, but different reading.
As you can see from the above, the query ignores pitch accent. The word \u81ea\u8eab is still shown, despite having a different pitch accent compared to \u5730\u9707.
Note
This indicator will be yellow (or blue on light mode) for new cards only. After the first review, the indicator will be the same color as the default info circle (grey).
The tooltip behaves very similarly properties to Kanji hover's tooltip:
- New cards are greyed out.
- You can click on words to open them in Anki's card browser.
- Pitch accent is shown without requiring the user to hover over the word by default. This is different from Kanji hover's tooltip.
See here for information on how the examples are chosen, and how to customize it.
"},{"location":"ui/#images-pitch-accent","title":"Images & Pitch Accent","text":"See the Images page for information on the following:
- Blurring images
- Specifying default images
- Automatically formatting pictures within the definition
See the Pitch Accent page for information on the following:
- Pitch accent notation
- Automatic pitch accent coloring
- How to override the pitch accent of any word
"},{"location":"ui/#external-links","title":"External Links","text":"New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
External links are shown as icons in the Extra Info
collapsable field by default. By default, hovering over them will show the url. Click on the desired icon to visit to the desired site.
See also: UI Customization (External Links).
"},{"location":"ui/#conclusion","title":"Conclusion","text":"This page shows various aspects of the user interface, but says little about actually modifying it. Head over to the UI Customization page to see just that.
"},{"location":"updating/","title":"Updating: Overview","text":"So you want to update jp-mining-note? Awesome, here's what you got in store!
"},{"location":"updating/#what-to-expect","title":"What to Expect","text":"Updating JPMN usually comprises of updating two things separately:
- The JPMN template itself within Anki. The internal updater does most of the work, so you should not have to do much on this end.
- External settings, such as the Yomichan settings required to interface with Anki. The internal updater CANNOT interface with these, so you will have to manually update these if they exist.
"},{"location":"updating/#what-to-expect-updating-the-jpmn-template","title":"What to Expect: Updating the JPMN template","text":" - Any changes you made to the templates WILL BE LOST (outside of the small dedicated section at the bottom of the CSS). This is because the updater replaces your template in place, and overrides any changes.
- Fields may be added, repositioned, etc. Existing fields should not be removed.
- It runs any necessary batch edits to all notes, meaning the data within any given note may be subtly changed.
As the updater can do many things to your collection, it is always recommended to make a complete backup of your collection before updating.
"},{"location":"updating/#what-to-expect-external-settings","title":"What to Expect: External Settings","text":"After running the main updater, there may be changes that the user must make, because the updater simply cannot update those particular details. User-required changes are usually present for major updates (i.e. if any of the first two numbers in the version change).
Some common user-required changes include:
- Updating the Yomichan templates
- Updating optional add-on configs
All of these user required changes should be listed under the Setup Changes page, which should be read after running the main installer.
"},{"location":"updating/#updating","title":"Updating!","text":"Now that you have a general idea of what's going to happen...
See how to update JPMN here!
"},{"location":"updatingfinalsteps/","title":"Final Steps","text":""},{"location":"updatingfinalsteps/#final-steps","title":"Final Steps","text":"By now, you should be done updating the note! Please do the following checks to make sure everything properly works:
- Preview an existing card, to ensure that nothing looks odd.
-
Create a new card and make sure nothing looks odd.
Example Japanese sentences to test card creation \u300c\u6211\u306a\u304c\u3089\u99ac\u9e7f\u99ac\u9e7f\u3057\u3044\u3053\u3068\u3092\u601d\u3044\u3064\u3044\u305f\u3082\u306e\u3060\u3068\u5606\u606f\u3057\u3064\u3064\u3082\u3001\u79c1\u306f\u9759\u304b\u306b\u30d9\u30c3\u30c9\u306b\u8fd1\u4ed8\u304f\u300d
\u300c\u30b8\u30a7\u30e9\u30fc\u30c8\u3092\u8cb7\u3046\u304a\u91d1\u304c\u306a\u3044\u3068\u306f\uff01\u7d66\u6599\u65e5\u307e\u3067\u53ce\u5165\u306e\u5f53\u3066\u3082\u306a\u3057\u3001\u81ea\u708a\u3059\u308b\u3057\u304b\u3042\u308a\u307e\u305b\u3093\u306d\u300d
\u300c\u3053\u308c\u304c\u5c11\u5e74\u8a8c\u3060\u3063\u305f\u3089\u9806\u4f4d\u4e0a\u304c\u3063\u3066\u308b\u305e\u3002\u305d\u3057\u3066\u30c8\u30fc\u30ca\u30e1\u30f3\u30c8\u7de8\u3067\u30a2\u30cb\u30e1\u5316\u6c7a\u5b9a\u3060\u300d
\u300c\u3042\u306e\u6642\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u4e0a\u3067\u8272\u3093\u306a\u8cea\u554f\u304c\u3067\u304d\u308b\u30b5\u30a4\u30c8\u306b\u6295\u7a3f\u3057\u305f\u3089\u3001\u89aa\u5207\u306a\u4eba\u304c\u5546\u54c1\u540d\u3068\u58f2\u3063\u3066\u3044\u308b\u5834\u6240\u3092\u6559\u3048\u3066\u304f\u308c\u305f\u3093\u3067\u3059\u300d
\u300c\u7b2c\u4e8c\u6b21\u4e16\u754c\u5927\u6226\u306b\u304a\u3051\u308b\u9023\u5408\u56fd\u8ecd\u306e\u91cd\u8981\u62e0\u70b9\u3067\u3059\u2026\u300d
"},{"location":"updatingjpmn/","title":"Updating: JPMN","text":"This section is dedicated to updating the JPMN template in Anki.
"},{"location":"updatingjpmn/#preliminary-steps","title":"Preliminary steps","text":" -
Ensure that your note is named exactly JP Mining Note
. To do this, head over to:
(Main Window) \u2192 Tools
\u2192 Manage Note Types
.
If your note is named differently, please rename it to JP Mining Note
.
-
Please make a backup of your entire Anki collection, if you haven't already.
"},{"location":"updatingjpmn/#updating-the-note","title":"Updating the Note","text":"You can update the note in one of two ways:
- Via JPMN Manager, an Anki add-on. If you don't know which method to choose, choose this one.
- Via command line. This method is recommended for people who are familiar with
git
and python
, and don't want to download an Anki add-on.
Option 1: Via JPMN Manager (click here) Note
If you have previously installed Aquafina's old version of the JPMN add-on, then you must remove it before installing the new version below. The old and new versions will conflict with each other if they are both installed. In your list of Anki add-ons, you should only see JPMN Manager with prereleases New Version
. If you see JPMN Manager with prereleases
then please remove it and restart Anki before proceeding.
This add-on simply wraps around the python script mentioned below, and should behave the exact same as running the script manually.
Video demo (click here) - If you haven't installed the JPMN Manager add-on yet, do so with the following code:
301910299
. Be sure to restart Anki after installing. -
Make sure there is something to update to in the first place. You can do this by:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Check for note updates
-
Update the note by navigating to the following:
(Main Window) \u2192 Tools
\u2192 JPMN Manager
\u2192 Update jp-mining-note
-
You may see additional instructions. If you do, please continue the updating process with the Setup Changes page
There may be further steps outside of just updating the card, such as updating Yomichan's templates / format. These should be recorded in the Setup Changes page.
Afterward seeing that page, please view the final steps section.
-->
Option 2: Via Command Line (click here) WindowsLinux & macOS :: assuming you are at the root of the repo, i.e. after the following commands:\n:: $ git clone https://github.com/arbyste/jp-mining-note.git\n:: $ cd jp-mining-note\n:: Since we are using the prerelease version, make sure you switch\n:: to the dev branch\ngit checkout dev\n:: grabs the latest version of the dev branch\ngit pull --force\n\n:: Make sure you have Anki open and Anki-Connect installed!\n:: Also ensure that your python version is 3.9 or higher.\npython tools\\install.py --update\n
# assuming you are at the root of the repo, i.e. after the following commands:\n# $ git clone https://github.com/arbyste/jp-mining-note.git\n# $ cd jp-mining-note\n# Since we are using the prerelease version, make sure you switch\n# to the dev branch\ngit checkout dev\n# grabs the latest version of the dev branch\ngit pull --force\n\n# Make sure you have Anki open and Anki-Connect installed!\n# Also ensure that your python version is 3.9 or higher.\npython3 tools/install.py --update\n
There may be further steps outside of just updating the card, such as updating Yomichan's templates / format. These should be recorded in the Setup Changes page.
Afterward seeing that page, please view the final steps section.
Why can't I just copy/paste the templates, or just re-install the .apkg file to update the note? In short, updating via Anki or Python performs many operations that cannot be done with a simple note transfer. Most importantly, there are operations (usually under batch.py) that change the data within the actual fields themselves, and these are ran automatically on note update. If you attempt to update your note manually, these actions will not be ran, and can result in unwanted changes to your note!
Additionally, many manual operations are done for you by updating the note with the Python script, such as automatically creating and re-arranging new fields.
If you still want to attempt manually updating the note, then there will be little to no support given.
"},{"location":"updatingjpmn/#common-errors","title":"Common Errors","text":"This section will document common errors that occur when attempting to update the note.
"},{"location":"updatingjpmn/#anki-connect-is-missing-actions","title":"Anki-Connect is missing actions","text":"Anki-Connect is likely outdated. To fix this, remove and re-download Anki-Connect from the AnkiWeb page.
Note
It seems that the Check for Updates
occasionally fails to update the add-on, despite the fact that a newer version of the add-on exists. That is why I recommend re-downloading from the AnkiWeb page instead of using this feature.
"},{"location":"updatingjpmn/#fieldverifierexception","title":"FieldVerifierException","text":"This class of errors means that the field list was edited at some point after the installation or last update of JPMN. The field list can be accessed by navigating to the following:
(Main window) \u2192 Browse
\u2192 Fields...
.
The installation script is picky about fields and its order, and by default, the script will reject any note type with modifications to the field list.
To fix this, there are a few cases to go through.
The field order has been changed. If the field order has been changed, and nothing else has been changed, you should be able to preserve your existing field list order by running the installation script with the --ignore-order
flag:
JPMN ManagerPython Script Tools
\u2192 JPMN Manager
\u2192 Run installer with arguments
--update --ignore-order\n
python3 install.py --update --ignore-order\n
Alternatively, you can re-order the field list beforehand. This can be done with the following batch command:
reposition_fields\n
New field(s) have been created. You have two options. Neither of these will delete your existing field(s).
-
If you want to preserve your existing field list order, then you can run the script with the --ignore-order
flag, like above.
-
If you want to have the field list order match exactly with the current note, then re-order all the new fields to be below the last Comment
field. Of course, this can be a temporary move; you can move the fields back to their previous positions after the update.
Note
On rare occasions, you might have added a field that serves the same purpose as a field that will be created on update. If so, rename your field to the field that will be added, and move the field under the Comment
field.
For example, if your note doesn't have PAPositions
but you added a field Positions
that fulfills the same purpose, then rename Positions
to PAPositions
.
Field(s) were removed or renamed. Unfortunately, there is no way to ignore removed or renamed fields. If you removed a field, please re-add the field. Likewise, if you renamed a field, please rename it back to the original name. See here for more info on why they cannot be ignored.
"},{"location":"updatingyomichan/","title":"Updating: Yomichan","text":"This section is dedicated to updating Yomichan settings required to use JPMN.
"},{"location":"updatingyomichan/#updating-yomichans-anki-card-format","title":"Updating Yomichan's Anki Card Format","text":"To update the Yomichan Format, the steps should be almost the same as the one specified already in the setup. The most important difference is that if a new field was added or a field has been renamed, then the field will not show up automatically in Yomichan.
"},{"location":"updatingyomichan/#refreshing-yomichan-fields","title":"Refreshing Yomichan Fields","text":"Video Demo (click here) TODO update the video...
- As always, create a backup of your Yomichan settings, just in case.
- After installing the note update, create a temporary copy of the note by:
Tools
\u2192 Manage Note Types
\u2192 Add
\u2192 Select Clone: JP Mining Note
\u2192 Ok
\u2192 Name this to anything you want. The following examples will use JP Mining Note copy
. \u2192 Ok
\u2192 Close
- If you are currently viewing Yomichan Settings, please refresh the page.
- Head over to Anki Card Format as before.
- In the top right corner, change
Model
to JP Mining Note copy
, and then change it back to JP Mining Note
. (If you don't see JP Mining Note copy
, please refresh the page.) - Update the fields as specified.
- It should be specified in the text you see when updating. However, you should also simply compare the table on the setup page to your filled out fields.
- Remove the temporary note:
Tools
\u2192 Manage Note Types
\u2192 (select JP Mining Note copy
) \u2192 Delete
Explanation
Using the temporary copy of the updated card means that fields that remain unchanged between the old card and new card will be transferred automatically in the Yomichan Format. If you simply choose some random model like Basic
, then almost none of the fields will be preserved, as the Basic
card does not have any matching fields with the JP Mining Note
model.
"},{"location":"updatingyomichan/#updating-yomichan-templates","title":"Updating Yomichan Templates","text":"Like the above, you can simply follow the steps already specified in setup.
Again, please make a backup of your Yomichan settings just in case, and again, please make sure you reset the existing templates (unless you know what you are doing).
Note that your Yomichan template options will be reset if you follow all the steps. I recommend temporarily saving a copy of the Yomichan templates so you can easily reset your Yomichan template options after updating.
"},{"location":"wordindicators/","title":"Word Indicators (TODO)","text":"New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found.
\u540c (\u540c\u3058)\u8aad (\u8aad\u307f\u65b9)\u5b57 (\u6f22\u5b57) This indicates the card is a duplicate.
(TODO image)
This shows cards with the same reading, ignoring pitch accent (also known as \u540c\u97f3\u7570\u7fa9\u8a9e.) For example, the word \u81ea\u8eab is still shown, despite having a different pitch accent to \u5730\u9707.
(TODO update image)
This indicates that there are other card(s) with the same kanji, but different reading.
(TODO image)
"},{"location":"wordindicators/#interface","title":"Interface","text":"This indicator will be yellow (or blue on light mode) for new cards only. After the first review, the indicator will be the same color as the default info circle (grey).
"},{"location":"wordindicators/#interface-new-cards","title":"Interface: New Cards","text":"Just like with Kanji Hover, new cards are greyed out.
(TODO image)
"},{"location":"wordindicators/#interface-pitch-accents","title":"Interface: Pitch Accents","text":"Unlike Kanji Hover, pitch accents are automatically shown (without having to hover over the word), to emphasize the importance of different word pitches on similar words.
(TODO image)
"},{"location":"wordindicators/#interface-open-card","title":"Interface: Open Card","text":"Just like with Kanji Hover, you can click on the word to open the specified card within Anki's card browser.
(TODO image)
"},{"location":"wordindicators/#refresh-button","title":"Refresh Button","text":"TODO - Connected with Kanji Hover: editing some other card shown in the results will not show due to cache - pressing the refresh button on the info circle should fix
"},{"location":"wordindicators/#prefetching-results","title":"Prefetching Results","text":"TODO safe mode
"},{"location":"yomichantemplates/","title":"Yomichan Template Options (TODO)","text":"Yomichan template options are options that are specified, as you may have guessed, in Yomichan's templates. These options are applied on card creation, so changing these options will only affect cards created in the future.
"},{"location":"yomichantemplates/#accessing-editing","title":"Accessing & Editing","text":"TODO video
To access the Yomichan template options, head to the Yomichan templates as normal:
- Navigate to Yomichan Settings.
- Make sure that advanced settings are turned on (bottom left corner).
- Go to the
Anki
section - Select
Configure Anki card templates...
The options should be available at the very top of the template code.
"}]}
\ No newline at end of file
diff --git a/sentences/index.html b/sentences/index.html
index 60b6439d..310bfc21 100644
--- a/sentences/index.html
+++ b/sentences/index.html
@@ -2159,7 +2159,7 @@ Sentence Max Width IndicatorAutomatic word highlighting¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Usually, the word within the sentence is already bolded by Yomichan.
However, there are some cases where the word within the sentence may not be bold,
such as when external programs update the Sentence
field, or if you are using
@@ -2253,7 +2253,7 @@
Adding or removing quotesSentenceReading
Furigana Options¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, the furigana for the full sentence (on the back side of the card)
is shown on hover, given that this SentenceReading
field is filled out.
If SentenceReading
is not filled out, then the sentence will show as usual
@@ -2298,7 +2298,7 @@
Furigana: Simple CSS optionsFurigana: When to show¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
By default, furigana is shown on hover.
This can be changed to only be shown on click, or always/never shown.
Furigana: Hide spacing¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Furigana that extends past the length of the kanji will add additional spacing around the kanjis,
which may be unpleasant to look at.
One solution to this is to simply hide the spacing until hover or click.
@@ -2412,7 +2412,7 @@
Generating Sentence FuriganaFurigana Generation: AJT Japanese¶
TODO
Furigana Generation: Yomichan Helper¶
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
helper: {jpmn-sentence-bolded-furigana-plain}
@@ -2427,7 +2427,7 @@ Furigana Generation: Yomichan Helpe
Keeping and removing newlines within the display sentence¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
You can add newlines to the Sentence
field to make the full sentence
field have cleaner line breaks.
If you do this, you will need to regenerate the SentenceReading
@@ -2468,7 +2468,7 @@
Keeping and r
Multiple Sentences¶
-
New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
- TODO
- summary: split with multiple newlines, i.e.
<br><br>
diff --git a/sitemap.xml b/sitemap.xml
index e4160d07..c19d3040 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,312 +2,312 @@
https://arbyste.github.io/jp-mining-note-prerelease/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/alternatives/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/autopa/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/backfilling/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/batch/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/blockquotes/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/building/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/cardtypes/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/cardtypes2/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/changingcardtype/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/compiletimeoptions/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/customcss/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/definitions/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/externallinks/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/faq/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/fieldref/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/fields/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/frequencies/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/images/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/importing/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/infocircle/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/jpmnhandlebars/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/jpresources/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/jpresourcesother/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/kanjihover/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/keybinds/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/modding/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/moddingtips/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/modules/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/other/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/overrides/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/personalsetup/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/preface/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/principles/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/quickstart/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/runtimeoptions/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/scripts/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/sentences/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setup/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupandroid/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupanki/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupasbplayer/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupchanges/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupereaders/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupextraanki/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupextrayomichan/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupgoldendict/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupios/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupjidoujisho/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupjl/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupmpvacious/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setuptextmedia/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/setupyomichan/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/themes/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/tooltipresults/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/ui/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/updating/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/updatingfinalsteps/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/updatingjpmn/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/updatingyomichan/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/wordindicators/
- 2024-02-15
+ 2024-02-16
daily
https://arbyste.github.io/jp-mining-note-prerelease/yomichantemplates/
- 2024-02-15
+ 2024-02-16
daily
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index 3911316d..ddcdaaf8 100644
Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ
diff --git a/tooltipresults/index.html b/tooltipresults/index.html
index 844ae557..752345dd 100644
--- a/tooltipresults/index.html
+++ b/tooltipresults/index.html
@@ -2199,7 +2199,7 @@ Customizing Sentences & Pitch Ac
Highlight the word within the tooltips¶
-New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.12.0.0
(latest version: 0.12.0.0-prerelease-16
)
Within the tooltips, the word within the sentence is not highlighted by default.
This is to emphasize the importance of the kanji over the word.
However, this comes at the cost of having to scan through the entire sentence to find the word.
diff --git a/ui/index.html b/ui/index.html
index 58df09b2..77d4217e 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -1941,7 +1941,7 @@ Info Circle
Locking the Info Circle¶
-New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
You can toggle (click on) the info circle to lock the tooltip in place.
This may be useful for copying/pasting errors and other debugging purposes.
@@ -2000,7 +2000,7 @@ Kanji Hover
Word Indicators¶
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words in your deck are found.
The indicators are as follows:
@@ -2044,7 +2044,7 @@ Images & Pitch Accent
External Links¶
-New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.10.3.0
(latest version: 0.12.0.0-prerelease-16
)
External links are shown as icons in the Extra Info
collapsable field by default.
By default, hovering over them will show the url.
Click on the desired icon to visit to the desired site.
diff --git a/wordindicators/index.html b/wordindicators/index.html
index bde4fcdb..a0a160a3 100644
--- a/wordindicators/index.html
+++ b/wordindicators/index.html
@@ -1911,7 +1911,7 @@
Word Indicators (TODO)
-New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-15
)
+New in version 0.11.0.0
(latest version: 0.12.0.0-prerelease-16
)
Indicators will be shown to the top-left of the reading when similar words
in your deck are found.