lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 1 Nov 2023 23:56:49 +0900
From:   Akira Yokosawa <akiyks@...il.com>
To:     vegard.nossum@...cle.com
Cc:     akiyks@...il.com, alexs@...nel.org, carlos.bilbao@....com,
        corbet@....net, federico.vaga@...a.pv.it,
        linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
        siyanteng@...ngson.cn, src.res.211@...il.com
Subject: Re: [PATCH] docs: translations: add translations links when they
 exist

Hi,

On Sat, 28 Oct 2023 18:29:31 +0200, Vegard Nossum wrote:
> Add a new Sphinx extension that knows about the translations of kernel
> documentation and can insert links to the translations at the top of
> the document.
> 
> It basically works like this:
> 
> 1. Register a new node type, LanguagesNode.
> 
> 2. Register a new transform, TranslationsTransform, that inserts a new
>    LanguageNode at the top of every document. The LanguageNode contains
>    "pending references" to translations of the document. The key here
>    is that these are pending (i.e. unresolved) references that may or
>    may not actually exist.
> 
> 3. Register a 'doctree-resolved' event that iterates over all the
>    LanguageNode nodes. Any unresolved references are filtered out; the
>    list of resolved references is passed to the 'translations.html'
>    template and rendered as an HTML node (if HTML output is selected).
> 
> Testing: make htmldocs with v7.3.0.

So, I've started playing with this.

It looks like this introduces hysteresis in successive runs of
"make htmldocs" and "make latexdocs".

Steps to reproduce

  1. Run "make cleandocs"

  2. Run "make htmldocs"

  3. Run "make latexdocs"

This aborts with the message (under Sphinx 7.2.6):

  Extension error (translations):
  Handler <function process_languages at 0x7f122f343420> for event 'doctree-resolved' threw an exception (exception: 'LaTeXBuilder' object has no attribute 'templates')
  make[2]: *** [Documentation/Makefile:128: latexdocs] Error 2
  make[1]: *** [/linux/Makefile:1695: latexdocs] Error 2
  make: *** [Makefile:234: __sub-make] Error 2
  Command exited with non-zero status 2

If I run "make latexdocs" in step 2 and "make htmldocs" in step 3,
both runs complete successfully, but html pages don't have the
expected links to other translations.

All I can do is to report the symptoms.
Vegard, can you look into them?

