Help with #typeans not displaying ordered lists. (Yomitan)

Hello,

Ive been using an semi-automated system to add cards into my Anki decks that is essentially just a web clipper that feeds into a big table, that I then export as a .csv and then import that into Anki. But, I recently made the change to using Yomitan (I’m studying Japanese) to automatically add cards into my decks using the AnkiConnect add-on, cutting out the need to export the table.

The issue is when I save a kanji with Yomitan, it saves the meaning ({glossary}) of the kanji as a numbered list in the meaning field of the note type I use for kanji, which would normally be fine but I like to type in my answers using {{type:Meaning}}. It seems like #typeans doesn’t recognize the line breaks that are apart of the numbered list and it displays the text as a big blob of words without any line breaks or spaces (unless the spaces are part of the item in the numbered list) making it a confusing mess that’s hard to read.

Yomitan to Anki settings


Is there a way to get the #typeans text to display the text any better? Maybe get it to display a numbered list or a work around to force spaces where there would be line breaks so at least the words are broken up. This might be something I have to fix in the Yomitan to Anki saving process, such as changing the formatting of how the fields are saved, but I tried a few things and nothing seemed to change the output. I’ve tried a few things like putting ol /ol around {{type:Meaning}} or trying to force certain text formats but nothing seems to work.

#typeans is functioning as it should and is accurately comparing the answer to what I typed, but It would be annoying to deal with that graphical issue when I have a deck that might eventually be thousands of cards long.

This might be more of a question for the Yomitan forums if there is one, but im desperate for an answer.

Here’s my card code:

Front:

<br>
<div style='font-family: "Arial"; font-size: 40px; font-weight: bold; color: #ff00aa; '>Meaning</div>
<div style='font-family: "Arial"; font-size: 150px;'>{{Kanji}}</div>
<br><br>
<hr id="answer" style="max-width:700px;border:0; border-bottom:1px solid gray;">
<br><br>
{{type:Meaning}}

Back:

<br>
<div style='font-family: "Arial"; font-size: 40px; font-weight: bold; color: #ff00aa; '>Meaning</div>
<div style='font-family: "Arial"; font-size: 150px;'>{{Kanji}}</div>
<br><br>
<hr id="answer" style="max-width:700px;border:0; border-bottom:1px solid gray;">
<br><br>

{{type:Meaning}}

Styling:

.card {
    font-family: arial;
    font-size: 20px;
    text-align: center;
    color: black;
    background-color: white;
}
#typeans {
font-family: arial !important;
font-size: 25px !important;
margin:0 auto;
width: 400px  !important;
text-transform: capitalize;

}

.typeGood {
color:#000;background-color:transparent;
font-size: 30px;
font-family: arial;
font-weight: bold;
text-decoration: underline;
color: #8FBC8F;
} 

.typeBad {
color:#000;background-color:transparent;
font-size: 30px;
font-family: arial;
color: #CD5C5C;
} 

.typeMissed {
font-family: arial;
color:#000;background-color:transparent;
font-size: 30px;
color: #696969;

}

input[type=text] {
border: 2px solid gray !important;
padding: 2px;
border-radius: 25px;
text-align: center !important;
color: white;

}

[Question cross-posted]

No. Type-answer fields strip out all formatting, so Anki can do a character-by-character comparison. That’s why they are really only well-suited for very short answers where spelling matters.

Your options are –

  1. Put less text/unformatted text in the field – but it looks like you’re not in control of what gets put there.
  2. Stop trying to use type-answer for this – which, since it’s in your native language, seems unnecessary.

As an alternative, you can write your answer anywhere and compare it yourself to the back of the card. You can type it in a text window open next to Anki. There are even add-ons and template modifications you can use to type or write in a blank field on the front of the card that persists to the back.

Thanks for your help! I was trying to look for ways to somehow inject spaces or line breaks in-between the words after type-answer processes my input, but from inspecting the code with WebView Inspector it seems like there’s no way to do it.

You’re right, I don’t really need to use type-answer if im going to be inputting my native language, considering the english portion of the fields is the only one with the issue of having a ordered list inside it after it gets sent info from Yomitan. So I could just have basic flashcards for recalling the meaning, but type-answer for the readings since the reading fields don’t have that issue.

