Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation about translated=True attribute on nodes #11508

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 114 additions & 0 deletions doc/usage/advanced/intl.rst
Expand Up @@ -340,6 +340,120 @@ There is a `sphinx translation page`_ for Sphinx (master) documentation.

Detail is here: https://docs.transifex.com/getting-started-1/translators


Using Sphinx's internals to extend translations functionality
-------------------------------------------------------------

.. versionadded:: 7.1.0

During the build process, Sphinx marks each translated node that with a ``translated=True`` attribute,
meaning it was able to find the translated version of the paragraph to the target language.
Developers and users with coding knowledge, can be benefit from this attribute to build extensions around translations.

The following example shows a minimal Sphinx extension that covers 3 different usage for this attribute:

* Mark untranslated paragraphs with a different background color using
* Calculate translated percentage per page and total
* Use a custom substitution to show the translated percentage of the page


.. code-block:: python
:caption: translated.py

import docutils
from sphinx.transforms import SphinxTransform


class TranslationsManipulation(SphinxTransform):
default_priority = 50

def apply(self, **kwargs):
filename = self.document.get('source') # absolute source filename

# Default values for current source filename
self.app._translations[filename] = {
'total': 0,
'translated': 0,
}

# Traverse all the nodes of the document
for node in self.document.traverse():
if not hasattr(node, 'get'):
# Discard nodes we cannot access to its attributes
continue

if any([isinstance(child, docutils.nodes.Text) for child in node.children]):
# Only work over nodes with a text child
if node.get('translated', False):
# Increase the translated nodes
self.app._translations[filename]['translated'] += 1
css_class = self.app.env.config.translated_class
else:
css_class = self.app.env.config.untranslated_class

# Append our custom untranslated CSS class to the node
classes = node.get('classes', [])
classes.append(css_class)
node.replace_attr('classes', classes)

# Increase the total of nodes
self.app._translations[filename]['total'] += 1


# Calculate total percentage of the page translated
self.app._translations[filename]['percentage'] = (
self.app._translations[filename]['translated'] /
self.app._translations[filename]['total']
) * 100

# Handle substitutions (used as ``|translated-page-percentage|`` in .rst source files)
substitution = 'translated-page-percentage'
for ref in self.document.findall(docutils.nodes.substitution_reference):
refname = ref['refname']
if refname == substitution:
text = self.app._translations[filename]['percentage']
newnode = docutils.nodes.Text(text)
if 'classes' in ref:
ref.replace_attr('classes', [])
ref.replace_self(newnode)


def setup(app):
"""
Setup ``translated`` Sphinx extension.
"""
# CSS class to add to translated nodes
app.add_config_value('translated_class', 'translated', 'env')
app.add_config_value('untranslated_class', 'untranslated', 'env')

# Add the CSS file with our custom styles
app.add_css_file('translated.css')

app.add_transform(TranslationsManipulation)

# Define an internal variable to store translated percentages
app._translations = {}

return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

The ``.css`` added looks like the following:

.. code-block:: css
:caption: _static/translated.css

.translated {
background-color: rgba(0, 255, 0, .20)
}

.untranslated {
background-color: rgba(255, 0, 0, .20)
}


.. rubric:: Footnotes

.. [1] See the `GNU gettext utilities
Expand Down