Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/carpentries/pegboard

R6 classes for exploring the content Carpentries Lessons :triangular_ruler:
https://github.com/carpentries/pegboard

Last synced: 3 months ago
JSON representation

R6 classes for exploring the content Carpentries Lessons :triangular_ruler:

Awesome Lists containing this project

README

        

---
output: github_document
---

# {pegboard}: Parse Source Files in The Carpentries Workbench

```{r, include = FALSE}
options(width = 300)
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#|",
fig.path = "man/figures/README-",
out.width = "100%"
)
```

[![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)

> [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)
```