https://github.com/ropensci-review-tools/babeldown
Helpers for Automatic Translation of Markdown-based Content
https://github.com/ropensci-review-tools/babeldown
Last synced: 1 day ago
JSON representation
Helpers for Automatic Translation of Markdown-based Content
- Host: GitHub
- URL: https://github.com/ropensci-review-tools/babeldown
- Owner: ropensci-review-tools
- License: other
- Created: 2023-01-17T11:43:17.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2025-07-23T13:02:52.000Z (3 months ago)
- Last Synced: 2025-07-30T00:12:25.412Z (3 months ago)
- Language: R
- Homepage: https://docs.ropensci.org/babeldown/
- Size: 247 KB
- Stars: 24
- Watchers: 2
- Forks: 4
- Open Issues: 13
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - ropensci-review-tools/babeldown - Helpers for Automatic Translation of Markdown-based Content (R)
README
---
output: github_document
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# babeldown
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[](https://github.com/ropensci-review-tools/babeldown/actions/workflows/R-CMD-check.yaml)
The goal of babeldown is to support workflows that include automatic translation of Markdown-based R content, through [DeepL API](https://www.deepl.com/en/docs-api/).
With babeldown you can translate: Markdown strings (`babeldown::deepl_translate_markdown_string()`) and Markdown files (`babeldown::deepl_translate()`) in general; Quarto book chapters (`babeldown::deepl_translate_quarto()`) and Hugo blog posts (`babeldown::deepl_translate_hugo()`) in particular.
With babeldown you can also _update_ translations, see `babeldown::deepl_update()`.
## Installation and setup
You can install the development version of babeldown from [rOpenSci R-universe](https://ropensci.r-universe.dev/):
``` r
install.packages('babeldown', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org'))
```
Or from [GitHub](https://github.com/) with:
``` r
# install.packages("pak")
pak::pak("ropensci-review-tools/babeldown")
```
### API URL
The DeepL API URL depends on your API plan.
babeldown uses the DeepL _free_ API URL by default.
If you use a Pro plan, set the API URL via
```{r, eval=FALSE}
# Only for Pro plan users
Sys.setenv("DEEPL_API_URL" = "https://api.deepl.com")
```
### API key
Set your API key via the environment variable `DEEPL_API_KEY`.
You could store it with the [keyring](https://r-lib.github.io/keyring/index.html) package, once per user/machine.
The code below will prompt you to enter your API key interactively.
```r
keyring::key_set("deepl", prompt = "API key:")
```
In any script you use babeldown, you'd retrieve the key like so:
```{r}
Sys.setenv(DEEPL_API_KEY = keyring::key_get("deepl"))
```
### Line wrapping
We recommend to start a new line in your Markdown document after each sentence or sentence part (after a comma for instance), for more informative Git diffs.
We also recommend not starting a new line in the middle of something that's between square brackets (in particular references and in-line footnotes) as it would break the way babeldown tries to protect those.
You might be interested in the [aeolus package](https://docs.ropensci.org/aeolus/) for fixing line breaks.
#### RStudio Visual Editor
If you use RStudio Visual Editor, you can choose ["sentence" as line-wrapping option](https://rstudio.github.io/visual-markdown-editing/markdown.html#line-wrapping).
## Troubleshooting
Getting an HTTP error 456 means you've used up all your API credits.
Use `deepl_usage()` (or the online DeepL API interface) to get your usage data.
The DeepL API might mix up some punctuation, for instance:
```{r}
babeldown::deepl_translate_markdown_string(
"[So _incredibly_ **wonderful**](https://ropensci.org)!",
source_lang = "EN",
target_lang = "ES"
)
babeldown::deepl_translate_markdown_string(
"[So _incredibly_ **wonderful**!](https://ropensci.org)",
source_lang = "EN",
target_lang = "ES"
)
babeldown::deepl_translate_markdown_string(
"[So _incredibly_ **wonderful!**](https://ropensci.org)",
source_lang = "EN",
target_lang = "ES"
)
```
## Examples
### Markdown string translation
```{r}
babeldown::deepl_translate_markdown_string(
"[So _incredibly_ **wonderful**](https://ropensci.org)",
source_lang = "EN",
target_lang = "ES"
)
```
### File translation
```{r}
english_lines <- c(
"## A cool section", "",
"This is the first paragraph. `system.file()` is cool, right?", "",
"Another paragraph. I really enjoy developing R packages.", "",
"Do you enjoy debugging?"
)
file <- withr::local_tempfile()
brio::write_lines(english_lines, file)
out_path <- withr::local_tempfile()
babeldown::deepl_translate(
path = file,
out_path = out_path,
source_lang = "EN",
target_lang = "ES",
formality = "less"
)
readLines(out_path)
```
You can also indicate YAML fields to translate, using the `yaml_fields` argument.
By default, `title` and `description` are translated.
```{r}
english_lines <- c(
"---",
"title: Nice document",
"description: An example for sure",
"---",
"## A cool section", "",
"This is the first paragraph. `system.file()` is cool, right?", "",
"Another paragraph. I really enjoy developing R packages.", "",
"Do you enjoy debugging?"
)
file <- withr::local_tempfile()
brio::write_lines(english_lines, file)
out_path <- withr::local_tempfile()
babeldown::deepl_translate(
path = file,
out_path = out_path,
source_lang = "EN",
target_lang = "ES",
formality = "less"
)
readLines(out_path)
```
### Glossary creation or update
```{r}
filename <- system.file("example-es-en.csv", package = "babeldown")
# file contents for info
readr::read_csv(filename, show_col_types = FALSE)
# create (or update) glossary
babeldown::deepl_upsert_glossary(
filename,
glossary_name = "rstats-glosario",
target_lang = "Spanish",
source_lang = "English"
)
```
### File translation with glossary
```{r}
file <- withr::local_tempfile()
brio::write_lines(english_lines, file)
out_path <- withr::local_tempfile()
babeldown::deepl_translate(
path = file,
out_path = out_path,
source_lang = "EN",
target_lang = "ES",
formality = "less",
glossary = "rstats-glosario"
)
readLines(out_path)
```
### Quarto book chapters
You can use babeldown to translate chapters of a Quarto multilingual book set up with babelquarto.
See the article describing [the workflow](https://docs.ropensci.org/babeldown/articles/quarto.html).
### Hugo posts
You can also use babeldown to translate blog posts of a Hugo multilingual website using leaf bundles (posts as `index.md` inside a content subfolder) and saving translations along each other (for instance Spanish post as `index.es.md` inside the same subfolder).
See `babeldown::deepl_translate_hugo()`.
If your Hugo website is set up differently, either open an issue or use `babeldown::deepl_translate()`.
#### Hugo shortcodes
Hugo shortcodes are supported but not very flexibly: you need to use `param="value"` with no space, and double quotes.