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

Duplicate label in translation only

Open jpmckinney opened this issue 4 years ago • 6 comments

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.

jpmckinney avatar Apr 28 '21 21:04 jpmckinney

I've created a PR with a failing test: https://github.com/executablebooks/MyST-Parser/pull/360

jpmckinney avatar Apr 28 '21 22:04 jpmckinney

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?

chrisjsewell avatar Apr 28 '21 23:04 chrisjsewell

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.

jpmckinney avatar Apr 29 '21 01:04 jpmckinney

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

n-peugnet avatar Sep 06 '22 17:09 n-peugnet

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

jpmckinney avatar Sep 06 '22 18:09 jpmckinney

I can not reproduce this anymore. I "git bisected" the fix to this commit: 8daa00b89be0fe51dd028985eeb762bb8fe13642

n-peugnet avatar Apr 07 '24 20:04 n-peugnet