Skip to contents

The goal of babelquarto is to render a Quarto multilingual book structured like the rOpenSci dev guide:

  • each qmd is present once for the main language,
  • and once more for each other language with an extension à la .es.qmd

Installation

You can install the development version of babelquarto from GitHub with:

# install.packages("devtools")
devtools::install_github("ropensci-review-tools/quartobabel")

Example

Create a starter/example book.

parent_dir <- withr::local_tempdir()
babelquarto::quarto_multilingual_book(parent_dir = parent_dir, book_dir = "blop")
readLines(file.path(parent_dir, "blop", "_quarto.yml"))
#>  [1] "project:"                          "  type: book"                     
#>  [3] ""                                  "book:"                            
#>  [5] "  title: \"blop\""                 "  author: \"Jane Doe\""           
#>  [7] "  date: \"4/21/2023\""             "  chapters:"                      
#>  [9] "    - index.qmd"                   "    - intro.qmd"                  
#> [11] "    - summary.qmd"                 "    - references.qmd"             
#> [13] ""                                  "bibliography: references.bib"     
#> [15] ""                                  "format:"                          
#> [17] "  html:"                           "    theme: cosmo"                 
#> [19] ""                                  "babelquarto:"                     
#> [21] "  mainlanguage: 'en'"              "  languages: ['es', 'fr']"        
#> [23] "lang: en"                          "title-es: title in es"            
#> [25] "title-fr: title in fr"             "description-es: description in es"
#> [27] "description-fr: description in fr" "author-es: author in es"          
#> [29] "author-fr: author in fr"
fs::dir_tree(file.path(parent_dir, "blop"))
#> /tmp/RtmpyJ7bhh/file95c4335e59e9/blop
#> ├── _quarto.yml
#> ├── cover.png
#> ├── index.es.qmd
#> ├── index.fr.qmd
#> ├── index.qmd
#> ├── intro.es.qmd
#> ├── intro.fr.qmd
#> ├── intro.qmd
#> ├── references.bib
#> ├── references.es.qmd
#> ├── references.fr.qmd
#> ├── references.qmd
#> ├── summary.es.qmd
#> ├── summary.fr.qmd
#> └── summary.qmd

Render it. We end up with three books, that cross-link to each other from the left sidebar.

