Skip to content

Commit 6564545

Browse files
authored
Agregar script de traducción automática (#1682)
* Agregar script de traducción automática Se utiliza deep_translator en vez de googletrans para evitar los problemas de timeout, y restricciones del módulo. No se agregó el módulo en el archivo `requirements.txt` pues no es necesario para la construcción de la documentación. El script utiliza `polib` para iterar sobre las entradas de un archivo po determinado y luego reemplaza mediante expresiones regulares todas las sentencias de sphinx, por ejemplo: This :mod:`polib` module allows you to handle :ref:`translations`. quedaría como: This XASDF00 module allows you to handle XASDF02. texto que luego peude ser traducido sin problemas de alterar los espacios, acentos invertidos, dos puntos, etc, que es un problem usual al utilizar otros servicios de traducción automática. La traducción quedaría: Este módulo XASDF00 te permite manejar XASDF02. a lo que luego se vuelven a reemplazar los textos temporales por su contenido original: Este módulo :mod:`polib` te permite manejar :ref:`translations`. * agregar comentarios de la revisión * Update scripts/translate.py
1 parent 50f9098 commit 6564545

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

scripts/translate.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import os
2+
import re
3+
import sys
4+
from typing import Dict, Tuple
5+
6+
import polib
7+
8+
VERBOSE = False
9+
DEBUG = False
10+
SKIP_TRANSLATED_ENTRIES = True
11+
12+
try:
13+
from deep_translator import GoogleTranslator
14+
except ImportError:
15+
print("Error: This util script needs `deep_translator` to be installed")
16+
sys.exit(1)
17+
18+
_patterns = [
19+
":c:func:`[^`]+`",
20+
":c:type:`[^`]+`",
21+
":c:macro:`[^`]+`",
22+
":c:member:`[^`]+`",
23+
":c:data:`[^`]+`",
24+
":py:data:`[^`]+`",
25+
":py:mod:`[^`]+`",
26+
":func:`[^`]+`",
27+
":mod:`[^`]+`",
28+
":ref:`[^`]+`",
29+
":class:`[^`]+`",
30+
":pep:`[^`]+`",
31+
":data:`[^`]+`",
32+
":exc:`[^`]+`",
33+
":term:`[^`]+`",
34+
":meth:`[^`]+`",
35+
":envvar:`[^`]+`",
36+
":file:`[^`]+`",
37+
":attr:`[^`]+`",
38+
":const:`[^`]+`",
39+
":issue:`[^`]+`",
40+
":opcode:`[^`]+`",
41+
":option:`[^`]+`",
42+
":program:`[^`]+`",
43+
":keyword:`[^`]+`",
44+
":RFC:`[^`]+`",
45+
":doc:`[^`]+`",
46+
"``[^`]+``",
47+
"`[^`]+`__",
48+
"`[^`]+`_",
49+
"\*\*.+\*\*", # bold text between **
50+
"\*.+\*", # italic text between *
51+
]
52+
53+
_exps = [re.compile(e) for e in _patterns]
54+
55+
def protect_sphinx_directives(s: str) -> Tuple[dict, str]:
56+
"""
57+
Parameters:
58+
string containing the text to translate
59+
60+
Returns:
61+
dictionary containing all the placeholder text as keys
62+
and the correct value.
63+
"""
64+
65+
i = 0
66+
d: Dict[str, str] = {}
67+
for exp in _exps:
68+
matches = exp.findall(s)
69+
if DEBUG:
70+
print(exp, matches)
71+
for match in matches:
72+
ph = f"XASDF{str(i).zfill(2)}"
73+
s = s.replace(match, ph)
74+
if ph in d and VERBOSE:
75+
print(f"Error: {ph} is already in the dictionary")
76+
print("new", match)
77+
print("old", d[ph])
78+
d[ph] = match
79+
i += 1
80+
return d, s
81+
82+
83+
def undo_sphinx_directives_protection(placeholders: dict, translated_text: str) -> str:
84+
for ph, value in placeholders.items():
85+
translated_text = translated_text.replace(ph, value)
86+
if DEBUG:
87+
print(ph, value)
88+
print(translated_text)
89+
return translated_text
90+
91+
92+
if __name__ == "__main__":
93+
filename = sys.argv[1]
94+
if not os.path.isfile(filename):
95+
print(f"File not found: '{filename}'")
96+
sys.exit(-1)
97+
98+
po = polib.pofile(filename)
99+
translator = GoogleTranslator(source="en", target="es")
100+
101+
for entry in po:
102+
# If the entry has already a translation, skip.
103+
if SKIP_TRANSLATED_ENTRIES and entry.msgstr:
104+
continue
105+
106+
print("\nEN|", entry.msgid)
107+
placeholders, temp_text = protect_sphinx_directives(entry.msgid)
108+
if VERBOSE:
109+
print(temp_text)
110+
print(placeholders)
111+
112+
# Translate the temporary text without sphinx statements
113+
translated_text = translator.translate(temp_text)
114+
115+
# Recover sphinx statements
116+
real_text = undo_sphinx_directives_protection(placeholders, translated_text)
117+
print("ES|", real_text)
118+
119+
# Replace the po file translated entry
120+
entry.msgstr = real_text
121+
122+
# Save the file after all the entries are translated
123+
po.save()

0 commit comments

Comments
 (0)