> 
> Signed-off-by: Vegard Nossum <vegard.nossum@...cle.com>
> ---
>  Documentation/conf.py                         |  2 +-
>  Documentation/sphinx-static/custom.css        |  8 ++
>  .../sphinx/templates/translations.html        | 12 +++
>  Documentation/sphinx/translations.py          | 96 +++++++++++++++++++
>  4 files changed, 117 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/sphinx/templates/translations.html
>  create mode 100644 Documentation/sphinx/translations.py
> 
> diff --git a/Documentation/conf.py b/Documentation/conf.py
> index d4fdf6a3875a..64eab500b2cd 100644
> --- a/Documentation/conf.py
> +++ b/Documentation/conf.py
> @@ -55,7 +55,7 @@ needs_sphinx = '1.7'
>  extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include',
>                'kfigure', 'sphinx.ext.ifconfig', 'automarkup',
>                'maintainers_include', 'sphinx.ext.autosectionlabel',
> -              'kernel_abi', 'kernel_feat']
> +              'kernel_abi', 'kernel_feat', 'translations']
>  
>  if major >= 3:
>      if (major > 3) or (minor > 0 or patch >= 2):
> diff --git a/Documentation/sphinx-static/custom.css b/Documentation/sphinx-static/custom.css
> index 084a884f6fb7..33adee4a35d9 100644
> --- a/Documentation/sphinx-static/custom.css
> +++ b/Documentation/sphinx-static/custom.css
> @@ -73,3 +73,11 @@ input.kernel-toc-toggle { display: none; }
>      h3.kernel-toc-contents { display: inline; }
>      div.kerneltoc a { color: black; }
>  }
> +
> +/* Language selection bar */
> +div.language-selection {
> +    background: #eeeeee;
> +    border: 1px solid #cccccc;
> +    margin-bottom: 1em;
> +    padding: .5em;
> +}
> diff --git a/Documentation/sphinx/templates/translations.html b/Documentation/sphinx/templates/translations.html
> new file mode 100644
> index 000000000000..08afb595c203
> --- /dev/null
> +++ b/Documentation/sphinx/templates/translations.html
> @@ -0,0 +1,12 @@
> +<!-- SPDX-License-Identifier: GPL-2.0 -->
> +<!-- Copyright © 2023, Oracle and/or its affiliates. -->
> +
> +{# Create a language bar for translations #}
> +{% if languages|length > 0: %}
> +<div class="language-selection">
> +Languages:
> +{% for ref in languages: %}
> +<a href="{{ ref.refuri }}">{{ ref.astext() }}</a>{% if not loop.last %}, {% endif %}
> +{% endfor %}
> +</div>
> +{% endif %}
> diff --git a/Documentation/sphinx/translations.py b/Documentation/sphinx/translations.py
> new file mode 100644
> index 000000000000..e1da811bdaf0
> --- /dev/null
> +++ b/Documentation/sphinx/translations.py
> @@ -0,0 +1,96 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright © 2023, Oracle and/or its affiliates.
> +# Author: Vegard Nossum <vegard.nossum@...cle.com>
> +#
> +# Add translation links to the top of the document.
> +#
> +
> +import os
> +
> +from docutils import nodes
> +from docutils.transforms import Transform
> +
> +import sphinx
> +from sphinx import addnodes
> +from sphinx.errors import NoUri

NoUri is not in sphinx.errors prior to Sphinx 2.
I think it is a good chance to finally get rid of Sphinx 1.7.x
support.

        Thanks, Akira

> +
> +all_languages = {
> +    # English is always first
> +    None: 'English',
> +
> +    # Keep the rest sorted alphabetically
> +    'zh_CN': 'Chinese',
> +    'it_IT': 'Italian',
> +    'ja_JP': 'Japanese',
> +    'ko_KR': 'Korean',
> +    'sp_SP': 'Spanish',
> +    'zh_TW': 'Taiwanese',
> +}
> +
> +class LanguagesNode(nodes.Element):
> +    pass
> +
> +class TranslationsTransform(Transform):
> +    default_priority = 900
> +
> +    def apply(self):
> +        app = self.document.settings.env.app
> +        if app.builder.format not in ['html']:
> +            return
> +
> +        docname = self.document.settings.env.docname
> +
> +        this_lang_code = None
> +        components = docname.split(os.sep)
> +        if components[0] == 'translations' and len(components) > 2:
> +            this_lang_code = components[1]
> +
> +            # normalize docname to be the untranslated one
> +            docname = os.path.join(*components[2:])
> +
> +        new_nodes = LanguagesNode()
> +
> +        for lang_code, lang_name in all_languages.items():
> +            if lang_code == this_lang_code:
> +                continue
> +
> +            if lang_code is None:
> +                target_name = docname
> +            else:
> +                target_name = os.path.join('translations', lang_code, docname)
> +
> +            pxref = addnodes.pending_xref('', refdomain='std',
> +                reftype='doc', reftarget='/' + target_name, modname=None,
> +                classname=None, refexplicit=True)
> +            pxref += nodes.Text(lang_name)
> +            new_nodes += pxref
> +
> +        self.document.insert(0, new_nodes)
> +
> +def process_languages(app, doctree, docname):
> +    for node in doctree.traverse(LanguagesNode):
> +        languages = []
> +
> +        # Iterate over the child nodes; any resolved links will have
> +        # the type 'nodes.reference', while unresolved links will be
> +        # type 'nodes.Text'.
> +        languages = list(filter(lambda xref:
> +            isinstance(xref, nodes.reference), node.children))
> +
> +        html_content = app.builder.templates.render('translations.html',
> +            context={
> +                'languages': languages,
> +            })
> +
> +        node.replace_self(nodes.raw('', html_content, format='html'))
> +
> +def setup(app):
> +    app.add_node(LanguagesNode)
> +    app.add_transform(TranslationsTransform)
> +    app.connect('doctree-resolved', process_languages)
> +
> +    return {
> +        'parallel_read_safe': True,
> +        'parallel_write_safe': True,
> +    }
> -- 
> 2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