Skip to content

Commit c8fa252

Browse files
authored
Merge pull request #28 from EmilHvitfeldt/addin
add chunk addin
2 parents b3054f2 + b8a7dd3 commit c8fa252

File tree

7 files changed

+241
-1
lines changed

7 files changed

+241
-1
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ VignetteBuilder:
3535
knitr
3636
Encoding: UTF-8
3737
LazyData: true
38-
RoxygenNote: 7.1.0
38+
RoxygenNote: 7.1.1

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ S3method(mask_rx,default)
1111
S3method(mask_rx,with_flair)
1212
S3method(print,with_flair)
1313
export("%>%")
14+
export(chunk_addin)
1415
export(decorate)
1516
export(decorate_chunk)
1617
export(decorate_code)

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
- `txt_style()` now accepts a `class` argument specifying a vector of classes to
66
be applied to the `<span>` of the decorated text (@gadenbuie, #18).
77

8+
- `chunk_addin()` RStudio addin have been added. add `decorate()` chunk after
9+
selected chunk when used.
10+
811
## Bugs and fixes
912

1013
* NULL document types are now treated as default html

R/chunk_addin.R

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#' Add decorate chunk after chunk
2+
#'
3+
#' Call this function as an addin to add a decorate chunk after a selected
4+
#' chunk.
5+
#'
6+
#' @export
7+
chunk_addin <- function() {
8+
9+
# Gets The active Documeent
10+
ctx <- rstudioapi::getActiveDocumentContext()
11+
12+
# Checks that a document is active
13+
if (!is.null(ctx)) {
14+
15+
# Extracts selection as a string
16+
selected_text <- ctx$selection[[1]]$text
17+
18+
# modify string
19+
selected_text <- add_flair_chunk(selected_text)
20+
21+
# replaces selection with string
22+
rstudioapi::modifyRange(ctx$selection[[1]]$range, selected_text)
23+
}
24+
}
25+
26+
add_flair_chunk <- function(x) {
27+
x <- stringr::str_split(x, "\n")[[1]]
28+
header_loc <- stringr::str_detect(x, "```\\{r")
29+
end_loc <- stringr::str_detect(x, "^```$")
30+
31+
if (!any(header_loc) || !any(end_loc)) {
32+
stop("No chunk detected")
33+
}
34+
35+
chunk_header <- x[header_loc][1]
36+
37+
chunk_header <- stringr::str_remove(chunk_header, "```\\{r *,{0,1} *")
38+
39+
chunk_header <- stringr::str_remove(chunk_header, "\\}")
40+
41+
chunk_params <- stringr::str_split(chunk_header, ", *")[[1]]
42+
43+
if (all(stringr::str_detect(chunk_params, "=")) || chunk_params == "") {
44+
stop("Chunk must be named")
45+
}
46+
47+
chunk_name <- chunk_params[!stringr::str_detect(chunk_params, "=")]
48+
49+
flair_chunk <- c(
50+
'',
51+
glue::glue('```{r [chunk_name]_flair, echo = FALSE}',
52+
.open = "[", .close = "]"),
53+
glue::glue('decorate("{chunk_name}")'),
54+
'```'
55+
)
56+
57+
chunk_params <- chunk_params[!stringr::str_detect(chunk_params, "include")]
58+
59+
chunk_params <- c(chunk_params, "include = FALSE")
60+
61+
x[which(header_loc)[1]] <- paste0("```{r ",
62+
paste(chunk_params, collapse = ", "),
63+
"}")
64+
65+
res <- c(
66+
x[seq(1, which(end_loc)[1])],
67+
flair_chunk
68+
)
69+
70+
if (which(end_loc)[1] < length(x)) {
71+
res <- c(res, x[seq(which(end_loc)[1] + 1, length(x))])
72+
}
73+
74+
stringr::str_c(res, collapse = "\n")
75+
}

inst/rstudio/addins.dcf

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Name: Add decorate flair chunk
2+
Description: Add decorate flair chunk
3+
Binding: chunk_addin
4+
Interactive: false
5+

man/chunk_addin.Rd

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-chunk_addin.R

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
test_that("add_flair_chunk works", {
2+
expect_equal(
3+
add_flair_chunk(
4+
'
5+
```{r name}
6+
mean(x)
7+
```
8+
'
9+
),
10+
'
11+
```{r name, include = FALSE}
12+
mean(x)
13+
```
14+
15+
```{r name_flair, echo = FALSE}
16+
decorate("name")
17+
```
18+
'
19+
)
20+
21+
expect_equal(
22+
add_flair_chunk(
23+
'
24+
25+
```{r name}
26+
mean(x)
27+
```
28+
29+
'
30+
),
31+
'
32+
33+
```{r name, include = FALSE}
34+
mean(x)
35+
```
36+
37+
```{r name_flair, echo = FALSE}
38+
decorate("name")
39+
```
40+
41+
'
42+
)
43+
44+
})
45+
46+
test_that("add_flair_chunk only affects first chunk", {
47+
expect_equal(
48+
add_flair_chunk(
49+
'
50+
51+
```{r name}
52+
mean(x)
53+
```
54+
55+
```{r sum}
56+
sum(x)
57+
```
58+
59+
'
60+
),
61+
'
62+
63+
```{r name, include = FALSE}
64+
mean(x)
65+
```
66+
67+
```{r name_flair, echo = FALSE}
68+
decorate("name")
69+
```
70+
71+
```{r sum}
72+
sum(x)
73+
```
74+
75+
'
76+
)
77+
78+
})
79+
80+
test_that("add_flair_chunk flips include = TRUE", {
81+
expect_equal(
82+
add_flair_chunk(
83+
'
84+
85+
```{r name, include = TRUE}
86+
mean(x)
87+
```
88+
89+
```{r sum}
90+
sum(x)
91+
```
92+
93+
'
94+
),
95+
'
96+
97+
```{r name, include = FALSE}
98+
mean(x)
99+
```
100+
101+
```{r name_flair, echo = FALSE}
102+
decorate("name")
103+
```
104+
105+
```{r sum}
106+
sum(x)
107+
```
108+
109+
'
110+
)
111+
112+
})
113+
114+
test_that("add_flair_chunk throws errors", {
115+
expect_error(
116+
add_flair_chunk(
117+
'
118+
```{r name}
119+
mean(x)
120+
'
121+
)
122+
)
123+
124+
expect_error(
125+
add_flair_chunk(
126+
'
127+
```{r}
128+
sum(x)
129+
```
130+
'
131+
)
132+
)
133+
134+
expect_error(
135+
add_flair_chunk(
136+
'
137+
```{r, eval=FALSE}
138+
sum(x)
139+
```
140+
'
141+
)
142+
)
143+
144+
})

0 commit comments

Comments
 (0)