Skip to content

Commit

Permalink
use yaml_metadata_block for preserve_yaml feature when possible (#2190)
Browse files Browse the repository at this point in the history
This fixes change in Pandoc 2.13 about `yaml_metadata_block` for `commonmark` based formats (fixes #2118)
  • Loading branch information
cderv authored Jul 21, 2021
1 parent 5273047 commit 0af6b35
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 9 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: rmarkdown
Type: Package
Title: Dynamic Documents for R
Version: 2.9.4
Version: 2.9.5
Authors@R: c(
person("JJ", "Allaire", role = "aut", email = "[email protected]"),
person("Yihui", "Xie", role = c("aut", "cre"), email = "[email protected]", comment = c(ORCID = "0000-0003-0645-5666")),
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
rmarkdown 2.10
================================================================================

- `md_document()` will now handle correctly `preserve_yaml` value for all variants and all pandoc versions (#2190).
* with `preserve_yaml = TRUE`, markdown output will keep the YAML metadata block from the Rmd file.
* with `preserve_yaml = FALSE`, markdown output will have no YAML metadata block.

This fixes a breaking change in Pandoc 2.13 regarding `gfm`, `commonmark` and `commonmark_x` which now supports `yaml_metadata_block` by default (#2118).

- New supported syntax for Shiny prerendered documents: you can now use `server: shiny` or `server: type: shiny`.

- Ability to inject additional functions into Shiny prerendered server scope using the "server-extras" context.
Expand Down
58 changes: 50 additions & 8 deletions R/md_document.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
#' see the documentation on R Markdown \link[=rmd_metadata]{metadata}.
#' @inheritParams html_document
#' @param variant Markdown variant to produce (defaults to "markdown_strict").
#' Other valid values are "commonmark", "markdown_github", "markdown_mmd",
#' markdown_phpextra", or even "markdown" (which produces pandoc markdown).
#' You can also compose custom markdown variants, see the
#' \href{https://pandoc.org/MANUAL.html}{pandoc online documentation}
#' for details.
#' Other valid values are "commonmark", "gfm", "commonmark_x", "markdown_mmd",
#' markdown_phpextra", "markdown_github", or even "markdown" (which produces
#' pandoc markdown). You can also compose custom markdown variants, see the
#' \href{https://pandoc.org/MANUAL.html}{pandoc online documentation} for
#' details.
#' @param preserve_yaml Preserve YAML front matter in final document.
#' @param fig_retina Scaling to perform for retina displays. Defaults to
#' \code{NULL} which performs no scaling. A setting of 2 will work for all
Expand Down Expand Up @@ -48,8 +48,9 @@ md_document <- function(variant = "markdown_strict",
pandoc_args = NULL,
ext = ".md") {


# base pandoc options for all markdown output
args <- c(if (variant != "markdown" || preserve_yaml) "--standalone")
args <- c(if (preserve_yaml) "--standalone")

# table of contents
args <- c(args, pandoc_toc_args(toc, toc_depth))
Expand All @@ -60,8 +61,11 @@ md_document <- function(variant = "markdown_strict",
# pandoc args
args <- c(args, pandoc_args)

# add post_processor for yaml preservation
post_processor <- if (preserve_yaml && variant != 'markdown') {
# variants
variant <- adapt_md_variant(variant, preserve_yaml)

# add post_processor for yaml preservation if not supported by pandoc
post_processor <- if (preserve_yaml && !grepl('yaml_metadata_block', variant, fixed = TRUE)) {
function(metadata, input_file, output_file, clean, verbose) {
input_lines <- read_utf8(input_file)
partitioned <- partition_yaml_front_matter(input_lines)
Expand All @@ -88,3 +92,41 @@ md_document <- function(variant = "markdown_strict",
post_processor = post_processor
)
}

adapt_md_variant <- function(variant, preserve_yaml) {
variant_base <- gsub("^([^+-]*).*", "\\1", variant)
variant_extensions <- gsub(sprintf("^%s", variant_base), "", variant)

set_extension <- function(format, ext, add = TRUE) {
ext <- paste0(ifelse(add, "+", "-"), ext)
if (grepl(ext, format, fixed = TRUE)) return(format)
paste0(format, ext, collapse = "")
}

add_yaml_block_ext <- function(extensions, preserve_yaml) {
set_extension(variant_extensions, "yaml_metadata_block", preserve_yaml)
}

# yaml_metadata_block extension
variant_extensions <- switch(
variant_base,
gfm =,
commonmark =,
commonmark_x = {
if (pandoc_available(2.13)) {
add_yaml_block_ext(variant_extensions, preserve_yaml)
} else {
variant_extensions
}
},
markdown =,
markdown_phpextra =,
markdown_github =,
markdown_mmd =,
markdown_strict = add_yaml_block_ext(variant_extensions, preserve_yaml),
# do not modified for unknown (yet) md variant
variant_extensions
)

paste0(variant_base, variant_extensions, collapse = "")
}
5 changes: 5 additions & 0 deletions tests/testthat/_snaps/md_document/yaml-block-markdown-meta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: test
---

content
1 change: 1 addition & 0 deletions tests/testthat/_snaps/md_document/yaml-block-markdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: test
---

content
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: test
---

content
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: test
---

content
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: test
---

content
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
75 changes: 75 additions & 0 deletions tests/testthat/test-md_document.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
local_edition(3)

test_that("adapt_md_variant() adds extensions to markdown variants", {
expect_identical(adapt_md_variant("markdown", TRUE), "markdown+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_phpextra", TRUE), "markdown_phpextra+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_mmd", TRUE), "markdown_mmd+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_strict", TRUE), "markdown_strict+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_github", TRUE), "markdown_github+yaml_metadata_block")

expect_identical(adapt_md_variant("markdown", FALSE), "markdown-yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_phpextra", FALSE), "markdown_phpextra-yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_mmd", FALSE), "markdown_mmd-yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_strict", FALSE), "markdown_strict-yaml_metadata_block")
expect_identical(adapt_md_variant("markdown_github", FALSE), "markdown_github-yaml_metadata_block")

expect_identical(adapt_md_variant("markdown+yaml_metadata_block", TRUE), "markdown+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown-yaml_metadata_block", TRUE), "markdown-yaml_metadata_block+yaml_metadata_block")
expect_identical(adapt_md_variant("markdown+yaml_metadata_block", FALSE), "markdown+yaml_metadata_block-yaml_metadata_block")
expect_identical(adapt_md_variant("markdown-yaml_metadata_block", FALSE), "markdown-yaml_metadata_block")

# ignore correctly unsupported variants
expect_identical(adapt_md_variant("markdown_new", TRUE), "markdown_new")
expect_identical(adapt_md_variant("markdown_new", FALSE), "markdown_new")
})

test_that("adapt_md_variant() ignored unknown variants", {
expect_identical(adapt_md_variant("markdown_new", TRUE), "markdown_new")
expect_identical(adapt_md_variant("markdown_new", FALSE), "markdown_new")
})

test_that("adapt_md_variant() with special variants (pandoc >= 2.13)", {
skip_if_not_pandoc('2.13')
expect_identical(adapt_md_variant("commonmark", TRUE), "commonmark+yaml_metadata_block")
expect_identical(adapt_md_variant("gfm", TRUE), "gfm+yaml_metadata_block")
expect_identical(adapt_md_variant("commonmark_x", TRUE), "commonmark_x+yaml_metadata_block")
expect_identical(adapt_md_variant("commonmark", FALSE), "commonmark-yaml_metadata_block")
expect_identical(adapt_md_variant("gfm", FALSE), "gfm-yaml_metadata_block")
expect_identical(adapt_md_variant("commonmark_x", FALSE), "commonmark_x-yaml_metadata_block")

expect_identical(adapt_md_variant("gfm+yaml_metadata_block", TRUE), "gfm+yaml_metadata_block")
expect_identical(adapt_md_variant("gfm-yaml_metadata_block", TRUE), "gfm-yaml_metadata_block+yaml_metadata_block")
expect_identical(adapt_md_variant("gfm+yaml_metadata_block", FALSE), "gfm+yaml_metadata_block-yaml_metadata_block")
expect_identical(adapt_md_variant("gfm-yaml_metadata_block", FALSE), "gfm-yaml_metadata_block")

})

test_that("adapt_md_variant() with special variants (pandoc < 2.13)", {
skip_if_pandoc('2.13')
expect_identical(adapt_md_variant("commonmark", TRUE), "commonmark")
expect_identical(adapt_md_variant("gfm", TRUE), "gfm")
expect_identical(adapt_md_variant("commonmark_x", TRUE), "commonmark_x")
expect_identical(adapt_md_variant("commonmark", FALSE), "commonmark")
expect_identical(adapt_md_variant("gfm", FALSE), "gfm")
expect_identical(adapt_md_variant("commonmark_x", FALSE), "commonmark_x")
})

test_that("md_document() can preserve yaml", {
skip_on_cran() # avoid pandoc issue on CRAN
expect_snapshot_md <- function(variant, preserve_yaml) {
rmd <- local_rmd_file(c("---", "title: test", "---", "", "content"))
res <- render(rmd, md_document(variant, preserve_yaml = preserve_yaml), quiet = TRUE)
expect_snapshot_file(res, sprintf("yaml-block-%s%s.md", variant, if (preserve_yaml) "-meta" else ""))
}
expect_snapshot_md("markdown", preserve_yaml = FALSE)
expect_snapshot_md("markdown_phpextra", preserve_yaml = FALSE)
expect_snapshot_md("markdown_mmd", preserve_yaml = FALSE)
expect_snapshot_md("markdown_strict", preserve_yaml = FALSE)
expect_snapshot_md("markdown_github", preserve_yaml = FALSE)
expect_snapshot_md("markdown", preserve_yaml = TRUE)
expect_snapshot_md("markdown_phpextra", preserve_yaml = TRUE)
expect_snapshot_md("markdown_mmd", preserve_yaml = TRUE)
expect_snapshot_md("markdown_strict", preserve_yaml = TRUE)
expect_snapshot_md("markdown_github", preserve_yaml = TRUE)
})

0 comments on commit 0af6b35

Please sign in to comment.