MyST-Parser icon indicating copy to clipboard operation
MyST-Parser copied to clipboard

Internationalization does not work on indirect links

Open jeanas opened this issue 2 years ago • 3 comments

When translating documentation via PO files, indirect links like

paragraph [indirect link text][target] ...

[target]: https://example.com

don't work. The markup seems ignored.

Here is a minimal reproducer: myst-bug.zip. In the extracted directory myst-bug, run the command

sphinx-build -D language=fr . build

and open build/index.html, which looks like this:

(EDITED: the image was the wrong one)

image

jeanas avatar Jan 24 '23 22:01 jeanas

AFAICS, for reST, indirect references lead to special nodes that are resolved later, but in MyST, they are already resolved by markdown-it-py. Now, when it substitutes the original paragraph, Sphinx's i18n transform uses the parser on the translated text alone, so markdown-it-py doesn't have the context to resolve the cross-reference.

Not sure how to tackle this.

jeanas avatar Jan 24 '23 22:01 jeanas

We are having the same issue on the CWL project user guide. I spent some time debugging it today, and I think @Jean-Abou-Samra 's note about the missing context to resolve the cross-reference is correct.

From what I could tell, MyST parses the Markdown files handling the references, and producing the document object for Docutils like <paragraph>Some text with a <reference attrs...>link</refenrece></paragraph>. But when the Sphinx sphinx.transforms.i18n.Locale is called, it will use the string value of the text to translate it.

And when it publishes/produces the new document node, it won't have the <paragraph> with the <reference>, nor the original AST/tokens with attrs extracted from the cross-reference links.

Publishing calls the MyST parser that sees the translated string with links, but since it has nothing in the context to resolve the links (as @Jean-Abou-Samra pointed, I believe), it does not modify the string.

I think it is hard to change the order of how things happen in Sphinx, MyST, and Docutils. But there might be a way to hand down the data for the <reference>s to be used again when the MyST parser is called by the Locale transform.

-Bruno

kinow avatar Jan 25 '23 23:01 kinow

Fixed my local build with the following diff to MyST parser:

```diff
diff --git a/myst_parser/parsers/sphinx_.py b/myst_parser/parsers/sphinx_.py
index 94d5aef..2be1d77 100644
--- a/myst_parser/parsers/sphinx_.py
+++ b/myst_parser/parsers/sphinx_.py
@@ -66,5 +66,15 @@ class MystParser(SphinxParser):
                 config = merge_file_level(config, topmatter, warning)
 
         parser = create_md_parser(config, SphinxRenderer)
+        # TODO: In the first pass, the call above will use MarkdownIt over the whole document,
+        #       populating the ``.md_env`` correctly. Over the next passes, from transforms as
+        #       ``sphinx.transforms.i18n.Locale`` it will create a blank new document, as well
+        #       as a new MarkdownIT parser but using just the Docutils document that is being
+        #       translated. As a result of this, the translation has no reference-links, and it
+        #       gives you the translation without resolving the links. Here we just re-use the
+        #       ``md_env`` dictionary that contains the ``.references`` populated in the first
+        #       pass, fixing i18n with MyST Parser.
+        env = {} if not hasattr(document.settings, 'md_env') else document.settings.md_env
         parser.options["document"] = document
-        parser.render(inputstring)
+        parser.render(inputstring, env)
+        document.settings.md_env = parser.renderer.md_env

I copied the whole file content into my conf.py, and replaced the MySTParser:

def setup(app):
    """Sphinx setup callback."""

    # TODO: Here we replace the MySTParser (that replaces the Sphinx default parser...),
    #       with our patched version above.
    app.add_source_parser(MystParser, override=True)

That produced the text in Portuguese with links as expected (instead of [text][reference]):

image

I am not sure if that's worth a pull request… probably better for a maintainer to take a look first and then suggest a way forward, I think.

I hope that helps others.

-Bruno

kinow avatar Jan 26 '23 23:01 kinow