I’m not much of a programmer (obviously), but It really feels like there’s is a way to change the way Yomitan generates its cards and sends it to Anki considering they both use css and html. I was able to mess around with Yomitan’s Anki card generating code because they allow you to make your own edits, and was able to directly affect the way the ordered list shows up in Anki, but I wasn’t able to get it to stop generating as an ordered list. I’m not sure if it’s possible to stop it from generating as an ordered list considering the info its clipping is an ordered list.
what it clips
what it shows up as

This kinda goes beyond the scope of normal forum help, but here’s the code for Yomitans Anki card generating code, the chunk that’s responsible for generating the issue would be labeled “glossary”. I tried deleting code that would generate the text as an ordered list, but again I have zero programming knowledge outside of customizing cards, so it just ended up breaking it and I had to reset it. I’m sure there is a way to do it but I wouldn’t be able to figure it out. Thanks for your help anyway!

{{#*inline "glossary-single"}}
    {{~#unless brief~}}
        {{~#scope~}}
            {{~set "any" false~}}
            {{~#each definitionTags~}}
                {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
                    {{~#if (get "any")}}, {{else}}<i>({{/if~}}
                    {{name}}
                    {{~set "any" true~}}
                {{~/if~}}
            {{~/each~}}
            {{~#unless noDictionaryTag~}}
                {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
                    {{~#if (get "any")}}, {{else}}<i>({{/if~}}
                    {{dictionaryAlias}}
                    {{~set "any" true~}}
                {{~/if~}}
            {{~/unless~}}
            {{~#if (get "any")}})</i> {{/if~}}
        {{~/scope~}}
        {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
    {{~/unless~}}
    {{~#if (op "<=" glossary.length 1)~}}
        {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
    {{~else if @root.compactGlossaries~}}
        {{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
    {{~else~}}
        <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
    {{~/if~}}
    {{~set "previousDictionary" dictionary~}}
{{/inline}}

{{#*inline "audio"}}
    {{~#if (hasMedia "audio")~}}
        [sound:{{getMedia "audio"}}]
    {{~/if~}}
{{/inline}}

{{#*inline "character"}}
    {{~definition.character~}}
{{/inline}}

{{#*inline "dictionary"}}
    {{~definition.dictionary~}}
{{/inline}}

{{#*inline "dictionary-alias"}}
    {{~definition.dictionaryAlias~}}
{{/inline}}

{{#*inline "expression"}}
    {{~#if merge~}}
        {{~#if modeTermKana~}}
            {{~#each definition.reading~}}
                {{{.}}}
                {{~#unless @last}}、{{/unless~}}
            {{~else~}}
                {{~#each definition.expression~}}
                    {{{.}}}
                    {{~#unless @last}}、{{/unless~}}
                {{~/each~}}
            {{~/each~}}
        {{~else~}}
            {{~#each definition.expression~}}
                {{{.}}}
                {{~#unless @last}}、{{/unless~}}
            {{~/each~}}
        {{~/if~}}
    {{~else~}}
        {{~#if modeTermKana~}}
            {{~#if definition.reading~}}
                {{definition.reading}}
            {{~else~}}
                {{definition.expression}}
            {{~/if~}}
        {{~else~}}
            {{definition.expression}}
        {{~/if~}}
    {{~/if~}}
{{/inline}}

{{#*inline "furigana"}}
    {{~#if merge~}}
        {{~#each definition.expressions~}}
            <span class="expression-{{termFrequency}}">{{~furigana .~}}</span>
            {{~#unless @last}}、{{/unless~}}
        {{~/each~}}
    {{~else~}}
        {{furigana definition}}
    {{~/if~}}
{{/inline}}

{{#*inline "furigana-plain"}}
    {{~#if merge~}}
        {{~#each definition.expressions~}}
            <span class="expression-{{termFrequency}}">{{~furiganaPlain .~}}</span>
            {{~#unless @last}}、{{/unless~}}
        {{~/each~}}
    {{~else~}}
        {{furiganaPlain definition}}
    {{~/if~}}
{{/inline}}

{{~#*inline "glossary"~}}
    <div style="text-align: left;" class="yomitan-glossary">
    {{~#scope~}}
        {{~#if (op "===" definition.type "term")~}}
            {{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
                {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
                {{~#if definition.glossaryScopedStyles~}}
                    <style>{{{definition.glossaryScopedStyles}}}</style>
                {{~/if~}}
            {{~/unless~}}
        {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
            {{~#if (op ">" definition.definitions.length 1)~}}
                <ol>
                    {{~#each definition.definitions~}}
                        {{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
                            <li data-dictionary="{{dictionary}}">
                                {{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
                            </li>
                            {{~#if dictScopedStyles~}}
                                <style>{{{dictScopedStyles}}}</style>
                            {{~/if~}}
                        {{~/unless~}}
                    {{~/each~}}
                </ol>
            {{~else~}}
                {{~#each definition.definitions~}}
                    {{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
                        {{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
                        {{~#if glossaryScopedStyles~}}
                            <style>{{{glossaryScopedStyles}}}</style>
                        {{~/if~}}
                    {{~/unless~}}
                {{~/each~}}
            {{~/if~}}
        {{~else if (op "===" definition.type "kanji")~}}
            {{~#if (op ">" definition.glossary.length 1)~}}
                <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
            {{~else~}}
                {{~#each definition.glossary~}}{{.}}{{~/each~}}
            {{~/if~}}
        {{~/if~}}
    {{~/scope~}}
    </div>
{{~/inline~}}

{{#*inline "glossary-no-dictionary"}}
    {{~> glossary noDictionaryTag=true ~}}
{{/inline}}

{{#*inline "glossary-brief"}}
    {{~> glossary brief=true ~}}
{{/inline}}

{{~#*inline "glossary-first"~}}
    <div style="text-align: left;" class="yomitan-glossary">
    {{~#scope~}}
        {{~#if (op "===" definition.type "term")~}}
            {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
            {{~#if definition.glossaryScopedStyles~}}
                <style>{{{definition.glossaryScopedStyles}}}</style>
            {{~/if~}}
        {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
            {{~#if (op ">" definition.definitions.length 1)~}}
                {{~#with definition.definitions.[0]~}}
                    {{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
                    {{~#if glossaryScopedStyles~}}
                        <style>{{{glossaryScopedStyles}}}</style>
                    {{~/if~}}
                {{~/with~}}
            {{~else~}}
                {{~#with definition.definitions.[0]~}}
                    {{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
                    {{~#if glossaryScopedStyles~}}
                        <style>{{{glossaryScopedStyles}}}</style>
                    {{~/if~}}
                {{~/with~}}
            {{~/if~}}
        {{~/if~}}
    {{~/scope~}}
    </div>
{{~/inline~}}

{{#*inline "glossary-first-no-dictionary"}}
    {{~> glossary-first noDictionaryTag=true ~}}
{{/inline}}

{{#*inline "glossary-first-brief"}}
    {{~> glossary-first brief=true ~}}
{{/inline}}

{{#*inline "kunyomi"}}
    {{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}

{{#*inline "onyomi"}}
    {{~#each definition.onyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}

{{#*inline "onyomi-hiragana"}}
    {{~#each definition.onyomi}}{{hiragana .}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}

{{#*inline "reading"}}
    {{~#unless modeTermKana~}}
        {{~#if merge~}}
            {{~#each definition.reading~}}
                {{{.}}}
                {{~#unless @last}}、{{/unless~}}
            {{~/each~}}
        {{~else~}}
            {{~definition.reading~}}
        {{~/if~}}
    {{~/unless~}}
{{/inline}}

{{#*inline "sentence"}}
    {{~#if definition.cloze}}{{{definition.cloze.sentence}}}{{/if~}}
{{/inline}}

{{#*inline "cloze-prefix"}}
    {{~#if definition.cloze}}{{{definition.cloze.prefix}}}{{/if~}}
{{/inline}}

{{#*inline "cloze-body"}}
    {{~#if definition.cloze}}{{{definition.cloze.body}}}{{/if~}}
{{/inline}}

{{#*inline "cloze-body-kana"}}
    {{~#if definition.cloze}}{{{definition.cloze.bodyKana}}}{{/if~}}
{{/inline}}

{{#*inline "cloze-suffix"}}
    {{~#if definition.cloze}}{{{definition.cloze.suffix}}}{{/if~}}
{{/inline}}

{{#*inline "tags"}}
    {{~#mergeTags definition group merge}}{{this}}{{/mergeTags~}}
{{/inline}}

{{~#*inline "url"~}}
    <a href="{{definition.url}}">{{definition.url}}</a>
{{~/inline~}}

{{#*inline "screenshot"}}
    {{~#if (hasMedia "screenshot")~}}
        <img src="{{getMedia "screenshot"}}" />
    {{~/if~}}
{{/inline}}

{{#*inline "document-title"}}
    {{~context.document.title~}}
{{/inline}}

{{! Pitch Accents }}
{{#*inline "pitch-accent-item"}}
    {{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}

{{#*inline "pitch-accent-item-disambiguation"}}
    {{~#scope~}}
        {{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
        {{~#if (op ">" (property (get "exclusive") "length") 0)~}}
            {{~set "separator" ""~}}
            <em>({{#each (get "exclusive")~}}
                {{~get "separator"~}}{{{.}}}
            {{~/each}} only) </em>
        {{~/if~}}
    {{~/scope~}}
{{/inline}}

{{#*inline "pitch-accent-list"}}
    {{~#if (op ">" pitchCount 0)~}}
        {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
        {{~#each pitches~}}
            {{~#each pitches~}}
                {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
                    {{~> pitch-accent-item-disambiguation~}}
                    {{~> pitch-accent-item format=../../format~}}
                {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
            {{~/each~}}
        {{~/each~}}
        {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
    {{~/if~}}
{{/inline}}

{{#*inline "pitch-accents"}}
    {{~> pitch-accent-list format='text'~}}
{{/inline}}

{{#*inline "pitch-accent-graphs"}}
    {{~> pitch-accent-list format='graph'~}}
{{/inline}}

{{#*inline "pitch-accent-graphs-jj"}}
    {{~> pitch-accent-list format='graph-jj'~}}
{{/inline}}

{{#*inline "pitch-accent-positions"}}
    {{~> pitch-accent-list format='position'~}}
{{/inline}}

{{~#*inline "pitch-accent-categories"~}}
    {{~#each (pitchCategories @root)~}}{{~.~}}{{~#unless @last~}},{{~/unless~}}{{~/each~}}
{{~/inline~}}
{{! End Pitch Accents }}

{{#*inline "phonetic-transcriptions"}}
    {{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
        <ul>
            {{~#each definition.phoneticTranscriptions~}}
                {{~#each phoneticTranscriptions~}}
                    <li>
                        {{~set "any" false~}}
                        {{~#each tags~}}
                            {{~#if (get "any")}}, {{else}}<i>({{/if~}}
                            {{name}}
                            {{~set "any" true~}}
                        {{~/each~}}
                        {{~#if (get "any")}})</i> {{/if~}}
                        {{ipa~}}
                    </li>
                {{~/each~}}
            {{~/each~}}
        </ul>
    {{~/if~}}
{{/inline}}

{{#*inline "clipboard-image"}}
    {{~#if (hasMedia "clipboardImage")~}}
        <img src="{{getMedia "clipboardImage"}}" />
    {{~/if~}}
{{/inline}}

{{#*inline "clipboard-text"}}
    {{~#if (hasMedia "clipboardText")}}{{{getMedia "clipboardText"}}}{{/if~}}
{{/inline}}

{{#*inline "conjugation"}}
    {{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
        {{~set "multiple" false~}}
        {{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
            {{~set "multiple" true~}}
        {{~/if~}}
        {{~#if (get "multiple")~}}<ul>{{/if~}}
            {{~#each definition.inflectionRuleChainCandidates~}}
                {{~#if (op ">" inflectionRules.length 0)~}}
                    {{~#if (get "multiple")~}}<li>{{/if~}}
                    {{~#each inflectionRules~}}
                        {{~#if (op ">" @index 0)}} « {{/if~}}
                        {{name}}
                    {{~/each~}}
                    {{~#if (get "multiple")~}}</li>{{/if~}}
                {{~/if~}}
            {{~/each~}}
        {{~#if (get "multiple")~}}</ul>{{/if~}}
    {{~/if~}}
{{/inline}}

{{#*inline "frequencies"}}
    {{~#if (op ">" definition.frequencies.length 0)~}}
        <ul style="text-align: left;">
        {{~#each definition.frequencies~}}
            <li>
            {{~#if (op "!==" ../definition.type "kanji")~}}
                {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
                    {{~furigana expression reading~}}
                ) {{/if~}}
            {{~/if~}}
            {{~dictionaryAlias}}: {{frequency~}}
            </li>
        {{~/each~}}
        </ul>
    {{~/if~}}
{{/inline}}

{{#*inline "frequency-harmonic-rank"}}
    {{~#if (op "===" definition.frequencyHarmonic -1) ~}}
        9999999
    {{~else ~}}
        {{definition.frequencyHarmonic}}
    {{~/if~}}
{{/inline}}

{{#*inline "frequency-harmonic-occurrence"}}
    {{~#if (op "===" definition.frequencyHarmonic -1) ~}}
        0
    {{~else ~}}
        {{definition.frequencyHarmonic}}
    {{~/if~}}
{{/inline}}

{{#*inline "frequency-average-rank"}}
    {{~#if (op "===" definition.frequencyAverage -1) ~}}
        9999999
    {{~else ~}}
        {{definition.frequencyAverage}}
    {{~/if~}}
{{/inline}}

{{#*inline "frequency-average-occurrence"}}
    {{~#if (op "===" definition.frequencyAverage -1) ~}}
        0
    {{~else ~}}
        {{definition.frequencyAverage}}
    {{~/if~}}
{{/inline}}

{{#*inline "stroke-count"}}
    {{~#scope~}}
        {{~set "found" false~}}
        {{~#each definition.stats.misc~}}
            {{~#if (op "===" name "strokes")~}}
                {{~set "found" true~}}
                Stroke count: {{value}}
            {{~/if~}}
        {{~/each~}}
        {{~#if (op "!" (get "found"))~}}
            Stroke count: Unknown
        {{~/if~}}
    {{~/scope~}}
{{/inline}}

{{#*inline "part-of-speech-pretty"}}
    {{~#if (op "===" . "v1")~}}Ichidan verb
    {{~else if (op "===" . "v5")~}}Godan verb
    {{~else if (op "===" . "vk")~}}Kuru verb
    {{~else if (op "===" . "vs")~}}Suru verb
    {{~else if (op "===" . "vz")~}}Zuru verb
    {{~else if (op "===" . "adj-i")~}}I-adjective
    {{~else if (op "===" . "n")~}}Noun
    {{~else~}}{{.}}
    {{~/if~}}
{{/inline}}

{{#*inline "part-of-speech"}}
    {{~#scope~}}
        {{~#if (op "!==" definition.type "kanji")~}}
            {{~set "first" true~}}
            {{~#each definition.expressions~}}
                {{~#each wordClasses~}}
                    {{~#unless (get (concat "used_" .))~}}
                        {{~> part-of-speech-pretty . ~}}
                        {{~#unless (get "first")}}, {{/unless~}}
                        {{~set (concat "used_" .) true~}}
                        {{~set "first" false~}}
                    {{~/unless~}}
                {{~/each~}}
            {{~/each~}}
            {{~#if (get "first")~}}Unknown{{~/if~}}
        {{~/if~}}
    {{~/scope~}}
{{/inline}}

{{#*inline "search-query"}}
    {{~#multiLine}}{{context.fullQuery}}{{/multiLine~}}
{{/inline}}

{{#*inline "popup-selection-text"}}
    {{~#if (hasMedia "popupSelectionText")}}{{{getMedia "popupSelectionText"}}}{{/if~}}
{{/inline}}

{{#*inline "sentence-furigana"}}
    {{~#if definition.cloze~}}
        {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
            {{{getMedia "textFurigana" definition.cloze.sentence escape=false}}}
        {{~else~}}
            {{{definition.cloze.sentence}}}
        {{~/if~}}
    {{~/if~}}
{{/inline}}

{{~> (lookup . "marker") ~}}
1 Like

UPDATE: I was able to figure out a solution!

I was able to go into the Yomitan’s Anki card generating code and strip out the parts that were generating the definitions as an ordered list. I honestly should have just tried a little harder lol, but after realizing you can look at fields as if they were in a HTML editor, I was able better cross reference the exact Yomitan code responsible for generating the ordered list and modify it.

 <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>

Turned into:

{{#each definition.glossary}}{{.}}, {{/each}}

This allowed type-answer to process it as one big chunk of text instead, including the ", " I made it put after every item in the ordered list it came from, instead of individual items that were then smushed together after processing. It makes it look so much better and easier to read. It now looks like this:

2 Likes

You might want to turn on “Compact glossaries” in the extension’s settings on top of that, otherwise each of the glossary definitions, when containing multiple terms, might still appear as an unordered list of its own.


Also, if you are interested in alternative solutions, there are ways to make lists work with typing by using a custom <input> element instead of Anki’s {type:...}. This has the benefit of keeping the field organized, even for words with a very large number of meanings.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.