Merge tag 'for-6.10-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-block.git] / Documentation / sphinx / translations.py
1 # SPDX-License-Identifier: GPL-2.0
2 #
3 # Copyright © 2023, Oracle and/or its affiliates.
4 # Author: Vegard Nossum <vegard.nossum@oracle.com>
5 #
6 # Add translation links to the top of the document.
7 #
8
9 import os
10
11 from docutils import nodes
12 from docutils.transforms import Transform
13
14 import sphinx
15 from sphinx import addnodes
16 from sphinx.errors import NoUri
17
18 all_languages = {
19     # English is always first
20     None: 'English',
21
22     # Keep the rest sorted alphabetically
23     'zh_CN': 'Chinese (Simplified)',
24     'zh_TW': 'Chinese (Traditional)',
25     'it_IT': 'Italian',
26     'ja_JP': 'Japanese',
27     'ko_KR': 'Korean',
28     'sp_SP': 'Spanish',
29 }
30
31 class LanguagesNode(nodes.Element):
32     pass
33
34 class TranslationsTransform(Transform):
35     default_priority = 900
36
37     def apply(self):
38         app = self.document.settings.env.app
39         docname = self.document.settings.env.docname
40
41         this_lang_code = None
42         components = docname.split(os.sep)
43         if components[0] == 'translations' and len(components) > 2:
44             this_lang_code = components[1]
45
46             # normalize docname to be the untranslated one
47             docname = os.path.join(*components[2:])
48
49         new_nodes = LanguagesNode()
50         new_nodes['current_language'] = all_languages[this_lang_code]
51
52         for lang_code, lang_name in all_languages.items():
53             if lang_code == this_lang_code:
54                 continue
55
56             if lang_code is None:
57                 target_name = docname
58             else:
59                 target_name = os.path.join('translations', lang_code, docname)
60
61             pxref = addnodes.pending_xref('', refdomain='std',
62                 reftype='doc', reftarget='/' + target_name, modname=None,
63                 classname=None, refexplicit=True)
64             pxref += nodes.Text(lang_name)
65             new_nodes += pxref
66
67         self.document.insert(0, new_nodes)
68
69 def process_languages(app, doctree, docname):
70     for node in doctree.traverse(LanguagesNode):
71         if app.builder.format not in ['html']:
72             node.parent.remove(node)
73             continue
74
75         languages = []
76
77         # Iterate over the child nodes; any resolved links will have
78         # the type 'nodes.reference', while unresolved links will be
79         # type 'nodes.Text'.
80         languages = list(filter(lambda xref:
81             isinstance(xref, nodes.reference), node.children))
82
83         html_content = app.builder.templates.render('translations.html',
84             context={
85                 'current_language': node['current_language'],
86                 'languages': languages,
87             })
88
89         node.replace_self(nodes.raw('', html_content, format='html'))
90
91 def setup(app):
92     app.add_node(LanguagesNode)
93     app.add_transform(TranslationsTransform)
94     app.connect('doctree-resolved', process_languages)
95
96     return {
97         'parallel_read_safe': True,
98         'parallel_write_safe': True,
99     }