-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
README.Rmd
162 lines (129 loc) · 5.62 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
---
output: github_document
---
# {pegboard}: Parse Source Files in The Carpentries Workbench <img src='man/figures/logo.png' align='right' alt='' width=120 />
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
options(width = 300)
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#|",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
<!-- badges: start -->
[![pegboard status badge](https://carpentries.r-universe.dev/badges/pegboard)](https://carpentries.r-universe.dev)
[![R-CMD-check status](https://github.com/carpentries/pegboard/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/carpentries/pegboard/actions/workflows/R-CMD-check.yaml)
[![Codecov test coverage](https://codecov.io/gh/carpentries/pegboard/branch/main/graph/badge.svg)](https://codecov.io/gh/carpentries/pegboard?branch=main)
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental)
[![CRAN status](https://www.r-pkg.org/badges/version/pegboard)](https://CRAN.R-project.org/package=pegboard)
<!-- badges: end -->
> [pegboard] is tempered hardboard which is pre-drilled with evenly spaced
> holes. The holes are used to accept pegs or hooks to support various items,
> such as tools in a workshop.
>
> https://en.wikipedia.org/wiki/Pegboard
The {pegboard} package is part of [The Carpentries
Workbench](https://carpentries.github.io/workbench/) and it's main
functionality is to parse Markdown and R Markdown documents into XML
representations (via [{tinkr}](https://docs.ropensci.org/tinkr/)). By using XML,
we are able to easily arrange and parse the elements of the lessons which makes
two things possible:
- parse and validate the lessons for structural markdown elements
- translate markdown syntax of Carpentries-style materials from the
[styles lesson infrastructure
(Jekyll-based)](https://github.com/carpentries/styles) to The Workbench
(Pandoc-based) (see the [lesson transition
tool](https://github.com/carpentries/lesson-transition#readme) for details)
There are two [{R6}](https://cran.r-project.org/package=R6) objects in the
package:
- Episode: stores the xml content of a single Markdown or R Markdown file.
This extends the the [`tinkr::yarn`
class](https://docs.ropensci.org/tinkr/reference/yarn.html). See
`vignette("intro-episode", package = "pegboard")` for more info.
- Lesson: stores all publishable markdown content as `Episodes` within a
lesson. See `vignette("intro-episode", package = "pegboard")` for more info.
One simple usage is getting a summary of the content of an episode. Let's
investigate the contents of [the "Episode Structure"
episode](https://carpentries.github.io/sandpaper-docs/episodes.html) of the
Workbench documentation:
```{r}
library("pegboard")
library("withr")
# Download the file we need ------------------------------------
src <- "https://raw.githubusercontent.com/carpentries/sandpaper-docs/main/episodes/episodes.Rmd"
tmp <- local_tempfile(fileext = ".Rmd")
download.file(src, tmp)
# Load episode
ep <- Episode$new(tmp)
# Summary -------------------------------------------------------------
# confirm that we are using sandpaper and get a summary of the contents
ep$confirm_sandpaper()$summary()
# Validation ----------------------------------------------------------
# NOTE: a lot of invalid links because files do not exist outside of
# the lesson context
lnk <- ep$validate_links()
str(lnk, max.level = 1)
hdg <- ep$validate_headings()
str(hdg, max.level = 1)
div <- ep$validate_divs()
str(div, max.level = 1)
```
## Installation
{pegboard} is not currently on CRAN, but it can be installed from our
[Carpentries Universe](https://carpentries.r-universe.dev/ui#builds)
(updated every hour) with the following commands:
``` r
options(repos = c(
carpentries = "https://carpentries.r-universe.dev/",
CRAN = "https://cran.rstudio.com/"
))
install.packages("pegboard")
```
## Example
To use {pegboard} in the context of The Workbench, you will need to have a
lesson handy. If you don't have one, you can use the `get_lesson()` function,
which will use [{gert}](https://r-lib.github.io/gert/) to clone a lesson
repository to your computer.
(NOTE: this file was last run on `r Sys.time()`)
```{r example, message = FALSE}
library("pegboard")
library("purrr")
library("xml2")
library("fs")
d <- fs::file_temp(pattern = "PBREADME")
rng <- get_lesson("swcarpentry/r-novice-gapminder", path = d, jekyll = FALSE)
rng
# Get a summary of all the elements in each episode
rng$summary()
# Validate lesson elements
rng$validate_links()
rng$validate_divs()
rng$validate_headings() # this is not run by default in sandpaper lessons
```
### Manipulation
The XML contents of the lesson are contained within the `$body` element of the
Episode object and anything you do to that XML document is retained within the
object itself (see the [{tinkr} documentation](https://docs.ropensci.org/tinkr)
for more details):
```{r}
ep1 <- rng$episodes[[1]]
ep1$body
ep1$head(20) # show the first 20 lines of the file
new_content <- r"{
#### NEW CONTENT
Hello! This is **new markdown content** generated via the
[{pegboard}](https://carpentries.github.io/pegboard) package that will
appear above the objectives block!
}"
ep1$add_md(new_content, where = 0L)
ep1$head(20) # the new content has been added to the top
ep1$headings[[1]] # the first heading is level 4. Let's change that using {xml2}
xml2::xml_set_attr(ep1$headings[[1]], "level", "2")
ep1$head(20)
ep1$headings[[1]] # the first heading is now level 2
# write the file
ep1$write(fs::path_dir(ep1$path), format = "Rmd")
readLines(ep1$path, 20)
```