Donnez un peu plus de classe à vos packages grâce à {cli}

Tags : Autour de R, Actualités, Ressources
Date :

On a parfois besoin d’afficher des messages dans la console, que ce soit pour avertir la personne qui va utiliser le package qu’on est en train de développer d’éventuels erreurs/warning ou fournir une information (cf cet article), ou encore par exemple pour suivre l’état d’avancement d’un calcul. La console peut vite se retrouver surchargée et ce qu’on voulait mettre en avant se retrouve à moitié perdu au milieu. Alors qu’est-ce-qu’on peut faire pour améliorer nos messages dans la console ? Utiliser {cli} bien sûr !

Les couleurs

Regardons ensemble ce qu’on a dans ce package, qui fait partie du tidyverse :

  • des fonctions col_*() pour colorer notre texte :
library(cli)
cat("Le", col_red("bonheur "), col_magenta("est parfois "), col_green("caché "), "dans l'",
    col_cyan("inconnu"), ".", col_black(" (Victor Hugo)"))

  • des fonctions bg_*() pour la couleur du fond :
cat(bg_blue(col_white("L'essence des ")), bg_black(col_white("mathématiques")), 
    bg_cyan(col_red(" c'est la liberté.")), col_black(" (Georg Cantor)"))

Les styles et formats

  • des fonctions style_*() pour appliquer un style au texte :
cat("En", style_bold("mathématiques"), ", on ne ", style_dim("comprend"), 
    style_inverse("pas"), "les", style_underline("choses"), "on s'y",  
    style_italic("habitue"), ".")

  • la fonction combine_ansi_styles() nous permet de créer notre propre style en combinant les fonctions précédentes :
style1 <- combine_ansi_styles("cyan", "bold")
style2 <- combine_ansi_styles("red", "italic")
cat(style2("Quelle est votre ambition dans la vie ? \n"),
    style1("Devenir immortel et mourir."))

Exemple de formats définis :

cat(
  cli_text("Caratères en {.strong gras}"),
  cli_text("Un bout de code : {.code sum(a) / length(a)}"),
  cli_text("Un nom de package : {.pkg cli}"),
  cli_text("Un nom de fonction : {.fn cli_text}"),
  cli_text("Une touche clavier : {.kbd ENTER}"),
  cli_text("Un nom de fichier : {.file /usr/bin/env}"),
  cli_text("Une adresse mail : {.email [email protected]}"),
  cli_text("Une URL: {.url https://acme.com}")
)

Les autres possibilités d’affichage

Les titres

Les fonctions cli_h1(), cli_h2() et cli_h3() permettent d’afficher des titres de niveau 1, 2 et 3 :

cli_h1("Titre de niveau 1")
cli_h2("Titre de niveau 2")
cli_h3("Titre de niveau 3")

les listes

Il y a deux façons de faire des listes non ordonnées, la première via la fonction cli_li() :

cli_li(c("élément un", "élément deux", "élément trois"))

Et de façon équivalente, mais en créant les éléments de la liste un par un, via les fonctions cli_ul() et cli_li() :

{
  cli_ul() # ouverture du container de la liste
  cli_li("elem. 1")
  cli_li("elem. 2")
  cli_li("elem. 3")
  cli_end() # fermeture du container de la liste
}

Même logique pour les listes ordonnées : la fonction cli_ol() nous permet de créer une liste numérotée, d’un bloc :

cli_ol(c("élément un", "élément deux", "élément trois"))

Et en créant les éléments de la liste un par un, via les fonctions cli_ol() et cli_li() :

{
  cli_ol() # ouverture du container de la liste
  cli_li("elem. 1")
  cli_li("elem. 2")
  cli_li("elem. 3")
  cli_end() # fermeture du container de la liste
}

Il est également possible de faire des listes à plusieurs niveaux :

{
  cli_ol() # ouverture du container de la liste
  cli_li("elem. 1")
  ul_id <- cli_ul()
  cli_li("UN")
  cli_li("DEUX")
  cli_end(ul_id)
  cli_li("elem. 2")
  cli_li("elem. 3")
  cli_end() # fermeture du container de la liste
}

Les droites horizontales

Avec la fonction cli_rule() (ou rule(), à qui on peut passer plus de paramètres comme la couleur), on peut afficher des droites horizontales simples :

{cli_rule()
  cli_text(packageDescription("cli")$Description)
  rule(line = 2)}

ou avec du texte à droite, à gauche, au centre :

cat(rule(left = "Gauche", col = "red"),
    rule(right = "Droite", background_col = "blue"),
    rule(center = "Centre", line_col = "green", line = "~"))

Les boites/cadres

La fonction boxx() nous permet de dessiner un genre de cadre autour du texte :
Et si vous aimez faire des boites dans vos scripts vous pouvez regarder cet utilitaire https://github.com/ThinkR-open/littleboxes

boxx(style2("Haut les cœurs !"))

boxx("Haut les cœurs !", border_col = "red")

Spinners et autres symboles

Pour une démo de tous les spinners de {cli}, tapez demo_spinners() dans votre console.

Les fonctions ansi_with_hidden_cursor() et demo_spinners() nous permettent d’insérer un spinner, par exemple :

ansi_with_hidden_cursor(demo_spinners("shark"))

Pour accéder à la liste des spinners disponibles dans {cli} : list_spinners()

On peut également insérer des symboles dans le texte que nous souhaitons afficher :

cli_text("{symbol$tick} no errors  |  {symbol$cross} 2 warnings")

Vous retrouverez la liste complètes des symboles en appelant list_symbols().

Informer sur les étapes d’un process avec les alertes

{cli} dispose de fonctions propres aux différentes étapes d’un process :

  • on déclare le début d’un process grâce à la fonction cli_process_start() qui prendra en paramètres : le nom du process, le message en cas de succès, le message en cas d’erreur, …
  • il s’agit ensuite de déclarer le succès ou l’échec de process, avec les fonctions cli_process_done() ou cli_process_failed()
  • on notifie enfin la fin du process grâce à la fonction cli_end() si on n’a pas passé le paramètre .auto_close = TRUE à la fonction cli_process_start().

On peut également utiliser les autres fonctions d’alertes de {cli} :

  • cli_alert() pour afficher un message simple
  • cli_alert_info() pour afficher un message d’information
  • cli_alert_warnng pour afficher un message de warning
  • cli_alert_danger pour afficher un message d’erreur
  • cli_alert_success() pour afficher un message de réussite

Par exemple :

my_process <- function(x) {
  cli_process_start(
    msg = "Test de la fonction log",
    msg_done = "Le log a bien été calculé",
    .auto_close = TRUE
  )
  if (!is.numeric(x)) {
    cli_alert_danger("x doit être numerique !")
    cli_process_failed()
    stop()
  } else if(x < 0) {
    cli_alert_warning("x doit être positif...")
    cli_process_failed()
    stop()
  } else {
    cli_alert_success("all good !")
    cli_process_done()
  }
  return(log(x))
}

En conclusion

Et voilà, plus d’excuses pour renvoyer des messages indigestes dans votre console !


À propos de l'auteur


Commentaires


À lire également

Nos formations Certifiantes à R sont finançables à 100% via le CPF

Nos formations disponibles via moncompteformation.gouv.fr permettent de délivrer des Certificats de Qualifications Professionnelles (CQP) reconnus par l’état. 3 niveaux de certifications existent :

Contactez-nous pour en savoir plus.