What the hell is <strong>rasciidoc</strong>?

# What the hell is rasciidoc?

Andreas Dominik Cullmann

Inspired by Karl Broman`s reader on using knitr with asciidoc (https://kbroman.org/knitr_knutshell/pages/asciidoc.html), this is a wrapper to and a slight modification of knitr.

## Knitting

### A Minimal Example

Suppose, you have a file that reads

    file_name <- system.file("files", "minimal", "plot.Rasciidoc",
                             package = "rasciidoc")
    cat(readLines(file_name), sep = "\n")

    ## = Some Title
    ## Your Name
    ## :toc2:
    ## :numbered:
    ## :data-uri:
    ## :duration: 120
    ##
    ## == A Section
    ##
    ## === A Subsection
    ##
    ## * A list with a https://en.wikipedia.org/wiki/Hyperlink[link].
    ## * Yet another entry in the list.
    ##
    ## == Code
    ## //begin.rcode
    ## a  <- c(2, 3, 4, 10) # <1>
    ## value <- 0 # <2>
    ## for (a_i in a) { # <3>
    ##     value <- value + a_i  # <4>
    ## }
    ## print(value) # <5>
    ## //end.rcode
    ##
    ##
    ## == A new section
    ##
    ## //begin.rcode a_plot, dev = "png", fig.cap = "A Plot"
    ## plot(1:10)
    ## //end.rcode

If you run `render` on this file (we use a temporary directory here)

    withr::with_dir(tempdir(), {
                        file.copy(file_name, ".")
                        rasciidoc::render(basename(file_name))
    })

    ## Warning in run_knit(file_name, knit = knit, envir = envir, write_to_disk =
    ## write_to_disk): Setting option knit to TRUE based on the file contents!

    ## Due to the CRAN policy of not writing "anywhere else on the file system apart from the R session's temporary directory" we work on a temporary copy of /tmp/RtmpVTucXi/plot.Rasciidoc.
    ## Thus all internal sourcing and internal links will be broken and any output is written to /tmp/RtmpVTucXi. Set the option "write_to_disk" to TRUE (using
    ##      options("write_to_disk" = TRUE)
    ## ) to bypass this. You may want to include the above line into your ~/.Rprofile.

    ##
    ##
    ## processing file: /tmp/RtmpVTucXi/plot.Rasciidoc

    ## 1/4
    ## 2/4 [unnamed-chunk-8]
    ## 3/4
    ## 4/4 [a_plot]

    ## output file: /tmp/RtmpVTucXi/plot.asciidoc

    ## [1] TRUE
    ## attr(,"info")
    ## attr(,"info")$python
    ## [1] "/usr/bin/python"
    ##
    ## attr(,"info")$input
    ## [1] "/tmp/RtmpVTucXi/plot.asciidoc"
    ##
    ## attr(,"info")$output
    ## [1] "/tmp/RtmpVTucXi/plot.Rasciidoc" "/tmp/RtmpVTucXi/plot.html"
    ##
    ## attr(,"info")$asciidoc
    ## [1] "/usr/bin/asciidoc"
    ##
    ## attr(,"info")$`source-highlight`
    ## [1] TRUE
    ##
    ## attr(,"info")$`git-asciidoc`
    ## [1] NA

you will create an HTML file that is identical to [this file](https://fvafrcu.gitlab.io/rasciidoc/inst/files/minimal/plot.html) and that you could browse using `browseURL(file.path(tempdir(), paste0(sub("\\..*$", "", basename(file_name)), ".html")))` from your current R session (vignettes like this are not allowed to start external programs like browsers, so you’ll have to do it yourself).

### A Simple Example

Suppose you changed your file to be less minimalistic:

    file_name <- system.file("files", "simple", "knit.Rasciidoc",
                             package = "rasciidoc")
    cat(readLines(file_name), sep = "\n")

    ## = Some Title
    ## Your Name
    ## :toc2:
    ## :numbered:
    ## :data-uri:
    ## :duration: 120
    ##
    ## == What is this About?
    ##
    ##
    ## === Some simple asciidoc
    ##
    ## * A list with a https://en.wikipedia.org/wiki/Hyperlink[link].
    ## * Yet another entry in the list.
    ##
    ## == Including Code
    ## Do not use the _include_ macro provided by asciidoc!
    ## //begin.rcode, label = "sum", code = readLines("src/sum.R")
    ## //end.rcode
    ##
    ##
    ## == A new section
    ##
    ## //begin.rcode, label = "my_sum", code = readLines("src/my_sum.R")
    ## //end.rcode
    ## === A subsection
    ## //begin.rcode, label = "value"
    ## print(value)
    ## //end.rcode
    ##
    ## //begin.rcode, label = "run my_sum"
    ## print(my_sum(1:3))
    ## //end.rcode
    ##
    ## Some inline code: Object +value+ has value +r value+.
    ##
    ##
    ## === Second subsection

This file obviously reads code from files in a subdirectory called "src/", so if you had that subdirectory and its files, too:

    my_directory <- file.path(tempdir(), "simple")
    dir.create(my_directory)
    withr::with_dir(my_directory, {
                        file.copy(file_name, ".")
                        file.copy(file.path(dirname(file_name), "src"), ".",
                                  recursive = TRUE)
    })

    ## [1] TRUE

    dir(my_directory, recursive = TRUE, full.names = TRUE)

    ## [1] "/tmp/RtmpVTucXi/simple/knit.Rasciidoc"
    ## [2] "/tmp/RtmpVTucXi/simple/src/my_sum.R"
    ## [3] "/tmp/RtmpVTucXi/simple/src/sum.R"

you could `render` the file

    rasciidoc::render(file.path(my_directory, basename(file_name)))

    ## Warning in run_knit(file_name, knit = knit, envir = envir, write_to_disk =
    ## write_to_disk): Setting option knit to TRUE based on the file contents!

    ## Due to the CRAN policy of not writing "anywhere else on the file system apart from the R session's temporary directory" we work on a temporary copy of /tmp/RtmpVTucXi/simple/knit.Rasciidoc.
    ## Thus all internal sourcing and internal links will be broken and any output is written to /tmp/RtmpVTucXi. Set the option "write_to_disk" to TRUE (using
    ##      options("write_to_disk" = TRUE)
    ## ) to bypass this. You may want to include the above line into your ~/.Rprofile.

    ##
    ##
    ## processing file: /tmp/RtmpVTucXi/simple/knit.Rasciidoc

    ## 1/9
    ## 2/9 [sum]
    ## 3/9
    ## 4/9 [my_sum]
    ## 5/9
    ## 6/9 [value]
    ## 7/9
    ## 8/9 [run my_sum]
    ## 9/9

    ## output file: /tmp/RtmpVTucXi/knit.asciidoc

    ## [1] TRUE
    ## attr(,"info")
    ## attr(,"info")$python
    ## [1] "/usr/bin/python"
    ##
    ## attr(,"info")$input
    ## [1] "/tmp/RtmpVTucXi/knit.asciidoc"
    ##
    ## attr(,"info")$output
    ## [1] "/tmp/RtmpVTucXi/knit.html"
    ##
    ## attr(,"info")$asciidoc
    ## [1] "/usr/bin/asciidoc"
    ##
    ## attr(,"info")$`source-highlight`
    ## [1] TRUE
    ##
    ## attr(,"info")$`git-asciidoc`
    ## [1] NA

and create an HTML file that is identical to [this file](https://fvafrcu.gitlab.io/rasciidoc/inst/files/simple/knit.html) and that you could browse using `browseURL(file.path(my_directory, paste0(sub("\\..*$", "", basename(file_name)), ".html")))` from your current R session .

## Spinnig

You can also use a spinnig file for input:

    file_name <- system.file("files", "simple", "spin.R_nolint",
                             package = "rasciidoc")
    cat(readLines(file_name), sep = "\n")

    ## #' = Some Title
    ## #' Your Name
    ## #' :toc2:
    ## #' :numbered:
    ## #' :data-uri:
    ## #' :duration: 120
    ## #'
    ## #' == What is this About?
    ## #'
    ## #' //begin_no_slide
    ## #' This will not show up on slides.
    ## #' //end_no_slide
    ## #'
    ## #' === Some simple asciidoc
    ## #'
    ## #' * A list with a https://en.wikipedia.org/wiki/Hyperlink[link].
    ## #' * Yet another entry in the list.
    ## #'
    ## #' == Including Code
    ## #' Do not use the _include_ macro provided by asciidoc!
    ## #' Instead prefix all source statements with
    ## #' ----
    ## #' #+ code = readLines("file_to_be_sourced")
    ## #' #+ include = FALSE
    ## #' ----
    ## #' It est use
    ## #' ----
    ## #' #+ code = readLines("src/sum.R")
    ## #' #+ include = FALSE
    ## #' source("src/sum.R")
    ## #' ----
    ## #' to produce
    ## #+ code = readLines("src/sum.R")
    ## #+ include = FALSE
    ## source("src/sum.R")
    ## #'
    ## #'
    ## message("A message, probably different output hooks.")
    ## #' == A new section
    ## #'
    ## #+ code = readLines("src/my_sum.R")
    ## #' === A subsection
    ## print(value)
    ## #'
    ## print(my_sum(1:3))
    ## #'
    ## #' Inline code does not work: Object +value+ has value +r value+.
    ## #'

You run `render` on it:

    withr::with_dir(tempdir(), {
                        file.copy(file_name, ".", overwrite = TRUE)
                        file.copy(file.path(dirname(file_name), "src"), ".",
                                  recursive = TRUE)
                        rasciidoc::render(basename(file_name))
    })

    ## 1/1

    ## Due to the CRAN policy of not writing "anywhere else on the file system apart from the R session's temporary directory" we work on a temporary copy of /tmp/RtmpVTucXi/spin.R_nolint.
    ## Thus all internal sourcing and internal links will be broken and any output is written to /tmp/RtmpVTucXi. Set the option "write_to_disk" to TRUE (using
    ##      options("write_to_disk" = TRUE)
    ## ) to bypass this. You may want to include the above line into your ~/.Rprofile.

    ## [1] TRUE
    ## attr(,"info")
    ## attr(,"info")$python
    ## [1] "/usr/bin/python"
    ##
    ## attr(,"info")$input
    ## [1] "/tmp/RtmpVTucXi/spin.asciidoc_nolint"
    ##
    ## attr(,"info")$output
    ## [1] "/tmp/RtmpVTucXi/spin.R_nolint" "/tmp/RtmpVTucXi/spin.html"
    ##
    ## attr(,"info")$asciidoc
    ## [1] "/usr/bin/asciidoc"
    ##
    ## attr(,"info")$`source-highlight`
    ## [1] TRUE
    ##
    ## attr(,"info")$`git-asciidoc`
    ## [1] NA

## Vignettes Using `rasciidoc`

This vignette is built by `rasciidoc`'s vignette engine (see https://gitlab.com/fvafrcu/rasciidoc/-/blob/master/vignettes/An_Introduction_to_rasciidoc.Rasciidoc for its input file).

Just add a

    ////
        %\VignetteIndexEntry{Your Vignette Entry}
        %\VignetteEngine{rasciidoc::rasciidoc}
    ////

block to your `rasciidoc` input file and add `rasciidoc` to the VignetteBuilder and Suggests fields of your package’s DESCRIPTION file.