Skip to contents

Wrapper around an XML representation of a Markdown document. It contains four publicly accessible slots: path, yaml, body, and ns.

Details

This class is a fancy wrapper around the results of to_xml() and has methods that make it easier to add, analyze, remove, or write elements of your markdown document.

Note

this requires the sourcepos attribute to be recorded when the object is initialised. See protect_unescaped() for details.

Public fields

path

[character] path to file on disk

yaml

[character] text block at head of file

body

[xml_document] an xml document of the (R)Markdown file.

ns

[xml_document] an xml namespace object defining "md" to commonmark.

Methods


Method new()

Create a new yarn document

Usage

yarn$new(path = NULL, encoding = "UTF-8", sourcepos = FALSE, ...)

Arguments

path

[character] path to a markdown episode file on disk

encoding

[character] encoding passed to readLines()

sourcepos

passed to commonmark::markdown_xml(). If TRUE, the source position of the file will be included as a "sourcepos" attribute. Defaults to FALSE.

...

arguments passed on to to_xml().

Returns

A new yarn object containing an XML representation of a (R)Markdown file.

Examples

path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
ex1
path2 <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex2 <- tinkr::yarn$new(path2)
ex2


Method reset()

reset a yarn document from the original file

Usage

yarn$reset()

Examples


path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
# OH NO
ex1$body
ex1$body <- xml2::xml_missing()
ex1$reset()
ex1$body


Method write()

Write a yarn document to Markdown/R Markdown

Usage

yarn$write(path = NULL, stylesheet_path = stylesheet())

Arguments

path

path to the file you want to write

stylesheet_path

path to the xsl stylesheet to convert XML to markdown.

Examples

path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
ex1
tmp <- tempfile()
try(readLines(tmp)) # nothing in the file
ex1$write(tmp)
head(readLines(tmp)) # now a markdown file
unlink(tmp)


Method show()

show the markdown contents on the screen

Usage

yarn$show(stylesheet_path = stylesheet())

Arguments

stylesheet_path

path to the xsl stylesheet to convert XML to markdown.

Returns

a character vector with one line for each line in the output

Examples

path <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex2 <- tinkr::yarn$new(path)
ex2$head(5)
ex2$tail(5)
ex2$show()


Method head()

show the head of the markdown contents on the screen

Usage

yarn$head(n = 6L, stylesheet_path = stylesheet())

Arguments

n

the number of elements to show from the top. Negative numbers

stylesheet_path

path to the xsl stylesheet to convert XML to markdown. exclude lines from the bottom

Returns

a character vector with n elements


Method tail()

show the tail of the markdown contents on the screen

Usage

yarn$tail(n = 6L, stylesheet_path = stylesheet())

Arguments

n

the number of elements to show from the bottom. Negative numbers

stylesheet_path

path to the xsl stylesheet to convert XML to markdown. exclude lines from the top

Returns

a character vector with n elements


Method add_md()

add an arbitrary Markdown element to the document

Usage

yarn$add_md(md, where = 0L)

Arguments

md

a string of markdown formatted text.

where

the location in the document to add your markdown text. This is passed on to xml2::xml_add_child(). Defaults to 0, which indicates the very top of the document.

Examples

path <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex <- tinkr::yarn$new(path)
# two headings, no lists
xml2::xml_find_all(ex$body, "md:heading", ex$ns)
xml2::xml_find_all(ex$body, "md:list", ex$ns)
ex$add_md(
  "# Hello\n\nThis is *new* formatted text from `{tinkr}`!",
  where = 1L
)$add_md(
  " - This\n - is\n - a new list",
  where = 2L
)
# three headings
xml2::xml_find_all(ex$body, "md:heading", ex$ns)
xml2::xml_find_all(ex$body, "md:list", ex$ns)
tmp <- tempfile()
ex$write(tmp)
readLines(tmp, n = 20)


Method protect_math()

Protect math blocks from being escaped

Usage

yarn$protect_math()

Examples

path <- system.file("extdata", "math-example.md", package = "tinkr")
ex <- tinkr::yarn$new(path)
ex$tail() # math blocks are escaped :(
ex$protect_math()$tail() # math blocks are no longer escaped :)


