MyST-Parser
MyST-Parser copied to clipboard
Duplicate label in translation only
Describe the bug
If you have content like this:
```{admonition} Example
Content
```
```{admonition} Example
Content
```
You get no warning when building in the source language.
However, if you translate the text and build, you get:
index.md:35:<translated>:1: WARNING: duplicate label index.md#ejemplo, other instance in index.md [myst.anchor]
Note that the label is itself translated, which is also unexpected.
To Reproduce
Follow the steps at https://github.com/jpmckinney/myst-parser-tests/blob/master/index.md#reproduction
Expected behavior
No warning. No translation of the label.
I've created a PR with a failing test: https://github.com/executablebooks/MyST-Parser/pull/360
Hmm, ok cheers so the label of an admonition get turned into an anchor. I was not aware of that, and it feels like that should not be the case?
and to check, anchors created from standard headings are not translated?
Hmm, ok cheers so the label of an admonition get turned into an anchor. I was not aware of that, and it feels like that should not be the case?
I guess the label of an admonition is an inline token after a heading_open token in markdown-it-py (or a nodes.title in docutils), so it's given an anchor under the current logic, though it shouldn't. I don't know if this is to be fixed here or in mdit-py-plugins or elsewhere.
and to check, anchors created from standard headings are not translated?
That's right. The HTML looks like:
<div class="section" id="about">
<h2>Chi siamo<a class="headerlink" href="#about" title="Link a questa intestazione">¶</a></h2>
The id is English, but the heading has been translated (originally, "About"). This is by Sphinx's design.
I recently stumbled on this issue, and it is very annoying. I can't just do like https://github.com/open-contracting/standard/commit/8b490c74d32f68776cafeee8f169131131229371 and suppress all myst.anchor warnings as some of them are very useful.
I tried to find the problem in the code and found one of the sources of this problem.
First of all the admonition directive of docutils produces something like this when executed:
[<admonition: <title...><paragraph...>>]
So it indeed contains a title docutils node.
The problem arises when the parser is executed a second time from the i18n transformer. Here is an exemple stacktrace leading to this problem:
File "/usr/bin/sphinx-build", line 33, in <module>
sys.exit(load_entry_point('Sphinx==4.5.0', 'console_scripts', 'sphinx-build')())
File "/usr/lib/python3/dist-packages/sphinx/cmd/build.py", line 290, in main
return build_main(argv)
File "/usr/lib/python3/dist-packages/sphinx/cmd/build.py", line 276, in build_main
app.build(args.force_all, filenames)
File "/usr/lib/python3/dist-packages/sphinx/application.py", line 318, in build
self.builder.build_all()
File "/usr/lib/python3/dist-packages/sphinx/builders/__init__.py", line 250, in build_all
self.build(None, summary=__('all source files'), method='all')
File "/usr/lib/python3/dist-packages/sphinx/builders/__init__.py", line 300, in build
updated_docnames = set(self.read())
File "/usr/lib/python3/dist-packages/sphinx/builders/__init__.py", line 407, in read
self._read_serial(docnames)
File "/usr/lib/python3/dist-packages/sphinx/builders/__init__.py", line 428, in _read_serial
self.read_doc(docname)
File "/usr/lib/python3/dist-packages/sphinx/builders/__init__.py", line 468, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/usr/lib/python3/dist-packages/sphinx/io.py", line 181, in read_doc
pub.publish()
File "/usr/lib/python3/dist-packages/docutils/core.py", line 219, in publish
self.apply_transforms()
File "/usr/lib/python3/dist-packages/docutils/core.py", line 200, in apply_transforms
self.document.transformer.apply_transforms()
File "/usr/lib/python3/dist-packages/sphinx/transforms/__init__.py", line 79, in apply_transforms
super().apply_transforms()
File "/usr/lib/python3/dist-packages/docutils/transforms/__init__.py", line 171, in apply_transforms
transform.apply(**kwargs)
File "/usr/lib/python3/dist-packages/sphinx/transforms/i18n.py", line 289, in apply
patch = publish_msgstr(self.app, msgstr, source,
File "/usr/lib/python3/dist-packages/sphinx/transforms/i18n.py", line 63, in publish_msgstr
doc = reader.read(
File "/usr/lib/python3/dist-packages/docutils/readers/__init__.py", line 72, in read
self.parse()
File "/usr/lib/python3/dist-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/home/nicolas/.local/lib/python3.10/site-packages/myst_parser/parsers/sphinx_.py", line 69, in parse
parser.render(inputstring)
File "/usr/lib/python3/dist-packages/markdown_it/main.py", line 267, in render
return self.renderer.render(self.parse(src, env), self.options, env)
File "/home/nicolas/.local/lib/python3.10/site-packages/myst_parser/mdit_to_docutils/base.py", line 232, in render
self._render_tokens(list(tokens))
File "/home/nicolas/.local/lib/python3.10/site-packages/myst_parser/mdit_to_docutils/base.py", line 211, in _render_tokens
self.rules[f"render_{child.type}"](child)
File "/home/nicolas/.local/lib/python3.10/site-packages/myst_parser/mdit_to_docutils/sphinx_.py", line 172, in render_heading
traceback.print_stack()
I found that the problem comes in part from this block: https://github.com/sphinx-doc/sphinx/blob/5e9550c78e3421dd7dcab037021d996841178f67/sphinx/transforms/i18n.py#L286-L288
if isinstance(node, nodes.title):
# This generates: <section ...><title>msgstr</title></section>
msgstr = msgstr + '\n' + '=' * len(msgstr) * 2
In my case, the msgstr value is 'See also' and it is then converted into 'See also\n================' because of it.
Then when it is parsed by myst it is interpreted as a heading and rendered using render_heading.
Commenting the above block solves the problem and I didn't see any difference from a quick glance in the result. It seems very odd that this block even exists as tries to recreate a source heading without even knowing what parser is used.
Using a debugger, it seems this block is only executed for the title nodes of admonition nodes.
Also seems to be related to https://github.com/sphinx-doc/sphinx/issues/8852
You might be able to create a workaround like this solution to a similar problem: https://github.com/executablebooks/MyST-Parser/issues/444#issuecomment-1179796223
I can not reproduce this anymore. I "git bisected" the fix to this commit: 8daa00b89be0fe51dd028985eeb762bb8fe13642