Skip to content

Commit

Permalink
tweak after #1335 @ijlyttle
Browse files Browse the repository at this point in the history
  • Loading branch information
yihui committed Dec 13, 2016
1 parent 81ce0ae commit 5b32862
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 36 deletions.
6 changes: 4 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGES IN knitr VERSION 1.16 (unreleased)

## NEW FEATURES

- adds two new options, `class.output` and `class.source` to apply additional HTML classes to output and source chunks, which can be useful for R Markdown documents with HTML output formats since you can define custom CSS styles for these classes (thanks, @ijlyttle #1335 and @AmeliaMN #1333)

## MAJOR CHANGES

- a warning will be emitted when the chunk option `fig.show='hold'` and the output format is Word (https://github.com/rstudio/bookdown/issues/249); `fig.show='hold'` will be changed to `'asis'` at the same time
Expand All @@ -10,8 +14,6 @@

## NEW FEATURES

- adds two new options, `class.output` and `class.source` to help you manage the appearance of output and source chunks. This can be useful in the context of `rmarkdown::render()` using `rmarkdown::html_document()` (@ijlyttle) # This note is aspirational for the moment - it's here so I can start a pull request.

- added a new hook function `hook_pngquant()` that can call `pngquant` to optimize PNG images (thanks, @slowkow, #1320)

## BUG FIXES
Expand Down
50 changes: 16 additions & 34 deletions R/hooks-md.R
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ css_text_align = function(align) {
if (align == 'default') '' else sprintf(' style="text-align: %s"', align)
}

# helper function to manage HTML classes; turn "a b" to "{.a .b}" for Pandoc
# fenced code blocks
block_class = function(x){
if (length(x) == 0) return()
classes = unlist(strsplit(x, '\\s+'))
.classes = paste0('.', classes, collapse = ' ')
paste0('{', .classes, '}')
}

#' @rdname output_hooks
#' @export
#' @param strict whether to use strict markdown or reST syntax; for markdown: if
Expand All @@ -107,31 +116,8 @@ render_markdown = function(strict = FALSE, fence_char = '`') {
set_html_dev()
opts_knit$set(out.format = 'markdown')
fence = paste(rep(fence_char, 3), collapse = '')
# helper function to manage classes
block_class = function(x){

classes = unlist(strsplit(x, split = ' '))
str_class = paste0('.', classes, collapse = ' ')
block_class = paste0('{', str_class, '}')

block_class
}
# four spaces lead to <pre></pre>
hook.t = function(x, options) {
if (strict) {
paste('\n', indent_block(x), '', sep = '\n')
} else {
x = paste(c('', x), collapse = '\n')
r = paste0('\n', fence_char, '{3,}')
if (grepl(r, x)) {
l = attr(gregexpr(r, x)[[1]], 'match.length')
l = max(l)
if (l >= 4) fence = paste(rep(fence_char, l), collapse = '')
}
paste0('\n\n', fence, x, fence, '\n\n')
}
}
hook.t.output = function(x, options) {
hook.t = function(x, options, class = NULL) {
# this code-block duplicated from hook.t()
if (strict) {
paste('\n', indent_block(x), '', sep = '\n')
Expand All @@ -143,21 +129,17 @@ render_markdown = function(strict = FALSE, fence_char = '`') {
l = max(l)
if (l >= 4) fence = paste(rep(fence_char, l), collapse = '')
}

# the rest is 'new'
class_header = NULL
if (!is.null(options$class.output)){
class_header = block_class(options$class.output)
}

paste0('\n\n', fence, class_header, x, fence, '\n\n')
paste0('\n\n', fence, block_class(class), x, fence, '\n\n')
}
}
hook.o = function(x, options) {
hook.t(x, options, options$class.output)
}
hook.r = function(x, options) {
language = tolower(options$engine)
if (language == 'node') language = 'javascript'
if (!options$highlight) language = 'text'
if (!is.null(options$class.source)){
if (!is.null(options$class.source)) {
language = block_class(c(language, options$class.source))
}
paste0('\n\n', fence, language, '\n', x, fence, '\n\n')
Expand All @@ -167,7 +149,7 @@ render_markdown = function(strict = FALSE, fence_char = '`') {
x = hilight_source(x, 'markdown', options)
(if (strict) hook.t else hook.r)(paste(c(x, ''), collapse = '\n'), options)
},
output = hook.t.output, warning = hook.t, error = hook.t, message = hook.t,
output = hook.o, warning = hook.t, error = hook.t, message = hook.t,
inline = function(x) {
fmt = pandoc_to()
fmt = if (length(fmt) == 1L) 'latex' else 'html'
Expand Down
7 changes: 7 additions & 0 deletions tests/testit/test-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,10 @@ assert(
restore_raw_output(pre$value, pre$chunks) %==%
'<em>hello</em>\n<special>content</special> *protect* me!\n<em>world</em>'
)

assert(
'block_class() turns a character vector into Pandoc attributes for code block classes',
block_class(NULL) %==% NULL, block_class('a') %==% '{.a}',
block_class('a b') %==% '{.a .b}',
block_class(c('a', 'b')) %==% '{.a .b}'
)

0 comments on commit 5b32862

Please sign in to comment.