Method protect_curly()

Protect curly phrases {likethat} from being escaped

Usage

yarn$protect_curly()

Examples

path <- system.file("extdata", "basic-curly.md", package = "tinkr")
ex <- tinkr::yarn$new(path)
ex$protect_curly()$head()


Method protect_unescaped()

Protect unescaped square braces from being escaped.

This is applied by default when you use yarn$new(sourcepos = TRUE).

Usage

yarn$protect_unescaped()

Examples

path <- system.file("extdata", "basic-curly.md", package = "tinkr")
ex <- tinkr::yarn$new(path, sourcepos = TRUE, unescaped = FALSE)
ex$tail()
ex$protect_unescaped()$tail()


Method clone()

The objects of this class are cloneable with this method.

Usage

yarn$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples


## ------------------------------------------------
## Method `yarn$new`
## ------------------------------------------------

path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
ex1
#> <yarn>
#>   Public:
#>     add_md: function (md, where = 0L) 
#>     body: xml_document, xml_node
#>     clone: function (deep = FALSE) 
#>     head: function (n = 6L, stylesheet_path = stylesheet()) 
#>     initialize: function (path = NULL, encoding = "UTF-8", sourcepos = FALSE, 
#>     ns: http://commonmark.org/xml/1.0
#>     path: /usr/local/lib/R/site-library/tinkr/extdata/example1.md
#>     protect_curly: function () 
#>     protect_math: function () 
#>     protect_unescaped: function () 
#>     reset: function () 
#>     show: function (stylesheet_path = stylesheet()) 
#>     tail: function (n = 6L, stylesheet_path = stylesheet()) 
#>     write: function (path = NULL, stylesheet_path = stylesheet()) 
#>     yaml: --- title: "What have these birds been studied for? Quer ...
#>   Private:
#>     encoding: UTF-8
#>     md_lines: function (path = NULL, stylesheet = NULL) 
#>     sourcepos: FALSE
path2 <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex2 <- tinkr::yarn$new(path2)
ex2
#> <yarn>
#>   Public:
#>     add_md: function (md, where = 0L) 
#>     body: xml_document, xml_node
#>     clone: function (deep = FALSE) 
#>     head: function (n = 6L, stylesheet_path = stylesheet()) 
#>     initialize: function (path = NULL, encoding = "UTF-8", sourcepos = FALSE, 
#>     ns: http://commonmark.org/xml/1.0
#>     path: /usr/local/lib/R/site-library/tinkr/extdata/example2.Rmd
#>     protect_curly: function () 
#>     protect_math: function () 
#>     protect_unescaped: function () 
#>     reset: function () 
#>     show: function (stylesheet_path = stylesheet()) 
#>     tail: function (n = 6L, stylesheet_path = stylesheet()) 
#>     write: function (path = NULL, stylesheet_path = stylesheet()) 
#>     yaml: --- title: "Untitled" author: "M. Salmon" date: "Septemb ...
#>   Private:
#>     encoding: UTF-8
#>     md_lines: function (path = NULL, stylesheet = NULL) 
#>     sourcepos: FALSE

## ------------------------------------------------
## Method `yarn$reset`
## ------------------------------------------------


