mirror of
https://github.com/jgm/pandoc.git
synced 2026-08-28 17:20:47 +08:00
RST reader: Fix nested placeholder resolution for inline elements (#11753)
Given RST like
.. _target:
See |sub|.
.. |sub| replace:: `text <target_>`_
'pandoc -f rst -t html' produces
<div id="target">
<p>See <a href="##REF##target">text</a>.</p>
</div>
instead of the expected
<div id="target">
<p>See <a href="#target">text</a>.</p>
</div>
It formerly worked and regressed with c8fda8f4d ("RST reader: Use a new
one-pass parsing strategy."), release 3.6.
What happens is that during parsing pass 1 the `replace::` value `text
<target_>`_ is parsed to
Link nullAttr [Str "text"] ("##REF##target", "")
and is stored in ParserState's substitution table. Separately, '|sub|'
usage is parsed to
Link nullAttr [Str "|sub|"] ("##SUBST##|sub|", "")
and is stored in the document tree. resolveReferences then replaces the
placeholder in the document node with substitution table node during
walkM. However, the freshly substituted ##REF## placeholder was not
revisited further, and appeared unresolved in the output.
To fix it, we resolve the node recursively until the result contains no
more placeholder. We must protect from self-references to avoid
endless recursion.
This commit is contained in:
@@ -220,5 +220,34 @@ tests = [ "line block with blank line" =:
|
||||
, "include newlines" =:
|
||||
"**before\nafter**" =?>
|
||||
para (strong (text "before\nafter"))
|
||||
, "bare reference reusing a named target resolves correctly" =:
|
||||
T.unlines
|
||||
[ ".. _target:"
|
||||
, ""
|
||||
, "See `alias <target_>`_ and again alias_."
|
||||
] =?>
|
||||
divWith ("target",[],[])
|
||||
(para ("See " <> link "#target" "" "alias" <> " and again " <>
|
||||
link "#target" "" "alias" <> "."))
|
||||
, "self-referencing named target does not loop forever" =:
|
||||
"See `a <a_>`_." =?>
|
||||
para ("See " <> link "##REF##a" "" "a" <> ".")
|
||||
, "reference to internal target embedded in a substitution" =:
|
||||
T.unlines
|
||||
[ ".. _target:"
|
||||
, ""
|
||||
, "See |sub|."
|
||||
, ""
|
||||
, ".. |sub| replace:: `text <target_>`_"
|
||||
] =?>
|
||||
divWith ("target",[],[])
|
||||
(para ("See " <> link "#target" "" "text" <> "."))
|
||||
, "circular substitution does not loop forever" =:
|
||||
T.unlines
|
||||
[ ".. |a| replace:: |a|"
|
||||
, ""
|
||||
, "Test |a| here."
|
||||
] =?>
|
||||
para ("Test " <> spanWith ("",[],[]) "|a|" <> " here.")
|
||||
]
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user