ropensci-review-tools / babelquarto

Renders a Multilingual Quarto Project (Book or Website)
https://docs.ropensci.org/babelquarto/
Other
30 stars 6 forks source link

babelquarto

R-CMD-check

The goal of babelquarto is to render a Quarto multilingual project, book or website.

Installation

You can install the development version of babelquarto from rOpenSci R-universe:

install.packages('babelquarto', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org'))

Or from GitHub with:

# install.packages("pak")
pak::pak("ropensci-review-tools/babelquarto")

Once using babelquarto, you cannot render your book or website using Quarto CLI (or the RStudio IDE render button) directly. You need to use babelquarto::render_book() or babelquarto::render_website(), respectively.

Example book

Create a starter/example book.

parent_dir <- withr::local_tempdir()
project_dir <- "blop"
babelquarto::quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir)
#> [1] "/tmp/RtmpBoDnhG/filedc9c5c49d508/blop"
readLines(file.path(parent_dir, project_dir, "_quarto.yml"))
#>  [1] "project:"                          "  type: book"                     
#>  [3] ""                                  "book:"                            
#>  [5] "  site-url: https://example.com"   "  title: \"blop\""                
#>  [7] "  author: \"Maëlle Salmon\""       "  date: \"6/24/2024\""            
#>  [9] "  chapters:"                       "    - index.qmd"                  
#> [11] "    - intro.qmd"                   "    - summary.qmd"                
#> [13] "    - references.qmd"              ""                                 
#> [15] "bibliography: references.bib"      ""                                 
#> [17] "format:"                           "  html:"                          
#> [19] "    theme: cosmo"                  ""                                 
#> [21] "babelquarto:"                      "  languagecodes:"                 
#> [23] "  - name: es"                      "    text: \"Version in es\""      
#> [25] "  - name: fr"                      "    text: \"Version in fr\""      
#> [27] "  - name: en"                      "    text: \"Version in en\""      
#> [29] "  mainlanguage: 'en'"              "  languages: ['es', 'fr']"        
#> [31] "title-es: title in es"             "title-fr: title in fr"            
#> [33] "description-es: description in es" "description-fr: description in fr"
#> [35] "author-es: author in es"           "author-fr: author in fr"          
#> [37] "lang: en"
fs::dir_tree(file.path(parent_dir, project_dir))
#> /tmp/RtmpBoDnhG/filedc9c5c49d508/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
babelquarto::render_book(file.path(parent_dir, project_dir))

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

Example website

Create a starter/example website.

parent_dir <- withr::local_tempdir()
project_dir <- "blop"
babelquarto::quarto_multilingual_website(parent_dir = parent_dir, project_dir = project_dir)
#> [1] "/tmp/RtmpBoDnhG/filedc9c76c8fd6a/blop"
readLines(file.path(parent_dir, project_dir, "_quarto.yml"))
#>  [1] "project:"                          "  type: website"                  
#>  [3] ""                                  "website:"                         
#>  [5] "  site-url: https://example.com"   "  title: \"blop\""                
#>  [7] "  navbar:"                         "    left:"                        
#>  [9] "      - href: index.qmd"           "        text: Home"               
#> [11] "      - about.qmd"                 ""                                 
#> [13] "format:"                           "  html:"                          
#> [15] "    theme: cosmo"                  "    css: styles.css"              
#> [17] "    toc: true"                     ""                                 
#> [19] ""                                  ""                                 
#> [21] ""                                  "babelquarto:"                     
#> [23] "  languagecodes:"                  "  - name: es"                     
#> [25] "    text: \"Version in es\""       "  - name: fr"                     
#> [27] "    text: \"Version in fr\""       "  - name: en"                     
#> [29] "    text: \"Version in en\""       "  mainlanguage: 'en'"             
#> [31] "  languages: ['es', 'fr']"         "title-es: title in es"            
#> [33] "title-fr: title in fr"             "description-es: description in es"
#> [35] "description-fr: description in fr" "author-es: author in es"          
#> [37] "author-fr: author in fr"           "lang: en"
fs::dir_tree(file.path(parent_dir, project_dir))
#> /tmp/RtmpBoDnhG/filedc9c76c8fd6a/blop
#> ├── _quarto.yml
#> ├── about.es.qmd
#> ├── about.fr.qmd
#> ├── about.qmd
#> ├── index.es.qmd
#> ├── index.fr.qmd
#> ├── index.qmd
#> └── styles.css
babelquarto::render_website(file.path(parent_dir, project_dir))

Example, source

Configure the base URL

Use the usual Quarto field, or use the site_url argument of babelquarto::render_book().

book:
  site-url: https://example.com

Configure the version text

If you want the choice to be between, say “English” and “Español” rather than “Version in EN” and “Version in ES”, add these fields under the babelquarto YAML key, in _quarto.yml:

babelquarto:
  languagecodes:
  - name: es
    text: "Español"
  - name: en
    text: "English"

Using babelquarto::register_main_language() and babelquarto::register_further_languages() will create the boilertemplate for these fields.

Configure templates

If you want, say, a banner with different content in the different languages, you can create a partial template and in it use the variables lang-fr and lang-en for instance for content in French and English.

The Quarto configuration file _quarto.yml would include:

format:
  html:
    template-partials:
      - metadata.html

The end of the metadata.html template would be:

<!-- copy content from https://github.com/quarto-dev/quarto-cli/blob/main/src/resources/formats/html/pandoc/metadata.html -->
<div class="alert alert-info alert-dismissible">
$if(lang-en)$Hello$endif$
$if(lang-fr)$Salut$endif$
$if(lang-es)$Hola$endif$
</div>

Content translation

From a book whose main language is English…

parent_dir <- withr::local_tempdir()
project_dir <- "babelbook"
quarto_bin <- quarto::quarto_path()
withr::with_dir(parent_dir, {
  sys::exec_wait(
    quarto_bin,
    args = c("create-project", project_dir, "--type", "book")
  )
})
#> [1] 0
project_path <- file.path(parent_dir, project_dir)
babelquarto::register_main_language(main_language = "en", project_path = project_path)
babelquarto::register_further_languages(further_languages = "es", project_path = project_path)

This is how the config file now looks like:

project:
  type: book

book:
  title: "babelbook"
  author: "Norah Jones"
  date: "6/24/2024"
  chapters:
    - index.qmd
    - intro.qmd
    - summary.qmd
    - references.qmd

bibliography: references.bib

format:
  html:
    theme: cosmo
  pdf:
    documentclass: scrreprt

babelquarto:
  languagecodes:
  - name: es
    text: "Version in es"
  - name: en
    text: "Version in en"
  mainlanguage: 'en'
  languages: ['es']
title-es: title in es
description-es: description in es
author-es: author in es
lang: en
  - 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.

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.

Note that babelquarto does not translate the content! Translation tooling lives in babeldown.