path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
# OH NO
ex1$body
#> {xml_document}
#> <document xmlns="http://commonmark.org/xml/1.0">
#>  [1] <paragraph>\n  <text xml:space="preserve">In the </text>\n  <link destin ...
#>  [2] <heading level="3">\n  <text xml:space="preserve">Getting a list of 50 s ...
#>  [3] <paragraph>\n  <text xml:space="preserve">For more details about the fol ...
#>  [4] <code_block info="r" xml:space="preserve" name=""># polygon for filterin ...
#>  [5] <paragraph>\n  <text xml:space="preserve">For the sake of simplicity, we ...
#>  [6] <code_block info="r" xml:space="preserve" name="">species &lt;- ebd %&gt ...
#>  [7] <paragraph>\n  <text xml:space="preserve">The species are Carrion Crow,  ...
#>  [8] <heading level="3">\n  <text xml:space="preserve">Querying the scientifi ...
#>  [9] <paragraph>\n  <text xml:space="preserve">Just like rOpenSci has a taxon ...
#> [10] <paragraph>\n  <text xml:space="preserve">We shall use </text>\n  <code  ...
#> [11] <paragraph>\n  <text xml:space="preserve">We first define a function ret ...
#> [12] <paragraph>\n  <text xml:space="preserve">We use </text>\n  <code xml:sp ...
#> [13] <code_block info="r" xml:space="preserve" name="">.get_papers &lt;- func ...
#> [14] <code_block xml:space="preserve" name="">##  [1] "Great spotted cuckoo n ...
#> [15] <paragraph>\n  <text xml:space="preserve">If we were working on a scient ...
#> [16] <paragraph>\n  <text xml:space="preserve">We then apply this function to ...
#> [17] <code_block info="r" xml:space="preserve" name="">get_papers &lt;- ratel ...
#> [18] <code_block xml:space="preserve" name="">## [1] 522\n</code_block>
#> [19] <code_block info="r" xml:space="preserve" name="">all_papers &lt;- uniqu ...
#> [20] <code_block xml:space="preserve" name="">## [1] 378\n</code_block>
#> ...
ex1$body <- xml2::xml_missing()
ex1$reset()
ex1$body
#> {xml_document}
#> <document xmlns="http://commonmark.org/xml/1.0">
#>  [1] <paragraph>\n  <text xml:space="preserve">In the </text>\n  <link destin ...
#>  [2] <heading level="3">\n  <text xml:space="preserve">Getting a list of 50 s ...
#>  [3] <paragraph>\n  <text xml:space="preserve">For more details about the fol ...
#>  [4] <code_block info="r" xml:space="preserve" name=""># polygon for filterin ...
#>  [5] <paragraph>\n  <text xml:space="preserve">For the sake of simplicity, we ...
#>  [6] <code_block info="r" xml:space="preserve" name="">species &lt;- ebd %&gt ...
#>  [7] <paragraph>\n  <text xml:space="preserve">The species are Carrion Crow,  ...
#>  [8] <heading level="3">\n  <text xml:space="preserve">Querying the scientifi ...
#>  [9] <paragraph>\n  <text xml:space="preserve">Just like rOpenSci has a taxon ...
#> [10] <paragraph>\n  <text xml:space="preserve">We shall use </text>\n  <code  ...
#> [11] <paragraph>\n  <text xml:space="preserve">We first define a function ret ...
#> [12] <paragraph>\n  <text xml:space="preserve">We use </text>\n  <code xml:sp ...
#> [13] <code_block info="r" xml:space="preserve" name="">.get_papers &lt;- func ...
#> [14] <code_block xml:space="preserve" name="">##  [1] "Great spotted cuckoo n ...
#> [15] <paragraph>\n  <text xml:space="preserve">If we were working on a scient ...
#> [16] <paragraph>\n  <text xml:space="preserve">We then apply this function to ...
#> [17] <code_block info="r" xml:space="preserve" name="">get_papers &lt;- ratel ...
#> [18] <code_block xml:space="preserve" name="">## [1] 522\n</code_block>
#> [19] <code_block info="r" xml:space="preserve" name="">all_papers &lt;- uniqu ...
#> [20] <code_block xml:space="preserve" name="">## [1] 378\n</code_block>
#> ...

## ------------------------------------------------
## Method `yarn$write`
## ------------------------------------------------

