Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Part of NDLA article-api
* Copyright (C) 2026 NDLA
*
* See LICENSE
*
*/

package no.ndla.articleapi.db.migration

import no.ndla.articleapi.db.HtmlMigration
import org.jsoup.nodes.Element

class V69__UnwrapNestedMathTags extends HtmlMigration {
override def convertHtml(doc: Element, language: String): Element = {
doc
.select("math math")
.forEach(nestedMath => {
val outermostMath = findOutermostMath(nestedMath)
if (nestedMath ne outermostMath) {
nestedMath
.attributes()
.forEach(attribute => {
if (!outermostMath.hasAttr(attribute.getKey)) {
outermostMath.attr(attribute.getKey, attribute.getValue): Unit
}
})
nestedMath.unwrap(): Unit
}
})
doc
}

private def findOutermostMath(element: Element): Element = findOutermostMath(element.parent(), element)

@annotation.tailrec
private def findOutermostMath(current: Element, outermostMath: Element): Element = {
if (current == null) outermostMath
else if (current.normalName() == "math") findOutermostMath(current.parent(), current)
else findOutermostMath(current.parent(), outermostMath)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Part of NDLA article-api
* Copyright (C) 2026 NDLA
*
* See LICENSE
*
*/

package no.ndla.articleapi.db.migration

import no.ndla.articleapi.{TestEnvironment, UnitSuite}

class V69__UnwrapNestedMathTagsTest extends UnitSuite with TestEnvironment {
val migration = new V69__UnwrapNestedMathTags

test("That nested math tags are unwrapped while keeping the outermost math tag") {
val oldArticle =
"""<section><p><math><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></math></p></section>"""
val newArticle = """<section><p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></p></section>"""

migration.convertContent(oldArticle, "nb") should be(newArticle)
}

test("That deep nested math tags are unwrapped while keeping the outermost math tag") {
val oldArticle =
"""<section><p><math><math xmlns="http://www.w3.org/1998/Math/MathML"><mi><math xmlns="http://www.w3.org/1998/Math/MathML">x</math></mi></math></math></p></section>"""
val newArticle = """<section><p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></p></section>"""

migration.convertContent(oldArticle, "nb") should be(newArticle)
}

test("That deeply nested math tags are fully unwrapped and missing attributes are copied to the outermost tag") {
val oldArticle =
"""<section><p><math display="block"><math xmlns="http://www.w3.org/1998/Math/MathML"><math style="color:red"><mi>x</mi></math><mo>+</mo><mi>y</mi></math></math></p></section>"""
val newArticle =
"""<section><p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML" style="color:red"><mi>x</mi><mo>+</mo><mi>y</mi></math></p></section>"""

migration.convertContent(oldArticle, "nb") should be(newArticle)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Part of NDLA draft-api
* Copyright (C) 2026 NDLA
*
* See LICENSE
*
*/

package no.ndla.draftapi.db.migration

import no.ndla.draftapi.db.HtmlMigration
import org.jsoup.nodes.Element

class V85__UnwrapNestedMathTags extends HtmlMigration {
override def convertHtml(doc: Element, language: String): Element = {
doc
.select("math math")
.forEach(nestedMath => {
val outermostMath = findOutermostMath(nestedMath)
if (nestedMath ne outermostMath) {
nestedMath
.attributes()
.forEach(attribute => {
if (!outermostMath.hasAttr(attribute.getKey)) {
outermostMath.attr(attribute.getKey, attribute.getValue): Unit
}
})
nestedMath.unwrap(): Unit
}
})
doc
}

private def findOutermostMath(element: Element): Element = findOutermostMath(element.parent(), element)

@annotation.tailrec
private def findOutermostMath(current: Element, outermostMath: Element): Element = {
if (current == null) outermostMath
else if (current.normalName() == "math") findOutermostMath(current.parent(), current)
else findOutermostMath(current.parent(), outermostMath)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Part of NDLA draft-api
* Copyright (C) 2026 NDLA
*
* See LICENSE
*
*/

package no.ndla.draftapi.db.migration
import no.ndla.draftapi.{TestEnvironment, UnitSuite}
class V85__UnwrapNestedMathTagsTest extends UnitSuite with TestEnvironment {
val migration = new V85__UnwrapNestedMathTags

test("That nested math tags are unwrapped while keeping the outermost math tag") {
val oldArticle =
"""<section><p><math><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></math></p></section>"""
val newArticle = """<section><p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></p></section>"""
migration.convertContent(oldArticle, "nb") should be(newArticle)
}

test("That deep nested math tags are unwrapped while keeping the outermost math tag") {
val oldArticle =
"""<section><p><math><math xmlns="http://www.w3.org/1998/Math/MathML"><mi><math xmlns="http://www.w3.org/1998/Math/MathML">x</math></mi></math></math></p></section>"""
val newArticle = """<section><p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math></p></section>"""
migration.convertContent(oldArticle, "nb") should be(newArticle)
}

test("That deeply nested math tags are fully unwrapped and missing attributes are copied to the outermost tag") {
val oldArticle =
"""<section><p><math display="block"><math xmlns="http://www.w3.org/1998/Math/MathML"><math style="color:red"><mi>x</mi></math><mo>+</mo><mi>y</mi></math></math></p></section>"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ser ut som at dette ikke funker for math-tagger som ikke er direkte barn av en annen math-tag, så hvis man endrer testen til dette:

Suggested change
"""<section><p><math display="block"><math xmlns="http://www.w3.org/1998/Math/MathML"><math style="color:red"><mi>x</mi></math><mo>+</mo><mi>y</mi></math></math></p></section>"""
"""<section><p><math display="block"><math xmlns="http://www.w3.org/1998/Math/MathML"><math style="color:red"><mi>x</mi></math><mo><math>+</math></mo><mi>y</mi></math></math></p></section>"""

Så feiler testen. Har sjekka i prod, og det er mange treff på math som ikke er direkte barn

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Har du testa artiklene i frontend og sett om dei feiler?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Det ser ut som om slike varianter ikkje fører til feil i rendering av matte, så då er det gjerne ikkje så farlig.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er det ikke veldig skummelt at vi har dypt nøstede math-tags? Hvor mye forekommer dette, og er det noe vi heller burde fikse manuelt?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eg tok feil. Det var i frontend men der gjør vi allerede en bortstripping av dobbel matte i graphql-api. Sjekka ed og der feiler det med matte nesta langt inne.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Det som er litt rart er at wiris lar deg redigere og vise matten i editoren heilt fint, sjølv om det er nesta mattetagger.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MathML lar deg fint neste math-tagger, men mathjax liker det ikkje så vi må nesten pakke det opp. Kanskje det må lages som en repeterbar migrering dersom wiris lar deg opprette det?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Har oppdatert migrering til å også pakke ut nesta math lenger inne

val newArticle =
"""<section><p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML" style="color:red"><mi>x</mi><mo>+</mo><mi>y</mi></math></p></section>"""
migration.convertContent(oldArticle, "nb") should be(newArticle)
}
}
Loading