From f8898063c68611122d75b0371ab42a255f2b863e Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Wed, 4 Sep 2019 12:25:00 +0900
Subject: [PATCH 1/6] Add blank lines when multiple plots are available with
captions
---
R/hooks-md.R | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/R/hooks-md.R b/R/hooks-md.R
index 3a45fc3090..787b6dbca6 100644
--- a/R/hooks-md.R
+++ b/R/hooks-md.R
@@ -1,27 +1,37 @@
#' @rdname hook_plot
#' @export
hook_plot_md = function(x, options) {
+ add_lines = function(x) {
+ if (
+ (isTRUE(options$echo) && options$fig.show != 'hold') ||
+ is.null(options$fig.cap) || options$fig.num %in% c(1L, options$fig.cur)
+ ) {
+ return(x)
+ }
+ paste0(x, "\n\n")
+ }
# if not using R Markdown v2 or output is HTML, just return v1 output
if (is.null(to <- pandoc_to()) || is_html_output(to))
- return(hook_plot_md_base(x, options))
+ return(add_lines(hook_plot_md_base(x, options)))
if ((options$fig.show == 'animate' || is_tikz_dev(options)) && is_latex_output())
return(hook_plot_tex(x, options))
+
office_output = to %in% c('docx', 'pptx', 'rtf', 'odt')
if (need_special_plot_hook(options)) {
if (is_latex_output()) {
# Pandoc < 1.13 does not support \caption[]{} so suppress short caption
if (is.null(options$fig.scap)) options$fig.scap = NA
- return(hook_plot_tex(x, options))
+ return(add_lines(hook_plot_tex(x, options)))
}
if (office_output) {
if (options$fig.align != 'default') {
warning('Chunk options fig.align is not supported for ', to, ' output')
options$fig.align = 'default'
}
- return(hook_plot_md_pandoc(x, options))
+ return(add_lines(hook_plot_md_pandoc(x, options)))
}
}
- hook_plot_md_base(x, options)
+ add_lines(hook_plot_md_base(x, options))
}
# decide if the markdown plot hook is not enough and needs special hooks like
From b76f273a6cb35eadc9e84886cef7183b3a592c5b Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Fri, 6 Sep 2019 10:25:14 +0900
Subject: [PATCH 2/6] add test for hook_plot_md_base
---
tests/testit/test-hooks-md.R | 37 ++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/tests/testit/test-hooks-md.R b/tests/testit/test-hooks-md.R
index 3e186b010a..2f13b6d331 100644
--- a/tests/testit/test-hooks-md.R
+++ b/tests/testit/test-hooks-md.R
@@ -67,8 +67,8 @@ x = "1.png"
w = h = 1
ex = "style='margin: 0;'"
cap = "foo"
-opt <- function(w = NULL, h =NULL, ex = NULL, cap = NULL, show = 'asis', ...) {
- list(out.width = w, out.height = h, out.extra = ex, fig.cap = cap, fig.show = show, ...)
+opt <- function(w = NULL, h =NULL, ex = NULL, cap = NULL, show = 'asis', align = 'default', ...) {
+ list(out.width = w, out.height = h, out.extra = ex, fig.cap = cap, fig.show = show, fig.align = align, ...)
}
assert("Include a plot by pandoc md", {
@@ -80,3 +80,36 @@ assert("Include a plot by pandoc md", {
(hook_plot_md_pandoc(x, opt(w = w, cap = cap, ex = ex)) %==%
sprintf("![%s](1.png){width=%s %s}", cap, w, ex))
})
+
+align = 'left'
+link = 'https://example.com'
+
+hook = hook_plot_md_base
+assert("Include a plot in variety of formats with hook_plot_md_base", {
+ # width, height, and extra are null, and align is default
+ (hook(x, opt()) %==% "![](1.png)")
+ (hook(x, opt(cap = cap)) %==% sprintf("![%s](1.png)", cap))
+ (hook(x, opt(fig.link = link)) %==% sprintf("[![](1.png)](%s)", link))
+ opts_knit$set(rmarkdown.pandoc.to = 'latex')
+ (hook(x, opt(cap = '')) %==% "![](1.png) ")
+ opts_knit$set(rmarkdown.pandoc.to = 'html')
+ (hook(x, opt(cap = '')) %==% "![](1.png)")
+ # html output with caption or width
+ (hook(x, opt(align = align, cap = cap)) %==%
+ sprintf('
', align, cap, cap))
+ ## add link
+ (hook(x, opt(w = w, cap = cap, fig.link = link)) %==%
+ sprintf('', link, cap, w, cap))
+ ## fig.caption is TRUE
+ (hook(x, opt(w = w, cap = cap, fig.topcaption = TRUE)) %==%
+ sprintf('', cap, cap, w))
+ ## plot1 is FALSE
+ (hook(x, opt(w = w, cap = cap, show = 'hold', fig.cur = 2, fig.num = 2)) %==%
+ sprintf('\n%s
\n', cap, w, cap))
+ ## plot2 is FALSE
+ (hook(x, opt(w = w, cap = cap, show = 'hold', fig.cur = 1, fig.num = 2)) %==%
+ sprintf('\n
', cap, w, cap))
+ # else
+ opts_knit$restore()
+ (hook(x, opt(align = 'center')) %==% '
')
+})
From 78c0104c5a48d9516d9f54b0178d28fa36c918ca Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Fri, 6 Sep 2019 11:05:23 +0900
Subject: [PATCH 3/6] fix: echo can be TRUE, FALSE, or integers
---
R/hooks-md.R | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/R/hooks-md.R b/R/hooks-md.R
index 787b6dbca6..2ad21348bc 100644
--- a/R/hooks-md.R
+++ b/R/hooks-md.R
@@ -3,7 +3,7 @@
hook_plot_md = function(x, options) {
add_lines = function(x) {
if (
- (isTRUE(options$echo) && options$fig.show != 'hold') ||
+ (!identical(options$echo, FALSE) && options$fig.show != 'hold') ||
is.null(options$fig.cap) || options$fig.num %in% c(1L, options$fig.cur)
) {
return(x)
From eb3ed65af68e1dfea68deed8db085db3c1404699 Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Fri, 6 Sep 2019 17:50:30 +0900
Subject: [PATCH 4/6] factor out add_lines and rename it to append_blank_lines
---
R/hooks-md.R | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/R/hooks-md.R b/R/hooks-md.R
index 2ad21348bc..0fbc360ab1 100644
--- a/R/hooks-md.R
+++ b/R/hooks-md.R
@@ -1,18 +1,9 @@
#' @rdname hook_plot
#' @export
hook_plot_md = function(x, options) {
- add_lines = function(x) {
- if (
- (!identical(options$echo, FALSE) && options$fig.show != 'hold') ||
- is.null(options$fig.cap) || options$fig.num %in% c(1L, options$fig.cur)
- ) {
- return(x)
- }
- paste0(x, "\n\n")
- }
# if not using R Markdown v2 or output is HTML, just return v1 output
if (is.null(to <- pandoc_to()) || is_html_output(to))
- return(add_lines(hook_plot_md_base(x, options)))
+ return(append_blank_lines(hook_plot_md_base(x, options), options))
if ((options$fig.show == 'animate' || is_tikz_dev(options)) && is_latex_output())
return(hook_plot_tex(x, options))
@@ -21,17 +12,17 @@ hook_plot_md = function(x, options) {
if (is_latex_output()) {
# Pandoc < 1.13 does not support \caption[]{} so suppress short caption
if (is.null(options$fig.scap)) options$fig.scap = NA
- return(add_lines(hook_plot_tex(x, options)))
+ return(append_blank_lines(hook_plot_tex(x, options), options))
}
if (office_output) {
if (options$fig.align != 'default') {
warning('Chunk options fig.align is not supported for ', to, ' output')
options$fig.align = 'default'
}
- return(add_lines(hook_plot_md_pandoc(x, options)))
+ return(append_blank_lines(hook_plot_md_pandoc(x, options), options))
}
}
- add_lines(hook_plot_md_base(x, options))
+ append_blank_lines(hook_plot_md_base(x, options), options)
}
# decide if the markdown plot hook is not enough and needs special hooks like
@@ -124,6 +115,16 @@ css_text_align = function(align) {
if (align == 'default') '' else sprintf(' style="text-align: %s"', align)
}
+append_blank_lines = function(x, options) {
+ if (
+ (!identical(options$echo, FALSE) && options$fig.show != 'hold') ||
+ is.null(options$fig.cap) || options$fig.num == options$fig.cur
+ ) {
+ return(x)
+ }
+ paste0(x, "\n\n")
+}
+
# turn a class string "a b" to c(".a", ".b") for Pandoc fenced code blocks
block_class = function(x) {
if (length(x) > 0) gsub('^[.]*', '.', unlist(strsplit(x, '\\s+')))
From 4d38103016b5e3bdd1c7be0c48a1ea4329569a0c Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Fri, 6 Sep 2019 17:50:40 +0900
Subject: [PATCH 5/6] add tests
---
tests/testit/test-hooks-md.R | 48 ++++++++++++++++++++++++++++++++----
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/tests/testit/test-hooks-md.R b/tests/testit/test-hooks-md.R
index 2f13b6d331..afbff9570f 100644
--- a/tests/testit/test-hooks-md.R
+++ b/tests/testit/test-hooks-md.R
@@ -67,8 +67,15 @@ x = "1.png"
w = h = 1
ex = "style='margin: 0;'"
cap = "foo"
-opt <- function(w = NULL, h =NULL, ex = NULL, cap = NULL, show = 'asis', align = 'default', ...) {
- list(out.width = w, out.height = h, out.extra = ex, fig.cap = cap, fig.show = show, fig.align = align, ...)
+align = 'left'
+link = 'https://example.com'
+opt <- function(
+ w = NULL, h =NULL, ex = NULL, align = 'default', cap = NULL, show = 'asis', ...
+) {
+ list(
+ out.width = w, out.height = h, out.extra = ex,
+ fig.align = align, fig.cap = cap, fig.show = show,...
+ )
}
assert("Include a plot by pandoc md", {
@@ -81,9 +88,6 @@ assert("Include a plot by pandoc md", {
sprintf("![%s](1.png){width=%s %s}", cap, w, ex))
})
-align = 'left'
-link = 'https://example.com'
-
hook = hook_plot_md_base
assert("Include a plot in variety of formats with hook_plot_md_base", {
# width, height, and extra are null, and align is default
@@ -113,3 +117,37 @@ assert("Include a plot in variety of formats with hook_plot_md_base", {
opts_knit$restore()
(hook(x, opt(align = 'center')) %==% '
')
})
+
+hook <- hook_plot_md
+assert('Check if hook_plot_md passes arguments to sub-functions', {
+ opts_knit$set(rmarkdown.pandoc.to = 'html')
+ (hook(x, opt()) %==% hook_plot_md_base(x, opt()))
+
+ opts_knit$set(rmarkdown.pandoc.to = 'latex')
+ o = opt(w = w)
+ (hook(x, o) %==% hook_plot_tex(x, o))
+
+ opts_knit$set(rmarkdown.pandoc.to = 'docx')
+ (hook(x, o) %==% hook_plot_md_pandoc(x, o))
+
+ opts_knit$set(rmarkdown.pandoc.to = 'markdown')
+ (hook(x, opt()) %==% hook_plot_md_base(x, opt()))
+ (hook(x, o) %==% hook_plot_md_base(x, o))
+})
+
+assert('Conditionally append blank lines to figures so that figure captions are displayed correctly', {
+ # Append when echo is FALSE or fig.show is hold and the current figure is not the last one
+ (append_blank_lines('a', list(echo = FALSE, fig.cap = cap, fig.num = 3, fig.cur = 1)) %==% 'a\n\n')
+ (append_blank_lines('a', list(fig.show = 'hold', fig.cap = cap, fig.num = 3, fig.cur = 1)) %==% 'a\n\n')
+
+ # Do not append when
+ ## echo is not FALSE
+ (append_blank_lines('', list(echo = TRUE)) %==% '')
+ ## fig.show is not hold
+ (append_blank_lines('', list(echo = FALSE, fig.show = 'asis')) %==% '')
+ ## fig.cap is NULL
+ (append_blank_lines('', list(echo = FALSE, fig.cap = NULL)) %==% '')
+ ## fig.num is equal to fig.cur
+ (append_blank_lines('', list(echo = FALSE, fig.cap = cap, fig.num = 1, fig.cur = 1)) %==% '')
+})
+
From e404aa865475fadb949c22206951d1a56047395d Mon Sep 17 00:00:00 2001
From: atusy <30277794+atusy@users.noreply.github.com>
Date: Fri, 6 Sep 2019 18:57:28 +0900
Subject: [PATCH 6/6] update news [skip ci]
---
NEWS.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/NEWS.md b/NEWS.md
index 2bf24ce42d..9c1449882b 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -4,6 +4,8 @@
- The chunk option `collapse = TRUE` now works as expected when the chunk option `attr.*` or `class.*` is provided. By this change, The chunk option `collapse = TRUE` forces `attr.*` and `class.*` be `NULL` except for the chunk options `attr.source` and `class.source` (thanks, @aosavi @cderv @atusy, #1902 #1906).
+- Captions disappeared when a chunk generates multiple figures continuously (thanks, @atusy, #1760)
+
# CHANGES IN knitr VERSION 1.30
## NEW FEATURES