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
16 changes: 10 additions & 6 deletions src/moin/converters/_tests/test_rst_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,17 @@ def test_field_list(self, input, output):
text""",
'<page><body><p>Abra <a xlink:href="wiki.local:#example">example</a> arba</p><span id="alias" /><span id="example" /><p>text</p></body></page>',
),
(
"A reference_ with no matching target links to a local Wiki item.",
'<page><body><p>A <a xlink:href="wiki.local:reference">reference</a> with no matching target links to a local Wiki item.</p></body></page>',
( # A reference_ with no matching target links to a local Wiki item.
"wiki references: `item`_, `namespace/item`_, `ns/item/subitem`_, `../sibling`_, `/subitem`_",
'<page><body><p>wiki references: <a xlink:href="wiki.local:item">item</a>,'
' <a xlink:href="wiki.local:namespace/item">namespace/item</a>,'
' <a xlink:href="wiki.local:ns/item/subitem">ns/item/subitem</a>,'
' <a xlink:href="wiki.local:../sibling">../sibling</a>,'
' <a xlink:href="wiki.local:/subitem">/subitem</a></p></body></page>',
),
(
"`Whitespace is\nnormalized & Case is KEPT.`_",
'<page><body><p><a xlink:href="wiki.local:Whitespace%20is%20normalized%20&amp;%20Case%20is%20KEPT.">Whitespace is\nnormalized &amp; Case is KEPT.</a></p></body></page>',
"`Whitespace is\nnormalized\xA0& CÄSE is Kept.`_",
'<page><body><p><a xlink:href="wiki.local:Whitespace%20is%20normalized%20&amp;%20CÄSE%20is%20Kept.">Whitespace is\nnormalized\xA0&amp; CÄSE is Kept.</a></p></body></page>',
),
( # in rST, reference-name matching is case insensitive:
"Chapter 1\n===============\n\nA reference to `chapter 1`_.\n",
Expand Down Expand Up @@ -357,7 +361,7 @@ def test_table(self, input, output):
"""
.. note::
:name: note-id

An admonition of type "note"
""",
'<page><body><span id="note-id" /><admonition type="note"><p>An admonition of type "note"</p></admonition></body></page>',
Expand Down
28 changes: 15 additions & 13 deletions src/moin/converters/rst_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from moin.utils.iri import Iri
from moin.utils.tree import html, moin_page, xlink, xinclude
from moin.utils.mime import Type, type_moin_document
from moin.wikiutil import anchor_name_from_text, normalize_pagename
from moin.wikiutil import anchor_name_from_text

from . import default_registry
from ._util import allowed_uri_scheme, decode_data, normalize_split_text
Expand Down Expand Up @@ -410,7 +410,8 @@ def visit_image(self, node):
"left": "left",
"center": "center",
"right": "right",
"top": "top", # rst parser creates error messages for top, bottom, and middle
# only for inline images:
"top": "top",
"bottom": "bottom",
"middle": "middle",
}
Expand Down Expand Up @@ -825,28 +826,29 @@ def get_transforms(self):
class WikiReferences(transforms.Transform):
"""Resolve references without matching target as local wiki references.

Set the "refuri" attribute to refer to a local wiki item.
The value is derived from the node's text content with
`moin.wikiutil.normalize_pagename()`.
Set the "refuri" attribute to the whitespace-normalized (but NOT case
normalized) link text (`visit_reference()` adds the "wiki.local" scheme.)

Cf. https://docutils.sourceforge.io/docs/api/transforms.html#docinfo.
Cf. https://docutils.sourceforge.io/docs/api/transforms.html.
"""

default_priority = 775
# Apply between `InternalTargets` (660) and `DanglingReferences` (850)

def apply(self) -> None:
for node in self.document.findall(nodes.reference):
# Skip resolved references, unresolvable references, and references with matching target:
# Skip resolved references, unresolvable references,
# and references with matching target:
if node.resolved or "refname" not in node or self.document.nameids.get(node["refname"]):
continue
# Get the name from the link text (the "refname" attribute is lowercased).
wikiname = normalize_pagename(node.astext(), None) # second arg is ignored
# Skip references whose "refname" attribute differs from the wikiname (exept for case):
if normalize_pagename(node["refname"], None) != wikiname.lower():
# Get the refuri from the link text (keep case)
refuri = nodes.whitespace_normalize_name(node.astext())
# Skip references whose "refname" attribute differs from the
# refuri by more than case:
if node["refname"] != refuri.lower():
continue
# Resolve the reference:
node["refuri"] = wikiname
node["refuri"] = refuri
# Mark as resolved:
del node["refname"]
node.resolved = True

Expand Down