diff --git a/DESCRIPTION b/DESCRIPTION index 68bcf6ace0..7dc25a674e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -65,6 +65,7 @@ Authors@R: c( person("Lorenz", "Walthert", role = "ctb"), person("Lucas", "Gallindo", role = "ctb"), person("Martin", "ModrĂ¡k", role = "ctb"), + person("Michael", "Braun", role = "ctb"), person("Michael", "Chirico", role = "ctb"), person("Michael", "Friendly", role = "ctb"), person("Michal", "Bojanowski", role = "ctb"), diff --git a/NEWS.md b/NEWS.md index 6bdd6971f7..da397dea65 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## NEW FEATURES +- Added a pattern and file type (.RLatex), so R code chunks in a LaTeX document can be defined within an Rcode environment. + - It is possible to customize the sign `\times` used for the scientific notation of inline numeric output via a global option, e.g., `options(knitr.inline.times = '\\cdot ')` (thanks, @wuffi @trentks, #1563). ## BUG FIXES diff --git a/R/output.R b/R/output.R index e65c50512d..bd25d78d27 100644 --- a/R/output.R +++ b/R/output.R @@ -232,10 +232,11 @@ knit = function(input, output = NULL, tangle = FALSE, text = NULL, quiet = FALSE ext, "' in built-in pattern lists; ", 'see ?knit_patterns on how to set up customized patterns') set_pattern(pattern) - if (pattern == 'rnw' && length(sweave_lines <- which_sweave(text)) > 0) + if (pattern %in% c('rnw','rlatex') && length(sweave_lines <- which_sweave(text)) > 0) remind_sweave(if (in.file) input, sweave_lines) opts_knit$set(out.format = switch( - pattern, rnw = 'latex', tex = 'latex', html = 'html', md = 'markdown', + pattern, rnw = 'latex', tex = 'latex', html = 'html', md = 'markdown', + rlatex = 'latex', rst = 'rst', brew = 'brew', asciidoc = 'asciidoc', textile = 'textile' )) } @@ -344,7 +345,7 @@ process_file = function(text, output) { auto_out_name = function(input, ext = tolower(file_ext(input))) { base = sans_ext(input) name = if (opts_knit$get('tangle')) c(base, '.R') else - if (ext %in% c('rnw', 'snw')) c(base, '.tex') else + if (ext %in% c('rnw', 'snw', 'rlatex')) c(base, '.tex') else if (ext %in% c('rmd', 'rmarkdown', 'rhtml', 'rhtm', 'rtex', 'stex', 'rrst', 'rtextile')) c(base, '.', substring(ext, 2L)) else if (grepl('_knit_', input)) sub('_knit_', '', input) else @@ -355,6 +356,7 @@ auto_out_name = function(input, ext = tolower(file_ext(input))) { # determine output format based on file extension ext2fmt = c( rnw = 'latex', snw = 'latex', tex = 'latex', rtex = 'latex', stex = 'latex', + rlatex = 'latex', htm = 'html', html = 'html', rhtml = 'html', rhtm = 'html', md = 'markdown', markdown = 'markdown', rmd = 'markdown', rmarkdown = 'markdown', brew = 'brew', rst = 'rst', rrst = 'rst' diff --git a/R/pattern.R b/R/pattern.R index 1899c6fafa..07a578d2ce 100644 --- a/R/pattern.R +++ b/R/pattern.R @@ -49,7 +49,16 @@ all_patterns = list( chunk.end = '^###[.]\\s+end[.]rcode\\s*$', ref.chunk = '^\\s*<<(.+)>>\\s*$', inline.code = '@r +([^@]+)\\s*@', - inline.comment = '^###[.].*') + inline.comment = '^###[.].*'), + + `rlatex` = list( + chunk.begin = "^\\s*\\\\begin\\{Rcode\\}(?:\\[(.*)?\\])?\\s*(%.*)?$", + chunk.end = "^\\s*\\\\end\\{Rcode\\}\\s*(%+.*|)$", + inline.code = "\\\\Sexpr\\{([^}]+)\\}", + inline.comment = "^\\s*%.*", + header.begin = "(^|\n)\\s*\\\\documentclass[^}]+\\}", + document.begin = "\\s*\\\\begin\\{document\\}", + ref.chunk = "^\\s*\\\\begin\\{Rcode\\}\\[(.*)\\].*$") ) .sep.label = '^(#|--)+\\s*(@knitr|----+)(.*?)-*\\s*$' # pattern for code chunks in an R script @@ -128,6 +137,9 @@ pat_rst = function() set_pattern('rst') pat_asciidoc = function() set_pattern('asciidoc') #' @rdname pat_fun pat_textile = function() set_pattern('textile') +#' @rdname pat_fun +pat_rlatex = function() set_pattern('rlatex') + # helper functions @@ -146,6 +158,7 @@ detect_pattern = function(text, ext) { if (ext %in% c('rmd', 'rmarkdown', 'markdown', 'md')) return('md') if (ext %in% c('rst', 'rrst')) return('rst') if (ext %in% c('asciidoc', 'rasciidoc', 'adoc', 'radoc')) return('asciidoc') + if (ext %in% c('rlatex', 'Rlatex', 'RLatex')) return('rlatex') } for (p in names(all_patterns)) { for (i in c('chunk.begin', 'inline.code')) { diff --git a/tests/testit/test-rlatex.R b/tests/testit/test-rlatex.R new file mode 100644 index 0000000000..bc636a2225 --- /dev/null +++ b/tests/testit/test-rlatex.R @@ -0,0 +1,22 @@ +library(testit) + +assert( + 'detect_pattern() automatically detects syntax patterns', + identical(detect_pattern('<<>>='), 'rnw'), + identical(detect_pattern('<>='), 'rnw'), + identical(detect_pattern('\\begin{Rcode}'), 'rlatex'), + identical(detect_pattern('\\begin{Rcode}[foo, bar=TRUE]'), 'rlatex'), + identical(detect_pattern('asdf', 'rlatex'), 'rlatex'), + detect_pattern('foo') %==% NULL +) + + +ce = all_patterns$rlatex$chunk.end +assert( + 'patterns for rlatex', + identical(grep(ce, ' \\end{Rcode}'), 1L), # spaces before @ + identical(grep(ce, '\\end{Rcode} '), 1L), # spaces after @ + identical(grep(ce, '\\end{Rcode} %asdf'), 1L), # comments after % + identical(grep(ce, '\\end{Rcode} asdf'), integer()), # only spaces/comments allowed + identical(grep(ce, ' \\end{Rcode} a% sdf'), integer()) +)