simplermarkdown/0000755000176200001440000000000014164655162013502 5ustar liggesuserssimplermarkdown/NAMESPACE0000644000176200001440000000056714164652623014730 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(file_subs_ext) export(markdown_block) export(md_figure) export(md_table) export(mdtangle) export(mdweave) export(mdweave_to_html) export(mdweave_to_pdf) export(mdweave_to_tex) export(output_eval) export(output_figure) export(output_raw) export(output_str) export(output_table) export(raw_block) importFrom(rjson,fromJSON) simplermarkdown/man/0000755000176200001440000000000014135021537014244 5ustar liggesuserssimplermarkdown/man/mdweave.Rd0000644000176200001440000000341314135021537016164 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mdweave.R \name{mdweave} \alias{mdweave} \title{Run the code in a markdown file and generate a new markdown file} \usage{ mdweave( fn, ofn = file_subs_ext(basename(fn), ".md", FALSE), cmd1 = "pandoc -s \\"\%1$s\\" -t json -o \\"\%2$s\\"", cmd2 = "pandoc -s \\"\%1$s\\" -t markdown -o \\"\%2$s\\"", ... ) } \arguments{ \item{fn}{filename of the markdown file (should use pandoc markdown).} \item{ofn}{name of the resulting markdown file.} \item{cmd1}{command used to run pandoc. See details.} \item{cmd2}{command used to run pandoc. See details.} \item{...}{ignored} } \value{ Returns the file name of the file generated (\code{ofn}). Called mainly for the side effect of parsing and generating a markdown file (and possibly secondary files such as figures). } \description{ Run the code in a markdown file and generate a new markdown file } \details{ \code{mdweave} calls pandoc twice. In the first call the markdown file is parsed by pandoc and the parse tree is written to a temporary file. This parse tree is the read by mdweave and any R-code in the tree is executed resulting in a modified parse tree. This file is then stored to a new temporary file. Pandoc is the called a second time to convert the new parse tree to a markdown file. The arguments \code{cmd1} and \code{cmd2} contain the calls used to run pandoc. The arguments can be used to, for example pas additional arguments to pandoc. They use positional arguments. In \code{cmd1}, the first argument (\code{\%1$s}) is the input file name and the second (\code{\%2$s}) the temporary file containing the parsed tree. In \code{cmd2}, the first argument is the temporary file with the modified parse tree and the second argument the output file. } simplermarkdown/man/output_fun.Rd0000644000176200001440000000454614142454705016761 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/output_fun.R \name{output_table} \alias{output_table} \alias{output_figure} \alias{output_eval} \alias{output_raw} \alias{output_str} \title{Output filters for code blocks in markdown} \usage{ output_table(code, language = "R", id = "", ...) output_figure(code, language = "R", id = "", ...) output_eval(code, language = "R", id = "", echo = TRUE, results = TRUE, ...) output_raw(code, language = "R", id = "", ...) output_str(code, language = "R", id = "", ...) } \arguments{ \item{code}{character vector containing the code of the code block} \item{language}{the language in which the code is written (as specified in the markdown file).} \item{id}{the identifier of the code block.} \item{...}{additional arguments specified as arguments in the code block are passed on to the filter function. Often these are ignored, or they are passed on to other functions (see 'Details').} \item{echo}{the code in \code{code} is repeated in the output.} \item{results}{include the results of running the code in the output. The output of code that explicitly writes to standard output is always included.} } \value{ The functions either return a character vector with markdown, or return a list with the correct structure to include in the pandow parse tree. } \description{ Output filters for code blocks in markdown } \details{ The filter functions \code{tab} and \code{fig} call \code{\link{md_table}} and \code{\link{md_figure}} respectively; additional arguments are passed on to those functions. Other filter functions ignore the additional arguments. It is also possible to write custom output filter. An output filter should have \code{code}, \code{language} and \code{id} as its first three arguments. It should either return a character vector containing the markdown that should be included in the resulting markdown file or an object that can be directly included in the pandoc parse tree. If the function does not return a character vector it is assumed the latter is returned. \code{simplermarkdown} defines a small number of valid object constructors: \code{\link{raw_block}} and \code{\link{markdown_block}}. The custom function should be available when running the markdown document through pandoc. The easiest way is to \code{\link{source}} or define the function in the markdown document before using it. } simplermarkdown/man/mdweave_to.Rd0000644000176200001440000000423614135025104016664 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mdweave_to.R \name{mdweave_to_pdf} \alias{mdweave_to_pdf} \alias{mdweave_to_tex} \alias{mdweave_to_html} \title{Run the code in a markdown file and generate a new document} \usage{ mdweave_to_pdf( fn, ofn = file_subs_ext(basename(fn), ".pdf", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = "pandoc \%3$s -s \\"\%1$s\\" -t latex -o \\"\%2$s\\"", ... ) mdweave_to_tex( fn, ofn = file_subs_ext(basename(fn), ".tex", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = "pandoc \%3$s -s \\"\%1$s\\" -t latex -o \\"\%2$s\\"", ... ) mdweave_to_html( fn, ofn = file_subs_ext(basename(fn), ".html", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = "pandoc \%3$s -s \\"\%1$s\\" -t html -o \\"\%2$s\\"", ... ) } \arguments{ \item{fn}{filename of the markdown file (should use pandoc markdown).} \item{ofn}{name of the resulting file.} \item{extra_arguments2}{extra arguments passed on to pandoc. Should be a length 1 character vector.} \item{run_in_temp}{When TRUE the intermediary markdown file and generated figures (when not using custom paths) are created in a temporary directory. Otherwise these will be generated in the same directory as the output file.} \item{cmd2}{command used to run pandoc. See details.} \item{...}{additional arguments are passed on to \code{\link{mdweave}}.} } \value{ Returns the name of the resulting outout file. } \description{ Run the code in a markdown file and generate a new document } \details{ These functions first call \code{\link{mdweave}} to run the code in the original file and convert the original markdown file to a new markdown file. This second markdown file is then converted to the desired output format using a second run of \code{pandoc}. In case of converting to pdf the file is required to have the extension \code{.pdf}. In case of converting to LaTeX, the file cannot have the extension \code{.pdf}. That is because in both cases the file is first converted to LaTeX. In case of a file with the extension \code{.pdf} the file is than further converted to PDF. } simplermarkdown/man/md_figure.Rd0000644000176200001440000000346614163071115016503 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/md_figure.R \name{md_figure} \alias{md_figure} \title{Generate a figure and generate the markdown to include the figure} \usage{ md_figure( expr, name, caption = "", id = "", dir = file.path(Sys.getenv("MDOUTDIR", "."), "figures"), device = c("png", "pdf"), ..., as_character = FALSE, echo = FALSE, results = FALSE ) } \arguments{ \item{expr}{the expressions to evaluate. Will generally contain plotting commands. The expressions are evaluated in the global environment.} \item{name}{the name of the figure.} \item{caption}{text of the caption. When omitted no caption is added to the figure.} \item{id}{id of the figure. When omitted or equal to NULL or an empty character, no id is added to the figure.} \item{dir}{name of the directory in which to store the file.} \item{device}{the graphics device to use for creating the image.} \item{...}{passed on to the graphics device.} \item{as_character}{return the figure as a character vector. If \code{FALSE} the figure will be written to the standard output.} \item{echo}{the code in \code{code} is repeated in the output.} \item{results}{include the results of running the code in the output. The output of code that explicitly writes to standard output is always included.} } \value{ When \code{as_character = FALSE} a character vector with the markdown needed to include the generated figure in a markdown file is returned. Otherwise, nothing is returned; the markdown is written to the console. } \description{ Will evaluate the expressions in \code{expr} and capture the output on the given plotting device in the given file. It will then generate the markdown needed to include that figure in a markdown document. } \details{ The image is stored in the file \code{dir/name.device}. } simplermarkdown/man/mdtangle.Rd0000644000176200001440000000242514133461355016335 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mdtangle.R \name{mdtangle} \alias{mdtangle} \title{Extract code from the code blocks in a markdown file} \usage{ mdtangle( fn, ofn = file_subs_ext(basename(fn), ".R"), extra_arguments = "", cmd = "pandoc \%3$s -s \\"\%1$s\\" -t json -o \\"\%2$s\\"", ... ) } \arguments{ \item{fn}{filename of the markdown file (should use pandoc markdown).} \item{ofn}{name of the resulting R-script} \item{extra_arguments}{extra arguments passed on to pandoc. Should be a length 1 character vector.} \item{cmd}{command used to run pandoc. See details.} \item{...}{ignored} } \value{ Returns the filename of the generated file. } \description{ Extract code from the code blocks in a markdown file } \details{ \code{mdtangle} calls pandoc. Pandoc will parse the markdown document and write the parsed file to temporary file. This file is read by \code{mdtangle} and the code is extracted from it and written to \code{ofn}. Using the \code{cmd} argument the exact command used to run pandoc can be modified. It is passed on to \code{\link{sprintf}} and uses positional arguments: (1) name of the input file, (2) location of the temporary file to which the parsed document is written, (3) the value of \code{extra_arguments}. } simplermarkdown/man/raw_block.Rd0000644000176200001440000000134614135021537016502 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/raw_block.R \name{raw_block} \alias{raw_block} \title{Return a raw chunk of text that can be included in the pandoc parse tree} \usage{ raw_block(content, language = "markdown") } \arguments{ \item{content}{a character vector containing the content to include in the final document.} \item{language}{language of the content} } \value{ Returns a \code{list} with the correct structure for a \code{RowBlock} in the pandoc parse tree. } \description{ Return a raw chunk of text that can be included in the pandoc parse tree } \details{ A raw block is included as is into the final markdown document. This can be used for example to include raw chunks of markdown. } simplermarkdown/man/md_table.Rd0000644000176200001440000000136714133461355016315 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/md_table.R \name{md_table} \alias{md_table} \title{Generate a markdown table from a data.frame} \usage{ md_table(tab, caption, as_character = FALSE, ...) } \arguments{ \item{tab}{a data frame} \item{caption}{text of the caption. When omitted no caption is added to the table.} \item{as_character}{return the table as a character vector. If \code{FALSE} the table will be written to the standard output.} \item{...}{unused.} } \value{ Then \code{as_character = FALSE} a character vector with the markdown containing the table is returned. Otherwise, nothing is returned; the markdown is then written to the console. } \description{ Generate a markdown table from a data.frame } simplermarkdown/man/file_subs_ext.Rd0000644000176200001440000000135714135021537017374 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/file_subs_ext.R \name{file_subs_ext} \alias{file_subs_ext} \title{Replace file extension by another file extension} \usage{ file_subs_ext(fn, new_ext, check = TRUE) } \arguments{ \item{fn}{character vector with file names} \item{new_ext}{character vector of length one with the new extension (when it does not start with a period a period is added).} \item{check}{check if the new file name is not equal to the original filename. If so, generate an error.} } \value{ Returns a character vector of the same length of \code{fn} with the extension of the file names in \code{fn} replaced by \code{new_ext}. } \description{ Replace file extension by another file extension } simplermarkdown/man/markdown_block.Rd0000644000176200001440000000122414135021537017526 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/markdown_block.R \name{markdown_block} \alias{markdown_block} \title{Return a code block object that can be included in the pandoc parse tree} \usage{ markdown_block(content, language, id = "", ...) } \arguments{ \item{content}{a character vector containing the code} \item{language}{language of the code in the code block} \item{id}{optional id of the code block} \item{...}{ignored.} } \value{ Returns a \code{list} with the correct structure for a code block in the pandoc parse tree. } \description{ Return a code block object that can be included in the pandoc parse tree } simplermarkdown/DESCRIPTION0000644000176200001440000000223514164655162015212 0ustar liggesusersPackage: simplermarkdown Title: Simple Engine for Generating Reports using R Version: 0.0.4 Authors@R: person(given = "Jan", family = "van der Laan", role = c("aut", "cre"), email = "r@eoos.dds.nl", comment = c(ORCID = "0000-0002-0693-1514")) Description: Runs R-code present in a pandoc markdown file and includes the resulting output in the resulting markdown file. This file can then be converted into any of the output formats supported by pandoc. The package can also be used as an engine for writing package vignettes. BugReports: https://github.com/djvanderlaan/simplermarkdown/issues URL: https://github.com/djvanderlaan/simplermarkdown License: GPL (>= 3) Encoding: UTF-8 RoxygenNote: 7.1.1 Imports: rjson, tools Suggests: MASS VignetteBuilder: simplermarkdown SystemRequirements: Pandoc (http://pandoc.org) needs to installed and available in the search path. NeedsCompilation: no Packaged: 2022-01-03 19:59:17 UTC; eoos Author: Jan van der Laan [aut, cre] () Maintainer: Jan van der Laan Repository: CRAN Date/Publication: 2022-01-03 20:20:02 UTC simplermarkdown/build/0000755000176200001440000000000014164652625014602 5ustar liggesuserssimplermarkdown/build/vignette.rds0000644000176200001440000000033014164652625017135 0ustar liggesusersmP 0,  | ?!pFn-5rupwݾ)Fy(y>~!߀cFLP,NoJF-Mʹ JU'xs1v*ˡR ej[H"Xrs0I-ǽϞ;'ά'{lzbLqj?iek=hU]4Đ쬁ousimplermarkdown/tests/0000755000176200001440000000000014164652625014645 5ustar liggesuserssimplermarkdown/tests/test_file_subs_ext.R0000644000176200001440000000056714135021537020660 0ustar liggesuserslibrary(simplermarkdown) expect_equal <- function(a, b) { stopifnot(isTRUE(all.equal(a,b))) } expect_equal( file_subs_ext("foo.x", "y"), "foo.y") expect_equal( file_subs_ext(c("foo.x", "bar.z"), "y"), c("foo.y", "bar.y")) expect_equal( file_subs_ext(c(".x", "foo/.bar.z"), "y"), c(".x.y", "foo/.bar.y")) expect_equal( file_subs_ext("", "y"), ".y") simplermarkdown/tests/test_mdweave.R0000644000176200001440000000655314164647250017466 0ustar liggesusers# mdweave a couple of documents and check if the output is the # same as the corresponding reference documents library(simplermarkdown) if (simplermarkdown:::has_pandoc()) { # We only want to check if the output of mdweave matches the reference if the # pandoc version matches that which generated the reference. Otherwise there # is a large chance that the output does not match pandoc_version <- system("pandoc --version", intern = TRUE) correct_pandoc_version <- c("pandoc 2.5", "Compiled with pandoc-types 1.17.5.4, texmath 0.11.2.2, skylighting 0.7.7") is_correct_pandoc_version <- all(pandoc_version[1:2] == correct_pandoc_version) # Create tempdir dir <- tempdir() dir.create(dir, recursive = TRUE, showWarnings = FALSE) oldwd <- setwd(dir) # When running tests the environment variable R_TESTS is set. This # causes issues when running a second R instance as mdweave does. Therefore # we unser it. old_env <- Sys.getenv("R_TESTS") Sys.setenv("R_TESTS" = "") # ============================================================================= message("Checking iris.md") md <- "iris.md" message("Weave file") fn <- system.file(file.path("examples", md), package = "simplermarkdown") mdweave(fn) message("Check if result generated") stopifnot(file.exists(md)) if (is_correct_pandoc_version) { message("Compare to reference") lines <- readLines(md) fn_ref <- system.file(file.path("examples_output", md), package = "simplermarkdown") lines_ref <- readLines(fn_ref) print(all.equal(lines, lines_ref)) system(paste0("diff ", md, " ", fn_ref)) writeLines(lines) stopifnot(isTRUE(all.equal(lines, lines_ref))) } message("Check images") # We don't check if the images are exactly the same; this probably # depends on the exact output device used; versions etc. stopifnot(file.exists("figures/iris.png")) message("Cleanup") #unlink(md) unlink("figures") # ============================================================================= message("Checking example1.md") md <- "example1.md" message("Weave file") fn <- system.file(file.path("examples", md), package = "simplermarkdown") mdweave(fn) message("Check if result generated") stopifnot(file.exists(md)) if (is_correct_pandoc_version) { message("Compare to reference") lines <- readLines(md) fn_ref <- system.file(file.path("examples_output", md), package = "simplermarkdown") lines_ref <- readLines(fn_ref) print(all.equal(lines, lines_ref)) system(paste0("diff ", md, " ", fn_ref)) stopifnot(isTRUE(all.equal(lines, lines_ref))) } message("Check images") # We don't check if the images are exactly the same; this probably # depends on the exact output device used; versions etc. stopifnot(file.exists("figures/foo.png")) stopifnot(file.exists("figures/test.pdf")) message("Cleanup") unlink(md) unlink("figures") # ============================================================================= # An markdown file without a header block gave an error with version 0.0.3. # Regression test fn <- tempfile(fileext=".md") writeLines("# Introduction", fn) fn2 <- tempfile(fileext=".md") mdweave(fn, fn2) unlink(fn) unlink(fn2) # ============================================================================= # END Sys.setenv("R_TESTS" = old_env) setwd(oldwd) } simplermarkdown/tests/test_mdtangle.R0000644000176200001440000000316514140220551017606 0ustar liggesusers# mdtangle a couple of documents and check if the output is the # same as the corresponding reference documents library(simplermarkdown) if (simplermarkdown:::has_pandoc()) { # Create tempdir dir <- tempdir() dir.create(dir, recursive = TRUE, showWarnings = FALSE) oldwd <- setwd(dir) # When running tests the environment variable R_TESTS is set. This # causes issues when running a second R instance as mdweave does. Therefore # we unser it. old_env <- Sys.getenv("R_TESTS") Sys.setenv("R_TESTS" = "") # ============================================================================= message("Checking iris.md") md <- "iris.md" r <- "iris.R" message("Tangle file") fn <- system.file(file.path("examples", md), package = "simplermarkdown") mdtangle(fn) message("Compare to reference") lines <- readLines(r) fn_ref <- system.file(file.path("examples_output", r), package = "simplermarkdown") lines_ref <- readLines(fn_ref) stopifnot(isTRUE(all.equal(lines, lines_ref))) message("Cleanup") unlink(r) # ============================================================================= message("Checking example1.md") md <- "example1.md" r <- "example1.R" message("Tangle file") fn <- system.file(file.path("examples", md), package = "simplermarkdown") mdtangle(fn) message("Compare to reference") lines <- readLines(r) fn_ref <- system.file(file.path("examples_output", r), package = "simplermarkdown") lines_ref <- readLines(fn_ref) stopifnot(isTRUE(all.equal(lines, lines_ref))) message("Cleanup") unlink(r) Sys.setenv("R_TESTS" = old_env) setwd(oldwd) } simplermarkdown/vignettes/0000755000176200001440000000000014164652625015513 5ustar liggesuserssimplermarkdown/vignettes/style.css0000644000176200001440000000101714133461355017356 0ustar liggesusers body { max-width: 50rem; margin-left: auto; margin-right: auto; font-family: system-ui; color: lightgray; background: #555555; } p, li { text-align: justify; } pre { background: #444; padding: 0.5rem; } h1, h2, h3, h4, h5 { color: orange; font-weight: bold; } h4, h5 { color: inherit; } h2 { margin-top: 3rem; } a { color: orange; } a:hover { color: lightblue; } pre code { color: white; background: inherit; padding: 0; } code { color: #e5c892; background: #444; padding: 0.2rem; } simplermarkdown/vignettes/intro.md0000644000176200001440000002356014163070760017167 0ustar liggesusers --- title: simplermarkdown css: "style.css" --- Introduction to simplermarkdown -------------------------------------- First write a markdown file using [pandoc markdown](https://pandoc.org/MANUAL.html#pandocs-markdown). The package uses pandoc to parse the markdown and runs any code blocks tagged as being R-code. The result a new markdown file that can be further processed using pandoc and compiled to, for example, PDF or HTML. To process your markdown file you can use the `mdweave` function: ``` mdweave("mydocument.md", "mydocument_woven.md") ``` The resulting document `mydocument_woven.md` can then be processes further using pandoc. Below is a ready to run example using an example document in the package: ``` library(simplermarkdown) example1 <- system.file("examples/example1.md", package = "simplermarkdown") mdweave(example1, "example1_woven.md") system("pandoc example1_woven.md -o example1.pdf") ``` The package also includes the functions `mdweave_to_pdf`, `mdweave_to_html` and `mdweave_to_tex`, that combine these last two function calls. Therefore, the example above could also have been written as: ``` library(simplermarkdown) example1 <- system.file("examples/example1.md", package = "simplermarkdown") mdweave_to_pdf(example1, "example1.pdf") ``` Although it is possible to pass additional arguments to `pandoc` through the `mdweave_to_...` functions, it is probably just as easy to call `pandoc` directly. ## Writing markdown An example of a basic code block tagged as being R-code is shown below. The id/label if the block is `codeblock1`. ````` ```{#codeblock1 .R} a <- 1+1 a ``` ````` By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. In the output file this will result in ```{#codeblock1 .R} a <- 1+1 a ``` Note that the `.R` needs to be the first argument starting with a `.` for the codeblock. For example ` ```{#codeblock .foo .R foo=bar} ` won't be evaluated, while ` ```{#codeblock foo=bar .R .foo} ` will. By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. Arguments can be used to suppress either showing the code or the output: ````` ```{#codeblock1 .R echo=FALSE results=TRUE} a <- 1+1 ``` ````` Inline code is also supported. Again it should be tagged with `{.R}`: ``` The average value of `Sepal.Width` is `mean(iris$Sepal.Width)`{.R} and that of `Petal.Width` is `mean(iris$Petal.Width)`{.R}. ``` The final result of the inline code will always be included as text into the resulting markdown document. In case of code blocks the code is passed on to a function. Depending on the function used this can result in a code blocks with the evaluated code (the default), tables, figures and you can also specify your own functions. ### Figures To generate a figure use the `output_figure` function. The function will run the code, capture any output on the specified device and generate a markdown image include. ````` ```{.R #myfigure fun=output_figure name="test" caption="My figure" device="pdf" width=8 height=6} plot(dta$Sepal.Width, dta$Petal.Width) ``` ````` `output_figure` accepts the options `caption` (default none), `device` (possible values are `"png"` and `"pdf"`), `echo` (default `FALSE`; echo the commands to the output) and `results` (default `FALSE`; show output of the command (other than the figure) in the output). Additional arguments such as `width` and `height` are passed on to the device (in this case `pdf()`). When an id is given for the code block (as `#myfigure` above) this is also added to the figure. The figures are saved in the folder `figures` in the current folder. This can be controlled by the `dir` argument. ### Tables To generate a table, we tell it to pass the code in the code block to the function `output_table` from the `simplermarkdown` package. This function will take the final result and generate a markdown table from that. Any additional arguments of the code block are passed on to the `output_table` function. ````` ```{.R #mytable fun=output_table caption="Sample iris"} dta$foo <- dta$Sepal.Width/dta$Sepal.Length dta[1:20, ] ``` ````` `output_table` only accepts the `caption` argument. Unfortunately, pandoc does not yet support adding id's to tables at the moment without the [pandoc crossref filter](https://github.com/lierdakil/pandoc-crossref). Therefore, simplermarkdown also doesn't add the id to the resulting table as this would interfere with regular pandoc use. Should you want to add an id to the table in order to use it with the crossref filter: you can either do ```` : Sample iris {#mytable} ```{.R fun=output_table} iris[1:5, ] ``` ```` or ```` ```{.R fun=output_table caption="Sample iris {#mytable}"} iris[1:5, ] ``` ```` ### Other output By using the `output_raw` filter, any other output can be generated. This function will run the code, capture any output and put that directly into the resulting markdown document. For example, let's print a list with all of the iris species: ````` ```{.R fun=output_raw} writeLines(paste("-", levels(iris$Species))) ``` ````` Or you can write your own filter function. This function will get the code in the code block as character vector as it's first argument, the language of the code block, and the id of the code block and any other arguments given. For example: ``` print_in_bold <- function(code, language = "R", id = "", ...) { cat("\n**", code, "**\n", sep = "") } ``` This function could for example be defined in a block in the markdown file. Afterwards, this function can be used in your markdown document as: ````` ```{.R fun=print_in_bold} Hello World! ``` ````` Using as a vignette engine ----------------------------------------------------------------------- To use simplermarkdown as an engine for your R-package vignettes you will need to do the following: #### Specify simplermarkdown as your vignette builder in your `DESCRIPTION` file: ``` VignetteBuilder: simplermarkdown ``` #### Add simplermarkdown as a dependency of your package. If your package doesn't use simplermarkdown otherwise you can add it to your `Suggests` field in the `DESCRIPTION` file: ``` Suggests: simplermarkdown ``` #### Use the extension `.md` for your vignette. Create the vignette in the `vignettes` directory in your package source. #### Specify the vignette engine in your vignette. You have to add the following line to your vignette: ``` %\VignetteEngine{simplermarkdown::mdweave_to_html} ``` Instead of `mdweave_to_html` you can also use `mdweave_to_pdf` to generate a vignette in PDF format. It is easiest to do this in a comment section in your markdown file. For example, start your markdown file with: ``` --- title: [The title of the vignette] --- [And the contents of your vignette] ``` ### Custom styling By default the default templates and styling of the pandoc installation on your machine will be used. However, you can also specify custom styling in the header of your markdown file. See the [documentation of Pandoc](https://pandoc.org/MANUAL.html) for more information. For example, if you generate HTML output and you want to use a custom CSS-stylesheet, you can place the stylesheet in the `vignettes` directory and refer to the stylesheet in the header: ``` --- title: [The title of the vignette] css: custom_styling.css --- ``` ## A note about paths and working directories simplermarkdown tries to assume as little as possible about possible workflows. However, this also means that you, the user, are responsible for some things where other packages might make assumpptions. One of the places where this is the case is for paths and working directories. And this is especially relevant when including figures and when generating figures using R. As an example take the following project directory: ````` report/ report.md figures/ figure1.png report/output/ ````` The report contains the following code: ````` ![Figure caption](figures/figure1.png) ```{.R fun=output_figure name="figure2" caption="Caption", device="png"} plot(1:10) ``` ````` Assume the current working directory is the root of the project directory and that we run `mdweave` as: ````` mdweave("report/report.md", "report/output/report.md") ````` Figures are by default created in the directory `figures` in the target directory. Therefore the directory structure after running `mdweave` is: ````` report/ report.md figures/ figure1.png ouput/ report.md figures/ figure2.png ````` And the resulting markdown file will contain the following markdown: ````` ![Figure caption](figures/figure1.png) ![Caption](report/output/figures/figure2.png) ````` As you can see, we now have two locations with figures. When running `pandoc` from the root directory of the project to create the final output: ````` pandoc report/output/report.md -s -o report/output/report.html ````` `pandoc` will not be able to find the first figure. It will find the second figure. When you would run the final `pandoc` command from the `report/output` directory. `pandoc` will not be able to find any of the figures. There are several possible solutions for the example above: - When working on linux or mac, you could create a symbolic link from `report/output/figures` to `report/figures`. - Copy `report/figures` to `report/output/figures`. - Path of least resistance: run `mdweave` and `pandoc` from the `report` directory and also put the output in the same directory. - And probably others. Note that the same issues occur when referencing stylsheets etc. in the meta block of the markdown file. simplermarkdown/NEWS0000644000176200001440000000153114164646354014204 0ustar liggesusers CHANGES IN SIMPLERMARKDOWN 0.0.4: NEW FEATURES: - `md_figure` and `output_figure` can now echo the commands used to generate the figure. Use the arguments `echo` and `results` for that. - Errors with hopefully more informative error messages in case something goes wrong with the calls to pandoc. BUG FIXES: - Markdown documents without a header block would generate an error. Fixed. - Output was truncated for longer blocks of code. Fixed. - Expressions such as `iris[, foo := Sepal.Width/Sepal.Length]` were 'translated' to `iris[, `:=`(foo, Sepal.Width/Sepal.Length)]` in the output. Fixed. - When pandoc is not installed an empty dummy vignette is generated. This prevents warnings on the CRAN machines without pandoc. This should already have been working in the previous version except for a bug. simplermarkdown/R/0000755000176200001440000000000014164652625013704 5ustar liggesuserssimplermarkdown/R/md_table.R0000644000176200001440000000211114163046444015564 0ustar liggesusers#' Generate a markdown table from a data.frame #' #' @param tab a data frame #' @param caption text of the caption. When omitted no caption is added to the #' table. #' @param as_character return the table as a character vector. If \code{FALSE} #' the table will be written to the standard output. #' @param ... unused. #' #' @return #' Then \code{as_character = FALSE} a character vector with the markdown #' containing the table is returned. Otherwise, #' nothing is returned; the markdown is then written to the console. #' #' @export #' md_table <- function(tab, caption, as_character = FALSE, ...) { res <- vector("list", ncol(tab)) for (i in seq_along(res)) { t <- format(tab[[i]]) t <- format(c(names(tab)[i], t)) nc <- max(nchar(t)) line <- paste0(rep("-", nc), collapse ="") t <- c(t[1], line, utils::tail(t, -1)) res[[i]] <- t } res <- do.call(paste, c("", res, "", sep = "|")) if (!missing(caption) && !is.null(caption)) { res <- c(paste0(": ", caption), "", res) } if (as_character) paste0(res, collapse="\n") else writeLines(res) } simplermarkdown/R/md_figure.R0000644000176200001440000000551014163046225015761 0ustar liggesusers#' Generate a figure and generate the markdown to include the figure #' #' Will evaluate the expressions in \code{expr} and capture the output on the #' given plotting device in the given file. It will then generate the markdown #' needed to include that figure in a markdown document. #' #' @param expr the expressions to evaluate. Will generally contain plotting #' commands. The expressions are evaluated in the global environment. #' @param name the name of the figure. #' @param caption text of the caption. When omitted no caption is added to the #' figure. #' @param id id of the figure. When omitted or equal to NULL or an empty #' character, no id is added to the figure. #' @param dir name of the directory in which to store the file. #' @param device the graphics device to use for creating the image. #' @param ... passed on to the graphics device. #' @param as_character return the figure as a character vector. If \code{FALSE} #' the figure will be written to the standard output. #' @param echo the code in \code{code} is repeated in the output. #' @param results include the results of running the code in the output. The #' output of code that explicitly writes to standard output is always #' included. #' #' @details #' The image is stored in the file \code{dir/name.device}. #' #' @return #' When \code{as_character = FALSE} a character vector with the markdown needed #' to include the generated figure in a markdown file is returned. Otherwise, #' nothing is returned; the markdown is written to the console. #' #' @export #' md_figure <- function(expr, name, caption = "", id = "", dir = file.path(Sys.getenv("MDOUTDIR", "."), "figures"), device = c("png", "pdf"), ..., as_character = FALSE, echo = FALSE, results = FALSE) { dir.create(dir, recursive = TRUE, showWarnings = FALSE) device <- match.arg(device) extension <- "" if (device == "png") { fn <- file.path(dir, paste0(name, ".png")) grDevices::png(fn, ...) } else if (device == "pdf") { fn <- file.path(dir, paste0(name, ".pdf")) grDevices::pdf(fn, ...) } on.exit(grDevices::dev.off()) # in order to handle both md_figure(plot(1:10) and # md_figure(str2expression("plot(1:10)")) expr <- if (is.expression(expr)) expr else as.expression(substitute(expr)) res <- utils::capture.output( source(exprs = expr, echo = echo, print.eval = results) ) # Check if, besides a figure, we also need to add the commands and # other output to the output if (echo || results) { res <- paste0(c("\n```", res, "```\n"), collapse = "\n") } else res <- character(0) # Generate the markdown for the figure id_str <- if (!is.null(id) && id != "") id_str <- paste0("{#", id, "}") else id_str = "" res <- paste0(res, "\n![", caption, "](", fn, ")", id_str, "\n") if (as_character) { res } else { cat(res) } } simplermarkdown/R/has_pandoc.R0000644000176200001440000000012214140220551016100 0ustar liggesusers has_pandoc <- function() { x <- Sys.which("pandoc") !is.na(x) && (x != "") } simplermarkdown/R/zzz.R0000644000176200001440000000060114140220551014640 0ustar liggesusers .onLoad <- function(libname, pkgname) { tools::vignetteEngine("mdweave_to_html", weave = mdweave_to_html_vignette, tangle = mdtangle_vignette, pattern = "[.][R]?md$", package = "simplermarkdown") tools::vignetteEngine("mdweave_to_pdf", weave = mdweave_to_pdf_vignette, tangle = mdtangle_vignette, pattern = "[.][R]?md$", package = "simplermarkdown") } simplermarkdown/R/file_subs_ext.R0000644000176200001440000000144414135021537016653 0ustar liggesusers #' Replace file extension by another file extension #' #' @param fn character vector with file names #' @param new_ext character vector of length one with the new extension (when #' it does not start with a period a period is added). #' @param check check if the new file name is not equal to the original #' filename. If so, generate an error. #' #' @return #' Returns a character vector of the same length of \code{fn} with the #' extension of the file names in \code{fn} replaced by \code{new_ext}. #' #' @export file_subs_ext <- function(fn, new_ext, check = TRUE) { if (substr(new_ext, 1, 1) != ".") new_ext <- paste0(".", new_ext) newfn <- paste0(tools::file_path_sans_ext(fn), new_ext); if (check && any(newfn == fn)) stop("fn already has extension '", new_ext, "'.") newfn } simplermarkdown/R/str_block.R0000644000176200001440000000013714133461355016004 0ustar liggesusers str_block <- function(content) { list( t = "Str", c = as.character(content) ) } simplermarkdown/R/filter_pandoc_json_tree.R0000644000176200001440000000727214163074704020713 0ustar liggesusers #' @importFrom rjson fromJSON #' filter_pandoc_json_tree <- function(con) { if (missing(con)) { con <- file("stdin") input <- readLines(con, warn = FALSE) close(con) dta <- rjson::fromJSON(input, simplify = FALSE) } else { dta <- rjson::fromJSON(file = con, simplify = FALSE) } # Extra step needed to get correct output; when meta is empty make sure # it is a named list; otherwire toJSON will generate 'meta: []' instead # of 'meta: {}' what pandoc expects if (is.list(dta$meta) && length(dta$meta) == 0) names(dta$meta) <- character(0) default_fun <- "output_eval" verbosity <- 1 # Go over all of the blocks in the tree; check if they contain R code and # evaluate the code dta$blocks <- parse_blocks(dta$blocks, default_fun = default_fun, verbosity = verbosity) dta } parse_blocks <- function(blocks, verbosity = 1, default_fun = "output_eval", eval_block = evaluate_code_block, eval_inline = evaluate_inline_code) { # The following type can all be handled the same way basic_types <- c("Emph", "Para", "Plain", "BlockQuote") # In the following types of content we will not look for code blocks and these # will nog be processed further types_to_ignore <- c("Str", "Space", "Str", "Strong", "Link", "Image", "Table", "SoftBreak") # Loop over the blocks and depending on the type process further; when we have # a block of R-code we will evaluate the code within it for (i in seq_along(blocks)) { block <- blocks[[i]] if (block$t == "Code") { block <- eval_inline(block, verbosity = verbosity) } else if (block$t == "CodeBlock") { block <- eval_block(block, verbosity = verbosity, default_fun = default_fun) } else if (block$t == "Header") { block$c[[3]] <- parse_blocks(block$c[[3]], verbosity, default_fun, eval_block, eval_inline) } else if (block$t == "BulletList") { for (j in seq_along(block$c)) block$c[[j]] <- parse_blocks(block$c[[j]], verbosity, default_fun, eval_block, eval_inline) } else if (block$t == "OrderedList") { for (j in seq_along(block$c[[2]])) block$c[[2]][[j]] <- parse_blocks(block$c[[2]][[j]], verbosity, default_fun, eval_block, eval_inline) } else if (block$t == "Div") { block$c[[2]] <- parse_blocks(block$c[[2]], verbosity, default_fun, eval_block, eval_inline) } else if (block$t %in% basic_types) { block$c <- parse_blocks(block$c, verbosity, default_fun, eval_block, eval_inline) } else if (block$t %in% types_to_ignore) { # do nothing } else { # also do nothing but report if (verbosity > 1) warning("Ignoring unsupported block type '", block$t, "'."); } blocks[[i]] <- block } blocks } evaluate_inline_code <- function(block, verbosity = 1) { b <- get_block(block) if (!is.null(b) && b$language == "R") { id <- if (b$id == "") "" else b$id if (verbosity > 0) message("Evaluating code in inline block '", id, "'.") block <- do.call(output_str, list(code = b$code, id = b$id, language = b$language)) } block } evaluate_code_block <- function(block, default_fun = "output_eval", verbosity = 1) { b <- get_block(block) if (!is.null(b) && b$language == "R") { id <- if (b$id == "") "" else b$id if (verbosity > 0) message("Evaluating code in block '", id, "'.") if (exists("fun", b$arguments)) { fun <- b$arguments$fun b$arguments$fun <- NULL } else { fun <- default_fun } res <- do.call(fun, c( list(code = b$code, id = b$id, language = b$language), b$arguments)) block <- if (is.character(res)) raw_block(res) else res } block } simplermarkdown/R/mdweave_to.R0000644000176200001440000001076514164646165016174 0ustar liggesusers#' Run the code in a markdown file and generate a new document #' #' @param fn filename of the markdown file (should use pandoc markdown). #' @param ofn name of the resulting file. #' @param extra_arguments2 extra arguments passed on to pandoc. Should be a length 1 #' character vector. #' @param run_in_temp When TRUE the intermediary markdown file and generated figures (when #' not using custom paths) are created in a temporary directory. Otherwise these will be #' generated in the same directory as the output file. #' @param cmd2 command used to run pandoc. See details. #' @param ... additional arguments are passed on to \code{\link{mdweave}}. #' #' @details #' These functions first call \code{\link{mdweave}} to run the code in the original #' file and convert the original markdown file to a new markdown file. This second #' markdown file is then converted to the desired output format using a second run #' of \code{pandoc}. #' #' In case of converting to pdf the file is required to have the extension #' \code{.pdf}. In case of converting to LaTeX, the file cannot have the extension #' \code{.pdf}. That is because in both cases the file is first converted to #' LaTeX. In case of a file with the extension \code{.pdf} the file is than #' further converted to PDF. #' #' @return #' Returns the name of the resulting outout file. #' #' @export #' @rdname mdweave_to mdweave_to_pdf <- function(fn, ofn = file_subs_ext(basename(fn), ".pdf", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = 'pandoc %3$s -s "%1$s" -t latex -o "%2$s"', ...) { # Check if extension of ofn is .pdf; this is required by pandoc if (!grepl("\\.pdf$", ofn)) stop("ofn should have the extension .pdf.") # First convert fn to md using mdweave if (run_in_temp) { dir <- tempfile() dir.create(dir, recursive = TRUE, showWarnings = FALSE) ofn_md <- file.path(dir, file_subs_ext(basename(fn), ".md", FALSE)) } else { ofn_md <- file_subs_ext(ofn, ".md", FALSE) if (ofn_md == fn) ofn_md <- paste0(ofn, ".md") } mdweave(fn, ofn_md, ...) # Convert md to pdf if (ofn == fn) stop("Output file (ofn) would overwrite input file (fn). ", "Specify another output filename (ofn).") cmd2 <- sprintf(cmd2, ofn_md, ofn, extra_arguments2) run_cmd(cmd2, paste0("Failed to convert the markdown file to PDF. ", "You may want to first run mdweave and inspect the resulting markdown ", "file. The command was '%3$s'.")) invisible(ofn) } #' @export #' @rdname mdweave_to mdweave_to_tex <- function(fn, ofn = file_subs_ext(basename(fn), ".tex", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = 'pandoc %3$s -s "%1$s" -t latex -o "%2$s"', ...) { if (grepl("\\.pdf$", ofn)) stop("ofn cannot have the extension .pdf.") # First convert fn to md using mdweave if (run_in_temp) { dir <- tempfile() dir.create(dir, recursive = TRUE, showWarnings = FALSE) ofn_md <- file.path(dir, file_subs_ext(basename(fn), ".md", FALSE)) } else { ofn_md <- file_subs_ext(ofn, ".md", FALSE) if (ofn_md == fn) ofn_md <- paste0(ofn, ".md") } mdweave(fn, ofn_md, ...) # Convert md to pdf if (ofn == fn) stop("Output file (ofn) would overwrite input file (fn). ", "Specify another output filename (ofn).") cmd2 <- sprintf(cmd2, ofn_md, ofn, extra_arguments2) run_cmd(cmd2, paste0("Failed to convert the markdown file to tex. ", "You may want to first run mdweave and inspect the resulting markdown ", "file. The command was '%3$s'.")) invisible(ofn) } #' @export #' @rdname mdweave_to mdweave_to_html <- function(fn, ofn = file_subs_ext(basename(fn), ".html", FALSE), extra_arguments2 = "--self-contained", run_in_temp = TRUE, cmd2 = 'pandoc %3$s -s "%1$s" -t html -o "%2$s"', ...) { # First convert fn to md using mdweave if (run_in_temp) { dir <- tempfile() dir.create(dir, recursive = TRUE, showWarnings = FALSE) ofn_md <- file.path(dir, file_subs_ext(basename(fn), ".md", FALSE)) } else { ofn_md <- file_subs_ext(ofn, ".md", FALSE) if (ofn_md == fn) ofn_md <- paste0(ofn, ".md") } mdweave(fn, ofn_md, ...) # Convert md to pdf if (ofn == fn) stop("Output file (ofn) would overwrite input file (fn). ", "Specify another output filename (ofn).") cmd2 <- sprintf(cmd2, ofn_md, ofn, extra_arguments2) run_cmd(cmd2, paste0("Failed to convert the markdown file to HTML. ", "You may want to first run mdweave and inspect the resulting markdown ", "file. The command was '%3$s'.")) invisible(ofn) } simplermarkdown/R/markdown_block.R0000644000176200001440000000112214135021537017005 0ustar liggesusers #' Return a code block object that can be included in the pandoc parse tree #' #' @param content a character vector containing the code #' @param language language of the code in the code block #' @param id optional id of the code block #' @param ... ignored. #' #' @return #' Returns a \code{list} with the correct structure for a code block in #' the pandoc parse tree. #' #' @export markdown_block <- function(content, language, id = "", ...) { list( t = "CodeBlock", c = list( list( id, list(language), list() ), content ) ) } simplermarkdown/R/md_weave_to_vignette.R0000644000176200001440000000173414140220551020211 0ustar liggesusers# Wrappers around the mdweave_to_* functions and mdtangle function intended # for use for handling vignettes. The main difference is that these functions # check if pandoc is available and if not will generate dummy output and not # generate an error. mdweave_to_html_vignette <- function(fn, ofn = file_subs_ext(basename(fn), "html", FALSE), ...) { if (!has_pandoc()) { writeLines("Cannot find pandoc. Not able to weave vignette.", ofn) ofn } else { mdweave_to_html(fn, ofn, ...) } } mdweave_to_pdf_vignette <- function(fn, ofn = file_subs_ext(basename(fn), "pdf", FALSE), ...) { if (!has_pandoc()) { writeLines("Cannot find pandoc. Not able to weave vignette.", ofn) ofn } else { mdweave_to_pdf(fn, ofn, ...) } } mdtangle_vignette <- function(fn, ofn = file_subs_ext(basename(fn), ".R"), ...) { if (!has_pandoc()) { writeLines("# Cannot find pandoc. Not able to tangle vignette.", ofn) ofn } else { mdtangle(fn, ofn, ...) } } simplermarkdown/R/get_block.R0000644000176200001440000000157214133461355015757 0ustar liggesusers get_block <- function(block) { if (block$t != "CodeBlock" && block$t != "Code") return(NULL) id <- block$c[[1]][[1]] language <- if (length(block$c[[1]][[2]])) block$c[[1]][[2]][[1]] else "" if (language != "R") return(NULL) args1 <- if (length(block$c[[1]][[2]]) > 1) { utils::tail(unlist(block$c[[1]][[2]]), -1) } else character(0L) arguments <- get_block_arguments(block$c[[1]][[3]]) code <- block$c[[2]] list( id = id, language = language, arguments_single = args1, arguments = arguments, code = code ) } get_block_arguments <- function(arguments) { sapply(arguments, function(a) { val <- a[[2]] if (val == "TRUE") { val <- TRUE } else if (val == "FALSE") { val <- FALSE } else if (grepl("^[0-9]+$", val)) { val <- as.numeric(val) } res <- list(val) names(res) <- a[[1]] res }) } simplermarkdown/R/mdtangle.R0000644000176200001440000000412714133461355015620 0ustar liggesusers#' Extract code from the code blocks in a markdown file #' #' @param fn filename of the markdown file (should use pandoc markdown). #' @param ofn name of the resulting R-script #' @param extra_arguments extra arguments passed on to pandoc. Should be a length 1 #' character vector. #' @param cmd command used to run pandoc. See details. #' @param ... ignored #' #' @details #' \code{mdtangle} calls pandoc. Pandoc will parse the markdown document and #' write the parsed file to temporary file. This file is read by #' \code{mdtangle} and the code is extracted from it and written to \code{ofn}. #' #' Using the \code{cmd} argument the exact command used to run pandoc can be #' modified. It is passed on to \code{\link{sprintf}} and uses positional #' arguments: (1) name of the input file, (2) location of the temporary file #' to which the parsed document is written, (3) the value of #' \code{extra_arguments}. #' #' @return #' Returns the filename of the generated file. #' #' @export #' mdtangle <- function(fn, ofn = file_subs_ext(basename(fn), ".R"), extra_arguments = "", cmd = 'pandoc %3$s -s "%1$s" -t json -o "%2$s"', ...) { tmp_ofn <- tempfile(fileext = ".json") on.exit(file.remove(tmp_ofn)) cmd <- sprintf(cmd, fn, tmp_ofn, extra_arguments) system(cmd) dta <- rjson::fromJSON(file = tmp_ofn, simplify = FALSE) default_fun <- "output_eval" verbosity <- 1 code <- character(0) gather_code <- function(block, default_fun = "eval", verbosity = 1) { b <- get_block(block) if (!is.null(b) && b$language == "R") { id <- if (b$id == "") "" else b$id if (verbosity > 0) message("Tangling code in block '", id, "'.") code <<- c(code, paste("#", id), b$code, "") } block } ignore_inline <- function(block, verbosity = 1) { block } # Go over all of the blocks in the tree; check if they contain R code and # evaluate the code dta$blocks <- parse_blocks(dta$blocks, default_fun = default_fun, verbosity = verbosity, eval_block = gather_code, eval_inline = ignore_inline) writeLines(code, con = ofn) invisible(ofn) } simplermarkdown/R/raw_block.R0000644000176200001440000000121414135021537015756 0ustar liggesusers #' Return a raw chunk of text that can be included in the pandoc parse tree #' #' @param content a character vector containing the content to include #' in the final document. #' @param language language of the content #' #' @details #' A raw block is included as is into the final markdown document. This can #' be used for example to include raw chunks of markdown. #' #' @return #' Returns a \code{list} with the correct structure for a \code{RowBlock} in #' the pandoc parse tree. #' #' @export raw_block <- function(content, language = "markdown") { list( t = "RawBlock", c = list(language, paste0(content, collapse="\n")) ) } simplermarkdown/R/output_fun.R0000644000176200001440000000627414142454655016247 0ustar liggesusers#' Output filters for code blocks in markdown #' #' @param code character vector containing the code of the code block #' @param language the language in which the code is written (as specified in #' the markdown file). #' @param id the identifier of the code block. #' @param ... additional arguments specified as arguments in the code block are #' passed on to the filter function. Often these are ignored, or they are #' passed on to other functions (see 'Details'). #' @param echo the code in \code{code} is repeated in the output. #' @param results include the results of running the code in the output. The #' output of code that explicitly writes to standard output is always #' included. #' #' @details #' The filter functions \code{tab} and \code{fig} call #' \code{\link{md_table}} and \code{\link{md_figure}} respectively; additional #' arguments are passed on to those functions. Other filter functions ignore the #' additional arguments. #' #' It is also possible to write custom output filter. An output filter should have #' \code{code}, \code{language} and \code{id} as its first three arguments. It #' should either return a character vector containing the markdown that should be #' included in the resulting markdown file or an object that can be directly #' included in the pandoc parse tree. If the function does not return a character #' vector it is assumed the latter is returned. \code{simplermarkdown} defines a #' small number of valid object constructors: \code{\link{raw_block}} and #' \code{\link{markdown_block}}. #' #' The custom function should be available when running the markdown document #' through pandoc. The easiest way is to \code{\link{source}} or define the #' function in the markdown document before using it. #' #' @return #' The functions either return a character vector with markdown, #' or return a list with the correct structure to include in the pandow parse #' tree. #' #' @rdname output_fun #' @export #' output_table <- function(code, language = "R", id = "", ...) { tab <- source(exprs = str2expression(code), echo = FALSE) md_table(tab$value, as_character = TRUE, ...) } #' @rdname output_fun #' @export #' output_figure <- function(code, language = "R", id = "", ...) { expr <- str2expression(code) md_figure(expr, as_character = TRUE, id = id, ...) } #' @rdname output_fun #' @export #' output_eval <- function(code, language = "R", id = "", echo = TRUE, results = TRUE, ...) { res <- utils::capture.output( source(textConnection(code), echo = echo, print.eval = results, max.deparse.length = Inf) ) if (echo && length(res) >= 1 && res[1] == "") res <- utils::tail(res, -1) res <- paste0(res, collapse="\n") markdown_block(res, language, id, ...) } #' @rdname output_fun #' @export #' output_raw <- function(code, language = "R", id = "", ...) { res <- utils::capture.output( source(exprs = str2expression(code), echo = FALSE) ) res <- paste0(res, collapse="\n") raw_block(res) } #' @rdname output_fun #' @export #' output_str <- function(code, language = "R", id = "", ...) { res <- source(exprs = str2expression(code), echo = FALSE) res <- paste0(as.character(res$value), collapse="\n") str_block(res) } simplermarkdown/R/mdweave.R0000644000176200001440000000736714164645760015476 0ustar liggesusers#' Run the code in a markdown file and generate a new markdown file #' #' @param fn filename of the markdown file (should use pandoc markdown). #' @param ofn name of the resulting markdown file. #' @param cmd1 command used to run pandoc. See details. #' @param cmd2 command used to run pandoc. See details. #' @param ... ignored #' #' @details #' \code{mdweave} calls pandoc twice. In the first call the markdown file is #' parsed by pandoc and the parse tree is written to a temporary file. This #' parse tree is the read by mdweave and any R-code in the tree is executed #' resulting in a modified parse tree. This file is then stored to a new #' temporary file. Pandoc is the called a second time to convert the new #' parse tree to a markdown file. #' #' The arguments \code{cmd1} and \code{cmd2} contain the calls used to run #' pandoc. The arguments can be used to, for example pas additional arguments #' to pandoc. They use positional arguments. In \code{cmd1}, the first argument #' (\code{%1$s}) is the input file name and the second (\code{%2$s}) the #' temporary file containing the parsed tree. In \code{cmd2}, the first argument #' is the temporary file with the modified parse tree and the second argument #' the output file. #' #' @return #' Returns the file name of the file generated (\code{ofn}). Called mainly for the #' side effect of parsing and generating a markdown file (and possibly secondary #' files such as figures). #' #' @export #' mdweave <- function(fn, ofn = file_subs_ext(basename(fn), ".md", FALSE), cmd1 = 'pandoc -s "%1$s" -t json -o "%2$s"', cmd2 = 'pandoc -s "%1$s" -t markdown -o "%2$s"', ...) { # Check if output filename does nog conflict with input filename if (ofn == fn) stop("Output file (ofn) would overwrite input file (fn). ", "Specify another output filename (ofn).") # Convert markdown to a parse tree in json tmp_ofn <- tempfile(fileext = ".json") cmd1 <- sprintf(cmd1, fn, tmp_ofn) run_cmd(cmd1, paste0("Failed to parse the markdown document to JSON (cmd1). ", "This probably means that the input markdown document contains errors. ", "The command was '%3$s'." )) # Set environment variable with location of output file # Possibly needed for filters to know where to put output # files such as figures outputdir <- dirname(ofn) dir.create(outputdir, recursive = TRUE, showWarnings = FALSE) Sys.setenv(MDOUTDIR = outputdir) on.exit(Sys.unsetenv("MDOUTDIR")) # Filter json (run R code in json) and save result dta <- filter_pandoc_json_tree(tmp_ofn) tmp_ifn <- tempfile(fileext = ".json") writeLines(rjson::toJSON(dta), tmp_ifn) # Convert json back to markdown cmd2 <- sprintf(cmd2, tmp_ifn, ofn) run_cmd(cmd2, paste0("Failed to convert the processed JSON file back to ", "markdown (cmd2). Either on of the output functions contains an error ", "or simplermarkdown has written invalid JSON. ", "The command was '%3$s'." )) # Cleanup; an earlier version used on.exit for this; currrent solution has the # advantage that in case of an error the old file are not deleted and can be # used for debugging file.remove(tmp_ofn) file.remove(tmp_ifn) # Return filename of the final file invisible(ofn) } run_cmd <- function(cmd, error_msg = "Failed to run '%1$s'; failed with status %2$d") { command <- gsub("^([a-zA-Z0-9]+) (.*)$", "\\1", cmd) args <- gsub("^([a-zA-Z0-9]+) (.*)$", "\\2", cmd) suppressWarnings({ status <- system2(command, args) }) if (status != 0) { if (status == 127) { stop("Running '", command, "' had status 127; this generally means that ", "'", command, "' could not be found. Make sure '", command, "' in on the path.") } else { stop(suppressWarnings(sprintf(error_msg, command, status, cmd))) } } } simplermarkdown/MD50000644000176200001440000000465414164655162014023 0ustar liggesuserse33c11e978345012487cb41b63e56606 *DESCRIPTION a25e0862f19e52e7bd51c3d835dd1185 *NAMESPACE bf9fc82ab0a04dca7d7152278692fa6d *NEWS 0599ab818666708009b028c50f8c0d00 *R/file_subs_ext.R 6027e9fec8cf55d797ed0bb983b0f250 *R/filter_pandoc_json_tree.R 777bfe1b09c0601ce81a9c1f18842724 *R/get_block.R 2d64fb282ba11ff51bc2a0d089b9462a *R/has_pandoc.R 642210acb07f643148c0acb7891b5bde *R/markdown_block.R 558acc2709a5f06dfaca364b22c153d0 *R/md_figure.R defb920f247d1b5f82e2178fbf86092a *R/md_table.R e9031c802848ad4d9102893e679b513f *R/md_weave_to_vignette.R b95943fa524377d9dfed7921808bc512 *R/mdtangle.R 7c956868eda3984999827f62683d14e0 *R/mdweave.R c1893346d5478718202f1d589bf2db99 *R/mdweave_to.R 2a6965c75524f635a428aec3c4257fe4 *R/output_fun.R dc07e16419bcfa4c2b326e2872e69daf *R/raw_block.R 133a728629cdff4b7a2c01f76c489908 *R/str_block.R 43af9eff23ab308a8d9190b92ac686ef *R/zzz.R 6b9980cb993529fcb776671e79484e21 *build/vignette.rds 86e2678051d0079f814de9839d2ec059 *inst/doc/intro.R e8c339afbb9b8131bdd4dfbcf0cdbbee *inst/doc/intro.html 2d10232e986bb2b058d1af40cc07f086 *inst/doc/intro.md 6d23f943d3d372142ec93569baafaf90 *inst/examples/example1.md c749143a4e6971dddcf3ba122811d764 *inst/examples/iris.md ea1d524709c15105bca6d7d953784c91 *inst/examples_output/example1.R c31846a085ce8dc242bc63451fe6f0aa *inst/examples_output/example1.md 557985eeb8bbf2b7095b8f298e3ca157 *inst/examples_output/figures/foo.png 4f62339dac95c889501ddab9aa1ab388 *inst/examples_output/figures/iris.png c8a277e20b6f7d5845c5191fada21858 *inst/examples_output/figures/test.pdf bd571e6933dfb3c69cf859ec38ab3d82 *inst/examples_output/iris.R c3e9292cbe471c7f8b471d94cf4c97e5 *inst/examples_output/iris.md 29858236ba43b890c5077d3d8cf45954 *inst/scripts/filter.R 3d710ecab0f71cd345725ef04a79387d *man/file_subs_ext.Rd a87b87573b30b6d0ea207c0872f2f786 *man/markdown_block.Rd c049f1a509b4bb43dcad5f4e549910a5 *man/md_figure.Rd ef1966f3415974a55c9dc765797ea679 *man/md_table.Rd 5581b15f8469ffbc1d1a76739b5bd061 *man/mdtangle.Rd 476fdb28b67bcdc924480d64ffa7e5e6 *man/mdweave.Rd 2f5fa82b50b5e455e36ccfa4a37c2b68 *man/mdweave_to.Rd 403d9f4a248296f76ab580de9962f4a9 *man/output_fun.Rd 7a5d3f80947320d8416ad97539ca61a2 *man/raw_block.Rd 21c475ab29d27c8d355edede8dd8e5b6 *tests/test_file_subs_ext.R 2135b217ff049ded9c6b61e150620021 *tests/test_mdtangle.R de2477cfb29a9a70d3337f9299d80239 *tests/test_mdweave.R 2d10232e986bb2b058d1af40cc07f086 *vignettes/intro.md 5e7d0597c9cdc2a8da86adac47fd5f71 *vignettes/style.css simplermarkdown/inst/0000755000176200001440000000000014164652625014460 5ustar liggesuserssimplermarkdown/inst/examples_output/0000755000176200001440000000000014135021537017704 5ustar liggesuserssimplermarkdown/inst/examples_output/iris.md0000644000176200001440000000361614142455163021206 0ustar liggesusers--- title: An analysis of iris --- Introduction ------------ From the help page of the iris data set: > This famous (Fisher's or Anderson's) iris data set gives the > measurements in centimeters of the variables sepal length and width > and petal length and width, respectively, for 50 flowers from each of > 3 species of iris. The species are *Iris setosa*, *versicolor*, and > *virginica*. Descriptives ------------ The table below shows for each of the iris species the mean value of the colums in the data set. : Mean values for each of the properties for each of the iris species. |Species |Sepal.Length|Sepal.Width|Petal.Length|Petal.Width| |----------|------------|-----------|------------|-----------| |setosa |5.006 |3.428 |1.462 |0.246 | |versicolor|5.936 |2.770 |4.260 |1.326 | |virginica |6.588 |2.974 |5.552 |2.026 | ``` > pal <- hcl.colors(3, "Dark2") > plot(iris$Sepal.Width, iris$Sepal.Length, pch = 20, + col = pal[iris$Species], xlab = "Sepal Width", ylab = "Sepal Length", + bty = "n", l .... [TRUNCATED] > legend("topright", legend = levels(iris$Species), + fill = pal, bty = "n", border = NA) ``` ![Relation between sepal length and width for the different iris species.](./figures/iris.png){#figure} Species prediction ------------------ ``` {.R} > library(MASS) > m <- lda(Species ~ Sepal.Width + Sepal.Length, data = iris) > p <- predict(m) > predicted_species <- p$class > table(predicted_species, iris$Species) predicted_species setosa versicolor virginica setosa 49 0 0 versicolor 1 36 15 virginica 0 14 35 ``` This model predicts in 80% of the cases the correct species. However, this is mainly for *setosa* for the other species the model predicts the correct species only for 71% of the records. simplermarkdown/inst/examples_output/figures/0000755000176200001440000000000014142437745021362 5ustar liggesuserssimplermarkdown/inst/examples_output/figures/iris.png0000644000176200001440000014504014142455163023034 0ustar liggesusersPNG  IHDR>_ pHYs&? IDATxw`TU3-@hH(E* wYgQkBW"DDpYRC %!^'ef?fcA33_̹|g(3sAGiA "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!d@2E "L@ SB)!dRaYY٫:tPwwcǮ[`0֭2dW-C[ QDJJߞ%PT:Njڳg]˗,Z裏>B(~666k֬y衇\;7BX]]=uԬn-!!䫯<|3duu>l6L\v׷9ssQQRl-**j|?\>}͛714FO>-ڵk4(Bp7|j]]]͛W}BCݸqkvʕ+Ϟ=+P՞-\.M 뮻jupooopȑ/ &L jӧO͋'O<񄛛[ Ko߾ ڕJe^ϟ7JΨo~J;cccwyڵcǎEEE*jҥZ˗ !<<<srrQ67 Ba0222Fi!Z-++-3QooZyrFFF7lpK]1X^ ̌|СCcbb PVV^x!&&ܹs_u I JQ.]ʓ322JJJn`$_z˗/0~h4B77sFFFm޼hr''Ƈ Too[9-*uV!O?-:SNBlٲ˥* `,,VVVJu޽`!Dvvv wJMMBIYX ԩ"--QY-aSNIӄanYX :~kפ٤-''ر~ڵkRgyp厎Ǐ?uTmmmii;㎒?u' .|Z-͛/j׿}!M1Z,۶m{ᇥB5MMMާO8IBI~Ξ=uСƪ;BkZ!믿+riфay#B/%%eCuttСرcy睤i9{]rehhhiiѣwi4EZ.F9B. sK3 +\5]5q cS*Өi@y`LB7)k.0 |u0.!s&~ɫ:`@e4^YQXdzO+U6MEEE/r` ȖB٭juR5k盻YB@&UJE`2B;M'ކE 訞~x\%mUWWQQQΡ-qFjjj~{zzFFF{u'̘1CP\~]P(6mTwgvwwڵI>?\Lzz#<3\r>0n:BsЄʚRs*m5!n\]02ǎB(JZ]]]-pww?ydΝ.]4}Ǐ !T*`B>}|wi+V8t޽{Z]]]{Ç !<8sL)ש_׭?~_~~K| .BHxyy'F+g{͘~swoHiК,_رcAAAjNӧOaa/(c0fΜy!CaccCm۶MĊΝ;:tBTW_}UdOJ~srrB|w%%pr„ Nھ}RJn_䬯)S{i]v !y[[cƌ t[_ĉkkkRZZ*?5+3޽رQ 6dȐFSw΅ 7nܷo_!Dzzzs7 /^B <'&&J'BRΝr˗Ϝ9{?!IBʍ9111v튋BL:5&&_qU!đ#GI| H[5 [5!6o,T=z5j4”Qlذ!///>>~ժU"1EEEB@!D||Mrww&fff6>%~,?>} z衸K.isokF5:qĉ't:Z\dɶm.^{՝;w !z)8w\;$%%ܹngc BĉJzj}1VBN4K. ҚH?B =z~{@@4*(7a!ĪU1:F8qbvvv u]BzKTξ}9RFbaaa zoo52dGBdgg 'Nh4#GB7 dCGiJBs9w\xxRufϞ-v̙BT*J% :t׷k׮+V{5kMMM5&L_SNEFFVUU;99,^Xѭ[>`رjٲeAF֮]+x]dgܹUUUZVP{Y~wQwjJ*))߿%Kbcc$44ɓ ҥ˼yjjjjuAAȑ#+WR1'O-.. 6mnjh.]7y=zf#!"L@ SB)!d@2E "L]4VQXQwsp5w9Fd0ʜbR0wEFTX^QXdpШFh ʪ2*4U@KΦjeXgQݼ[1e~q0J^2qn=][1U?rĥ<饳fZx[J_JKR tuehV+~ٳg=zϞ=Fb&MS(տVSSo?322+//ݻ Ŝ9s~in<==z?wvv ]hэ7ݺuB3fLJ/^}q>ltt{׮]'M駟sh͵-5kŔQ툳f`㿭EYG!-ipZS/ƨF;p>񷫡A6@{In<2 ̚5k͚5OJ1g!ĥKO~q!J2 ?O?f͚s ;,YDT!*++=JZNNNNNN^~ɓ'_^g߾}fBh4zΝ|ɬYN;x̙3xVӷo_! ޚc@`tUúvs1WIF2o@toCC{տy 2Nswo`go$ֵ .nV mV=;;{B ! ̙3?>dȐ޽;$$ܹs'Oӧ-[oWVV^~]R-_رcAAAjNӧOaa/\yyyySLξ{ϟ?_UUVVVΙ3ԩSi7P^^k׮_~OVmn0h_4K'%\Q\RY0B(⡑zK-z9 ٻ2~B֍ ';MOס=| lƆvqBvFawU b̙˗/߲e_M6t} !֭[سg;:رc߷oߤ7Ξ=7x駟k9x9r[o-]^{#G) !+RSS>!|nݺ>|VC;?֫W&k5+F (""'"X[!womMvU _Wi]ެY/_~С,?_ذabKik]N2壏>ڳgO@(XhQNNNBn..t0a„ ZmB^xA.]:hРnݺI/w%xDWg̘1቉ o͊+קO3gl۶'B%&&:::>9.\Blܸq߾} ._}}}]]]<3w;v8jԨaÆ 2$""Bi1Ԣ!m(`0\xQ1x7k׮8!ԩScbbg#BG J+6y:!\V6~kVEe7c BqAi1EBxC3G(MD 6ǯZJZ&666""RH*))ixwwwi"kfffYYYh&6֬* [;v1bhRR҅ zUwBϞ=Νk|mRRΝ;):qĉ't:Z\dɶm.^{՝;w6Oy̙9rK+*`!ĉ'Djl?sY9sb˖-|ÃBiUV55jĉ =z~{@@4wub ?~C鴷zi;rJ=ztsk`"U%ŕƻoڴi666\nZ;wn=XHHHJJJddz}||Q R81;;!C!yiB!Dvv /p FSEoݮ]f̘f0oذAVK#B_|'555::ɓ_|ɓ>h>}\kXT`t%՛Α.ݽ\{7>nܸ۷K?!Q_}ߟ2j(JR!oϝ;ww(J{{{i5R۱c& oܸqƍU+VNsqqٸqY~A !Ą P؟1B0ZoeUI|9Y5kE%'O|WwwwիW9s5 o'%%eѢEwqqQT<l`ԩS}A))S=zߞSOEEEw{Z\kPdd"!!܅̍ G.5nwU;/BT4>LBq:Bkye&.G WUM !5:SV ծC4@ WT/&dkj@=Bquu>;,=\% <,p pb}Q̍@0wQ]LY^ VHѴ|͛77wmǎM.,/ޔBqRLS g ~[]]իW-jR \xy"X {n=%%eӦM=z􈉉iR ߿XϞ={{i4F=haz jjj>3{{Oap0_D}x\m^ki IDAT P?>>駟:thgVUUݸqCPt4_׮]͛NizИ`0?+##gϞvvv.]rvvn䔔޽{waڵ+W<{lmmmXXѣ,YbcccR### F #ha_/++[lMӠmhFF]w%P*z~߾}[~mۘJ 4^uuukXk׮ x'Zy`0,X㕕~ٳg|A^K>|V(--#C.\P( wuu֭[ Ř1c޽[P̙3G駟vӳW\1cÀ֭['W(:N:=ۧP(MV\\3W\uW^yvҥ7]KFҵkŋZ,XЧOC&$$|Wfj}ζmZGOYfYÙ}WB9s;SdR :tBꤤy;v5%UWW7.!!At>|իz.ܷo߬Y&++믿޹s'|R_|… +**555֭gJ`}=Bi&''swީKu"""IߦM Zm) 6,((H7޿b-\~e˖ەׯ_WTeeeSL˛:uŋΝ;7v_7sǏZ$===;;{B-˛2eJvv{g}rΜ9NNɑ?~uV[]]zT(׮]k0M&mKx[JVZn)M)3g !lR}ӦM:.<uNnnndd͛wT*CBBvիWV^z%K !<<<֮]+(++hkV\\`Pz)2tCeee5nذA`^hѢ/7o,x'uTl_zyyy{{ !D^h0IJtҘi=!ĉkkkKi-VNj ~p׮]AAA#Fh%:wXXXB6.0>}9sf۶mZiii<@ֽ2H5hTT-\RTT#8p^* VΝr˗Ϝ9{V'+… =P\\ܥKZs>>ݻwkyǏ?C;wV*ݻw2eʖ-[6o|sBխ5*m`&N(?YQ׿ƖH-_A|?H+D !/< epѢEAnArr`8tPƦWVV^x믿:uъoڴi666\nZnV ,[C={իWw}wžFh޲۵k׌3 Cqq 6B) Z*??_jtҌ3>!Dvv`0FyʂW, >nܸ۷K{~ l2iҤׯ_ֶ{Glmmӹs眜'`Ԕ2]v!jc:AT1%Zɩ~ƍg̘-[yj}}XZNoB˾>]\ihʕ+/^ܠ=66VTLB vJie*U_'^6G95999۳gǣ>jq ` nt;Ā>Sz144tݺu^^^|󍯯 -`Q0&۵5ZA4ʂs3fڵ)))Ž{ׯߤI<WRl;׈޾JEl 1^̃) SB)!d@2E * sW̉m'@^*uۏ_9]^UQ)tt{ f@ ؖQX!.^][0=>}. ֩կ?fzy@FN_)h=-#jkl7Q!` #NM W̎@22w<4*̎@2/GF/gQR0/Q)OKΡ쬢 7G~dxy"(ghs̏) SB)!d@2E NNoLD7sW6&?m'Fw63Nzdwsegz-LimB;y()eښGWRY`s[7I9(@a0DFF !] V:|~ZX2oH2oO\vJ),+(zc[RayuFoW sט*h+LO9 ҠVoNjVdnvۿ9v%Dkz&N !rKku*rcTg4ܠNo8sߩMޝoJ*l8RP)+1ގS+k. Ju~שk'sK>vu+C`q&E ~d@2E "L@.` qv^Stv3w]`\!E?]=\[2ǔQqO˫Kuk.R `\Ӡ$"*nPQy ` k`&<L\ @0!ݽgBJ9d,߰B,3g32 +lսܦFtaB̍@0:BDE`T)! Ю@,/+ZhZsu 2kƮ 7PdFRMM?>o޼cǎUTT~g}f =Ee&^/XhQw裏lll֬Y3iҤ󃃃P5; `FJJJXXXPPPRR}skO>k>}͛G?H!DBBV& |g-A!7|j]]]͛W}ś7o>tЍ7:t`rj^I[_Bt<.lJ'.. Y3~||SO=5tЖ<|⮻Rý Ñ#GX(Nٷr' \c鑟.f 0##㥗^~ӓϞ=+۷ovR٫W/!Q$WnMwg1 ?}Q\Qhh5L}ʖ-[|ӓsssyzz !rrrn+Wr[[[?R$_=Ykbٳ]k%2k׮ x'Zs~YYh1R۹sgwss,E ÀEV@+.]dI|na΃>ʓ_~eGG[?R8ٹ4wپCeM6999͝;8996%nAA" jnɫW,Ha[z]vR'pYJeڵk ôiZ?+~~ @g\t6}=ܔ֮[NB^z%&&ύ !۪B܌ /УI[o\Bt4~ԾSwڕ4bĈ_nݺ?z^S222m_+@6uد@^'P)U.XѸ8!رcoi'ر~ڵk:uj:2RHς޽{Æ k7xc…ov]AżyZ_/x׌[4 is…!ŋwi;{lTTԡCQ[\\j+bԲ### FZRGA`slmmݻrR{{ѣGܹiK!Ph?,u'YlI95:PlkW΁4bljks˄1؝0eԤ2 &5)F2^=N*b=1^aLXgRA!AP^VYiNK*L:ዃ%5F?@B9dy#uzrAUqFt9HgV" +iAYUs?VFl to485{g`FBٽv2R:+M+"A]}<݌ԩ&foN3}t ůsG vL6jS#<>W]s|t)]+ppr4e:!ʔp.aNQ)!d@2E bQ00M=|*\GC" 2_2K͸QXlrWX:+ ߩBYQݔֵFQ}0Ŷ&Ŷ/vk'zR ?%|j{W͐V8ch]W3ď])B9L-(u%_ @c:}m~iF1w-e0RAW !m]-ΩjWsWa v3w&BX!"L@ SB)Vmgn\,wp#/ [ãF8ӟ.^)NUNwcwj%OrBo0x8֥OX!4)!e_jYi;5J>#mhWjes`NW| !Tu- Q15ia,龟8o)`92 iX7~B2 +U,сsWA!D9aNxӠ -2^W]_JɺQl@i鹥7 ~:!˵&˴n3'~B(o2RfZC;N\5q1C дbmJ=4Vlc}PR졫F,7w(̪B@ 4ƣ+iИFNTl#ujNvͮg<&Qi}]lMꅸ%=lW*t3R!ܚ9 #ujQ|;Ӕ,@lՓo j+upW/5w0[MI;Blh 6n׺v2Rf!$l_a#hָFtw^UP|;6 'Uv7^*|sƝ>.BƌY\_t/?o3B,1bBbBXRmU^$ ⏫uwG>rlsUGӒmt륲AB\(хtpkn7 M@D)!d@2E 2֎vJnO-vw!tP a E3.pu cR2vel;aRl;9aٝkg49Aյw|<))7_e]oN/nK~Bd^[cu Z@2MK;R1^lɅFd$8ڪ#u[tah0 !ȈƮCfT!`B!Bh[{7#ukc)3H wPPLm:9տAB{MW)s":==qY}}\|ߎשmXnnk:>&>ډRmINqBa]%UeYEvNξJ@{\#g;g;w`շ;-`(- ׯWWW7wBn\Iz}cܸqK.upp酛7o>}z]M_ IDAT@{tkw]lYQQQ >rRLJJJJJڲeѣG[6--@;w p͋/~Rm=#G<裵_x~a?MZ\ /7o^CH5@{s wBs=|򉏏J+WΟ?ޓZƌ~诿://˫˥@տS - .h4XOOOtS;wT(z#FL6-77#FhR 6n I|44ٻm~]Ց%Jy9?3&F˹eBN#C4VV!trrtQ 7|_UUU5+д-!P`0lJ= pDQ*ֶNeoQ(/[_[jv{/o57GEwtu6cU4rƍ*UGBJ~:H! )I0(JuEUld}-ﮮ]Q@qQQ i:id2;!CLyd{=eϜ9`@D`, `v~|`7HPvU%sku^Yz;~ B4:kU0 M6[ҫf$!=ؔ)S<==Ҟy晎n^qǏJǏRSS _Ε֟+9nR(;xB R:}apV۝5]}꼚<w6m-[d2z5 ϐڵk|+WryNNopܹ///'*۷{{{gY֤z֯_ό؅ ~-؈YWinձ5yr:[-p1T5u)nb[TfɃ"zeٗ^zi˖-!!!bar劙k>BΝ;_{s:99qDXX!8{G|>×-[lٲӧ/^YYY&5˗/_||횣07-&0>xt@5f<8N p1T{ 2:`E5ǎX#Ҳrn@"}۶mͽrs pK'ސiߜq6lx7,X[o-Zȓ^^E\"CT& yj 1w cthR"QJ 0&|p@ ^'mNNNن111ї@"E$S]etEZ CS9 9YȱFfjzIbZ_mh|nB؝*\ƽ];%&QJ 0-*j8GkjjT*;hBF_"mDI[&ꏄ,9ț{,NZ5=M T?K"#.^qjLzIBcLZh>/sJڌhy_Z5/L,2\BчeVIn w̜9h_|3dc_Ţf2< !fĵmrUK;>9t~r i7}jYDFpI/{U&'8^Mv+kN^ݓ2]sqsyufukպ:BHJX8In WWWO:-==駟NNNJoٳg/]OܹS$UTTᮉ_acz&4ӧO\R*;+44tϞ= BpyJe*mkZ}SL믿^j~~~|>iMMM)BP#;m=-I÷>.({ʷzOqOz‰)VVLʼnwDzzd{BpVcL ]6مSEͻW*5:Cëk rկ/U>_@F؜(5ǮUwG<掟)΄UF_uBȝwdRlBݷثABHM[p}ne]>?Vf(¦j-يNzIϕ~{$Xu%(y$ 9s廋5U, !:'[TnңԼwzs^R0;bP8c = xM[eUkZmU{h\}}УדcCGX~q3%m1g%y}„ck6̽sTopN#{zr,..6gN8Y_?ʯdx0̌y+~'8JG*ZOytmmJlPu Tq*Jkx !kuOV߼*Z=5%M;O5v|`ŴIt7*忾?VQ{3˭1^e usLJK fgBC8}o}3BCH;:j[—M bŹ.S y oEwc@e?:YzL:[~^lRS翬͜9s4==]$0wl=nW* `r*_ !7\I+9^7HaɢCҮ3ABH\֡"iZ%M0!D x܇tos0zJ~Ri8>y\8/|=&9|3~j=' qQ,<Ȳ:zy*5g.Z&7̈́p:ŋ:.%%LXCG g\O .Tmrx}\:fU#Wv;(%S9ll y!=\>'`7B$-O X`엔PUëFl#2mgIMMNMM}wR)!$++k%%% 0X$3đ.TQ;ثML))80"ҏl P(/MVRRiӦsBf̘#\~=!!aϞ=...Jlf|wgϡD.sJо!dY*UF'g ¡Ec^FE_<4$dz_z饑?`YV򈈈ӧ?3۷o ߀رc!v!B$MIVv+ ?{¢X@쁿KKiSꗅFݝ̊I+/D3DD)oMZJ/)8 !j-[%鿗0Tm 85 `O jI鄐,kPz}YsqSg[c>L^oI`/7'iUmz=JMklyf;cP߿rw :$4`;v*ZT._)G(4cB1 !eLWݣ${IpHKwEap $UjEW N%=(|kR@^^T"5nҸH $!ۢcUTdyBpON[yΰ8s)!J~4n[ZM?VtyəBqײBΕԅ |mN!pC{ ش(_PڭbU4쿴bف[ R7{mUO Bt?gڴ;!Ե{H 7Co߾!B1b`Sit Zh~}3,_='qϕ"wT#Ə5i)rp+z/~nFbа<4v,PЦTsy*-\_VQvw;|%4ȴFFxWk%&H #KFƨ@kP*8'  5g3$HDiz&lq\K)i@9¦FbBMXxIC"oa2Gܮ͝3>3VzIoM\qQOΤt!!ѯ VKFL )~VS3)Cq(C D{xyRO^Hf rB/IJF/)3ps-==eBl]szllLHswSW`FlL,"kr N[hc2aZ̸ؘZB{g a~~u&Oy>e8}'ӦMswwH$K.=jooxꩧjC=tY ` rp{衇v<}9sx<^KKD"1vlWWWPPRܶm?{3{SNѫ3`;!ljj tuuu!!!V^-Jl2{lcܹsݺu^^^mmm?5c a~Y3BCH՝((hmwwMj^(˛eNg@lPHdheMEf/Wңc%>wgAtm,96HZK@x<+:uM|ŋ/l1#'h9s ms .^x`7HIKKJΝ[z .Uo;QT{"$D<"/9 . ̉ƒ.( }x()luvJ E%^8qդU'J {>Yj8>aYݾ/Nұ:C$'YK[d079[J IDAT7bu\NN!$--/(( $%% xxTZTT4 bZ=ZŲ=UK-nba`wΗ؛k`S޾>6v}p5NQkUrwNsQJէ~|JѱCWܓվ/i{|<],1 f1\CwY+++#999&L1cƋ/;R4XLimmP5Pٙlumsouz`Y~rX{s<nߑk͞aT4w4p.2?JT>Lۧ|IpskN1r2rڵ^xARBx<^NNNNNݻ;sa%6===&o#|rqq wŀP reQÈ*{CJ C[Mw$꒷]k4ZW:]9 1;iTjNR=;w~Ν䔓SO] 91y{{{ggjZpsYVK+淅}ǰSzKUxکa^plfkz?.J 3x>qDXX!8{G|>8[BHppIK/lXe%K9nb~xzz#,_U!-q7'w\r%n|*v 1u UTfV\ H$ロh-K75`EOa5K^0;f^ґ<nzܚ$p$͈ ps2*`1nNi9vx f/|=pLK\SS>snNItttEEED HC~㳳KJJBT)P7?`mFFIGןjŪOWSA]DwO?6(]fo'}y oEPi ;NvՆCHxm^\8}oWߵ6=p>퉉/bOO?`'|R|۶m{7|Iz̚5ȑ#C &''s9s>C,zʕ+dZU,HڶW']aO/=vNygĈ[<s3BSv7y'N{oT$ e}*ywqD'kaF~CrrrAA  -wQYYi֏f͚\~}~IIIr?{.JÕJw}7p'xwMOO?< feeK0B&CNjx8qR˫׿b T*Ղ ^Bq9sY/ƍ_}B|ACT*~w}efjB0<ܶmۆ ƍg &={F) ;w0 3{x{aV3##̙3AJum:u ɔJ%!_|Ecl 3Jp!^v bxCz\\\N<믧Eٜ tر_'NqqqY`hw6ńGyd7n|!MMM=Ў;!!!!s!a ͛]]](eÇ^Z!8f !|ƍ V_~\._hvf`bYRi1QkWDQ* v9FBZ[[333!ܹ^kkk4iI&ѩA!JUŇ?+^ MQx<ƺ]wOKY¤FNڥp0!@CcPsW//\b([?R\<(>>(%buLp(Zm:Q:3$\orQYzʚv&8ՙT_}ܹ!!!NNNb8##W^s?`.gz* CUuk*i%+!IϾp=S[[8wܹsn_Μ9} `!Fc}0L!J+Wٲe˱cJKKO8M,744^Z*ҫăodDjR( 36b|Lh_y商ҿ/?~ܹs_xW^y^`VLKfX,Г:3`h30!4ܐ avv6!ߗHoB.\`$/Ku>n]o*_=ZU cNzWWWZ-96Stuu6wNK r7'vƌeuWsګ!ax..*P(J%!DTr6*Jř:pOGϳvSSҭ]QWWטBȾ}8`O>\U&CSO:thѣG7m?ќ5&CC}GK,IKK6mZpppSSSNNa-xoxu\2H!0 cW7n\UUG90,*Ä5k֘L=,ÄpHkz|Bb 7KWdﻧOs,Tz[po­0nyS+<9V Lh,TR cXB5閯TK=D@WehsRMZX-2ᡟfEO  eD'0jw̞={ԩgR Ƣ ' !_UvKʷz?{r.->P B7~,(}R>e) =˶\\`5SN}vu̙\BHiiYOJH+to{SEhRHO˕K/V^֋ճ]dUuCEe`]&4r<333//O"< xHHovvYT*:`Lh878PEK z#oZ+&9O{?zjnbQ~G[n5'MTZZRZZuV:uiFFK(X8Ytu:CZZkl ᧟~Jy7 w}W_8ky<>J)pck `_o>M.~bCKV` Lhx<̙39GE"QYY =52}h2SJ,8uqRl'O d0BqgWL.BH0 }H__N2'{f2q`I|_Ɔ0q$o'mLҹyzIg'.c C$/@C@I{]Nޞص>U*̄}'O|С/fdd t))) "gҦ^,;tZLդ]WkjIxb)&e'=rFne[)pNGagdC&>J0{hdRALh͛wС{nngz !"C'%NpG̳pFBH-LqP a&KFywyG*Boߞ^RR?Z`NIwUTTw}999Cd !YYY.KF !.\عs~[TTTWWaVd !fvp!8ȓeÇ_vgҥf, lRkSj!nޮ"$4M@_weZՖ6TUŇL,q{Z[eM>A!|$%t5ݜ܃|B| .T2C +zUJ;T]bogakWdn"_z?Os!ښyş@{ӦM+ɡrk!!$=͌(O!ռNy01tҪ%TZْ{j <jҦ/>*onx.Y1wM \dx,qRM RutU?URix(tw mߔ$V0B): B"Xhݪl^fիg>|pkkŋLb/_ٳ BRI >>h|M  PҭcW!.iQJU/Ү\/8:kbSgbθYI-)BQC))3S(Z-\ I:]O]#Pw5/6!ꫯ!7oH~O?Dy׮]KtKPk$zCO6>26djjtF ҰX<`XjhIu5AJBa,Y20I^m{&ȇֵ~<})+RRk9y|%ޮԒqsp 0߰lLSNBb!B`aq!GkOwg.̌O)$r[3-f fcV!J OoDµ^objIq7\CͲZyN?^RX7@ {y<2zISo &NZ>^zIđkf`_}%SyD>ƃ!\dF.xt 1LT)Vn0ob!ΝKIڳgϪU>oYbErrk(k !YYX솎՟-i)oVjtab .~ ME9Ils%?^>ϝ`^u+ζȚ]}&$O@Ҏ޶'ݜ}zΜ9 455ْ%K:Oba!1%>@ ضm۟ .lذ2gΜA!a~ 7CHټy00,1j_}Փ'O>|Cرj3`;nB>?mmm=aH."vڏ?X(Hc@C Aeeeggg||[PP,[l̙38)B]\\;fzBFc-&F"rvK׷Je}@/WoU(b'%QZ\}C P߿n !'s׏pi\K1qޑz ;M{v6w5'N0+jҚ.h1+;nƾ3|! &frݜ~ΝqwBOM}Z !!⤸%D^֮ vuxBMaiBd𝝬] !bY688̙3 , H$ ,?Q@[?^k !j}+9zB&=SABR\AB^*=%+. !DOK ?Lۧj]5'}nױY?ޣױ- l5 >/^|qT~^x!55%ƏwPJZTnhG]zRRo寇˛UPJLO7-3G)%{QI=;SZx֛]c5çmyl]2Z^^Nׯ߸qcrrrGGǁ{gϞ6<|ӧOgeeɍ#`J 8,+m*3FrwsUbHZZj#h$mu~ IDAT`~r&`4)Pwy yCN}}/5m0**駟G '&&Θ1#++kk׮tPo_s̢;' Rj^4()T}Ƈ%UOPOBc t*wv 0i4~.[lٲeCӧO_xFyPwGEqAbcCJI8)%3y!ß!KFa@9Ht{[k15w0 p_Gp@3ba(.D 0%r/q%PJzkr%LoKRpITO8ǟA)ЉCi1)% }9&'Y/v :q0j B2k2Gy8>n ݜ}BRJ}{M#+RRa󄗫/=!㯚@oZI !|8+hP%,c]yn!/H$8*ؾUo/3c]2P(u:ݮ]&M4h4??2q"0%zfd@쉂 5|`_̭K\. 931|ggZxX.47,:{7nꫯf !?ϲ,!D$?Cjժ;vxxx?399 ##̙37qalB{u֍7ĬX⫯ڳgHڹQr~al]! al[OBgB]=v!Ic희ZcBcIOuu9v!#Fy0EG4:5!$7bEA֮ F\n3Fkx{]"Oy:0gdX:q>e}ݕ 4kZY֭ `={` ұTV90yONN?󹃂<0DV)ɑh}G-u jiƒKxG+W 'sU*kp(ЕUzjP7Hٟz\ghX%ZSq<'/ BBa5ښ'U%uGO !Jݽ` BCt7\:j,\ EG~a0ꮬp1IVVic^R]}j!!ecCf ,BV uJjYoG+%!C%ml7WKV⨜|8 ቄB BK@CtMGJ'p1R,\C$p ߡ>ϼ3II.`lrAqI '.c bYZ${`fP=<8{0ߤAA sR=qу um<>X(l;cVEK#M1'$tvQ0*/+F+tw 6E9Ҷ"e[;.*`$vz3^wGߓy,PТpLpCh(4cB1 !vizzv.*GϴTj5>2|\gGh2;6rPYt5Gm'l =J4H8`{"$d:Q1 !`BC0F!Zv vEOXiYIBϲVg*~m'!Kޱ/wwa}^J3-&cq]NBgk`ZuNuW׳wӧ0|UçʪuJoJR4PH5)tW=#oh!z7dtqX,^oƐtBHVV hjT ?dnqX*[&+.ٵWcG~ah}kj-ڶ[R 'l=!ؾ@O }``V ٻucR BdeUm׊饭|P7H76D/)YhO&.ZQX֪J 9k)C_KS9U\N)V쩩,\d5W=NU0h`SYE yѡ^C+\Fh3`h`ss>vp1vANlD^ =݉?`ÄFKE^5#:!_6shJd .~b ҈IqD^#9ɴo;k-P u ZVj-ZukUGAE%,a' K6,3mL $7}"{w&;]:Jh$'WK)|PίhB q˘yA- n t}}n5Z4F~M_M=d`hߤҔZ!i-eDBfT/i'.l5m9xʨ}&L0Ez.ls9߳GLN6 w>{z/2;J}A0{=v8HA<4:Bz>;, I+4gap\B:!Rz wzbx p$1PGEEFOA a!:O NР!aS4:]1!tZ]jZ~>a@fߘ^) +AvbǍ LQjTI2]׷h?b!Zm7(7WĎw5IASMҺk⧌WnP^Ǵi'sJ 7|:ҩF[c\x!7 OPRVmwB;qt5}].={D5bUOUNCiC%;Gc*;l=3WTBRSs6Dr: GAxSt\2 *E @zjɃ6ndʕG 5k޽{ Yj> ,o***6m4iҤw}*'%¥K.XEخ/_`07tSUUի+,Z_~J ]ŒaÆ].\(嗋W^O~W^0tA>w_l68tիWڵ0>>C"ö#gwK"'>'F>Nz䓂szwTʬŅU@KMe:Ą CHRD}AI=Eq +8A+/~aDM/IA /]tj {Ϛ(檚YMSӅ_rlNQVki1FE J0J?ߛ1 t\+UV5ow8111eee~ܹs;yVp<_ 828O):Jl:ƃkh4tDXotiNqvgO4o  JVQ й DVIJ14:q:q׏M:AA[Ya&H8~0ocK4BL1Q.QACeG\\ܮ]233cbb"##333?Y,]=''G1xfBǏ+Qvg'MiPQ^{<+*}f+%]\Չ3-Ҡh[+(r;EoZ\ShP՚iPQ7YJM|lkiPa7ϮUp_ŮiPPRVSٯwsEEE3fBh4ñ}۷gee[KIʄ]=zB^Q=eeen555WqVJ}nC3a,%*>pmoh?U3/ *rNiu ӥrSY>\V[ܞ_`opNE+1hթ\+BT98}Z.Yv9%FUv^s:³g !Nŋ|!CTVVnܸqٲe999wݻ5g>DY`hmj6[LiBT{$wv@hxP3Vo j*e3AV6} uc@t,YDnYxAƍs=Vw8ܜۑɷSJҕ@{W]g' _`FcWzn/?sWHgV }t|>iKA{{=~5*u[1㠒NРVg]{{3^ 3gΜ9s\ǎ;cƌM6egg˫ܜɩB]Q=}ӧO_rE:Cz]&w#4_tuƨTBkVusը_DX@ϨίG9aS7V?EA=%}4b`պ޸(W/ @c?}]P2 Ǝqۘ{Szn9IIuFLsܾ1]UIR[.;t)ZkЇ$'&NοgoW۳pR!D`l)/+#r ~]WPz^7:r@E0#-z! I د/bpw,UFﮟh<vW?c7E ?yΟ}t>6dJOO^ZZ9n?SO?--*))i~ĈBK;iv^Kՙv@QM%yJJ#w:U:OlfίӑWU @=|Y˗:| $I9sf+[={_YYن XB\ Ҡ-i"cZh:; !$Ӡ󃙷U @=|o'xBvŋ?^QYY5m4ݾdɒ1c4-?|Zz!!Ă +0ͯ7!N~9->vɨ_| $ bo+V7-9dȐ]v55666N>BDGGԘf!3d%FHKުOd4{'O WzK*ܾVoYݏn/{cxXĐcҼYPv*.U;7[SF1ndQ˟3[o-f?Zp]5Tn﮹|ۤ&q2%rhpE60$*i u1GC3l!M;Iⴉz܆)^:Nt*@{>gהT v>$ӲE5ϗΈ ̴ɃbeEيw}ZW/i5{ͼ>0>FAk?9t8.~ ݒr-_U?kXFC&]ta",FAmg Rl&`z}Oǔqh64-Ɵw1茝?N#H:N.C5 ~T@*E "J@xl 3x~kIDFCH҃6oTz]7:rݙUJv>0 &cTk]0abB K~$IoGAK~waNyVz-I UrO_1ﭒWKF*z_4(p:sW}ܠiPa77ەW=r? \S/,)ڵ+Gݶ- Zqd4(k\{PAգ&궫# IDAT\ =e߿hv/a !l?Nv |ίpei +N甒Fu^3Wt~w5:]<TD=70Q^5kR&?58_pL%ƌ1`*]}%!D`|LL]҃z(ps@=GRul3U5a&{"v *.v!U>b ߭Q z9>M-:~w$Ba=?kLM-V8#X67T?Ӽk>KbIj[yBXjj~PP쇟5OB|v{EA%oiP;.lYw[%)}-Ҡp#'J~祊#PݵTVQwPANZ\ۭ U'*4WX/wes:e}we| 5VTy2{j'7 seǮJv{ce]ݐ`ԥ5zj'7V^jʯ| qI NJPh !BRz+4WnϑDHJ۞J _7$q40.:2mk{Aq=+$6qDv=G z0uF$hHJ=бvS1t{`KtB_Ԍ'(i}}N5}1qGKZzIѓ6}iBIDkDt[]Acp9SbUZNE NXMίGb6<%]7MgcU߳re\XUjOAc&t:m7FI#=½]Hg0B]t0!&pʕ3gܱcG[^zAb'@|͛7e\K!X,sdj*r \t ZtgnO>yС+ZEÆ S(wK/ :d29skɁ_~Jn`PCI%9ub?a^u]wqBIhyƪOf2?V>Q@[pE|2K,)((xgG\\ܮ]233cbb"##333?Y,Eao8Ӧ4(k9:oU\_=Cr5kL4(_/ZTT4c !Fq8۷o߾}{VVֺu블8rsye!}zw~I3?pXXʕ+%IuϞ=+p:/>pd*..~rrr>N,XӬ&uJO]&]@{gvyjkkbK0`ɒ%rKLLŋ 4nܸ>{ioVƅ/\0r+]$t]˗ݻ;b9s̙3ǵ}ر3fشiSvvBODwPkI IJrc=ztoFo\0''÷$d7G3Fu~=U@g #""ߛ'yI#"":bt?Hwsj ̌7Ln]KF%IlلFhZOLt{便=zbСZ2!1̄ 5:H+cgoF;T׿VlpppNN[t>|xÆ $͜9S׀BG@x?7UO+ !BA-ʿ1V" Vv0" 6:j`O[@%.Ż-ضa7D J3Y^;Jmfo4'%λYܠ^Q_x4V4Ch/V'\2 *R}:/A!DJ5< !jEAayB4V՜ZڼU ?䶽jg է,5էr;~TTZhitd:f2 T^Р^m /"H:.!Դ2c/ @{@E{'m7FB4m`Р^B%.!HZ?k{ 3?);>k{X^B@WĴ.El/(y}䰁j>5g?j SǤ_"7Z.nCst$sTZZۥl(-7Wb4z} k.4Vh㢻w@\k()BD)w-.G BP)!T@*E V3,\~踹Ro Nڧ+L;P^LM-aS1{F@%e*~Y4(>VodBJrGOZ:Є@PVårNTZei?k$]I PVPbv^ӳʊ;\;aƠz@(TZ >1׏P9!S8E}%Si.?0!9CRC*E "J@RBP)!T@*E "J@RBP)!TJӧO?>&&h4zDowܹoP\\6ҥKG^v hw[^^Bjjj***]|鬨v!yuuuVۅUVV=zU,44Ts͝;۵-\pv!mh4{?ko{~?o߾ޮ----""UBP)!T@*E "J@RBP)!T@*E y((55uΜ9#Fv!y3fvya'Ov!yƍ[]|TNr:ޮ\2 *E "J@RBP)!T@*E "J@RBP)!T@*E "J}RuuSO=_[Xrѣ"##g͚w^EW֞}iՒJW.ܹs-k{=ut}  kϾA \r̙;v츢U8(A-5'O}$i4N-˒%KVa0yN(]J;g}Ӂ%!!Gf͚WvI&Y]s_;/\Q6Bcۯ!DXXXVVVYYY}}ƍ#0`@}}}[~t\}Gݮ]:U+hxb!ҥK8vX x]EEE=|Mcccuu믿n4O?ndߗ8(UcccZZ|Hic !O?T>H}7󃃃of+WUU !zsBL8Q%s_r:_⣏>RLtu=b&y{!D߾}[_s_rrP;˖-k:Qܖ@A *=>F}ԩcƌiޞ4g!āZY}f944tۗ.]*صkWaaa׌"77Wѯ_?j8zoj2}t!Dnnn]]]+sPBvK\ܹ^:th JP!pbС]zBݻ3ftnjt:ӑ kXXX(IR߾}>O>wygzzzsA Mڹ/qPB UUU{`ʒ/>~׮]/BNNfKKK|G Beyg\m6ۊ+]w]qPBvK’%K ^z%#L+8(A>fȐ!n۷l_!ϟeeeB.V|iVQQь3pl߾}YYY֭-:rHvvvIIɧ~z7xU8(ؗ8(+WYfҤI/hEJP!.vmBE5%0Z9]d~ھ/={Vt:/^|T\\ow}FaÆx駟>x`XXغu *UK$?? [reӼmA *BvرGydB;G˷qt:Ev6W/,]tM5,^xРAƍFW2};w7{[Yܺ}dv}޼yYYYW:%pv1͏=|sDDʕ+۲|w׮nIwtn_j̙3?O;jٳ6lм])==]jО}?888''g->aIvн\{Bק>|xB#GJs_ٍ7huG_j5ͭl71ȟozPRRҴ3< ͷ裏 !t:M&ӫ* [ni˻͢EΝ;t:+**={ !x/$xêU$-[… f͚5f͚|aJhE;%JhpPN'͛״|h,_!3t7_z4_e`0V/_/^#4 Fj~L;%JS 8yʨotR}}};7b4m / :?33sƍo;Hٗ-[v &%%i4}zk֬Yzuppp /oܸn$)%%e֬Y+VطoqPBvK!8(Am$^BP)!T@*E "J@RBP)!T@*E "J@RBP)!T@*E "J@RBP)!T@*E "J@RBP)!T@*E "J@RBP)!'L-t3B@WOw...ZΝ۲e?bĈ#Gx+3i$F#ؽ{k-[lڴɵwϞ=BAEGG_>`AAA7.>k644466^xwMMM=} 7PUU2@DDİaÄ@XZZz!߮n۷O1yd%%%eӦMJ7|Vt3B@FO[Çj ,ؽ{w^ /_2̔)S{۷nt:(Iґ#G 9rN4 wV@Zʄ ,p퍊Zh/hX&t;m!'ڣG6o뮻ZQ޽{:B t-MׂVVV]`޼yoO>٢j⋳f͊ѣGzz믿 4wu$I۷o裏trױkرaaa=z:teΟ?k„ z^Q)'iӦ͜9S\5*@.ϧq}̷~{^s5|kLKK$?l{o̘1!!!=zXfUR/qЕ !_qܑ#GmZV~bРAMyBiɄo6W\ Ʀ%###O>ݴ#G"Ǐ/;Z{!DDDn_hhjmZwBe˖5|GB[~Wz뭙Bt>gBL0aۻm6!İa~ !z}rrr^y6 3%00矗$ԩS'Nӧ~kבt:=믿ݲe;v7l˿;oVYYYMMͦM Ν(/SZZ644<fbdgg8/&N IDATU46g DNhƌ^SS-g#n t+;;GZ7po6O###f̘ .طo_CCCRRo/jcǎ~'hz.s]aas9ʏ j򅠛7o{u:]FFF+/)5kֆ z}~m7azb۟x≥KF!Ddd[o%xP 3g~WEEE~C=4h !DNNk6f̘iӦ5?an:!~[hF-߰$22O>[fϞmrss[V[[+hqʱƎ/s^LiʽF ͪ*>+IRM(IwIϞ=q-K79:oG111sΝ;w|ӦMΝ;ٳggggˁĉBUVm߾N>-o8fױΜ9#(IVB;vΝ;rH^ј_ٳg޼y;wX,LHH>}$I*))~S<ͥ$$$\p-Ņh@7F t-&pFRϟ?+toٲE>&g|[ s]W^B"b0W^|y,:.55uʔ)Uɓ'B9[N>766vذaڼyܹsGδE{ j%eΜ9AAA/yX!đ#G ޽{==BͷP\\YyF9 wqĉ ~yyyfرc8\cǎUUUmݺU0 !f̘!ؼy~kٌFqZ٠7/pmT@Z'/=-`Z&_q1ׅ:qƦ Ae~|k|饗˗/wndIz/Ɉ#BCCNgVVӧ&N|֭[k!DzzA'OKKk1~zL!Z_/xg&L3dܸq!!!UUUoE!!!x ټOSkeh@Z222LΜ9sݺu߱cŋ-[&_,%K 8ɓ;v쨯w8{2eJeeѣ]m[V\YUUe2m6f̘G}T^@/REEܒw]wɓ1\tEj;9ɗ^T~4 !y!g}v78/W(_ꪍ7?'Y, zկZraQ!Vm B+))iZ;B̟?_ܴQB]v5-yAyF>јڣG!DPP/,/ߧO-[8 !FWZ9?O700b裏_}U^/0Ç?cBiI \|'OKKsD~Ξ=Ɨ9!t9zwٷo~GDD믿~ٲeyyy=\Uzw'O IOO_rȑ _{O:bQF=Çj~"q}S\\ܿG}ɓ<˓JKK~A%2u9322b^~ݻwϟ?:O>O>={BBBZ,ꫯ1BVUUx+@$^Ϲ뮻VZ/?#ޮ !T@*E HTTTRRVP'**BP)!T@*E "J@RBP)!T@*E "J@RBP)!T@*E "J@RBP)!T@*E "J@RBPK!cIENDB`simplermarkdown/inst/examples_output/figures/test.pdf0000644000176200001440000002231214142455164023027 0ustar liggesusers%PDF-1.4 %ρ\r 1 0 obj << /CreationDate (D:20211109122436) /ModDate (D:20211109122436) /Title (R Graphics Output) /Producer (R 4.1.1) /Creator (R) >> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 7 0 obj << /Type /Page /Parent 3 0 R /Contents 8 0 R /Resources 4 0 R >> endobj 8 0 obj << /Length 5479 /Filter /FlateDecode >> stream x]K%G.Xb Yb4[bXG`h-'39'<qOfTfDƣ^=Wo>|i:mc,r^~ǯ߽<w=?my|V﫷cݏi^w1i?+qNetޕYI|h?=IeGMuZsNrNJ p뇷w(Ӳbt5Q9`9LrӺ""!\WPRhCJVOVq{ef_y+$D>XEⰾ5WsB}j]WW ^t_괄.i@55WsR m3]zֽ[*6Yyy7]G"W >qX}9)6ęP[rOeS*U%.eRk3TRf!?Ư9s R96(sKNMuku {!=-ki;+f֭RtmK;!%t$VT&瘖#696k-9v{x3+2`̬ P8iVdNQx0;q xȀi˺CBlgY֭\ ,xt};EsKNu_H]ծ`Vښm%4bEݬ8V8rlPnVS/`v\a۔-)Tٲ+[Z#C,{,rmSRU-[jQNMu\$8yx2 y?SK*\$8̅ ht-9"r>2aea,úJzP܍8du5s>IiPtL}2iT6S8I,Dd@ GM9'8u0R9zC[YjoF4)3w ,-⬽(lF];'QYC"8g?9vX@H]%uDg罰k{X;'QgògaQ^TK=exWjRYs~2_aR ŠX;a 5vʘr7zJ&F{1:^+}W/%({A4.1}iYR:~ %Y~ y//K*aqp cVc1)^]c2ɡb,tekݽ5\l<ŁKw[rjJ=80s].i.B,,tq`4v榜zzŴE-S:;S>#]T8X[a;EsSNu_y4Noϰ 9BWXNܒSS`s%8'V}YJb_d:dc_bn+YF,ܥVm,냳q9/ΫrέsNwXyO5'gVg+96k-9v{,+]CY\(Mc^QXr’c{Y\#vc,+q`1m6&9XQ/慅?h v{ܗJj.צ:fkr@Hu`q%`w ErEq18݌Wg$G,T}qE\57ԋX{1{qYh'Æ%"j|M9"YāȵnX;P/c݅}_ `|ḵAHNMO{cX>&r*,-ڴcy"Tc |LsSNuy&_y#T}koTg]DbIY-&)bYkql8A98CQV0;HT0j3!Q 9ZTè[z`K ޱXVJ(gXQ+A#c[ܒS/`gɶkpzT㡭*}(ĊkpzTXU5v]5 A׫+yA⠥=jw揷q1H n`Ee;\ec[;sKNUؿ0ڝ ץ2M[L ,̓A+,`y榜z-P-f"֖ם )9"VX}ܐK/`Kpz`< ɑ+*KpzCcg|ܒS/`_~y}MCaN[̷x1r7 e8ȩeű-ܒSSb]1sLE#xN1ϰsyQ889ܔS/`GRծ)wM[nI ,ZCb;rl-9kkyۇygy ya Z3y9w<]iw Z+CsS.fc\^ܛ+nHL9\bEbF|/VjbLz-^,ƶ3y]3y]N;2L373y'xRL&egrȩfgr瘽K=+YtITK"4KX{ܗxCꗵ9m|_$Ǻ K|_Y͍m~ 9ڭ~_tNgo\_V|޸(Ēxpz[X5v57A=_>Kp>Z誵gJu'VT ;grSG|K=@ǂs|+Ǝ|,\z;wzYāJbl}TcT9ԇXʱ8KXrVsڝ^'rz9斜vfy0d{o| È^hhnɡE v :Z=CqQXRa&qc[ܒC/a]a|È6%8.w/z,9+*%8`:%a+XOzy\;qm%Ǻ K*{}۳iil`]1K)}_9ʷ%e/|X>6ܒSS`_-/ߗFȯĠ^4)=Db)IN2LNh_{VGM(>&LyWoy8x9:ytkl^=]{p5Do97a3mښ?˗UAW%r('r49ö䩟?=JlBi7?xW'\_~x> o$[uG-˯doMo{)k ǿ>ѿ쒥k~5_|矽~_~ij.]U_?w?O!??^+endstream endobj 3 0 obj << /Type /Pages /Kids [ 7 0 R ] /Count 1 /MediaBox [0 0 576 432] >> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << >> /ColorSpace << /sRGB 5 0 R >> >> endobj 5 0 obj [/ICCBased 6 0 R] endobj 6 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 9 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus 96/quoteleft 144/dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space] >> endobj 10 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica /Encoding 9 0 R >> endobj xref 0 11 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000005843 00000 n 0000005926 00000 n 0000006038 00000 n 0000006071 00000 n 0000000212 00000 n 0000000292 00000 n 0000008766 00000 n 0000009023 00000 n trailer << /Size 11 /Info 1 0 R /Root 2 0 R >> startxref 9120 %%EOF simplermarkdown/inst/examples_output/figures/foo.png0000644000176200001440000002643114142455164022654 0ustar liggesusersPNG  IHDRJ NPLTE  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~]} IDATxXGÀIbI,`DSL#xi v{%`h4{CbPD@DE8f0dNufgX XP L8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCKw?5ൺ!T0PK\?T [EkOP@1NP@9`Ɨ%134Q !7R=1WE1 ^R=ADIMw}HnjId`*L Fs_3l8a0DTҾiND/*םQ|}mh*p`¡ &*؜9=][*|IU_%ljQ% Ԝ 6_jQˈf`~"͉`㠗|hDMVqZRSƎiSs :j}- 67P0BHeuPmrpSFtɩ`R8/0Lq^I *3֪Dֱu% g]-~: "vk(߷zCsm%` +`[ő7 u64T0'C`w +v Vs. BZs= 0 d*Z=:à?|p{~ 7As {Wj\kD£{OHSytsFFP\7V%߆V3G>is8ڱHġr2g8u9k #6GY G"P+&26Tl#hU08՞WMv]P: w&`-mtG`P3>TGh?f_,đ#|"6xPXD|52Ϲvgqn))ɇ/cF` Yfba4N9vS1ji *wty=KɒH`1^ г˨" x<t/\` ^o]g[L׭>[*'C'$o`Yo=Rt?cƒ ֑σ(+ *XG.eNZӕ7T0/w) #[à_y_V`]jS[9.J`xB$uP:Mw7jԮ*%\ljnmX͊{ Gff5£X.={*lksO͎q o+^u ^lY꾏ӆ^M 3qfٮg_#5tUs cAk ]_5chZ3ryFovZzuW`;şQ7&NJ[Kz(l!t;s2qNp1hE,-06~df2Hs.ĪFYSe?=$L=9< #{>=e )A6ȬR4]|#Ra3MA6ʞ .:]0s uT61 6oaŹ`Q /?GWG~R/eoTZlB[BSaK'ںxqN7fip&m\2GFU4VUP+~C,S+`nXёh: }1\=CcX噒$XT@`Eٕ`LcSNLyG3t@ÚwU2-ּw&iPP :vh k7Oi5Wf%8&)(CD7]]C*{3HHurZX\;\T˘b8sz=ni&dQ g;\Nj.pо;iMܥ{Rߦe<՚ }'!,dq¼M,1xs ‚oTL]ݬ >lrK\gw8I|oiӏfWc6Qr86O$n2DhģpgPX4A5V0]{c4`C μկǸag -6kWov0[Ɗ Lp}7e<w6`}k = #t8nhŠyq}S-e8o|.\c# '|B?*S׏~2S wa\H<kTO^q +V:0_K$=ړBq jREzK{wb{\&qzMUotvXyǁ]rrS%]8יI]/h#^% 98ptva+/I|DLVg{9\5583|«d ~,4M#I͊ʡVIw5P(W OmP(.?w޽fbx,0L#Y.99bW.6785z&58R]PT0wڄyCpY7N݉ cpu\ @fl&ٿVF1I昁oUё5a֪7V[{[{A -NWl Euv$x$aWh.օny൝j#N1RLR_OoC^X28}2!G nn3|K;\|79䒱‘ !)dUff?=%{2nsfn ~8W^]8B|>8*,_v:c?Lh |6"x5qd'GWn#Qpܟ!: k*6tNsjI6:OF@ 鶸\5/ ]•JoH x ɏޒ?Ge=jDSmx0'GFoxl"21f{%vpUU^Ono~48&~t!hLiEkO聮ށݠvFn(͘RGq0Phu.PBEڄ/e9>ɜN2mx0E—2{DGO>cV=Hk ʮRWq |\((O|痍t'urkgNmaOH@3~tXoBݒ&i^al _8Q93C΁kB0HK12@rrGG@ZwqaжX`˱H.A f[UWn ;ƍ74&UE`+ES *Y`WQUNK^ Ypׁ.%^({  iUח">3 /X@K6WdseOɤ-'0ol[Jxz-G&^+-oǤX Ng3~ sy,9s@ CV, 2?X-=S1,o^ZQ0{z3ȲoӖR~s`m,&u6LdvB1#(~p8Z. SlE -̼8!?Ɂk^Za~pNSy.Ո xɪӘWT ۳a<yL ̎P^^%SOp0x%`A'xE}-sX1*T lEu9)@ D8T0Hpa( ~n[1''qXwlˬfT{;pm@)ނ=`q^')]> p lζ }r8y3o1[1 4wS=a;QW9-xm0\,@QNDΆFVtt( /oV!c|bCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0PCL8T0@p:fFS@ow!ˤނmf }q[plBIK >?:}q[p09~E 5o;Ӡ-o++{)8w*+{voW>'HE H{b T'@εyݻ ~zsҽ q`oKwvzUPA`恿?>:l\^W+b`¡ &s9λϾZ9_@1SA=τ9\:ւ_:{f~F,be".\-ȭu{, :1ʅ qe͌0E ,) =idU+89 `z⣄we*=tV7u6&:]"09rtӲ~?\8o}r8 s]IbS:\y",467ՙuVV)/С <{hWq%0A 2kJ7}Z]aW:ZHpskSKp82E/etyU!X4O1._ёVܙ ~=V:ו>g"[Ws~8e˸{=rbApQS7_km{,r:6%Ytm5+ i0m{#SuCM9'V\sxGi AŁ: PF0Q >-?GETf P F&kWgU/'V?-4%1Y⃂^*2KQ֣{*en]uWe~ZnPأȚP V\Rd}X IDATVUf8&jXdN[F;t?\1z~i0L-xe( nOdD}Ŋ[]m`PM'~DgPs+⣬ȑ뱖iP&Ԃ98?OhM`TV'Ȟ"e@ZpKځT8HnkdšA Yw(V4h4:|\`q1y#ejkYodYssshsYh1?X4[XY T*9ԣ6[[6n4?cj n/7Ru=$;WÖgu9ꠡIoL&S  N: R~8Gb`'+ѽfOԂ=3` `=$s-s4 13-N<9咊^h@\$Qװy t|(Z|-- 浃w,]oWa 䍬W`}+|f*rګYږH(w{I2}_QGv}r5gvdQwʦsn^ 9Cbgm.vY\hgd?EfU%k~*=FڜApN+3jh\I0S;bt]e1&}R3ǾCޥ∇$M$8IHJ0.˸)L8T0PCL8T0Pc4YXX`tJwuX%Yp+ItUII:[ .TriNN%F|*)Ɂ[4'''GVݘUVb,bwUҗ;ʂ[6$nk|(# ~e}W!8ƲeXJm @'ud$˷ >5d$ގaUbrdkOjQ.`(i,0KV`7kO%%9pZ1SddE:o*15#R0E*V.E^d%w1%ET xTR” a`ũbKZaUb}V̢*z{"(Gkt_,>QII:A')ɂ[@>|SZ~nLnړH5<#9,HMsSII:*&R:s5ŪĸU회^aiɂ[Ֆ=^$n ?|,9ړE8T0PCL8T0PCL8T0PCL8T0PCL8T0PS/ (WQ2j5V};-ac]V\ TpIo׺sPi ͠]p%*X(lؿ6ha]q_2 'AEހs? vtmS]E`Ehovgil *V_;]M'|lWr/pQ,3vlJGbt^4+D[%/?Jk%a`~h:B~\bz0Zy7{qOl/.$| +ӔL]9ܷq62ǯiw@"#pm`j@Sf |Jֶ$@;V|I`exh &.Bps`Ä 7!߂m2/Y-8 ޺`ǯj?U)-X GFl7yՁFvfHR&^YYxW f;Т-4PpDR2R/b3A`gƁiҾdg6-֏ZOۻe8W-Q PX|RJJ`cPq`Rt[V&rG_wx ep˦m9g B`u^ol+T0PCL8T0PCL8T0PCL8T0PCE hIENDB`simplermarkdown/inst/examples_output/iris.R0000644000176200001440000000100214142455163020772 0ustar liggesusers# table aggregate(iris[1:4], iris["Species"], mean) # figure pal <- hcl.colors(3, "Dark2") plot(iris$Sepal.Width, iris$Sepal.Length, pch = 20, col = pal[iris$Species], xlab = "Sepal Width", ylab = "Sepal Length", bty = 'n', las = 1) legend("topright", legend = levels(iris$Species), fill = pal, bty = 'n', border = NA) # library(MASS) m <- lda(Species ~ Sepal.Width + Sepal.Length, data = iris) p <- predict(m) predicted_species <- p$class table(predicted_species, iris$Species) simplermarkdown/inst/examples_output/example1.md0000644000176200001440000000361714142455164021756 0ustar liggesusers--- title: Title --- Header ====== - List item - Another list item And some text with `inline code`. ``` {#codeblock1 .R} > a <- 1 + 1 > b <- mean(a) + 10 > c <- a + b > c [1] 14 > dta <- iris ``` And some text : Sample iris |Sepal.Length|Sepal.Width|Petal.Length|Petal.Width|Species|foo | |------------|-----------|------------|-----------|-------|---------| |5.1 |3.5 |1.4 |0.2 |setosa |0.6862745| |4.9 |3.0 |1.4 |0.2 |setosa |0.6122449| |4.7 |3.2 |1.3 |0.2 |setosa |0.6808511| |4.6 |3.1 |1.5 |0.2 |setosa |0.6739130| |5.0 |3.6 |1.4 |0.2 |setosa |0.7200000| |5.4 |3.9 |1.7 |0.4 |setosa |0.7222222| |4.6 |3.4 |1.4 |0.3 |setosa |0.7391304| |5.0 |3.4 |1.5 |0.2 |setosa |0.6800000| |4.4 |2.9 |1.4 |0.2 |setosa |0.6590909| |4.9 |3.1 |1.5 |0.1 |setosa |0.6326531| |5.4 |3.7 |1.5 |0.2 |setosa |0.6851852| |4.8 |3.4 |1.6 |0.2 |setosa |0.7083333| |4.8 |3.0 |1.4 |0.1 |setosa |0.6250000| |4.3 |3.0 |1.1 |0.1 |setosa |0.6976744| |5.8 |4.0 |1.2 |0.2 |setosa |0.6896552| |5.7 |4.4 |1.5 |0.4 |setosa |0.7719298| |5.4 |3.9 |1.3 |0.4 |setosa |0.7222222| |5.1 |3.5 |1.4 |0.3 |setosa |0.6862745| |5.7 |3.8 |1.7 |0.3 |setosa |0.6666667| |5.1 |3.8 |1.5 |0.3 |setosa |0.7450980| ### And some text The mean of `Sepal.Width` is 3.06. This is larger than 2. Geen R-code ![My figure](./figures/test.pdf) ![](./figures/foo.png) simplermarkdown/inst/examples_output/example1.R0000644000176200001440000000052614142455164021553 0ustar liggesusers# codeblock1 a <- 1+1 b <- mean(a) + 10 # Dit is commentaat c <- a+b c dta <- iris # dta$foo <- dta$Sepal.Width/dta$Sepal.Length dta[1:20, ] # warning("FOO") plot(dta$Sepal.Width, dta$Petal.Width) # md_figure({ plot(dta$Sepal.Length, dta$Petal.Length) }, name = "foo") simplermarkdown/inst/examples/0000755000176200001440000000000014140260557016267 5ustar liggesuserssimplermarkdown/inst/examples/iris.md0000644000176200001440000000327614140224214017555 0ustar liggesusers--- title: An analysis of iris --- Introduction ------------------------- From the help page of the iris data set: > This famous (Fisher's or Anderson's) iris data set gives the > measurements in centimeters of the variables sepal length and > width and petal length and width, respectively, for 50 flowers > from each of 3 species of iris. The species are _Iris setosa_, > _versicolor_, and _virginica_. Descriptives -------------------------- The table below shows for each of the iris species the mean value of the colums in the data set. ```{.R #table fun=output_table caption="Mean values for each of the properties for each of the iris species."} aggregate(iris[1:4], iris["Species"], mean) ``` ```{.R #figure fun=output_figure caption="Relation between sepal length and width for the different iris species." name="iris" height=6 width=8 units="in" res=150 echo=TRUE} pal <- hcl.colors(3, "Dark2") plot(iris$Sepal.Width, iris$Sepal.Length, pch = 20, col = pal[iris$Species], xlab = "Sepal Width", ylab = "Sepal Length", bty = 'n', las = 1) legend("topright", legend = levels(iris$Species), fill = pal, bty = 'n', border = NA) ``` Species prediction --------------------------------- ```{.R} library(MASS) m <- lda(Species ~ Sepal.Width + Sepal.Length, data = iris) p <- predict(m) predicted_species <- p$class table(predicted_species, iris$Species) ``` This model predicts in `round(mean(predicted_species==iris$Species)*100)`{.R}% of the cases the correct species. However, this is mainly for *setosa* for the other species the model predicts the correct species only for `sel<-iris$Species!="setosa";round(100*mean(predicted_species[sel] == iris$Species[sel]))`{.R}% of the records. simplermarkdown/inst/examples/example1.md0000644000176200001440000000137214133461355020331 0ustar liggesusers--- title: Title --- # Header - List item - Another list item And some text with `inline code`. ``` {#codeblock1 .R echo=TRUE results=TRUE} a <- 1+1 b <- mean(a) + 10 # Dit is commentaat c <- a+b c dta <- iris ``` And some text ``` {.R fun=output_table caption="Sample iris"} dta$foo <- dta$Sepal.Width/dta$Sepal.Length dta[1:20, ] ``` ### And some text The mean of `Sepal.Width` is `m<-round(mean(dta$Sepal.Width), 2)`{.R}. This is `ifelse(m>2, "larger", "smaller")`{.R} than 2. ``` Geen R-code ``` ```{.R fun=output_figure name="test" caption="My figure" device="pdf" width=8 height=6} warning("FOO") plot(dta$Sepal.Width, dta$Petal.Width) ``` ```{.R fun=output_raw} md_figure({ plot(dta$Sepal.Length, dta$Petal.Length) }, name = "foo") ``` simplermarkdown/inst/doc/0000755000176200001440000000000014164652625015225 5ustar liggesuserssimplermarkdown/inst/doc/intro.html0000644000176200001440000004022114164652625017245 0ustar liggesusers simplermarkdown

simplermarkdown

Introduction to simplermarkdown

First write a markdown file using pandoc markdown. The package uses pandoc to parse the markdown and runs any code blocks tagged as being R-code. The result a new markdown file that can be further processed using pandoc and compiled to, for example, PDF or HTML.

To process your markdown file you can use the mdweave function:

mdweave("mydocument.md", "mydocument_woven.md")

The resulting document mydocument_woven.md can then be processes further using pandoc.

Below is a ready to run example using an example document in the package:

library(simplermarkdown)

example1 <- system.file("examples/example1.md", package = "simplermarkdown")

mdweave(example1, "example1_woven.md")

system("pandoc example1_woven.md -o example1.pdf")

The package also includes the functions mdweave_to_pdf, mdweave_to_html and mdweave_to_tex, that combine these last two function calls. Therefore, the example above could also have been written as:

library(simplermarkdown)
example1 <- system.file("examples/example1.md", package = "simplermarkdown")
mdweave_to_pdf(example1, "example1.pdf")

Although it is possible to pass additional arguments to pandoc through the mdweave_to_... functions, it is probably just as easy to call pandoc directly.

Writing markdown

An example of a basic code block tagged as being R-code is shown below. The id/label if the block is codeblock1.

```{#codeblock1 .R}
a <- 1+1
a
```

By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. In the output file this will result in

Note that the .R needs to be the first argument starting with a . for the codeblock. For example ```{#codeblock .foo .R foo=bar} won’t be evaluated, while ```{#codeblock foo=bar .R .foo} will.

By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. Arguments can be used to suppress either showing the code or the output:

```{#codeblock1 .R echo=FALSE results=TRUE}
a <- 1+1
```

Inline code is also supported. Again it should be tagged with {.R}:

The average value of `Sepal.Width` is `mean(iris$Sepal.Width)`{.R} and 
that of `Petal.Width` is `mean(iris$Petal.Width)`{.R}.

The final result of the inline code will always be included as text into the resulting markdown document. In case of code blocks the code is passed on to a function. Depending on the function used this can result in a code blocks with the evaluated code (the default), tables, figures and you can also specify your own functions.

Figures

To generate a figure use the output_figure function. The function will run the code, capture any output on the specified device and generate a markdown image include.

```{.R #myfigure fun=output_figure name="test" caption="My figure" 
  device="pdf" width=8 height=6}
plot(dta$Sepal.Width, dta$Petal.Width)
```

output_figure accepts the options caption (default none), device (possible values are "png" and "pdf"), echo (default FALSE; echo the commands to the output) and results (default FALSE; show output of the command (other than the figure) in the output). Additional arguments such as width and height are passed on to the device (in this case pdf()). When an id is given for the code block (as #myfigure above) this is also added to the figure.

The figures are saved in the folder figures in the current folder. This can be controlled by the dir argument.

Tables

To generate a table, we tell it to pass the code in the code block to the function output_table from the simplermarkdown package. This function will take the final result and generate a markdown table from that. Any additional arguments of the code block are passed on to the output_table function.

```{.R #mytable fun=output_table caption="Sample iris"}
dta$foo <- dta$Sepal.Width/dta$Sepal.Length
dta[1:20, ]
```

output_table only accepts the caption argument. Unfortunately, pandoc does not yet support adding id’s to tables at the moment without the pandoc crossref filter. Therefore, simplermarkdown also doesn’t add the id to the resulting table as this would interfere with regular pandoc use. Should you want to add an id to the table in order to use it with the crossref filter: you can either do

: Sample iris {#mytable}

```{.R fun=output_table}
iris[1:5, ]
```

or

```{.R fun=output_table caption="Sample iris {#mytable}"}
iris[1:5, ]
```

Other output

By using the output_raw filter, any other output can be generated. This function will run the code, capture any output and put that directly into the resulting markdown document. For example, let’s print a list with all of the iris species:

```{.R fun=output_raw}
writeLines(paste("-", levels(iris$Species)))
```

Or you can write your own filter function. This function will get the code in the code block as character vector as it’s first argument, the language of the code block, and the id of the code block and any other arguments given.

For example:

print_in_bold <- function(code, language = "R", id = "", ...) {
  cat("\n**", code, "**\n", sep = "")
}

This function could for example be defined in a block in the markdown file. Afterwards, this function can be used in your markdown document as:

```{.R fun=print_in_bold}
Hello World!
```

Using as a vignette engine

To use simplermarkdown as an engine for your R-package vignettes you will need to do the following:

Specify simplermarkdown as your vignette builder in your DESCRIPTION file:

VignetteBuilder: simplermarkdown

Add simplermarkdown as a dependency of your package.

If your package doesn’t use simplermarkdown otherwise you can add it to your Suggests field in the DESCRIPTION file:

Suggests: 
    simplermarkdown

Use the extension .md for your vignette.

Create the vignette in the vignettes directory in your package source.

Specify the vignette engine in your vignette.

You have to add the following line to your vignette:

%\VignetteEngine{simplermarkdown::mdweave_to_html}

Instead of mdweave_to_html you can also use mdweave_to_pdf to generate a vignette in PDF format. It is easiest to do this in a comment section in your markdown file. For example, start your markdown file with:

<!--
%\VignetteEngine{simplermarkdown::mdweave_to_html}
%\VignetteIndexEntry{The title of the vignette}
-->

---
title: [The title of the vignette]
---

[And the contents of your vignette]

Custom styling

By default the default templates and styling of the pandoc installation on your machine will be used. However, you can also specify custom styling in the header of your markdown file. See the documentation of Pandoc for more information. For example, if you generate HTML output and you want to use a custom CSS-stylesheet, you can place the stylesheet in the vignettes directory and refer to the stylesheet in the header:

<!--
%\VignetteEngine{simplermarkdown::mdweave_to_html}
%\VignetteIndexEntry{The title of the vignette}
-->

---
title: [The title of the vignette]
css: custom_styling.css
---

A note about paths and working directories

simplermarkdown tries to assume as little as possible about possible workflows. However, this also means that you, the user, are responsible for some things where other packages might make assumpptions. One of the places where this is the case is for paths and working directories. And this is especially relevant when including figures and when generating figures using R.

As an example take the following project directory:

report/
   report.md
   figures/
     figure1.png
report/output/

The report contains the following code:

![Figure caption](figures/figure1.png)

```{.R fun=output_figure name="figure2" caption="Caption", device="png"}
plot(1:10)
```

Assume the current working directory is the root of the project directory and that we run mdweave as:

mdweave("report/report.md", "report/output/report.md")

Figures are by default created in the directory figures in the target directory. Therefore the directory structure after running mdweave is:

report/
   report.md
   figures/
     figure1.png
   ouput/
     report.md
     figures/
       figure2.png

And the resulting markdown file will contain the following markdown:

![Figure caption](figures/figure1.png)

![Caption](report/output/figures/figure2.png)

As you can see, we now have two locations with figures. When running pandoc from the root directory of the project to create the final output:

pandoc report/output/report.md -s -o report/output/report.html

pandoc will not be able to find the first figure. It will find the second figure. When you would run the final pandoc command from the report/output directory. pandoc will not be able to find any of the figures.

There are several possible solutions for the example above:

  • When working on linux or mac, you could create a symbolic link from report/output/figures to report/figures.
  • Copy report/figures to report/output/figures.
  • Path of least resistance: run mdweave and pandoc from the report directory and also put the output in the same directory.
  • And probably others.

Note that the same issues occur when referencing stylsheets etc. in the meta block of the markdown file.

simplermarkdown/inst/doc/intro.md0000644000176200001440000002356014163070760016701 0ustar liggesusers --- title: simplermarkdown css: "style.css" --- Introduction to simplermarkdown -------------------------------------- First write a markdown file using [pandoc markdown](https://pandoc.org/MANUAL.html#pandocs-markdown). The package uses pandoc to parse the markdown and runs any code blocks tagged as being R-code. The result a new markdown file that can be further processed using pandoc and compiled to, for example, PDF or HTML. To process your markdown file you can use the `mdweave` function: ``` mdweave("mydocument.md", "mydocument_woven.md") ``` The resulting document `mydocument_woven.md` can then be processes further using pandoc. Below is a ready to run example using an example document in the package: ``` library(simplermarkdown) example1 <- system.file("examples/example1.md", package = "simplermarkdown") mdweave(example1, "example1_woven.md") system("pandoc example1_woven.md -o example1.pdf") ``` The package also includes the functions `mdweave_to_pdf`, `mdweave_to_html` and `mdweave_to_tex`, that combine these last two function calls. Therefore, the example above could also have been written as: ``` library(simplermarkdown) example1 <- system.file("examples/example1.md", package = "simplermarkdown") mdweave_to_pdf(example1, "example1.pdf") ``` Although it is possible to pass additional arguments to `pandoc` through the `mdweave_to_...` functions, it is probably just as easy to call `pandoc` directly. ## Writing markdown An example of a basic code block tagged as being R-code is shown below. The id/label if the block is `codeblock1`. ````` ```{#codeblock1 .R} a <- 1+1 a ``` ````` By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. In the output file this will result in ```{#codeblock1 .R} a <- 1+1 a ``` Note that the `.R` needs to be the first argument starting with a `.` for the codeblock. For example ` ```{#codeblock .foo .R foo=bar} ` won't be evaluated, while ` ```{#codeblock foo=bar .R .foo} ` will. By default the code in the code block is run and both the code and the output of the code are shown in the generated new code block. Arguments can be used to suppress either showing the code or the output: ````` ```{#codeblock1 .R echo=FALSE results=TRUE} a <- 1+1 ``` ````` Inline code is also supported. Again it should be tagged with `{.R}`: ``` The average value of `Sepal.Width` is `mean(iris$Sepal.Width)`{.R} and that of `Petal.Width` is `mean(iris$Petal.Width)`{.R}. ``` The final result of the inline code will always be included as text into the resulting markdown document. In case of code blocks the code is passed on to a function. Depending on the function used this can result in a code blocks with the evaluated code (the default), tables, figures and you can also specify your own functions. ### Figures To generate a figure use the `output_figure` function. The function will run the code, capture any output on the specified device and generate a markdown image include. ````` ```{.R #myfigure fun=output_figure name="test" caption="My figure" device="pdf" width=8 height=6} plot(dta$Sepal.Width, dta$Petal.Width) ``` ````` `output_figure` accepts the options `caption` (default none), `device` (possible values are `"png"` and `"pdf"`), `echo` (default `FALSE`; echo the commands to the output) and `results` (default `FALSE`; show output of the command (other than the figure) in the output). Additional arguments such as `width` and `height` are passed on to the device (in this case `pdf()`). When an id is given for the code block (as `#myfigure` above) this is also added to the figure. The figures are saved in the folder `figures` in the current folder. This can be controlled by the `dir` argument. ### Tables To generate a table, we tell it to pass the code in the code block to the function `output_table` from the `simplermarkdown` package. This function will take the final result and generate a markdown table from that. Any additional arguments of the code block are passed on to the `output_table` function. ````` ```{.R #mytable fun=output_table caption="Sample iris"} dta$foo <- dta$Sepal.Width/dta$Sepal.Length dta[1:20, ] ``` ````` `output_table` only accepts the `caption` argument. Unfortunately, pandoc does not yet support adding id's to tables at the moment without the [pandoc crossref filter](https://github.com/lierdakil/pandoc-crossref). Therefore, simplermarkdown also doesn't add the id to the resulting table as this would interfere with regular pandoc use. Should you want to add an id to the table in order to use it with the crossref filter: you can either do ```` : Sample iris {#mytable} ```{.R fun=output_table} iris[1:5, ] ``` ```` or ```` ```{.R fun=output_table caption="Sample iris {#mytable}"} iris[1:5, ] ``` ```` ### Other output By using the `output_raw` filter, any other output can be generated. This function will run the code, capture any output and put that directly into the resulting markdown document. For example, let's print a list with all of the iris species: ````` ```{.R fun=output_raw} writeLines(paste("-", levels(iris$Species))) ``` ````` Or you can write your own filter function. This function will get the code in the code block as character vector as it's first argument, the language of the code block, and the id of the code block and any other arguments given. For example: ``` print_in_bold <- function(code, language = "R", id = "", ...) { cat("\n**", code, "**\n", sep = "") } ``` This function could for example be defined in a block in the markdown file. Afterwards, this function can be used in your markdown document as: ````` ```{.R fun=print_in_bold} Hello World! ``` ````` Using as a vignette engine ----------------------------------------------------------------------- To use simplermarkdown as an engine for your R-package vignettes you will need to do the following: #### Specify simplermarkdown as your vignette builder in your `DESCRIPTION` file: ``` VignetteBuilder: simplermarkdown ``` #### Add simplermarkdown as a dependency of your package. If your package doesn't use simplermarkdown otherwise you can add it to your `Suggests` field in the `DESCRIPTION` file: ``` Suggests: simplermarkdown ``` #### Use the extension `.md` for your vignette. Create the vignette in the `vignettes` directory in your package source. #### Specify the vignette engine in your vignette. You have to add the following line to your vignette: ``` %\VignetteEngine{simplermarkdown::mdweave_to_html} ``` Instead of `mdweave_to_html` you can also use `mdweave_to_pdf` to generate a vignette in PDF format. It is easiest to do this in a comment section in your markdown file. For example, start your markdown file with: ``` --- title: [The title of the vignette] --- [And the contents of your vignette] ``` ### Custom styling By default the default templates and styling of the pandoc installation on your machine will be used. However, you can also specify custom styling in the header of your markdown file. See the [documentation of Pandoc](https://pandoc.org/MANUAL.html) for more information. For example, if you generate HTML output and you want to use a custom CSS-stylesheet, you can place the stylesheet in the `vignettes` directory and refer to the stylesheet in the header: ``` --- title: [The title of the vignette] css: custom_styling.css --- ``` ## A note about paths and working directories simplermarkdown tries to assume as little as possible about possible workflows. However, this also means that you, the user, are responsible for some things where other packages might make assumpptions. One of the places where this is the case is for paths and working directories. And this is especially relevant when including figures and when generating figures using R. As an example take the following project directory: ````` report/ report.md figures/ figure1.png report/output/ ````` The report contains the following code: ````` ![Figure caption](figures/figure1.png) ```{.R fun=output_figure name="figure2" caption="Caption", device="png"} plot(1:10) ``` ````` Assume the current working directory is the root of the project directory and that we run `mdweave` as: ````` mdweave("report/report.md", "report/output/report.md") ````` Figures are by default created in the directory `figures` in the target directory. Therefore the directory structure after running `mdweave` is: ````` report/ report.md figures/ figure1.png ouput/ report.md figures/ figure2.png ````` And the resulting markdown file will contain the following markdown: ````` ![Figure caption](figures/figure1.png) ![Caption](report/output/figures/figure2.png) ````` As you can see, we now have two locations with figures. When running `pandoc` from the root directory of the project to create the final output: ````` pandoc report/output/report.md -s -o report/output/report.html ````` `pandoc` will not be able to find the first figure. It will find the second figure. When you would run the final `pandoc` command from the `report/output` directory. `pandoc` will not be able to find any of the figures. There are several possible solutions for the example above: - When working on linux or mac, you could create a symbolic link from `report/output/figures` to `report/figures`. - Copy `report/figures` to `report/output/figures`. - Path of least resistance: run `mdweave` and `pandoc` from the `report` directory and also put the output in the same directory. - And probably others. Note that the same issues occur when referencing stylsheets etc. in the meta block of the markdown file. simplermarkdown/inst/doc/intro.R0000644000176200001440000000003114164652625016475 0ustar liggesusers# codeblock1 a <- 1+1 a simplermarkdown/inst/scripts/0000755000176200001440000000000014133461355016141 5ustar liggesuserssimplermarkdown/inst/scripts/filter.R0000644000176200001440000000027014133461355017550 0ustar liggesusers library(simplermarkdown) # Filter tree; read from srdin new_dta <- simplermarkdown:::filter_pandoc_json_tree() # Write filtered tree to stcout writeLines(rjson::toJSON(new_dta))