Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internationalization does not work on indirect links #690

Open
jeanas opened this issue Jan 24, 2023 · 3 comments
Open

Internationalization does not work on indirect links #690

jeanas opened this issue Jan 24, 2023 · 3 comments

Comments

@jeanas
Copy link
Contributor

jeanas commented Jan 24, 2023

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
Copy link
Contributor Author

jeanas commented Jan 24, 2023

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.

@kinow
Copy link

kinow commented Jan 25, 2023

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
Copy link

kinow commented Jan 26, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants