├── .gitignore
├── .vscode
└── settings.json
├── 1_Mining_Front.html
├── 2_Mining_Back.html
├── 3_Mining_Styling.css
├── Mining_temp.apkg
├── README.md
└── images
├── kanken.png
├── mining_template.gif
├── popup.png
├── search.png
├── sentence_back.png
├── sentence_front.png
├── vocab_back.png
└── vocab_front.png
/.gitignore:
--------------------------------------------------------------------------------
1 | test.*
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true
3 | }
4 |
--------------------------------------------------------------------------------
/1_Mining_Front.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{^*IsSentenceCard}}
7 | {{Expression}}
8 | {{#Hint}}
9 | {{Hint}}
10 | {{/Hint}} {{/*IsSentenceCard}}
11 |
12 |
13 | {{#*IsSentenceCard}}
14 |
15 | {{#SentenceFurigana}} {{kanji:SentenceFurigana}} {{/SentenceFurigana}}
16 | {{^SentenceFurigana}} {{kanji:Sentence}} {{/SentenceFurigana}}
17 |
18 | {{#Hint}}
19 | {{Hint}}
20 | {{/Hint}} {{/*IsSentenceCard}}
21 |
22 |
--------------------------------------------------------------------------------
/2_Mining_Back.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 | {{^*IsSentenceCard}}
13 |
14 | {{#ExpressionFurigana}}{{furigana:ExpressionFurigana}}{{/ExpressionFurigana}}
15 | {{^ExpressionFurigana}}{{Expression}}{{/ExpressionFurigana}}
16 |
17 | {{#Hint}}
18 |
{{Hint}}
19 | {{/Hint}}
20 |
21 |
22 | {{ExpressionAudio}} {{SentenceAudio}}
23 |
24 |
25 | {{#ExpressionFurigana}}{{kana:ExpressionFurigana}}{{/ExpressionFurigana}}
26 | {{^ExpressionFurigana}}{{ExpressionReading}}{{/ExpressionFurigana}}
27 |
28 |
29 | {{#PitchPosition}}
30 |
{{PitchPosition}}
31 | {{/PitchPosition}} 【{{Expression}}】
32 |
33 |
34 |
{{MainDefinition}}
35 |
36 |
37 |
38 |
{{Image}}
39 |
40 | {{#SentenceFurigana}} {{furigana:SentenceFurigana}} {{/SentenceFurigana}}
41 | {{^SentenceFurigana}} {{furigana:Sentence}} {{/SentenceFurigana}}
42 |
43 | {{#Translation}}
44 |
{{hint:Translation}}
45 | {{/Translation}} {{/*IsSentenceCard}}
46 |
47 |
48 | {{#*IsSentenceCard}}
49 |
50 | {{#SentenceFurigana}} {{furigana:SentenceFurigana}} {{/SentenceFurigana}}
51 | {{^SentenceFurigana}} {{furigana:Sentence}} {{/SentenceFurigana}}
52 |
53 | {{#Hint}}
54 |
{{Hint}}
55 | {{/Hint}} {{#Translation}}
56 |
{{hint:Translation}}
57 | {{/Translation}}
58 |
59 |
60 | {{ExpressionAudio}} {{SentenceAudio}}
61 |
62 |
63 | {{#ExpressionFurigana}}{{kana:ExpressionFurigana}}{{/ExpressionFurigana}}
64 | {{^ExpressionFurigana}}{{ExpressionReading}}{{/ExpressionFurigana}}
65 |
66 |
67 | {{#PitchPosition}}
68 |
{{PitchPosition}}
69 | {{/PitchPosition}} 【{{Expression}}】
70 |
71 |
72 |
{{MainDefinition}}
73 |
74 |
75 |
76 |
{{Image}}
77 | {{/*IsSentenceCard}}
78 |
79 |
80 |
81 |
82 |
83 |
84 |
111 |
112 |
113 |
114 |
124 |
125 |
126 |
714 |
--------------------------------------------------------------------------------
/3_Mining_Styling.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP&family=Noto+Serif+JP&display=swap");
2 |
3 | :root {
4 | /* Color theme */
5 | --dark-mode-bg-color: #1e1e2a;
6 | --dark-mode-fg-color: #dadada;
7 | --light-mode-bg-color: #fffaf0;
8 | --light-mode-fg-color: #333333;
9 |
10 | /* Pitch colors */
11 | --dark-mode-heiban: #39bae6;
12 | --dark-mode-atamadaka: #ec464f;
13 | --dark-mode-nakadaka: #ff8f40;
14 | --dark-mode-odaka: #6cbf43;
15 | --light-mode-heiban: #1aa0ce;
16 | --light-mode-atamadaka: #e92a35;
17 | --light-mode-nakadaka: #ff6b03;
18 | --light-mode-odaka: #61ad3b;
19 |
20 | /* PC Font sizes */
21 | --pc-main-font-size: 16px;
22 | --pc-main-def-size: 18px;
23 | --pc-vocab-font-size: 45px;
24 | --pc-sentence-font-size: 30px;
25 | --pc-back-sentence-font-size: 20px;
26 |
27 | /* Mobile font sizes */
28 | --mobile-main-font-size: 16px;
29 | --mobile-main-def-size: 16px;
30 | --mobile-vocab-font-size: 40px;
31 | --mobile-sentence-font-size: 32px;
32 | --mobile-back-sentence-font-size: 20px;
33 |
34 | /* Miscellaneous */
35 | --font-serif: "Noto Serif JP", serif;
36 | --font-sans: "Noto Sans JP", sans-serif;
37 | --max-width: 800px;
38 |
39 | font-size: var(--main-font-size);
40 | }
41 |
42 | .card.nightMode {
43 | --bg-color: var(--dark-mode-bg-color);
44 | --fg-color: var(--dark-mode-fg-color);
45 | --heiban: var(--dark-mode-heiban, initial);
46 | --atamadaka: var(--dark-mode-atamadaka, initial);
47 | --nakadaka: var(--dark-mode-nakadaka, initial);
48 | --odaka: var(--dark-mode-odaka, initial);
49 |
50 | --bg-elevated: rgba(255, 255, 255, 0.03);
51 | --bg-inset: rgba(255, 255, 255, 0.03);
52 | --fg-subtle: rgba(255, 255, 255, 0.3);
53 | --bold: #7d8590;
54 | }
55 |
56 | .card:not(.nightMode) {
57 | --bg-color: var(--light-mode-bg-color);
58 | --fg-color: var(--light-mode-fg-color);
59 | --heiban: var(--light-mode-heiban, initial);
60 | --atamadaka: var(--light-mode-atamadaka, initial);
61 | --nakadaka: var(--light-mode-nakadaka, initial);
62 | --odaka: var(--light-mode-odaka, initial);
63 |
64 | --bg-elevated: rgba(0, 0, 0, 0.03);
65 | --bg-inset: rgba(0, 0, 0, 0.06);
66 | --fg-subtle: rgba(0, 0, 0, 0.6);
67 | --bold: #999999;
68 | }
69 |
70 | .card {
71 | /* Remove this rule to adapt to system theme */
72 | background-color: var(--bg-color) !important;
73 | color: var(--fg-color) !important;
74 | }
75 |
76 | html.win,
77 | html.mac,
78 | html.linux:not(.android) {
79 | --main-font-size: var(--pc-main-font-size);
80 | --main-def-size: var(--pc-main-def-size);
81 | --vocab-font-size: var(--pc-vocab-font-size);
82 | --sentence-font-size: var(--pc-sentence-font-size);
83 | --back-sentence-font-size: var(--pc-back-sentence-font-size);
84 | }
85 |
86 | html.mobile {
87 | --main-font-size: var(--mobile-main-font-size);
88 | --main-def-size: var(--mobile-main-def-size);
89 | --vocab-font-size: var(--mobile-vocab-font-size);
90 | --sentence-font-size: var(--mobile-sentence-font-size);
91 | --back-sentence-font-size: var(--mobile-back-sentence-font-size);
92 | }
93 |
94 | #qa {
95 | display: flex;
96 | align-items: stretch;
97 | flex-direction: column;
98 | min-height: calc(100vh - 40px);
99 | font-family: var(--font-serif);
100 | font-size: var(--main-font-size);
101 | text-align: center;
102 | }
103 |
104 | /* ------- Mobile css ------- */
105 | @media (max-width: 512px) {
106 | .mono-def {
107 | flex-direction: column;
108 | }
109 | .images-container {
110 | justify-content: space-around;
111 | flex-direction: row !important;
112 | max-width: 100% !important;
113 | width: 100%;
114 | flex-wrap: wrap;
115 | }
116 | .images-container img {
117 | width: 44%;
118 | }
119 | .def-info {
120 | top: -1.5rem !important;
121 | }
122 | .replay-button {
123 | vertical-align: middle !important;
124 | }
125 | }
126 |
127 | /* ----- Front elements ----- */
128 |
129 | .vocab {
130 | font-size: var(--vocab-font-size);
131 | }
132 | .sentence {
133 | font-size: var(--sentence-font-size);
134 | display: inline-block;
135 | }
136 | #hint {
137 | margin-top: -5px;
138 | }
139 |
140 | /* ----- Back elements ----- */
141 |
142 | /* Header */
143 | header {
144 | color: var(--fg-subtle);
145 | height: 40px;
146 | text-align: right;
147 | width: 100%;
148 | font-size: 1rem;
149 | }
150 | .top-container {
151 | max-width: calc(var(--max-width) + 20px);
152 | margin: 0px auto;
153 | width: calc(100% - 20px);
154 | }
155 | .stars {
156 | margin: 0;
157 | margin-bottom: -3px;
158 | }
159 |
160 | /* Info (audio, reading) */
161 | .info {
162 | font-size: 1.75rem;
163 | }
164 |
165 | /* Replay button */
166 | .replay-button {
167 | vertical-align: baseline;
168 | }
169 | .replay-button svg {
170 | width: 1em;
171 | height: auto;
172 | }
173 |
174 | /* Pitch */
175 | .pitch {
176 | display: inline;
177 | }
178 | #pitch-tags {
179 | color: var(--bg-color);
180 | font-family: var(--font-serif);
181 | background-color: var(--fg-color);
182 | display: none;
183 | vertical-align: top;
184 | padding: 1px 3px;
185 | margin-right: -5px;
186 | }
187 | /* When multiple pitch */
188 | .pitch ul,
189 | #pitch-tags ul {
190 | list-style: none;
191 | display: inline;
192 | margin: 0;
193 | padding: 0;
194 | }
195 | .pitch li,
196 | #pitch-tags li {
197 | display: inline;
198 | }
199 | .pitch ul > li:not(:last-child)::after,
200 | #pitch-tags ul > li:not(:last-child)::after {
201 | content: "・";
202 | }
203 | .pitch ul > li:not(:last-child)::after {
204 | color: var(--fg-color);
205 | }
206 | #pitch-tags ul > li:not(:last-child)::after {
207 | color: var(--bg-color);
208 | }
209 |
210 | /* Definition container */
211 | .main-def {
212 | max-width: var(--max-width);
213 | font-size: var(--main-def-size);
214 | line-height: 1.75em;
215 | margin: 25px 0px;
216 | width: calc(100% - 20px);
217 | position: relative;
218 | }
219 |
220 | /* Definition info display */
221 | .def-info {
222 | position: absolute;
223 | top: -2rem;
224 | right: 10px;
225 | font-size: 0.9rem;
226 | color: var(--fg-subtle);
227 | opacity: 0;
228 | pointer-events: none;
229 | }
230 |
231 | /* MainDefinition */
232 | .definition {
233 | text-align: left;
234 | display: inline-block;
235 | }
236 |
237 | /* When monolingual definition */
238 | .mono-def {
239 | text-align: left;
240 | display: inline-flex;
241 | gap: 1rem;
242 | line-height: initial;
243 | width: fit-content;
244 | max-width: 100%;
245 | }
246 | .text-container {
247 | flex-grow: 1;
248 | max-width: 100%;
249 | }
250 | .images-container {
251 | display: flex;
252 | flex-direction: column;
253 | gap: 0.5rem;
254 | max-width: 30%;
255 | }
256 | .images-container img {
257 | max-width: 200px;
258 | height: auto;
259 | }
260 | .images-container:empty {
261 | display: none;
262 | }
263 |
264 | /* When JMDict definition */
265 | .definition > .jmdict-def {
266 | text-align: center !important;
267 | margin: auto;
268 | }
269 | .definition .jmdict-def ul {
270 | list-style: none;
271 | display: inline;
272 | padding: 0;
273 | }
274 | .definition .jmdict-def ul > li {
275 | display: inline;
276 | }
277 | .definition .jmdict-def ul > li:not(:last-child)::after {
278 | content: "; ";
279 | }
280 | .definition .jmdict-def ol {
281 | margin: 0;
282 | max-width: var(--max-width);
283 | display: inline-block;
284 | text-align: left;
285 | }
286 |
287 | /* Image */
288 | .image img {
289 | max-height: 200px;
290 | width: auto;
291 | border-radius: 8px;
292 | cursor: pointer;
293 | }
294 |
295 | /* Back sentence */
296 | .small-sentence {
297 | font-size: var(--back-sentence-font-size);
298 | display: inline-block;
299 | width: calc(100% - 20px);
300 | max-width: var(--max-width);
301 | }
302 |
303 | /* Translation button */
304 | a.hint {
305 | font-family: var(--font-sans);
306 | color: var(--fg-subtle);
307 | width: fit-content;
308 | font-size: 0.8rem;
309 | display: block;
310 | border-radius: 8px;
311 | padding: 5px 10px;
312 | margin: 0 auto;
313 | text-decoration: none;
314 | }
315 | a.hint:hover {
316 | color: var(--fg-color);
317 | }
318 |
319 | /* Footer */
320 | footer {
321 | margin-top: auto;
322 | width: 100%;
323 | }
324 | .bot-container {
325 | display: flex;
326 | justify-content: flex-end;
327 | max-width: calc(var(--max-width) + 20px);
328 | margin: 0px auto;
329 | width: calc(100% - 20px);
330 | }
331 | .tags-container {
332 | flex-grow: 1;
333 | }
334 | .tags {
335 | font-family: var(--font-sans);
336 | background-color: var(--bg-elevated);
337 | color: var(--fg-color);
338 | display: inline-block;
339 | padding: 1px 5px;
340 | cursor: pointer;
341 | border-radius: 5px;
342 | font-size: 0.7rem;
343 | line-height: 0.8rem;
344 | margin: auto 3px;
345 | text-overflow: ellipsis;
346 | overflow: hidden;
347 | max-width: 60dvw;
348 | white-space: nowrap;
349 | }
350 |
351 | .extras-toggle {
352 | width: 12px;
353 | }
354 |
355 | /* ----- Extras ----- */
356 |
357 | /* Hide extra info by default */
358 | .extras {
359 | display: none;
360 | }
361 |
362 | /* Popup CSS */
363 | .popup {
364 | font-family: var(--font-sans);
365 | background-color: var(--bg-elevated);
366 | display: inline-block;
367 | border-radius: 8px;
368 | padding: 10px;
369 | max-width: min(var(--max-width), calc(100% - 20px));
370 | }
371 |
372 | /* Misc. info */
373 | .misc-info ul {
374 | margin: 0;
375 | }
376 |
377 | /* Full definition */
378 | .full-def {
379 | font-family: var(--font-sans);
380 | text-align: left;
381 | display: inline-flex;
382 | }
383 | .full-def ol {
384 | margin: 0;
385 | }
386 |
387 | /* ----- Misc ----- */
388 |
389 | /* Furigana */
390 | .show-furigana > ruby rt {
391 | opacity: 1;
392 | }
393 | ruby rt {
394 | user-select: none;
395 | opacity: 0;
396 | }
397 | ruby:hover rt {
398 | opacity: 1;
399 | }
400 |
401 | /* Bold */
402 | b {
403 | color: var(--bold);
404 | font-weight: 400;
405 | }
406 | b > ruby rt {
407 | opacity: 1;
408 | }
409 |
410 | /* Dropdown */
411 | details {
412 | font-family: var(--font-sans);
413 | margin: 5px 0px;
414 | }
415 | summary {
416 | user-select: none;
417 | cursor: pointer;
418 | width: fit-content;
419 | margin: 0px auto;
420 | }
421 |
422 | /* Pitch graphs css */
423 | .pitch-char {
424 | color: var(--fg-color);
425 | }
426 | .pitch-low {
427 | position: relative;
428 | }
429 | .pitch-high {
430 | position: relative;
431 | }
432 | .pitch-high > .pitch-line {
433 | display: block;
434 | position: absolute;
435 | top: 0.1em;
436 | left: 0;
437 | right: 0;
438 | height: 0;
439 | border-top-width: 0.1em;
440 | border-top-style: solid;
441 | }
442 | .pitch-to-drop {
443 | position: relative;
444 | padding-right: 0.1em;
445 | margin-right: 0.1em;
446 | }
447 | .pitch-to-drop > .pitch-line {
448 | display: block;
449 | position: absolute;
450 | top: 0.1em;
451 | left: 0;
452 | right: 0;
453 | border-top-width: 0.1em;
454 | border-top-style: solid;
455 | right: -0.1em;
456 | height: 0.4em;
457 | border-right-width: 0.1em;
458 | border-right-style: solid;
459 | }
460 |
461 | /* Pitch coloring */
462 | .heiban {
463 | color: var(--heiban);
464 | }
465 | .atamadaka {
466 | color: var(--atamadaka);
467 | }
468 | .nakadaka {
469 | color: var(--nakadaka);
470 | }
471 | .odaka {
472 | color: var(--odaka);
473 | }
474 |
475 | /* Definition toggle css */
476 | .left-edge,
477 | .right-edge {
478 | position: absolute;
479 | top: 0;
480 | width: 50px;
481 | height: 100%;
482 | cursor: pointer;
483 | opacity: 0.4;
484 | }
485 | .left-edge {
486 | left: 0;
487 | border-radius: 8px 0px 0px 8px;
488 | }
489 | .right-edge {
490 | right: 0;
491 | border-radius: 0px 8px 8px 0px;
492 | }
493 | .left-edge:hover,
494 | .right-edge:hover {
495 | background-color: var(--bg-inset);
496 | cursor: pointer;
497 | }
498 |
499 | /* Image modal css */
500 | .modal-bg {
501 | position: fixed;
502 | display: none;
503 | top: 0;
504 | right: 0;
505 | bottom: 0;
506 | left: 0;
507 | background-color: rgba(0, 0, 0, 0.8);
508 | z-index: 1000;
509 | cursor: pointer;
510 | }
511 | .img-popup-container {
512 | position: absolute;
513 | top: 50%;
514 | left: 50%;
515 | transform: translate(-50%, -50%);
516 | width: min(calc(100% - 20px), calc(var(--max-width) + 200px));
517 | display: none;
518 | z-index: 1001;
519 | overflow: hidden;
520 | }
521 | .img-popup-img {
522 | width: 100%;
523 | }
524 |
--------------------------------------------------------------------------------
/Mining_temp.apkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/Mining_temp.apkg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JP-study
2 |
3 | - [Anki Mining Template](#anki-mining-template)
4 | - [Yomichan fields](#yomichan-fields)
5 | - [Other applications/add-ons](#other-applicationsadd-ons)
6 | - [Yomichan Handlebars templates](#yomichan-handlebars-templates)
7 | - [Yomichan popup custom CSS](#yomichan-popup-custom-css)
8 | - [Kanken Deck Template](#kanken-deck-template)
9 |
10 | ## Anki Mining Template
11 |
12 | Anki Mining card template for Japanese.
13 |
14 | [Download](https://github.com/rudnam/JP-study/raw/main/Mining_temp.apkg)
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ### Yomichan fields
23 |
24 | | Field | Value |
25 | | ------------------ | ------------------------------------------------- |
26 | | Expression | `{expression}` |
27 | | ExpressionFurigana | `{furigana-plain}` |
28 | | ExpressionReading | `{reading}` |
29 | | ExpressionAudio | `{audio}` |
30 | | MainDefinition | `{popup-selection-text}` |
31 | | Sentence | `{cloze-prefix}{cloze-body}{cloze-suffix}` |
32 | | SentenceFurigana | |
33 | | SentenceAudio | |
34 | | FullDefinition | `{glossary}` |
35 | | Image | |
36 | | Translation | |
37 | | PitchPosition | `{pitch-accent-positions}` |
38 | | Hint | |
39 | | Frequency | `{frequencies}` |
40 | | FreqSort | |
41 | | MiscInfo | `{document-title}` |
42 | | ExtraField | |
43 | | \*IsSentenceCard | |
44 |
45 | Notes:
46 |
47 | - When the **\*IsSentenceCard** field is filled with any character, card is turned into a sentence card. When empty, it is turned into a vocab card.
48 | - The **MainDefinition** field is for the displayed definition on the card. When empty, the template displays a definition from the **FullDefinition** field. The preferred dictionaries for the default definition can be changed in the [back template](https://github.com/rudnam/JP-study/blob/da0fcca7242513065a5706b58e089a38baab584e/2_Mining_Back.html#L653-L667).
49 | - The **PitchPosition** field takes in `{pitch-accent-positions}`. `{pitch-accents}` and `{pitch-accent-graphs}` will **not** work.
50 | - The **FreqSort** field is for frequency sorting. (See [freq](https://github.com/MarvNC/JP-Resources#sorting-mined-anki-cards-by-frequency))
51 | - The **Hint** field is for a hint on the front of the card (See [Animecards](https://animecards.site/ankicards/#the-hint-field)).
52 | - The furigana fields only take in plain furigana. (e.g. 漢字[かんじ] not 漢字).
53 | - The color scheme can be inherited from system by removing [this rule](https://github.com/rudnam/JP-study/blob/485e28eacb3445fa1cbf14714154063482c5bbe1/3_Mining_Styling.css#L70-L74) from the styling template.
54 |
55 | ### Other applications
56 |
57 | More info can be added using other applications.
58 |
59 | - For [mpvacious](https://github.com/Ajatt-Tools/mpvacious), fields can be filled like the following. In `subs2srs.conf`:
60 |
61 | ```
62 | model_name=Mining-JP
63 |
64 | sentence_field=Sentence
65 | secondary_field=Translation
66 | audio_field=SentenceAudio
67 | image_field=Image
68 | miscinfo_field=MiscInfo
69 |
70 | # The tag(s) added to new notes. Spaces separate multiple tags.
71 | note_tag=subs2srs アニメ::%n
72 | ```
73 |
74 | - For [jidoujisho](https://github.com/lrorpilla/jidoujisho), fields can be filled like the following:
75 |
76 | | Field | Value |
77 | | ------------------ | -------------- |
78 | | Expression | Term |
79 | | ExpressionFurigana | Furigana |
80 | | ExpressionReading | Reading |
81 | | ExpressionAudio | Term Audio |
82 | | Sentence | Sentence |
83 | | SentenceAudio | Sentence Audio |
84 | | FullDefinition | Meaning |
85 | | Image | Image |
86 | | FreqSort | Frequency |
87 | | MiscInfo | Context |
88 |
89 | - [x] Include image/audio HTML tags on export
90 | - [x] Use line break tag instead of newline on export
91 | - [x] Prepend dictionary name in meaning
92 |
93 | ## Yomichan Handlebars templates
94 |
95 | Custom Yomichan Handlebars templates.
96 |
97 | - `{selection-text-modified}` - Basically the same as the built-in `{selection-text}` but will ignore selected text if it is the same as the target vocab (for Yomichan search page).
98 |
99 | ```handlebars
100 | {{~#*inline "selection-text-modified"~}}
101 | {{~#set "selected"}}{{~> selection-text}}{{/set~}}
102 | {{~#set "pattern1"~}}
103 | [
104 | {{~#regexReplace "()|()|()|()|()|[\[\]]" "" "g"~}}
105 | {{~> cloze-body}}
106 | {{~/regexReplace~}}
107 | ]
108 | {{~/set~}}
109 | {{~#set "pattern2"~}}
110 | [
111 | {{~#regexReplace "()|()|()|()|()|[\[\]]" "" "g"~}}
112 | {{~#getMedia "textFurigana" definition.cloze.body escape=false}}{{~/getMedia~}}
113 | {{~/regexReplace~}}
114 | ]
115 | {{~/set~}}
116 | {{~#set "diff1"}}{{~#regexReplace (get "pattern1") ""~}}{{~#get "selected"}}{{/get~}}{{~/regexReplace~}}{{/set~}}
117 | {{~#set "diff2"}}{{~#regexReplace (get "pattern2") ""~}}{{~#get "selected"}}{{/get~}}{{~/regexReplace~}}{{/set~}}
118 |
119 | {{~#if (op "&&"
120 | (op ">" (property (get "diff1") "length") (op "-" (property (get "selected") "length") (property (get "diff1") "length")))
121 | (op ">" (property (get "diff2") "length") (op "-" (property (get "selected") "length") (property (get "diff2") "length")))
122 | )}}
123 | {{~> selection-text}}
124 | {{/if~}}
125 | {{~/inline~}}
126 | ```
127 |
128 | - `{grammar-pt}` - fills out a field when a grammar dictionary has an entry.
129 |
130 | ```handlebars
131 | {{#*inline "grammar-pt"}}
132 | {{~#set "grammar-dicts" ~}}
133 | {{~#regexMatch "JLPT文法解説まとめ|日本語文法辞典\(全集\)"~}}
134 | {{~> glossary}}
135 | {{~/regexMatch~}}
136 | {{/set~}}
137 | {{~#if (op "!==" "" (get "grammar-dicts"))~}}x{{/if}}
138 | {{/inline}}
139 | ```
140 |
141 | - `{context}` - Context tag. e.g. `ラノベ::また、同じ夢を見ていた` if in ttsu, etc. Used with [Field To Tag](https://ankiweb.net/shared/info/1600845494) or [FieldReporter](https://ankiweb.net/shared/info/569864517)
142 |
143 | ```handlebars
144 | {{#*inline "context"}}
145 | {{~#if (regexMatch "reader\.ttsu\.app" "" definition.url)~}}
146 | {{~#set "ln-title" ~}}{{~#regexReplace " | " "_"~}}
147 | {{~#regexMatch ".+?(?= \| ッツ Ebook Reader)"~}}{{~context.document.title~}}{{~/regexMatch~}}
148 | {{~/regexReplace~}}{{/set~}}
149 | ラノベ::{{~get "ln-title"~}}
150 | {{~else if (regexMatch "mokuro" "" context.document.title)~}}
151 | {{~#set "manga-title" ~}}{{~#regexReplace " | " "_"~}}
152 | {{~#regexMatch ".+?(?= \| mokuro)"~}}{{~context.document.title~}}{{~/regexMatch~}}
153 | {{~/regexReplace~}}{{/set~}}
154 | 漫画::{{~get "manga-title"~}}
155 | {{~else if (regexMatch "nhk.or.jp" "" definition.url)~}}
156 | ニュース::NHKニュース
157 | {{~else if (regexMatch "news.yahoo.co.jp" "" definition.url)~}}
158 | ニュース::Yahooニュース
159 | {{~else if (regexMatch "twitter.com" "" definition.url)~}}
160 | ツイッター
161 | {{~else if (regexMatch "youtube.com" "" definition.url)~}}
162 | {{~#set "youtube-title" ~}}{{~#regexReplace " | " "_"~}}
163 | {{~#regexMatch ".+?(?= - YouTube)"~}}{{~context.document.title~}}{{~/regexMatch~}}
164 | {{~/regexReplace~}}{{/set~}}
165 | ユーチューブ::{{~get "youtube-title"~}}
166 | {{~/if~}}
167 | {{/inline}}
168 | ```
169 |
170 | ## Yomichan popup custom CSS
171 |
172 | Custom CSS for changing the Yomichan popup appearance.
173 |
174 |
175 |
176 |
177 |
178 |
179 | Font download links:
180 |
181 | - Noto Sans JP: [https://fonts.google.com/noto/specimen/Noto+Sans+JP](https://fonts.google.com/noto/specimen/Noto+Sans+JP)
182 | - UD Digi Kyokasho N-R: [https://learnjapanese.moe/font/#windows-10](https://learnjapanese.moe/font/#windows-10)
183 |
184 | Just copy and paste the following CSS into Yomichan's custom CSS.
185 |
186 | ```css
187 | body {
188 | font-family: "Inter", "Noto Sans JP", sans-serif;
189 | --background-color: #1e1e2a;
190 | --input-background-color: color-mix(
191 | in srgb,
192 | var(--background-color),
193 | #fff 5%
194 | );
195 | }
196 |
197 | .headword {
198 | font-family: "UD Digi Kyokasho N";
199 | }
200 |
201 | /* Disable furigana on search page */
202 | rt.query-parser-segment-reading {
203 | display: none;
204 | }
205 |
206 | /* Collapse lists of links */
207 | .definition-item:not([data-dictionary="JMdict"])
208 | .gloss-list:has(.gloss-content > a:only-child) {
209 | list-style: none;
210 | display: inline;
211 | padding-left: 0;
212 | }
213 | .definition-item:not([data-dictionary="JMdict"])
214 | .gloss-list:has(.gloss-content > a:only-child)
215 | * {
216 | display: inline;
217 | }
218 | .definition-item:not([data-dictionary="JMdict"])
219 | .gloss-item:has(.gloss-content > a:only-child):not(:last-child)::after {
220 | content: " | ";
221 | }
222 |
223 | /* Collapse JMnedict entries */
224 | .definition-item[data-dictionary="JMnedict"] .gloss-list {
225 | list-style: none;
226 | display: inline;
227 | padding-left: 0;
228 | }
229 | .definition-item[data-dictionary="JMnedict"] .gloss-list * {
230 | display: inline;
231 | }
232 | .definition-item[data-dictionary="JMnedict"]
233 | .gloss-list
234 | > .gloss-item:not(:last-child)::after {
235 | content: " | ";
236 | }
237 |
238 | /* Collapse Jitendex entries */
239 | .definition-item[data-dictionary*="Jitendex"] .gloss-sc-ul {
240 | list-style: none;
241 | display: inline;
242 | padding-left: 0;
243 | }
244 | .definition-item[data-dictionary*="Jitendex"] .gloss-sc-ul > .gloss-sc-li {
245 | display: inline;
246 | }
247 | .definition-item[data-dictionary*="Jitendex"]
248 | .gloss-sc-ul
249 | > .gloss-sc-li:not(:last-child)::after {
250 | content: "; ";
251 | }
252 |
253 | /* Make Jitendex example sentences smaller */
254 | .definition-item[data-dictionary*="Jitendex"]
255 | *[data-sc-content="example-sentence-a"] {
256 | font-size: 1em !important;
257 | }
258 |
259 | /* Only show summary for Pixiv */
260 | [data-sc-pixiv="children"],
261 | [data-sc-pixiv="related-tags"],
262 | [data-sc-pixiv="continue-reading"],
263 | [data-sc-pixiv="nav-header"] {
264 | display: none;
265 | }
266 |
267 | /* Only show the first 2 frequency lists */
268 | span.frequency-group-item:nth-child(n + 3) {
269 | display: none;
270 | }
271 | /* Show on hover */
272 | span.frequency-group-item:first-child:has(.tag-label:hover) ~ * {
273 | display: inline-block;
274 | }
275 |
276 | /* Only show the first pitch dictionary */
277 | li.pronunciation-group:first-child ~ * {
278 | display: none;
279 | }
280 | ol.pronunciation-group-list:not([data-count="1"]) {
281 | list-style: none;
282 | padding: 0;
283 | }
284 | /* Show on hover */
285 | li.pronunciation-group:first-child:has(.tag:hover) ~ * {
286 | display: inline-block;
287 | }
288 |
289 | /* Hide add duplicate */
290 | button.action-button[title="Add duplicate expression (Alt + E)"] {
291 | display: none;
292 | }
293 | ```
294 |
295 | ## Kanken Deck Template
296 |
297 | Anki card template for the [Kanken Deck](https://ankiweb.net/shared/info/759825185).
298 |
299 |
300 |
301 |
302 |
303 | Font download link: [https://github.com/adobe-fonts/source-han-serif/raw/release/Variable/TTF/SourceHanSerif-VF.ttf](https://github.com/adobe-fonts/source-han-serif/raw/release/Variable/TTF/SourceHanSerif-VF.ttf)
304 |
305 | Just copy and paste the following templates into Anki.
306 |
307 | - Front Template
308 |
309 | ```html
310 |
311 |
312 | Kanken Level: ?
313 |
{{SentenceFront}}
314 | {{#Picture}} {{Picture}}
315 |
316 | {{/Picture}} {{KankenAudio}}
317 |
318 |
321 |
322 |
323 |
386 | ```
387 |
388 | - Back Template
389 |
390 | ```html
391 |
392 |
393 | Kanken Level: {{KankenLevel}}
394 |
{{SentenceBack}}
395 | {{#Picture}} {{Picture}}
396 |
397 | {{/Picture}} {{KankenAudio}}
398 |
399 |
402 |
407 |
408 |
409 |
471 | ```
472 |
473 | - Styling
474 |
475 | ```css
476 | @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP&family=Noto+Serif+JP&display=swap");
477 |
478 | html.win,
479 | html.mac,
480 | html.linux:not(.android) {
481 | --main-font: "Noto Serif JP", serif;
482 | }
483 |
484 | html.mobile {
485 | --main-font: "Noto Serif JP", serif;
486 | }
487 |
488 | .card.nightMode {
489 | --main-bg: #1c2127;
490 | --main-color: #dadada;
491 | --sub-color: #7d8590;
492 | --grey: rgba(128, 128, 128, 0.1);
493 | --accent: #2980f1;
494 | font-family: var(--main-font);
495 | background-color: var(--main-bg);
496 | color: var(--main-color);
497 | font-size: 20px;
498 | text-align: center;
499 | }
500 |
501 | #qa {
502 | display: flex;
503 | align-items: stretch;
504 | flex-direction: column;
505 | min-height: calc(100vh - 40px);
506 | }
507 |
508 | @font-face {
509 | font-family: "Noto Serif JP";
510 | src: local("Noto Serif JP"), local("Noto Serif JP Regular"),
511 | url("_NotoSerifJP.otf");
512 | }
513 |
514 | /* ----- Front elements ----- */
515 | #content {
516 | margin-top: 24px;
517 | }
518 |
519 | .sentence {
520 | font-size: 28px;
521 | }
522 |
523 | /* PC replay button */
524 | .replay-button {
525 | margin-top: -5px;
526 | }
527 | .replay-button svg {
528 | width: 30px;
529 | height: auto;
530 | }
531 | .replay-button svg path {
532 | fill: var(--main-color);
533 | transition: 0.2s;
534 | }
535 | .replay-button svg circle {
536 | fill: var(--main-bg);
537 | display: none;
538 | }
539 | .replay-button:hover svg path {
540 | fill: var(--sub-color);
541 | }
542 |
543 | /* Grid */
544 | #container {
545 | margin: auto;
546 | border-style: solid;
547 | border-color: var(--grey);
548 | background-color: rgba(255, 255, 255, 0);
549 | }
550 | .vert-line {
551 | position: absolute;
552 | border-style: none;
553 | border-right-style: dotted;
554 | border-color: var(--grey);
555 | }
556 | .hori-line {
557 | position: absolute;
558 | border-style: none;
559 | border-bottom-style: dotted;
560 | border-color: var(--grey);
561 | }
562 |
563 | /* ----- Back elements ----- */
564 |
565 | /* Stroke diagram */
566 | #diagram {
567 | line-height: 0;
568 | }
569 | #diagram > img {
570 | height: 140px;
571 | width: 140px;
572 | position: relative;
573 | z-index: 100;
574 | }
575 |
576 | /* Extra info */
577 | #extra {
578 | opacity: 0;
579 | }
580 |
581 | #extra:hover {
582 | opacity: 1;
583 | }
584 |
585 | /* ---------- Misc ---------- */
586 |
587 | /* Remove default margins */
588 | * {
589 | margin: 0px;
590 | padding: 0px;
591 | }
592 |
593 | /* Images */
594 | img {
595 | height: 200px;
596 | width: auto;
597 | border-radius: 8px;
598 | }
599 |
600 | /* Underline CSS */
601 | u {
602 | text-decoration: none;
603 | color: var(--accent);
604 | font-weight: 400;
605 | }
606 |
607 | /* Line margins */
608 | hr {
609 | margin-top: 0.5em;
610 | margin-bottom: 0.5em;
611 | }
612 | ```
613 |
--------------------------------------------------------------------------------
/images/kanken.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/kanken.png
--------------------------------------------------------------------------------
/images/mining_template.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/mining_template.gif
--------------------------------------------------------------------------------
/images/popup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/popup.png
--------------------------------------------------------------------------------
/images/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/search.png
--------------------------------------------------------------------------------
/images/sentence_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/sentence_back.png
--------------------------------------------------------------------------------
/images/sentence_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/sentence_front.png
--------------------------------------------------------------------------------
/images/vocab_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/vocab_back.png
--------------------------------------------------------------------------------
/images/vocab_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rudnam/JP-study/3db58ebb455e6cb11fbe2dff77434693fc7a3c60/images/vocab_front.png
--------------------------------------------------------------------------------