Support de langue : polices et synthèse vocale
Mon blog prend désormais en charge neuf langues : japonais (ja
), espagnol (es
), hindi (hi
), chinois (zh
), anglais (en
), français (fr
), allemand (de
), arabe (ar
), et chinois traditionnel (hant
). Vous pouvez trouver le site à https://lzwjava.github.io
Lorsque l’on traite plusieurs langues dans un environnement informatique, plusieurs aspects nécessitent une attention particulière.
Gestion des polices
Différentes langues nécessitent des polices spécifiques pour un rendu correct, notamment lors de la génération de PDFs avec LaTeX. Le code Python suivant montre comment sélectionner des polices appropriées en fonction du système d’exploitation et de la langue :
if platform.system() == "Darwin":
if lang == "hi":
CJK_FONT = "Kohinoor Devanagari"
elif lang == "ar":
CJK_FONT = "Geeza Pro"
elif lang in ["en", "fr", "de", "es"]:
CJK_FONT = "Helvetica"
elif lang == "zh":
CJK_FONT = "PingFang SC"
elif lang == "hant":
CJK_FONT = "PingFang TC"
elif lang == "ja":
CJK_FONT = "Hiragino Sans"
else:
CJK_FONT = "Arial Unicode MS"
else:
if lang == "hi":
CJK_FONT = "Noto Sans Devanagari"
elif lang == "ar":
CJK_FONT = "Noto Naskh Arabic"
elif lang in ["en", "fr", "de", "es"]:
CJK_FONT = "DejaVu Sans"
elif lang == "zh":
CJK_FONT = "Noto Sans CJK SC"
elif lang == "hant":
CJK_FONT = "Noto Sans CJK TC"
elif lang == "ja":
CJK_FONT = "Noto Sans CJK JP"
else:
CJK_FONT = "Noto Sans"
command = [
'pandoc',
input_markdown_path,
'-o', output_pdf_path,
'-f', 'markdown',
'--pdf-engine', 'xelatex',
'-V', f'romanfont={CJK_FONT}',
'-V', f'mainfont={CJK_FONT}',
'-V', f'CJKmainfont={CJK_FONT}',
'-V', f'CJKsansfont={CJK_FONT}',
'-V', f'CJKmonofont={CJK_FONT}',
'-V', f'geometry:{GEOMETRY}',
'-V', 'classoption=16pt',
'-V', 'CJKoptions=Scale=1.1',
'-V', 'linestretch=1.5'
]
Il est important de noter que cette solution n’est pas parfaite. Par exemple, le texte hindi à l’intérieur des commentaires de bloc de code pourrait ne pas se rendre comme prévu.
Text-to-Speech
J’utilise Google Text-to-Speech pour générer des versions audio de mes billets de blog. Le code suivant montre comment je sélectionne le code de langue approprié pour le moteur de synthèse vocale :
synthesis_input = texttospeech.SynthesisInput(text=chunk)
if language_code == "en-US":
voice_name = random.choice(["en-US-Journey-D", "en-US-Journey-F", "en-US-Journey-O"])
elif language_code == "cmn-CN":
voice_name = random.choice(["cmn-CN-Wavenet-A", "cmn-CN-Wavenet-B", "cmn-CN-Wavenet-C", "cmn-CN-Wavenet-D"])
elif language_code == "es-ES":
voice_name = random.choice(["es-ES-Journey-D", "es-ES-Journey-F", "es-ES-Journey-O"])
elif language_code == "fr-FR":
voice_name = random.choice(["fr-FR-Journey-D", "fr-FR-Journey-F", "fr-FR-Journey-O"])
elif language_code == "yue-HK":
voice_name = random.choice(["yue-HK-Standard-A", "yue-HK-Standard-B", "yue-HK-Standard-C", "yue-HK-Standard-D"])
elif language_code == "ja-JP":
voice_name = random.choice(["ja-JP-Neural2-B", "ja-JP-Neural2-C", "ja-JP-Neural2-D"])
elif language_code == "hi-IN":
voice_name = random.choice(["hi-IN-Wavenet-A", "hi-IN-Wavenet-B", "hi-IN-Wavenet-C", "hi-IN-Wavenet-D", "hi-IN-Wavenet-E", "hi-IN-Wavenet-F"])
elif language_code == "de-DE":
voice_name = random.choice(["de-DE-Journey-D", "de-DE-Journey-F", "de-DE-Journey-O"])
elif language_code == "ar-XA":
voice_name = random.choice(["ar-XA-Wavenet-A", "ar-XA-Wavenet-B", "ar-XA-Wavenet-C", "ar-XA-Wavenet-D"])
text_to_speech(
text=article_text,
output_filename=output_filename,
task=task,
language_code=language_code,
dry_run=dry_run,
progress=progress
)
Actuellement, l’audio est généré pour le contenu chinois et anglais. Pour étendre le support à d’autres langues, les codes de langue correspondants doivent être configurés.
Résumé
Les langues diffèrent principalement en deux aspects : leur représentation écrite (forme) et leur forme parlée (prononciation). La sélection des polices et les configurations de synthèse vocale traitent ces deux aspects respectivement.