Skip to content

Commit 997336d

Browse files
Merge pull request #233 from jonmcalder/rmd
- Allow styling of Rmd files(#233).
2 parents 3ae0989 + 27c0c53 commit 997336d

15 files changed

+245
-34
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Collate:
5454
'serialize.R'
5555
'serialized_tests.R'
5656
'style_guides.R'
57+
'style_rmd.R'
5758
'styler.R'
5859
'token-create.R'
5960
'transform.R'

R/style_rmd.R

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#' Transform code from R or Rmd files
2+
#'
3+
#' A wrapper for [utf8::transform_lines_enc()] which initiates the styling of
4+
#' either R or Rmd files by passing the relevant transformer function for each
5+
#' case.
6+
#'
7+
#' @inheritParams utf8::transform_lines_enc
8+
#' @param ... Further arguments passed to `utf8::transform_lines_enc()`.
9+
transform_code <- function(path, fun, verbose, ...) {
10+
if (grepl("\\.R$", path, ignore.case = TRUE)) {
11+
utf8::transform_lines_enc(path, fun = fun, ...)
12+
} else if (grepl("\\.Rmd$", path, ignore.case = TRUE)) {
13+
utf8::transform_lines_enc(path, fun = partial(transform_rmd, transformer_fun = fun), ...)
14+
} else {
15+
stop(path, " is not an R or Rmd file")
16+
}
17+
}
18+
19+
#' Transform Rmd contents
20+
#'
21+
#' Applies the supplied transformer function to code chunks identified within
22+
#' an Rmd file and recombines the resulting (styled) code chunks with the text
23+
#' chunks.
24+
#'
25+
#' @param lines A character vector of lines from an Rmd file
26+
#' @param transformer_fun A styler transformer function
27+
#' @importFrom purrr flatten_chr
28+
transform_rmd <- function(lines, transformer_fun) {
29+
chunks <- identify_chunks(lines)
30+
chunks$r_chunks <- map(chunks$r_chunks, transformer_fun)
31+
32+
map2(chunks$text_chunks, c(chunks$r_chunks, list(character(0))), c) %>%
33+
flatten_chr()
34+
}
35+
36+
37+
#' Identify chunks within Rmd contents
38+
#'
39+
#' Identifies the code and text chunks within an Rmd file, and returns these
40+
#' as a nested list.
41+
#'
42+
#' @param lines a character vector of lines from an Rmd file
43+
#'
44+
#' @importFrom purrr map2
45+
#' @importFrom rlang seq2
46+
identify_chunks <- function(lines) {
47+
pattern <- get_knitr_pattern(lines)
48+
if (is.null(pattern$chunk.begin) || is.null(pattern$chunk.end)) {
49+
stop("Unrecognized chunk pattern!", call. = FALSE)
50+
}
51+
52+
starts <- grep(pattern$chunk.begin, lines, perl = TRUE)
53+
ends <- grep(pattern$chunk.end, lines, perl = TRUE)
54+
55+
if (length(starts) != length(ends)) {
56+
stop("Malformed file!", call. = FALSE)
57+
}
58+
59+
r_chunks <- map2(starts, ends, ~lines[seq2(.x + 1, .y - 1)])
60+
61+
text_chunks <- map2(c(1, ends), c(starts, length(lines)), ~lines[seq2(.x, .y)])
62+
63+
lst(r_chunks, text_chunks)
64+
}
65+
66+
#' Get chunk pattern
67+
#'
68+
#' Determine a regex pattern for identifying R code chunks.
69+
#'
70+
#' @inheritParams identify_chunks
71+
get_knitr_pattern <- function(lines) {
72+
pattern <- knitr:::detect_pattern(lines, "rmd")
73+
if (!is.null(pattern)) {
74+
knitr::all_patterns[[pattern]]
75+
} else {
76+
NULL
77+
}
78+
}

R/transform.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ transform_files <- function(files, transformers) {
2727
invisible(changed)
2828
}
2929

30-
#' Transform a file an give customized message
30+
#' Transform a file and output a customized message
3131
#'
32-
#' Wraps `utf8::transform_lines_enc()` and gives customized messages.
32+
#' Wraps `utf8::transform_lines_enc()` and outputs customized messages.
3333
#' @param max_char_path The number of characters of the longest path. Determines
3434
#' the indention level of `message_after`.
3535
#' @param message_before The message to print before the path.
@@ -51,7 +51,7 @@ transform_file <- function(path,
5151
n_spaces_before_message_after <-
5252
max_char_after_message_path - char_after_path
5353
message(message_before, path, ".", appendLF = FALSE)
54-
changed <- utf8::transform_lines_enc(path, fun = fun, verbose = verbose, ...)
54+
changed <- transform_code(path, fun = fun, verbose = verbose, ...)
5555

5656
message(
5757
rep(" ", max(0, n_spaces_before_message_after)),

R/ws.R

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,6 @@ style_file <- function(path,
144144
transformers = style(...)) {
145145
withr::with_dir(
146146
dirname(path),
147-
prettify_one(transformers, basename(path))
147+
transform_files(basename(path), transformers)
148148
)
149149
}
150-
151-
#' Prettify one R file
152-
#'
153-
#' This is a helper function for style_dir.
154-
#' @inheritParams style_dir
155-
#' @param path The path to a file that should be styled.
156-
prettify_one <- function(transformers, path) {
157-
if (!grepl("\\.[Rr]$", path)) stop(path, " is not a .R file")
158-
transform_files(path, transformers)
159-
}

man/get_knitr_pattern.Rd

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/identify_chunks.Rd

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/prettify_one.Rd

Lines changed: 0 additions & 18 deletions
This file was deleted.

man/transform_code.Rd

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/transform_file.Rd

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/transform_rmd.Rd

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)