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 9import os 10 11from docutils import nodes 12from docutils.transforms import Transform 13 14import sphinx 15from sphinx import addnodes 16from sphinx.errors import NoUri 17 18all_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 31class LanguagesNode(nodes.Element): 32 pass 33 34class 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 69def 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 91def 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 } 100