2023-12-15 15:37:01 +03:00
# 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 (Simplified) ' ,
' zh_TW ' : ' Chinese (Traditional) ' ,
' it_IT ' : ' Italian ' ,
' ja_JP ' : ' Japanese ' ,
' ko_KR ' : ' Korean ' ,
' sp_SP ' : ' Spanish ' ,
}
class LanguagesNode ( nodes . Element ) :
2024-02-15 09:41:09 +03:00
pass
2023-12-15 15:37:01 +03:00
class TranslationsTransform ( Transform ) :
default_priority = 900
def apply ( self ) :
app = self . document . settings . env . app
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 : ] )
2024-02-15 09:41:09 +03:00
new_nodes = LanguagesNode ( )
new_nodes [ ' current_language ' ] = all_languages [ this_lang_code ]
2023-12-15 15:37:01 +03:00
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 ) :
if app . builder . format not in [ ' html ' ] :
node . parent . remove ( node )
continue
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 = {
2024-02-15 09:41:09 +03:00
' current_language ' : node [ ' current_language ' ] ,
2023-12-15 15:37:01 +03:00
' 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 ,
}