babelquarto::render_book(book_path = file.path(parent_dir, "blop"))
#> [1m[34m[1/4] index.qmd[39m[22m
#> [1m[34m[2/4] intro.qmd[39m[22m
#> [1m[34m[3/4] summary.qmd[39m[22m
#> [1m[34m[4/4] references.qmd[39m[22m
#> 
#> Output created: _book/index.html
#> 
#> [1m[34m[1/4] index.es.qmd[39m[22m
#> [1m[34m[2/4] intro.es.qmd[39m[22m
#> [1m[34m[3/4] summary.es.qmd[39m[22m
#> [1m[34m[4/4] references.es.qmd[39m[22m
#> 
#> Output created: _book/index.es.html
#> 
#> [1m[34m[1/4] index.fr.qmd[39m[22m
#> [1m[34m[2/4] intro.fr.qmd[39m[22m
#> [1m[34m[3/4] summary.fr.qmd[39m[22m
#> [1m[34m[4/4] references.fr.qmd[39m[22m
#> 
#> Output created: _book/index.fr.html
fs::dir_tree(file.path(parent_dir, "blop", "_book"))
#> /tmp/RtmpyJ7bhh/file95c4335e59e9/blop/_book
#> ├── es
#> │   ├── index.es.html
#> │   ├── index.html
#> │   ├── intro.es.html
#> │   ├── references.es.html
#> │   ├── search.json
#> │   ├── site_libs
#> │   │   ├── bootstrap
#> │   │   │   ├── bootstrap-icons.css
#> │   │   │   ├── bootstrap-icons.woff
#> │   │   │   ├── bootstrap.min.css
#> │   │   │   └── bootstrap.min.js
#> │   │   ├── clipboard
#> │   │   │   └── clipboard.min.js
#> │   │   ├── quarto-html
#> │   │   │   ├── anchor.min.js
#> │   │   │   ├── popper.min.js
#> │   │   │   ├── quarto-syntax-highlighting.css
#> │   │   │   ├── quarto.js
#> │   │   │   ├── tippy.css
#> │   │   │   └── tippy.umd.min.js
#> │   │   ├── quarto-nav
#> │   │   │   ├── headroom.min.js
#> │   │   │   └── quarto-nav.js
#> │   │   └── quarto-search
#> │   │       ├── autocomplete.umd.js
#> │   │       ├── fuse.min.js
#> │   │       └── quarto-search.js
#> │   └── summary.es.html
#> ├── fr
#> │   ├── index.fr.html
#> │   ├── index.html
#> │   ├── intro.fr.html
#> │   ├── references.fr.html
#> │   ├── search.json
#> │   ├── site_libs
#> │   │   ├── bootstrap
#> │   │   │   ├── bootstrap-icons.css
#> │   │   │   ├── bootstrap-icons.woff
#> │   │   │   ├── bootstrap.min.css
#> │   │   │   └── bootstrap.min.js
#> │   │   ├── clipboard
#> │   │   │   └── clipboard.min.js
#> │   │   ├── quarto-html
#> │   │   │   ├── anchor.min.js
#> │   │   │   ├── popper.min.js
#> │   │   │   ├── quarto-syntax-highlighting.css
#> │   │   │   ├── quarto.js
#> │   │   │   ├── tippy.css
#> │   │   │   └── tippy.umd.min.js
#> │   │   ├── quarto-nav
#> │   │   │   ├── headroom.min.js
#> │   │   │   └── quarto-nav.js
#> │   │   └── quarto-search
#> │   │       ├── autocomplete.umd.js
#> │   │       ├── fuse.min.js
#> │   │       └── quarto-search.js
#> │   └── summary.fr.html
#> ├── index.html
#> ├── intro.html
#> ├── references.html
#> ├── search.json
#> ├── site_libs
#> │   ├── bootstrap
#> │   │   ├── bootstrap-icons.css
#> │   │   ├── bootstrap-icons.woff
#> │   │   ├── bootstrap.min.css
#> │   │   └── bootstrap.min.js
#> │   ├── clipboard
#> │   │   └── clipboard.min.js
#> │   ├── quarto-html
#> │   │   ├── anchor.min.js
#> │   │   ├── popper.min.js
#> │   │   ├── quarto-syntax-highlighting.css
#> │   │   ├── quarto.js
#> │   │   ├── tippy.css
#> │   │   └── tippy.umd.min.js
#> │   ├── quarto-nav
#> │   │   ├── headroom.min.js
#> │   │   └── quarto-nav.js
#> │   └── quarto-search
#> │       ├── autocomplete.umd.js
#> │       ├── fuse.min.js
#> │       └── quarto-search.js
#> └── summary.html
# if (require("servr") && rlang::is_interactive()) {
#   servr::httw(file.path(parent_dir, "blop", "_book"))
# }

Note that this does not translate the content! Translation tooling will live in babeldown.

Content translation

From a book whose main language is English…

  • Register languages in the Quarto configuration, for instance
babelquarto:
  mainlanguage: 'en'
  languages: ['es', 'fr']
  • qmd/Rmd files. bla.qmd translation in Spanish would live in bla.es.qmd.
  • parts. The part title translation can be stored in _quarto.yml like so:
  - part: Building Your Package
    part-es: Construyendo tu paquete
    chapters:
    - pkg_building.Rmd
    - pkg_ci.Rmd
    - pkg_security.Rmd

If it does not exist, babelquarto falls back to the part title in the main language.

  • title, author, description. Their translation can be stored in _quarto.yml like so (NOT in the book list):
book:
  title: Cool book
  author: Myself

title-es: Libro genial
author-es: Yo misma

If these fields do not exist, babelquarto falls back to their text in the main language.