Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue 2116] - New chunk option to add separators to subfloat environment #2140

Merged
merged 19 commits into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Duplicate chunk label error will now be thrown with code chunks using `code` or `file` chunk options (thanks, @mine-cetinkaya-rundel, #2126).

- Simplified R Markdown's inline code parser (thanks, @atusy, #2143).

- By following suggestions of @jakubkaczor, a new chunk option called `fig.subsep` was added. This option is focused on improving Latex sub-figures arrangement (see Latex [sub-figures section in RMarkdow cookbook](https://bookdown.org/yihui/rmarkdown-cookbook/latex-subfigure.html)). This option is available only for PDF output (and, will be ignored in other output formats). With this option, you can add Latex commands between (and around) each sub-figure (or each `\subfloat` Latex environment).

# CHANGES IN knitr VERSION 1.39

## MAJOR CHANGES
Expand Down
47 changes: 47 additions & 0 deletions R/hooks-latex.R
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,53 @@ hook_plot_tex = function(x, options) {
sprintf('height=%s', options$out.height),
options$out.extra), collapse = ',')

# If the chunk have sub-figures, check if we need to add a subfloat separator
# between each sub-figure.
subsep = options$fig.subsep
if (any(is.na(subsep))) {
# Considering the intention of `fig.subsep`, NA values should not be found.
# If they are, we should warn the user about this mistake.
stop("Found `NA` values in `fig.subsep` chunk option!")
}

if (usesub && !is.null(subsep)) {
# User can provide a single separator, or, a vector of multiple separators.
# Number of elements in this vector can vary from `fig.num - 1` to `fig.num + 1`.
n_subsep = length(subsep)
subsep_out_of_boundaries = !( n_subsep == 1L || n_subsep %in% (-1:1 + fig.num) )
# If the length of `fig.subsep` does not comply with these boundaries, stop the user.
if (subsep_out_of_boundaries) {
message = paste0(
"`fig.subsep` should be a single character value",
", or, a character vector with number of elements ranging from ",
sprintf("%d to %d", fig.num - 1, fig.num + 1)
)
message = sprintf("%s. But currently, `fig.subsep` have %d elements.`", message, n_subsep)
stop(message)
}
# If `fig.subsep` is a single separator, this separator will be added
# to all the plots, except the first in the set.
if (n_subsep == 1L && !plot1) {
sub1 = paste(subsep, sub1, sep = '\n')
}

# If user provides a vector with `fig.num - 1` or `fig.num` elements, use this case:
if (n_subsep %in% (fig.num + -1:0)) {
sub1 = paste(subsep[fig.cur], sub1, sep = '\n')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is buggy when n_subsep == fig.num - 1, because fig.cur ranges from 1 to fig.num (when fig.cur == fig.num, subsep[fig.cur] will be out of bound). For this case, we should conditionally add subsep to sub1 when !plot1. I've fixed the problem in my changes.

}

# If user provides a vector with more than `fig.num` elements, use the two cases below:
if (n_subsep > fig.num && !plot2) {
sub1 = paste(subsep[fig.cur], sub1, sep = '\n')
}
if (n_subsep > fig.num && plot2) {
# If is the last plot in set, then, prefix the current subfloat envir with
# the current separator, and, postfix-it with the next/last separator.
sub1 = paste(subsep[fig.cur], sub1, sep = '\n')
sub2 = paste(sub2, subsep[fig.cur + 1L], sep = "\n")
}
}

paste0(
fig1, align1, sub1, resize1,
if (tikz) {
Expand Down