martes, 26 de septiembre de 2023 From rOpenSci (https://ropensci.org/es/blog/2023/09/26/c%C3%B3mo_traducir_una_entrada_de_blog_de_hugo_con_babeldown/). Except where otherwise noted, content on this site is licensed under the CC-BY license.
Como parte de nuestro proyecto editorial multilingüe y con financiación del Consorcio R hemos trabajado en el paquete R babeldown para traducir contenido basado en Markdown utilizando la API de DeepL. En esta nota técnica, mostraremos cómo puedes utilizar babeldown para traducir un artículo de blog que utiliza Hugo.
Traducir un artículo de blog en Markdown desde tu consola de R no sólo es más cómodo (cuando ya has escrito dicho artículo en R), sino también menos frustrante. Con babeldown, en comparación con copiar y pegar el contenido del artículo en algún servicio de traducción, no se romperá la sintaxis Markdown1, ni se traducirán las líneas de código. Esto funciona porque, detrás de escena, babeldown utiliza tinkr para producir XML que luego envía a la API DeepL, marcando algunas etiquetas como no traducibles. A continuación, convierte el XML traducido por DeepL de nuevo en Markdown.
Ahora bien, como era de esperar, ¡este contenido traducido por la máquina aún no es perfecto! Aún necesitarás una o dos personas para revisar y corregir la traducción. Entonces, ¿por qué no hacer que una persona traduzcan el artículo desde cero? Hemos observado que para las personas voluntarias que participan en nuestras traduciones, editar una traducción automática es más rápido que traducir todo el artículo, y que libera espacio mental para centrarse en la aplicación de reglas de traducción como la redacción neutra en cuanto al género.
babeldown::deepl_translate_hugo()
asume que el sitio web de Hugo utiliza
content/camino-a-la-hoja/index.md
);content/camino-a-la-hoja/index.es.md
.babeldown podría ampliarse para funcionar con otras configuraciones multilingües de Hugo. Si estás interesado en utilizar babeldown con una configuración diferente, ¡ abre un issue en la sección correspondiente en el repositorio de babeldow!
Ten en cuenta que babeldown no podrá determinar el idioma por defecto de tu sitio web2, así que aunque el idioma por defecto de tu sitio web sea el inglés, babeldown colocará una traducción al inglés en un archivo llamado “.en.md” y no “.md”. Hugo reconocerá el nuevo archivo igualmente (al menos en nuestra configuración).
Comprueba primero que la API DeepL admite los idiomas de origen y destino que desees.
Busca la documentación de los parámetros source_lang
y target_lang
de la API para obtener una lista completa.
Una vez que sepas que podrás aprovechar la API de DeepL, tendrás que crear una cuenta para la API del servicio de traducción de DeepL. Ten en cuenta que incluso para obtener una cuenta gratuita es necesario registrar un método de pago con ellos.
Necesitarás instalar babeldown desde el Universo R de rOpenSci:
install.packages('babeldown', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org'))
A continuación, en cada sesión de R, establece tu clave de API DeepL mediante la variable de entorno DEEPL_API_KEY. Puedes almacenarla de una vez por todas con el paquete keyring y recuperarla en tus scripts de la siguiente manera:
Sys.setenv(DEEPL_API_KEY = keyring::key_get("deepl"))
Por último, la URL de la API DeepL depende de tu plan. babeldown utiliza por defecto la URL de API gratuita DeepL. Si utilizas un plan Pro, establece la URL de la API en cada sesión/script de R mediante
Sys.setenv("DEEPL_API_URL" = "https://api.deepl.com")
Puedes ejecutar el siguiente código:
babeldown::deepl_translate_hugo(
post_path = <path-to-post>,
source_lang = "EN",
target_lang = "ES",
formality = "less" # that's how we roll here!
)
pero te recomendamos que trabajes un poco más por tu propio bien.
Si utilizas el control de versiones, ¡tener la traducción como un diff es muy práctico!
index.es.md
) bajo el nombre del artículo de destino (index.en.md
) haz commit y luego push.babeldown::deepl_translate_hugo()
con force = TRUE
.Ahora vamos a repasar esto de nuevo, pero con un flujo de trabajo de programación. Utilizaremos fs y gert (¡pero hazlo como mejor te resulte a ti!). Suponemos que tu directorio actual es la raíz de la carpeta del sitio web, y también la raíz del repositorio git.
index.es.md
) con el nombre del artículo de blog de destino (index.en.md
). Haz commit y luego push.fs::file_copy(
file.path("content", "blog", "2023-10-01-r-universe-interviews", "index.es.md"),
file.path("content", "blog", "2023-10-01-r-universe-interviews", "index.en.md")
)
gert::git_add(file.path("content", "blog", "2023-10-01-r-universe-interviews", "index.en.md"))
gert::git_commit("Add translation placeholder")
gert::git_push()
gert::git_branch_create("translation-tech-note")
babeldown::deepl_translate_hugo()
con force = TRUE
.babeldown::deepl_translate_hugo(
post_path = file.path("content", "blog", "2023-10-01-r-universe-interviews", "index.es.md"),
force = TRUE,
yaml_fields = c("title", "description", "tags"),
source_lang = "ES",
target_lang = "EN-US"
)
También puedes omitir post_path
si estás ejecutando el código desde la IDE de RStudio y si el archivo abierto y en foco (el que ves encima de tu consola) es el post que hay que traducir.
babeldown::deepl_translate_hugo(
force = TRUE,
yaml_fields = c("title", "description", "tags"),
source_lang = "ES",
target_lang = "EN-US"
)
gert::git_add(file.path("content", "blog", "2023-10-01-r-universe-interviews", "index.en.md"))
gert::git_commit("Add translation")
gert::git_push()
Abre un PR desde el “translation-tech-note” a la rama “new-post”.
La única diferencia entre las dos ramas es la traducción automática de "content/blog/2023-10-01-r-universe-interviews/index.en.md"
.
Las personas que traducen o revisan pueden entonces ¡abrir un segundo PR a la rama de traducción con sus ediciones! O pueden añadir sus ediciones como sugerencias.
Al final debería haber dos o tres ramas:
Los PR se fusionan en este orden:
Yanina retocó la traducción automática sugiriendo cambios en el PR, y luego aceptándolos.
Por defecto, babeldown traduce los campos YAML “título” y “descripción”.
Si tienes texto en más campos, utiliza la opción yaml_fields
argumento de babeldown::deepl_translate_hugo()
.
Ten en cuenta que si babeldown traduce el título, actualiza el slug.
Imagina que tienes algunas preferencias para algunas palabras, algo que irás construyendo con el tiempo.
readr::read_csv(
system.file("example-es-en.csv", package = "babeldown"),
show_col_types = FALSE
)
## # A tibble: 2 × 2
## Spanish English
## <chr> <chr>
## 1 paquete package
## 2 repositorio repository
Puedes registrar estas traducciones preferidas en un glosario en tu cuenta de DeepL.
deepl_upsert_glossary(
<path-to-csv-file>,
glossary_name = "rstats-glosario",
target_lang = "Spanish",
source_lang = "English"
)
Utilizarías exactamente el mismo código para actualizar el glosario, de ahí el nombre “upsert” de la función. Necesitas un glosario por cada par de idiomas de origen y destino: el glosario inglés-español no puede utilizarse, por ejemplo, para el español-inglés.
En tu babeldown::deepl_translate_hugo()
llamada utilizarás el nombre del glosario (aquí “rstats-glosario”) para el argumento glossary
.
deepl_translate_hugo()
tiene un formality
argumento.
Ahora bien, la API de DeepL sólo admite esto para algunos idiomas, como se explica en el apartado de la documentación del parámetro formality
de la API:
Establece si el texto traducido debe inclinarse hacia un lenguaje formal o informal. Actualmente, esta opción sólo funciona para las lenguas de destino DE (alemán), FR (francés), IT (italiano), ES (español), NL (neerlandés), PL (polaco), PT-BR y PT-PT (portugués), JA (japonés) y RU (ruso). (…) La configuración de este parámetro con una lengua de destino que no admita la formalidad fallará, a menos que se utilice una de las opciones prefer_…
Por tanto, para asegurarnos de que una traducción funcionará, en lugar de escribir formality = "less"
puedes escribir formality = "prefer_less"
que sólo utilizará la formalidad si está disponible.
En este post hemos explicado cómo traducir una entrada del blog de Hugo utilizando babeldown.
Aunque lo esencial es utilizar una llamada a babeldown::deepl_translate_hugo()
,
babeldown tiene funciones para traducir capítulos de libros Quarto, cualquier archivo Markdown y cualquier cadena Markdown, con argumentos similares y uso recomendado, ¡así que explora su referencia!
Nos encantaría que nos cuentes tus casos de uso.
Pero deberías consultar tinkr docs para ver qué puede cambiar en el estilo de sintaxis Markdown. ↩︎
añadir código para manejar la “desconcertante variedad de posibles ubicaciones de configuración” de Hugo y dos formatos posibles (YAML y TOML) está fuera del alcance de babeldown en este momento. ↩︎