gohugoio / hugo-goldmark-extensions

Work in progress.
Apache License 2.0
18 stars 5 forks source link

passthrough: Inconsistent parsing #4

Closed jmooring closed 8 months ago

jmooring commented 9 months ago

This test passes:

func TestExample27(t *testing.T) {
    input := `Block $$a^*=x-b^*$$ equation

Inline $a^*=x-b^*$ equation`
    expected := `<p>Block </p>
$$a^*=x-b^*$$
<p> equation</p>
<p>Inline $a^*=x-b^*$ equation</p>`
    actual := Parse(t, input)

    c := qt.New(t)
    c.Assert(actual, qt.Equals, expected)
}

This test fails:

func TestExample28(t *testing.T) {
    input := `Inline $a^*=x-b^*$ equation

Block $$a^*=x-b^*$$ equation`
    expected := `<p>Inline $a^*=x-b^*$ equation</p>
<p>Block </p>
$$a^*=x-b^*$$
<p> equation</p>`
    actual := Parse(t, input)

    c := qt.New(t)
    c.Assert(actual, qt.Equals, expected)
}

test output

got:
  "<p>Inline $a^*=x-b^*$ equation</p>\n<p>Block $$a^*=x-b^*$$ equation</p>"
want:
  "<p>Inline $a^*=x-b^*$ equation</p>\n<p>Block </p>\n$$a^*=x-b^*$$\n<p> equation</p>"

The only difference between the two tests is the order in which the paragraphs are placed.

j2kun commented 8 months ago

Found the root cause:

goldmark's walking algorithm is a bit simplistic: https://github.com/yuin/goldmark/blob/90c46e0829c11ca8d1010856b2a6f6f88bfc68a3/ast/ast.go#L497-L501

        for c := n.FirstChild(); c != nil; c = c.NextSibling() {
            if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
                return WalkStop, err
            }
        }

In my case, I replace the current node with a new set of nodes, and the call to c.NextSibling gives nil. Since goldmark doesn't support a worklist style of walk, I'll have to modify my walk to update the node in place.