path <- system.file("extdata", "example1.md", package = "tinkr")
ex1 <- tinkr::yarn$new(path)
ex1
#> <yarn>
#>   Public:
#>     add_md: function (md, where = 0L) 
#>     body: xml_document, xml_node
#>     clone: function (deep = FALSE) 
#>     head: function (n = 6L, stylesheet_path = stylesheet()) 
#>     initialize: function (path = NULL, encoding = "UTF-8", sourcepos = FALSE, 
#>     ns: http://commonmark.org/xml/1.0
#>     path: /usr/local/lib/R/site-library/tinkr/extdata/example1.md
#>     protect_curly: function () 
#>     protect_math: function () 
#>     protect_unescaped: function () 
#>     reset: function () 
#>     show: function (stylesheet_path = stylesheet()) 
#>     tail: function (n = 6L, stylesheet_path = stylesheet()) 
#>     write: function (path = NULL, stylesheet_path = stylesheet()) 
#>     yaml: --- title: "What have these birds been studied for? Quer ...
#>   Private:
#>     encoding: UTF-8
#>     md_lines: function (path = NULL, stylesheet = NULL) 
#>     sourcepos: FALSE
tmp <- tempfile()
try(readLines(tmp)) # nothing in the file
#> Warning: cannot open file '/tmp/RtmpaCSEEc/file49972839dbe': No such file or directory
#> Error in file(con, "r") : cannot open the connection
ex1$write(tmp)
head(readLines(tmp)) # now a markdown file
#> [1] "---"                                                                               
#> [2] "title: \"What have these birds been studied for? Querying science outputs with R\""
#> [3] "slug: birds-science"                                                               
#> [4] "authors:"                                                                          
#> [5] "  - name: Maëlle Salmon"                                                           
#> [6] "    url: https://masalmon.eu/"                                                     
unlink(tmp)

## ------------------------------------------------
## Method `yarn$show`
## ------------------------------------------------

path <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex2 <- tinkr::yarn$new(path)
ex2$head(5)
#> ---
#> title: "Untitled"
#> author: "M. Salmon"
#> date: "September 6, 2018"
#> output: html_document
ex2$tail(5)
#> | Cyanistes caeruleus        | Eurasian Blue Tit   | 233 | 
#> | Chroicocephalus ridibundus | Black-headed Gull   | 223 | 
#> 
#> blabla
#> 
ex2$show()
#> ---
#> title: "Untitled"
#> author: "M. Salmon"
#> date: "September 6, 2018"
#> output: html_document
#> ---
#> 
#> ```{r setup, include=FALSE, eval=TRUE}
#> knitr::opts_chunk$set(echo = TRUE)
#> ```
#> 
#> ## R Markdown
#> 
#> This is an ~~R Markdown document~~. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.
#> 
#> When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
#> 
#> ```{r, eval=TRUE, echo=TRUE}
#> summary(cars)
#> ```
#> 
#> ## Including Plots
#> 
#> You can also embed plots, for example:
#> 
#> ```{python, fig.cap="pretty plot", echo=-c(1, 2), eval=TRUE}
#> plot(pressure)
#> ```
#> 
#> ```{python}
#> plot(pressure)
#> ```
#> 
#> Non-RMarkdown blocks are also considered
#> 
#> ```bash
#> echo "this is an unevaluted bash block"
#> ```
#> 
#> ```
#> This is an ambiguous code block
#> ```
#> 
#> Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
#> 
#> | scientific\_name            | common\_name         | n   | 
#> | :------------------------- | :------------------ | --: |
#> | Corvus corone              | Carrion Crow        | 288 | 
#> | Turdus merula              | Eurasian Blackbird  | 285 | 
#> | Anas platyrhynchos         | Mallard             | 273 | 
#> | Fulica atra                | Eurasian Coot       | 268 | 
#> | Parus major                | Great Tit           | 266 | 
#> | Podiceps cristatus         | Great Crested Grebe | 254 | 
#> | Ardea cinerea              | Gray Heron          | 236 | 
#> | Cygnus olor                | Mute Swan           | 234 | 
#> | Cyanistes caeruleus        | Eurasian Blue Tit   | 233 | 
#> | Chroicocephalus ridibundus | Black-headed Gull   | 223 | 
#> 
#> blabla
#> 

## ------------------------------------------------
## Method `yarn$add_md`
## ------------------------------------------------

