Bug report: Newlines duplicated within fields

Hi, I’m new here. I have a bug to report, but I’m not sure which subforum to post on. So mods, please shift this to the correct place!

I have a frustrating bug, in that newlines are appear to be duplicated during field replacement. For example I have a card with the field {{Wiktionary}} with the contents:

挑战
Verb
<ol>
  <li>(literally) to challenge (to a fight); to throw down the gauntlet</li>
  <li>(figuratively) to challenge (invite someone to take part in a contest)</li>
  <li>(figuratively) to challenge (put demands on); to test</li>
  <li>(figuratively) to challenge (dispute the validity of something)</li>
</ol>
Noun
<ol>
  <li>challenge; difficulty</li>
</ol>

I create this within AnkiDroid. If I have on the back:

<div>
  <ol>
    <li>A</li>
    <li>B</li>
  </ol>
</div>
{{Wiktionary}}

The result is:

  1. A
  2. B

挑战
Verb

    1. (literally) to challenge (to a fight); to throw down the gauntlet

    2. (figuratively) to challenge (invite someone to take part in a contest)

    3. (figuratively) to challenge (put demands on); to test

    4. (figuratively) to challenge (dispute the validity of something)

Noun

    1. challenge; difficulty

This shows that field replacement doesn’t simply insert the HTML code so that it matches the ordered list format of the HTML code above it.

If I open this card in AnkiWeb, I can see the newlines inserted when editing the card. If I remove them, then in AnkiDroid the {{Wiktionary}} field has had all newlines removed.

Is this a real bug or a design feature? How can I avoid it? I’m currently using CSS to set top and bottom margins to -20px to avoid the ugliness.

Cheers,

Edward

I forgot to mention, but after field replacement the HTML code is obviously:

<div>
  <ol>
    <li>A</li>
    <li>B</li>
  </ol>
</div>
挑战
Verb
<ol>

  <li>(literally) to challenge (to a fight); to throw down the gauntlet</li>

  <li>(figuratively) to challenge (invite someone to take part in a contest)</li>

  <li>(figuratively) to challenge (put demands on); to test</li>

  <li>(figuratively) to challenge (dispute the validity of something)</li>

</ol>

Noun
<ol>

  <li>challenge; difficulty</li>

</ol>

[If this is AnkiDroid-specific, you may want to move it to the AnkiDroid category.]

Maybe it is AnkiDroid’s conversion of HTML in fields to the Anki internal HTML format. I tried creating cards on Anki Desktop (Linux) and AnkiWeb with the following in a field:

<div class="test">
  <ol>
    <li>x</li>
    <li>y</li>
  </ol>
</div>

But in both of those, the HTML was not recognised as HTML and the output included the HTML tags!

Edit: Using AnkiDroid to open the AnkiWeb card with HTML in the field, the field content ends up as:

<div>&lt;div class="test"&gt;
</div><div>&nbsp; &lt;ol&gt;</div>&nbsp; &nbsp; &lt;li&gt;x&lt;/li&gt;
&nbsp; &nbsp; &lt;li&gt;y&lt;/li&gt;
<div>&nbsp; &lt;/ol&gt;</div><div>&lt;/div&gt;
</div>

Are you putting your HTML in the right type of field?

When editing in AnkiDroid, you directly see the HTML. But when editing in AnkiWeb, you see the parsed/formatted version of the field. In AnkiDesktop, you can see either/both the HTML and the formatted version.

If you’re putting HTML in a formatted field (on AnkiWeb or AnkiDesktop), that definitely won’t work. As you can see, all of the < and > that mark the tags are encoded with their entity names (like &gt;), so that it won’t be mistaken for parsable HTML – it’s just text.

Possibly related: Editing a note turns insignificant newlines into explicit line breaks · Issue #3304 · ankidroid/Anki-Android · GitHub

1 Like

Ah, I now see that I can see the HTML in AnkiDesktop! My newlines input into the field in AnkiDroid have been bizarrely converted to <br>. That’s why exactly the same HTML list added to the Back Template and a field end up being rendered differently!

For reference, the HTML field that I manually input into AnkiDroid as

Verb
<ol>
  <li>(literally) to challenge (to a fight); to throw down the gauntlet</li>
  <li>(figuratively) to challenge (invite someone to take part in a contest)</li>
  <li>(figuratively) to challenge (put demands on); to test</li>
  <li>(figuratively) to challenge (dispute the validity of something)</li>
</ol>
Noun
<ol>
  <li>challenge; difficulty</li>
</ol>

is converted internally to:

Verb<br><ol><br>  <li>(literally) to challenge (to a fight); to throw down the gauntlet</li><br>  <li>(figuratively) to challenge (invite someone to take part in a contest)</li><br>  <li>(figuratively) to challenge (put demands on); to test</li><br>  <li>(figuratively) to challenge (dispute the validity of something)</li><br></ol><br>Noun<br><ol><br>  <li>challenge; difficulty</li><br></ol>

If I manually replace <br> on AnkiDesktop with newlines, then the newlines are accepted and the list becomes normal!

Thanks, that is clearly the same issue. For a permanent record, I’ll repost my response on that bug report.


I think I have encountered the same bug - or more like logic issue - and reported it on the Anki forum at:

https://forums.ankiweb.net/t/bug-report-newlines-duplicated-within-fields/40884

Newlines input into AnkiDroid fields are being converted to <br>. This is in the file:

AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt

Specifically in the function convertToHtmlNewline(). The argument replaceNewlines appears be set to true. So all newlines in fields are converted to <br>.

For reference, the code is:

    /**
     * @param replaceNewlines Converts [FieldEditText.NEW_LINE] to HTML linebreaks
     */
    @VisibleForTesting
    @CheckResult
    fun getFieldsAsBundleForPreview(editFields: List<NoteField?>?, replaceNewlines: Boolean): Bundle {
        val fields = Bundle()
        // Save the content of all the note fields. We use the field's ord as the key to
        // easily map the fields correctly later.
        if (editFields == null) {
            return fields
        }
        for (e in editFields) {
            if (e?.fieldText == null) {
                continue
            }
            val fieldValue = convertToHtmlNewline(e.fieldText!!, replaceNewlines)
            fields.putString(e.ord.toString(), fieldValue)
        }
        return fields
    }

    fun convertToHtmlNewline(fieldData: String, replaceNewlines: Boolean): String {
        return if (!replaceNewlines) {
            fieldData
        } else {
            fieldData.replace(FieldEditText.NEW_LINE, "<br>")
        }
    }

This is being called from:

AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt

The code is:

        private fun shouldReplaceNewlines(): Boolean {
            return AnkiDroidApp.instance.sharedPrefs()
                .getBoolean(PREF_NOTE_EDITOR_NEWLINE_REPLACE, true)
        }

Looking through the interface, I found this option buried under:

Settings -> Advanced -> Workarounds -> Replace newlines with HTML

The text of this option is:

In the Note Editor, convert any instances of <br> to newlines when editing a card

Turing this off fixes the problem! But the logic seems reversed, as newlines are instead being converted to <br> and vice versa.

As a solution, could this option please be turned off by default? Having this option on by defaut is frighteningly confusing. And maybe the text of the option clarified by changing to:

In the Note Editor, convert all newlines to be stored internally within the card as <br> (HTML line breaks)