Messages in this thread | | | Date | Mon, 30 Oct 2023 12:30:52 +0100 | From | Federico Vaga <> | Subject | Re: [PATCH] docs: translations: add translations links when they exist |
| |
I find it a nice initiative :)
On Sat, Oct 28, 2023 at 06:29:31PM +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. > >Signed-off-by: Vegard Nossum <vegard.nossum@oracle.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:
Should also "Languages" subject to translation? Or perhaps, nothing. Just the list of 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@oracle.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 >+ >+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',
Minor comment. Should we use the language name in its original language?
Example:
[... snip ...] 'it_IT': Italiano, [... snip ...] 'sp_SP': Español, [... snip ...]
>+} >+ >+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
We could show all languages (remove the above two lines) to have a consistent output among pages.
>+ 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 >
-- Federico Vaga
| |