path <- system.file("extdata", "example2.Rmd", package = "tinkr")
ex <- tinkr::yarn$new(path)
# two headings, no lists
xml2::xml_find_all(ex$body, "md:heading", ex$ns)
#> {xml_nodeset (2)}
#> [1] <heading level="2">\n  <text xml:space="preserve">R Markdown</text>\n</he ...
#> [2] <heading level="2">\n  <text xml:space="preserve">Including Plots</text>\ ...
xml2::xml_find_all(ex$body, "md:list", ex$ns)
#> {xml_nodeset (0)}
ex$add_md(
  "# Hello\n\nThis is *new* formatted text from `{tinkr}`!",
  where = 1L
)$add_md(
  " - This\n - is\n - a new list",
  where = 2L
)
# three headings
xml2::xml_find_all(ex$body, "md:heading", ex$ns)
#> {xml_nodeset (3)}
#> [1] <heading level="1">\n  <text xml:space="preserve">Hello</text>\n</heading>
#> [2] <heading level="2">\n  <text xml:space="preserve">R Markdown</text>\n</he ...
#> [3] <heading level="2">\n  <text xml:space="preserve">Including Plots</text>\ ...
xml2::xml_find_all(ex$body, "md:list", ex$ns)
#> {xml_nodeset (1)}
#> [1] <list type="bullet" tight="true">\n  <item>\n    <paragraph>\n      <text ...
tmp <- tempfile()
ex$write(tmp)
readLines(tmp, n = 20)
#>  [1] "---"                                         
#>  [2] "title: \"Untitled\""                         
#>  [3] "author: \"M. Salmon\""                       
#>  [4] "date: \"September 6, 2018\""                 
#>  [5] "output: html_document"                       
#>  [6] "---"                                         
#>  [7] ""                                            
#>  [8] "```{r setup, include=FALSE, eval=TRUE}"      
#>  [9] "knitr::opts_chunk$set(echo = TRUE)"          
#> [10] "```"                                         
#> [11] ""                                            
#> [12] "# Hello"                                     
#> [13] ""                                            
#> [14] "- This"                                      
#> [15] "- is"                                        
#> [16] "- a new list"                                
#> [17] ""                                            
#> [18] "This is *new* formatted text from `{tinkr}`!"
#> [19] ""                                            
#> [20] "## R Markdown"                               

## ------------------------------------------------
## Method `yarn$protect_math`
## ------------------------------------------------

path <- system.file("extdata", "math-example.md", package = "tinkr")
ex <- tinkr::yarn$new(path)
ex$tail() # math blocks are escaped :(
#> 
#> $$
#> Q\_{N(norm)}=\\frac{C\_N +C\_{N-1}}2\\times
#> \\frac{\\sum *{i=N-n}^{N}Q\_i} {\\sum*{j=N-n}^{N}{(\\frac{C\_j+C\_{j-1}}2)}}
#> $$
#> 
ex$protect_math()$tail() # math blocks are no longer escaped :)
#> 
#> $$
#> Q_{N(norm)}=\frac{C_N +C_{N-1}}2\times
#> \frac{\sum _{i=N-n}^{N}Q_i} {\sum_{j=N-n}^{N}{(\frac{C_j+C_{j-1}}2)}}
#> $$
#> 

## ------------------------------------------------
## Method `yarn$protect_curly`
## ------------------------------------------------

path <- system.file("extdata", "basic-curly.md", package = "tinkr")
ex <- tinkr::yarn$new(path)
ex$protect_curly()$head()
#> ---
#> title: basic curly
#> ---
#> 
#> # preface {#pre-face .unnumbered}
#> 

## ------------------------------------------------
## Method `yarn$protect_unescaped`
## ------------------------------------------------

path <- system.file("extdata", "basic-curly.md", package = "tinkr")
ex <- tinkr::yarn$new(path, sourcepos = TRUE, unescaped = FALSE)
ex$tail()
#> ![a pretty puppy](https://placedog.net/200/300){#dog alt="a picture
#> of a dog"}
#> 
#> \[a span with attributes\]{.span-with-attributes
#> style='color: red;'}
#> 
ex$protect_unescaped()$tail()
#> ![a pretty puppy](https://placedog.net/200/300){#dog alt="a picture
#> of a dog"}
#> 
#> [a span with attributes]{.span-with-attributes
#> style='color: red;'}
#>