|
| 1 | +#' Write YAML Metadata Block for Quarto Documents |
| 2 | +#' |
| 3 | +#' Creates a YAML metadata block that can be dynamically inserted into Quarto |
| 4 | +#' documents from R code chunks. This allows setting metadata values based on |
| 5 | +#' R computations, which can then be used with Quarto's conditional content |
| 6 | +#' features like `when-meta` and `{{< meta >}}` shortcodes. |
| 7 | +#' |
| 8 | +#' @param ... Named arguments to include in the metadata block. Names become |
| 9 | +#' the metadata keys and values become the metadata values. These take |
| 10 | +#' precedence over any conflicting keys in `.list`. |
| 11 | +#' @param .list Optional list of additional metadata to include. This is useful |
| 12 | +#' when you have metadata stored in a list variable. Keys in `.list` are |
| 13 | +#' overridden by any matching keys provided in `...`. |
| 14 | +#' |
| 15 | +#' @return A character string containing the formatted YAML metadata block, |
| 16 | +#' wrapped with `knitr::asis_output()` so it renders as raw markdown. |
| 17 | +#' Returns `NULL` invisibly if no metadata is provided. |
| 18 | +#' |
| 19 | +#' @details |
| 20 | +#' The function converts R values to YAML format and wraps them in YAML |
| 21 | +#' delimiters (`---`). Logical values are converted to lowercase strings |
| 22 | +#' ("true"/"false") to ensure compatibility with Quarto's metadata system. |
| 23 | +#' |
| 24 | +#' When both `...` and `.list` contain the same key, the value from `...` |
| 25 | +#' takes precedence and will override the value from `.list`. |
| 26 | +#' |
| 27 | +#' If no metadata is provided (empty `...` and `NULL` or empty `.list`), |
| 28 | +#' the function returns `NULL` without generating any output. |
| 29 | +#' |
| 30 | +#' **Important**: When using this function in Quarto documents, you must set |
| 31 | +#' the chunk option `output: asis` (or `#| output: asis`) for the metadata |
| 32 | +#' block to be properly processed by Quarto. |
| 33 | +#' |
| 34 | +#' This addresses the limitation where Quarto metadata must be static and |
| 35 | +#' cannot be set dynamically from R code during document rendering. |
| 36 | +#' |
| 37 | +#' @examples |
| 38 | +#' \dontrun{ |
| 39 | +#' # In a Quarto document R chunk with `#| output: asis`: |
| 40 | +#' admin <- TRUE |
| 41 | +#' user_level <- "advanced" |
| 42 | +#' |
| 43 | +#' # Set metadata dynamically |
| 44 | +#' write_yaml_metadata_block( |
| 45 | +#' admin = admin, |
| 46 | +#' level = user_level, |
| 47 | +#' timestamp = Sys.Date() |
| 48 | +#' ) |
| 49 | +#' |
| 50 | +#' # Use with .list parameter |
| 51 | +#' metadata_list <- list(version = "1.0", debug = FALSE) |
| 52 | +#' write_yaml_metadata_block(.list = metadata_list) |
| 53 | +#' |
| 54 | +#' # Direct arguments override .list values |
| 55 | +#' base_config <- list(theme = "dark", debug = TRUE) |
| 56 | +#' write_yaml_metadata_block( |
| 57 | +#' debug = FALSE, # This overrides debug = TRUE from base_config |
| 58 | +#' author = "John", |
| 59 | +#' .list = base_config |
| 60 | +#' ) |
| 61 | +#' |
| 62 | +#' # Then use in Quarto with conditional content: |
| 63 | +#' # ::: {.content-visible when-meta="admin"} |
| 64 | +#' # Admin-only content here |
| 65 | +#' # ::: |
| 66 | +#' } |
| 67 | +#' |
| 68 | +#' @section Quarto Usage: |
| 69 | +#' To use this function in a Quarto document, create an R code chunk with |
| 70 | +#' the `output: asis` option: |
| 71 | +#' |
| 72 | +#' ``` |
| 73 | +#' ```{r} |
| 74 | +#' #| output: asis |
| 75 | +#' write_yaml_metadata_block(admin = TRUE, version = "1.0") |
| 76 | +#' ``` |
| 77 | +#' ``` |
| 78 | +#' |
| 79 | +#' Without the `output: asis` option, the YAML metadata block will be |
| 80 | +#' displayed as text rather than processed as metadata by Quarto. |
| 81 | +#' |
| 82 | +#' |
| 83 | +#' @export |
| 84 | +write_yaml_metadata_block <- function(..., .list = NULL) { |
| 85 | + meta <- list(...) |
| 86 | + if (!is.null(.list)) { |
| 87 | + meta <- merge_list(.list, list(...)) |
| 88 | + } |
| 89 | + if (length(meta) == 0) { |
| 90 | + return() |
| 91 | + } |
| 92 | + res <- as_yaml(meta) |
| 93 | + yaml_block <- paste0("---\n", res, "---\n") |
| 94 | + knitr::asis_output(yaml_block) |
| 95 | +} |
0 commit comments