├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── test-coverage.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── add-load-cc-expr.r ├── as-yml.r ├── build-site.r ├── cc-dendro.r ├── chunk-options.r ├── chunk-writer.r ├── class-and-tag.r ├── depth-first-pres-list-visitor.r ├── headers.r └── ld-write-file.r ├── README.md ├── README.rmd ├── appveyor.yml ├── codecov.yml ├── cran-comments.md ├── docs ├── 404.html ├── CODE_OF_CONDUCT.html ├── LICENSE.html ├── articles │ ├── index.html │ ├── listdown.html │ └── listdown_files │ │ └── header-attrs-2.7 │ │ └── header-attrs.js ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml └── reference │ ├── Rplot001.png │ ├── as_ld_yml.html │ ├── create_load_cc_expr.html │ ├── index.html │ ├── ld_build_html_site.html │ ├── ld_bundle_doc.html │ ├── ld_cc_dendro.html │ ├── ld_chunk_opts.html │ ├── ld_create_doc.html │ ├── ld_make_chunks.html │ ├── ld_rmarkdown_header.html │ ├── ld_site_yaml.html │ ├── ld_workflowr_header.html │ ├── ld_write_file.html │ └── listdown.html ├── inst ├── CITATION └── jss │ ├── clean.sh │ ├── cover-letter.txt │ ├── jss.bst │ ├── jss.cls │ ├── jsslogo.jpg │ ├── listdown-jss.pdf │ ├── listdown-jss.tex │ ├── pre-review-response.md │ ├── references.bib │ └── supplemental-material │ ├── .Rhistory │ ├── clean.sh │ ├── jss.bst │ ├── jss.cls │ ├── jsslogo.jpg │ ├── listdown-jss.R │ ├── listdown-jss.rmd │ └── make.sh ├── man ├── as_ld_yml.Rd ├── class_and_tag.Rd ├── create_load_cc_expr.Rd ├── ld_build_html_site.Rd ├── ld_bundle_doc.Rd ├── ld_cc_dendro.Rd ├── ld_chunk_opts.Rd ├── ld_create_doc.Rd ├── ld_make_chunks.Rd ├── ld_rmarkdown_header.Rd ├── ld_site_yaml.Rd ├── ld_workflowr_header.Rd ├── ld_write_file.Rd └── listdown.Rd ├── tests ├── testthat.r └── testthat │ ├── reference-data │ ├── anscombe-quartet.rmd │ ├── as-yml.rds │ ├── cc-dendro.rds │ ├── cc-list.rds │ ├── chunk-decorator-option-1.rds │ ├── chunk-option-1.rds │ ├── chunk-option-2.rds │ ├── chunk-option-3.rds │ ├── chunk-option-4.rds │ ├── ld-cc-list-2-output.rds │ ├── listdown-page-bundle-after-creation.rds │ ├── listdown-page-bundle.rds │ ├── option-check.rds │ ├── option-chunk-check.rds │ ├── site_yaml.rds │ ├── test-make-chunks-1.rds │ ├── test-make-chunks-2.rds │ ├── test-no-package.rds │ ├── test-print-ld.rds │ ├── test-print-with-decorator.rds │ ├── test-rmarkdown-header.rds │ ├── test-setup-expr.rds │ ├── test-workflowr-header.rds │ └── test_list.rds │ ├── reference.r │ ├── test-add-chunk-elem-option.r │ ├── test-add-chunk-option.r │ ├── test-as-yml.r │ ├── test-cc-dendro.r │ ├── test-chunk-opts.r │ ├── test-create-doc.r │ ├── test-create-html-site.r │ ├── test-headers.r │ ├── test-list.r │ ├── test-make-chunks.r │ ├── test-no-list-decorators.r │ ├── test-no-package.r │ ├── test-setup-expr.r │ ├── test-site-yaml.r │ └── test-write-file.r └── vignettes ├── .gitignore ├── comp-comp.rds └── listdown.rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | ^\.travis\.yml$ 3 | ^README\.Rmd$ 4 | ^README\.md$ 5 | ^README\.html$ 6 | ^codecov\.yml$ 7 | ^appveyor\.yml$ 8 | ^CODE_OF_CONDUCT\.md$ 9 | ^cran-comments\.md$ 10 | ^CRAN-RELEASE$ 11 | ^inst/JSS4145_prescreened.zip$ 12 | ^inst/JSS4145_prescreened$ 13 | ^inst/jss* 14 | ^inst/r-medicine-2020$ 15 | ^\.github$ 16 | ^docs$ 17 | ^.*\.Rproj$ 18 | ^\.Rproj\.user$ 19 | ^CRAN-SUBMISSION$ 20 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # NOTE: This workflow is overkill for most R packages 2 | # check-standard.yaml is likely a better choice 3 | # usethis::use_github_action("check-standard") will install it. 4 | # 5 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 6 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 7 | on: 8 | push: 9 | branches: 10 | - main 11 | - master 12 | pull_request: 13 | branches: 14 | - main 15 | - master 16 | 17 | name: R-CMD-check 18 | 19 | jobs: 20 | R-CMD-check: 21 | runs-on: ${{ matrix.config.os }} 22 | 23 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 24 | 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | config: 29 | - {os: macOS-latest, r: 'release'} 30 | - {os: windows-latest, r: 'release'} 31 | - {os: ubuntu-18.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest", http-user-agent: "R/4.0.0 (ubuntu-18.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions" } 32 | - {os: ubuntu-18.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 33 | 34 | env: 35 | RSPM: ${{ matrix.config.rspm }} 36 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 37 | 38 | steps: 39 | - uses: actions/checkout@v2 40 | 41 | - uses: r-lib/actions/setup-r@v1 42 | id: install-r 43 | with: 44 | r-version: ${{ matrix.config.r }} 45 | http-user-agent: ${{ matrix.config.http-user-agent }} 46 | 47 | - uses: r-lib/actions/setup-pandoc@v1 48 | 49 | - name: Install pak and query dependencies 50 | run: | 51 | install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") 52 | saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") 53 | shell: Rscript {0} 54 | 55 | - name: Restore R package cache 56 | uses: actions/cache@v2 57 | with: 58 | path: | 59 | ${{ env.R_LIBS_USER }}/* 60 | !${{ env.R_LIBS_USER }}/pak 61 | key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }} 62 | restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1- 63 | 64 | - name: Install system dependencies 65 | if: runner.os == 'Linux' 66 | run: | 67 | pak::local_system_requirements(execute = TRUE) 68 | pak::pkg_system_requirements("rcmdcheck", execute = TRUE) 69 | shell: Rscript {0} 70 | 71 | - name: Install dependencies 72 | run: | 73 | pak::local_install_dev_deps(upgrade = TRUE) 74 | pak::pkg_install("rcmdcheck") 75 | shell: Rscript {0} 76 | 77 | - name: Session info 78 | run: | 79 | options(width = 100) 80 | pkgs <- installed.packages()[, "Package"] 81 | sessioninfo::session_info(pkgs, include_base = TRUE) 82 | shell: Rscript {0} 83 | 84 | - name: Check 85 | env: 86 | _R_CHECK_CRAN_INCOMING_: false 87 | run: | 88 | options(crayon.enabled = TRUE) 89 | rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 90 | shell: Rscript {0} 91 | 92 | - name: Show testthat output 93 | if: always() 94 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 95 | shell: bash 96 | 97 | - name: Upload check results 98 | if: failure() 99 | uses: actions/upload-artifact@main 100 | with: 101 | name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results 102 | path: check 103 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | - master 6 | pull_request: 7 | branches: 8 | - main 9 | - master 10 | 11 | name: test-coverage 12 | 13 | jobs: 14 | test-coverage: 15 | runs-on: macOS-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - uses: r-lib/actions/setup-r@v1 22 | 23 | - uses: r-lib/actions/setup-pandoc@v1 24 | 25 | - name: Query dependencies 26 | run: | 27 | install.packages('remotes') 28 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 29 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 30 | shell: Rscript {0} 31 | 32 | - name: Restore R package cache 33 | uses: actions/cache@v2 34 | with: 35 | path: ${{ env.R_LIBS_USER }} 36 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 37 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 38 | 39 | - name: Install dependencies 40 | run: | 41 | install.packages(c("remotes")) 42 | remotes::install_deps(dependencies = TRUE) 43 | remotes::install_cran("covr") 44 | shell: Rscript {0} 45 | 46 | - name: Test coverage 47 | run: covr::codecov() 48 | shell: Rscript {0} 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | inst/JSS4145_prescreened 2 | inst/JSS4145_prescreened.zip 3 | inst/r-medicine-2020 4 | inst/jss 5 | .Rproj.user 6 | README.html 7 | /*.Rproj 8 | 9 | ## Ignore all demo files: 10 | /anscombe* 11 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (https://www.contributor-covenant.org), version 1.0.0, available at 25 | https://contributor-covenant.org/version/1/0/0/. 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: listdown 2 | Title: Create R Markdown from Lists 3 | Version: 0.5.5 4 | Authors@R: c( 5 | person("Michael J.", "Kane", 6 | role = c("aut", "cph", "cre"), 7 | email = "michael.kane@yale.edu", 8 | comment = c(ORCID = "http://orcid.org/0000-0003-1899-6662") 9 | )) 10 | Description: Programmatically create R Markdown documents from lists. 11 | License: Apache License (>= 2.0) 12 | Encoding: UTF-8 13 | Depends: R (>= 4.0.0) 14 | Language: en-US 15 | Imports: 16 | checkmate, 17 | rmarkdown, 18 | tibble, 19 | yaml, 20 | fs 21 | Suggests: 22 | DT, 23 | ggplot2, 24 | testthat, 25 | purrr, 26 | knitr 27 | Enhances: 28 | workflowr 29 | URL: https://github.com/kaneplusplus/listdown 30 | BugReports: https://github.com/kaneplusplus/listdown/issues 31 | RoxygenNote: 7.2.3 32 | VignetteBuilder: knitr 33 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.character,listdown_header) 4 | S3method(ld_make_chunks,listdown) 5 | S3method(print,ld_cc_dendro) 6 | S3method(print,ld_page_bundle) 7 | S3method(print,listdown) 8 | S3method(print,listdown_header) 9 | export(as_ld_yml) 10 | export(class_and_tag) 11 | export(create_load_cc_expr) 12 | export(ld_build_html_site) 13 | export(ld_bundle_doc) 14 | export(ld_cc_dendro) 15 | export(ld_chunk_opts) 16 | export(ld_create_doc) 17 | export(ld_make_chunks) 18 | export(ld_rmarkdown_header) 19 | export(ld_site_yaml) 20 | export(ld_workflowr_header) 21 | export(ld_write_file) 22 | export(listdown) 23 | importFrom(checkmate,assert) 24 | importFrom(checkmate,check_character) 25 | importFrom(checkmate,check_class) 26 | importFrom(checkmate,check_list) 27 | importFrom(checkmate,check_null) 28 | importFrom(checkmate,check_numeric) 29 | importFrom(fs,path_abs) 30 | importFrom(fs,path_rel) 31 | importFrom(rmarkdown,render) 32 | importFrom(rmarkdown,render_site) 33 | importFrom(stats,na.omit) 34 | importFrom(tibble,as_tibble) 35 | importFrom(tibble,tibble) 36 | importFrom(utils,browseURL) 37 | importFrom(utils,tail) 38 | importFrom(yaml,as.yaml) 39 | importFrom(yaml,write_yaml) 40 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # listdown 0.2.8 2 | 3 | * Inital release to CRAN. 4 | 5 | # listdown 0.2.9 6 | 7 | * Minor updates for JSS submission based on comments. 8 | 9 | # listdown 0.2.10 10 | 11 | * Added CODE_OF_CONDUCT.md to .Rbuildignore 12 | 13 | # listdown 0.2.11 14 | 15 | * Removed the package name from the description title. 16 | 17 | # listdown 0.2.12 18 | 19 | * Title was put into title case. 20 | 21 | # listdown 0.2.13 22 | 23 | * dontrun was turned into donttest per CRAN feedback. 24 | 25 | # listdown 0.2.15 26 | 27 | * donttest was turned into dontrun per CRAN feedback. 28 | * vignette no longer writes files. 29 | * listdown() function can take a string literal for read expression. 30 | 31 | # listdown 0.2.16 32 | 33 | * Example fiddling for CRAN. 34 | 35 | # listdown 0.2.17 36 | 37 | * Gave up on ld_write_file. 38 | 39 | # listdown 0.2.18 40 | 41 | * Added rmarkdown Suggestion back. 42 | 43 | # listdown 0.2.21 44 | 45 | * Fixed a bug related to unnamed computational component lists elements. 46 | 47 | # listdown 0.4.0 48 | 49 | * Mulitple bug fixes. 50 | * The listdown() function now supports a `setup_expr` which, if specified 51 | is placed in a setup block. 52 | 53 | # listdown 0.4.1 54 | 55 | * Bug fixes. 56 | * Experimental "bundling" added. 57 | 58 | # listdown 0.4.6 59 | 60 | * Added class_and_tag() function for convenience. 61 | * Bundling functionality added with testing. 62 | 63 | # listdown 0.5.4 64 | 65 | * Fixed a path issue. 66 | * Fixed a regression test failure flagged by CRAN. 67 | -------------------------------------------------------------------------------- /R/add-load-cc-expr.r: -------------------------------------------------------------------------------- 1 | 2 | #' @title Create an expression to load a Computational Component 3 | #' 4 | #' @description An expression to load a computational component can be either 5 | #' a raw expression, a variable holding the expression, or a string. The 6 | #' return is an unevaluated expression. 7 | #' @param load_cc_expr a string or expression that should be use to load 8 | #' the computational components. 9 | #' @export 10 | create_load_cc_expr <- function(load_cc_expr) { 11 | if (is.character(load_cc_expr)) { 12 | # If it's a string literal, then call str2lang on it. 13 | load_cc_expr <- str2lang(load_cc_expr) 14 | } else { 15 | load_cc_expr <- tryCatch( { 16 | lce <- eval(load_cc_expr) 17 | if (is.character(lce)) { 18 | # It's a variable holding a string. Call str2lang on it. 19 | str2lang(lce) 20 | } else { 21 | # It's a bare expression. 22 | load_cc_expr 23 | } 24 | }, 25 | # It's a bare expression. 26 | finally = load_cc_expr) 27 | } 28 | load_cc_expr 29 | } 30 | -------------------------------------------------------------------------------- /R/as-yml.r: -------------------------------------------------------------------------------- 1 | 2 | # Helper function Eval Parse Paste (epp) 3 | epp <- function(..., env = parent.frame(n = 2)) { 4 | eval(parse(text = paste0(...)), envir = env) 5 | } 6 | 7 | last_index_as_list <- function(loc) { 8 | re <- regexpr("\\[\\[[0-9]+\\]\\]$", loc) 9 | # Get the list location. Not the list element. 10 | paste0(substr(loc, 1, re[1] - 1), 11 | "[", 12 | gsub("\\]\\]", "", gsub("\\[\\[", "", substr(loc, re, nchar(loc)))), 13 | "]") 14 | } 15 | 16 | #' @title Turn a Computational Component List into YAML with Class Information 17 | #' 18 | #' @description Create an object of type yaml::yml from a list of 19 | #' computational components. The function recursively descends into the list 20 | #' and when an element type is not a list the class information substituted 21 | #' for the object. 22 | #' @param x a named list of computational components. 23 | #' @importFrom yaml as.yaml 24 | #' @examples 25 | #' if (require("ggplot2")) { 26 | #' 27 | #' cc_list <- list( 28 | #' Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 29 | #' `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 30 | #' `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 31 | #' `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 32 | #' geom_point()) 33 | #' 34 | #' as_ld_yml(cc_list) 35 | #' } 36 | #' @export 37 | as_ld_yml <- function(x) { 38 | 39 | depth_first_copy <- function(loc = "") { 40 | elem <- epp("x", loc) 41 | locs <- vapply(seq_along(elem), 42 | function(i) paste0(loc, "[[", i, "]]"), NA_character_) 43 | for (loc in locs) { 44 | elem <- epp("x", loc) 45 | 46 | if (inherits(elem, "list")) { 47 | depth_first_copy(loc) 48 | } else { 49 | loc_list <- last_index_as_list(loc) 50 | if (is.null(names(epp("x", loc_list)))) { 51 | eval(parse(text = paste("x", loc, " <<- paste(", 52 | deparse(class(elem)), ", collapse = \":\")"))) 53 | } else { 54 | # Wrap in a list for formatting. 55 | eval(parse(text = paste("x", loc, " <<- list(paste(", 56 | deparse(class(elem)), ", collapse = \":\"))"))) 57 | } 58 | } 59 | } 60 | } 61 | depth_first_copy() 62 | as.yaml(x) 63 | } 64 | -------------------------------------------------------------------------------- /R/cc-dendro.r: -------------------------------------------------------------------------------- 1 | 2 | #' @title Show the list of Computational Components as a Dendrogram 3 | #' 4 | #' @description This function creates text dendrograms from 5 | #' a list of computational components. It is useful for 6 | #' creating a dendrogram of the the computational components of a listdown 7 | #' object allowing the user to view the components hierarchically. 8 | #' @param x a named list of computational components 9 | #' @examples 10 | #' if (require("ggplot2")) { 11 | #' 12 | #' cc_list <- list( 13 | #' Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 14 | #' `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 15 | #' `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 16 | #' `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 17 | #' geom_point()) 18 | #' 19 | #' ld_cc_dendro(cc_list) 20 | #' } 21 | #' @importFrom checkmate assert check_list 22 | #' @export 23 | ld_cc_dendro <- function(x) { 24 | 25 | assert( 26 | check_list(x) 27 | ) 28 | 29 | tdt_impl <- function(x, prefix_string) { 30 | for (i in seq_along(x)) { 31 | list_name <- names(x[i]) 32 | if (is.null(list_name)) { 33 | list_name <- '""' 34 | } 35 | vert_sep <- ifelse(i == length(x), " o-- ", " |-- ") 36 | tree_str <<- c(tree_str, paste0(prefix_string, vert_sep, list_name)) 37 | if (!class(x[[i]])[1] == "list") { 38 | in_sep <- ifelse(i == length(x), " ", " |") 39 | tree_str <<- c(tree_str, 40 | paste0(prefix_string, in_sep, " o-- ", 41 | "object of type(s):", 42 | paste0(class(x[[i]]), collapse = " "))) 43 | } else { 44 | tdt_impl(x[[i]], paste0(prefix_string, " ")) 45 | } 46 | } 47 | } 48 | tree_str <- as.character(as.list(match.call())$x) 49 | tdt_impl(x, " ") 50 | class(tree_str) <- "ld_cc_dendro" 51 | tree_str 52 | } 53 | 54 | #' @export 55 | print.ld_cc_dendro <- function(x, ...) { 56 | cat("\n", paste(x, sep = "", collapse = "\n"), "\n", "\n", sep = "") 57 | invisible(x) 58 | } 59 | -------------------------------------------------------------------------------- /R/chunk-options.r: -------------------------------------------------------------------------------- 1 | 2 | chunk_option_list <- c( 3 | "child", 4 | "code", 5 | "engine", 6 | "eval", 7 | "include", 8 | "purl", 9 | "collapse", 10 | "echo", 11 | "results", 12 | "error", 13 | "message", 14 | "warning", 15 | "comment", 16 | "highlight", 17 | "prompt", 18 | "strip.white", 19 | "tidy", 20 | "opts.label", 21 | "R.options", 22 | "ref.label", 23 | "autodep", 24 | "cache", 25 | "cache.comments", 26 | "cache.lazy", 27 | "cache.path", 28 | "cache.vars", 29 | "dependson", 30 | "anipots", 31 | "interval", 32 | "dev", 33 | "dev.args", 34 | "dpi", 35 | "external", 36 | "fig.align", 37 | "fig.cap", 38 | "fig.env", 39 | "fig.ext", 40 | "fig.height", 41 | "fig.width", 42 | "fig.keep", 43 | "fig.lp", 44 | "fig.path", 45 | "fig.pos", 46 | "fig.process", 47 | "fig.retina", 48 | "fig.scap", 49 | "fig.subcap", 50 | "fig.show", 51 | "fig.showtext", 52 | "out.extra", 53 | "out.height", 54 | "out.width", 55 | "resize.height", 56 | "resize.width", 57 | "sanitize", 58 | "" 59 | ) 60 | 61 | not_r_chunk_opts <- function(x) { 62 | x[!(vapply(x, function(opt) opt %in% chunk_option_list, FALSE))] 63 | } 64 | 65 | #' @title Apply Chunk Options to a Presentation Object 66 | #' @description This function allows the user to set chunk options for 67 | #' individual elements of a presentation list. 68 | #' @param pres_obj the presentation list element whose chunk options should 69 | #' be modified. 70 | #' @param chunk_name the name of the chunk. By default this is NULL, 71 | #' corresponding to no chunk name. 72 | #' @param ... named chunk options and their values. 73 | #' @param chunk_opts list of chunk options can be specified. Takes priority 74 | #' over arguments provided to ... 75 | #' @export 76 | ld_chunk_opts <- function(pres_obj, chunk_name = NULL, ..., chunk_opts = NULL) { 77 | a <- attributes(pres_obj) 78 | if (is.null(chunk_opts)) { 79 | chunk_opts <- list(...) 80 | } 81 | not_r_chunk_opts <- not_r_chunk_opts(names(chunk_opts)) 82 | if (length(not_r_chunk_opts) > 0) { 83 | stop("Unrecognized options:\n\t", 84 | paste(not_r_chunk_opts, collapse = "\n\t"), 85 | "\n", sep = "") 86 | } 87 | a$listdown <- c(chunk_name, chunk_opts) 88 | attributes(pres_obj) <- a 89 | pres_obj 90 | } 91 | -------------------------------------------------------------------------------- /R/class-and-tag.r: -------------------------------------------------------------------------------- 1 | #' Prepend Class Information and Add Attributes 2 | #' 3 | #' @description listdown decorators map list element to functions. This 4 | #' function is provided for convenience to prepend a class and attributes, 5 | #' which can then be used by custom decorators to display those element. 6 | #' @param .x an object to add class and attribute information to. 7 | #' @param new_class the name of the class to be prepended to .x. 8 | #' @param ... the attributes to attach to .x. 9 | #' @export 10 | class_and_tag <- function(.x, new_class, ...) { 11 | if (!is.character(new_class)) { 12 | stop("New class should be of type character.") 13 | } 14 | dots <- list(...) 15 | for (n in names(dots)) { 16 | attributes(.x)[[n]] <- dots[[n]] 17 | } 18 | class(.x) <- c(new_class, class(.x)) 19 | .x 20 | } 21 | -------------------------------------------------------------------------------- /R/depth-first-pres-list-visitor.r: -------------------------------------------------------------------------------- 1 | 2 | list_loc_string <- function(ll) { 3 | if (is.null(ll)) { 4 | NULL 5 | } else { 6 | paste0("[[", paste0(ll, collapse = "]][["), "]]") 7 | } 8 | } 9 | 10 | list_loc_list_string <- function(ll) { 11 | if (length(ll) == 1) { 12 | paste0("[", ll, "]") 13 | } else { 14 | paste0(list_loc_string(ll[-length(ll)]), "[", ll[length(ll)], "]") 15 | } 16 | } 17 | 18 | list_loc_ind_to_name <- function(pl, env = parent.frame(n = 2)) { 19 | ret <- gsub("\\[\\[[0-9]+\\]\\]", "", pl) 20 | re <- gregexpr("\\[\\[[0-9]+\\]\\]", pl)[[1]] 21 | re_len <- attr(re, "match.length") 22 | for (i in seq_along(re)) { 23 | idx <- substr(pl, re[i], re[i] + re_len[i] - 1) 24 | idx_name <- names(epp(ret, last_index_as_list(idx))) 25 | # Wrap in backticks if the names isn't a valid variable name. 26 | if (!is.null(idx_name) && idx_name != make.names(idx_name)) { 27 | idx_name <- paste0("`", idx_name, "`") 28 | } 29 | ret <- paste0( 30 | ret, 31 | ifelse(!is.null(idx_name), 32 | paste0("$", idx_name), 33 | idx)) 34 | } 35 | ret 36 | } 37 | 38 | get_attribute_options <- function(ld, pres_obj = NULL) { 39 | ret <- list() 40 | if (!is.null(pres_obj) && "listdown" %in% names(attributes(pres_obj))) { 41 | ret <- attributes(pres_obj)$listdown 42 | } 43 | ret 44 | } 45 | 46 | make_chunk_option_string <- function(chunk_opts) { 47 | named_elements <- chunk_opts[names(chunk_opts) != ""] 48 | unnamed_element <- chunk_opts[names(chunk_opts) == ""] 49 | ret <- character() 50 | if (length(unnamed_element) > 0 && unnamed_element != "") { 51 | ret <- paste(ret, unnamed_element[[1]]) 52 | } 53 | if (length(named_elements)) { 54 | opt_strings <- 55 | paste(names(named_elements), 56 | vapply(named_elements, deparse, NA_character_), 57 | sep = " = ") 58 | ret <- paste(opt_strings, collapse = ", ") 59 | } 60 | if (length(ret) > 0 && nchar(ret) > 0 && substr(ret, 1, 1) != " ") { 61 | ret <- paste0(" ", ret) 62 | } 63 | if (length(ret) == 0) { 64 | ret <- "" 65 | } 66 | ret 67 | } 68 | 69 | depth_first_concat <- function(cc_list, ld, heading = "#", 70 | list_location = c()) { 71 | 72 | ret_str <- "" 73 | 74 | depth_first_concat_impl <- function(cc_list, ld, heading, list_location) { 75 | 76 | current_location <- paste0("cc_list", list_loc_string(list_location)) 77 | 78 | 79 | list_locs <- lapply(seq_along(eval(parse(text = current_location))), 80 | function(x) c(list_location, x)) 81 | 82 | for (list_loc in list_locs) { 83 | pll <- paste0("cc_list", list_loc_list_string(list_loc)) 84 | pl <- paste0("cc_list", list_loc_string(list_loc)) 85 | pll_name <- names(eval(parse(text = pll))) 86 | if (length(pll_name) && pll_name != "") { 87 | ret_str <<- c(ret_str, 88 | sprintf(paste0(heading, " %s"), pll_name), 89 | "") 90 | } 91 | 92 | decorator_index <- which( 93 | vapply(names(ld$decorator), 94 | function(x) inherits(eval(parse(text = pl)), x), NA)) 95 | 96 | if (length(decorator_index) > 1) { 97 | decorator_index <- decorator_index[1] 98 | } 99 | 100 | 101 | chunk_opts <- ld$chunk_opts 102 | 103 | chunk_option_index <- which( 104 | vapply(names(ld$decorator_chunk_opts), 105 | function(x) inherits(eval(parse(text = pl)), x), NA)) 106 | 107 | if (length(chunk_option_index) > 1) { 108 | chunk_option_index <- chunk_option_index[1] 109 | } 110 | 111 | if (length(chunk_option_index) == 1) { 112 | new_chunk_opts <- ld$decorator_chunk_opts[[chunk_option_index]] 113 | for (i in seq_along(new_chunk_opts)) { 114 | chunk_opts[[names(new_chunk_opts)[i]]] <- new_chunk_opts[[i]] 115 | } 116 | } 117 | 118 | # Keep the last unnamed element (chunk name). 119 | unnamed_element <- which(names(chunk_opts) == "") 120 | if (length(unnamed_element) > 1) { 121 | chunk_opts <- chunk_opts[-unnamed_element[1]] 122 | } 123 | 124 | att_chunk_opts <- get_attribute_options(ld, eval(parse(text = pl))) 125 | 126 | for (i in seq_along(att_chunk_opts)) { 127 | chunk_opts[[names(att_chunk_opts)[i]]] <- att_chunk_opts[[i]] 128 | } 129 | 130 | # Keep the last unnamed element (chunk name). 131 | unnamed_element <- which(names(chunk_opts) == "") 132 | if (length(unnamed_element) > 1) { 133 | chunk_opts <- chunk_opts[-unnamed_element[1]] 134 | } 135 | 136 | chunk_opts_string <- make_chunk_option_string(chunk_opts) 137 | 138 | # Check to see if we have a decorator for the element. 139 | if (any( 140 | vapply(names(ld$decorator), 141 | function(x) inherits(eval(parse(text = pl)), x), NA))) { 142 | ret_str <<- c( 143 | ret_str, 144 | sprintf("```{r%s}", chunk_opts_string), 145 | ifelse(as.character(ld$decorator[[decorator_index]]) == "identity", 146 | list_loc_ind_to_name(pl), 147 | paste0(as.character(ld$decorator[decorator_index]), 148 | "(", list_loc_ind_to_name(pl), ")")), 149 | "```", 150 | "") 151 | 152 | } else if (inherits(eval(parse(text = pl)), "list")) { 153 | depth_first_concat_impl(cc_list = cc_list, ld = ld, 154 | heading = paste0(heading, "#"), 155 | list_location = list_loc) 156 | } else { 157 | # It's not one of the decorators, and it's not a list. Use the 158 | # default decorator. 159 | if (!is.null(ld$default_decorator)) { 160 | ret_str <<- c( 161 | ret_str, 162 | sprintf("```{r%s}", chunk_opts_string), 163 | ifelse(as.character(ld$default_decorator) == "identity", 164 | list_loc_ind_to_name(pl), 165 | paste0(as.character(ld$default_decorator), 166 | "(", list_loc_ind_to_name(pl), ")")), 167 | "```", 168 | "") 169 | } 170 | } 171 | } 172 | } 173 | depth_first_concat_impl(cc_list = cc_list, ld = ld, heading = heading, 174 | list_location = list_location) 175 | while (length(ret_str) > 0 && ret_str[length(ret_str)] == "") { 176 | ret_str <- ret_str[-length(ret_str)] 177 | } 178 | ret_str 179 | } 180 | -------------------------------------------------------------------------------- /R/headers.r: -------------------------------------------------------------------------------- 1 | #' @title Create an R Markdown Header 2 | #' @description Output an R Markdown header with specified parameters. 3 | #' @param title the title of the page. 4 | #' @param author the author of the page. The default is NULL - no author. 5 | #' @param date the date for the page. The default is NULL - no date. 6 | #' @param output the output format of the page. If NULL then no output format. 7 | #' The default is an html document. 8 | #' @export 9 | ld_rmarkdown_header <- function(title, 10 | author = NULL, 11 | date = NULL, 12 | output = c("html_document", 13 | "pdf_document", 14 | "word_document")) { 15 | ret <- list(title = title) 16 | if (!is.null(author)) { 17 | ret$author <- author 18 | } 19 | if (!is.null(date)) { 20 | ret$date <- date 21 | } 22 | ret$output <- output[1] 23 | class(ret) <- c("listdown_header", "list") 24 | ret 25 | } 26 | 27 | #' @title Create a workflowr Header 28 | #' @description Output a workflowr R Markdown header with specified title. 29 | #' @param title the title of the page. 30 | #' @param toc should the table of contents be generated? Default FALSE. 31 | #' @export 32 | ld_workflowr_header <- function(title, toc = FALSE) { 33 | ret <- list(title = title, 34 | site = "workflowr::wflow_site", 35 | output = 36 | list(`workflowr::wflow_html` = 37 | list(toc = toc)), 38 | editor_options = list(chunk_output_type = "console")) 39 | class(ret) <- c("listdown_header", "list") 40 | ret 41 | } 42 | 43 | #' @export 44 | print.listdown_header <- function(x, ...) { 45 | ret <- as.character(x) 46 | cat(ret, sep = "\n") 47 | invisible(ret) 48 | } 49 | 50 | #' @export 51 | #' @importFrom yaml as.yaml 52 | as.character.listdown_header <- function(x, ...) { 53 | c("---", 54 | unlist(strsplit(as.yaml(x, ...), "\n")), 55 | "---") 56 | } 57 | -------------------------------------------------------------------------------- /R/ld-write-file.r: -------------------------------------------------------------------------------- 1 | 2 | #' @title Write to an R Markdown File 3 | #' 4 | #' @description This function takes header information and a listdown 5 | #' object and writes to a specified file. 6 | #' @param rmd_header either a character or listdown_header with R Markdown 7 | #' header information. 8 | #' @param ld the listdown object that provides 9 | #' information on how a presentation object should be displayed in the 10 | #' output. 11 | #' @param file_name the output file to write to. 12 | #' @importFrom checkmate assert check_class check_character 13 | #' @importFrom yaml as.yaml 14 | #' @export 15 | ld_write_file <- function(rmd_header, ld, file_name) { 16 | 17 | assert( 18 | check_class(rmd_header, "listdown_header"), 19 | check_character(rmd_header), 20 | check_list(rmd_header), 21 | combine = "or" 22 | ) 23 | 24 | assert( 25 | check_class(ld, "listdown"), 26 | check_character(ld), 27 | combine = "or" 28 | ) 29 | 30 | if (inherits(rmd_header, "listdown_header")) { 31 | rmd_header <- as.character(rmd_header) 32 | } else if (is.list(rmd_header)) { 33 | rmd_header <- as.yaml(rmd_header) 34 | } 35 | 36 | if (inherits(ld, "listdown")) { 37 | ld <- ld_make_chunks(ld, rmd_dir = dirname(file_name)) 38 | } 39 | 40 | writeLines(c(rmd_header, ld), file_name) 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # listdown 4 | 5 | 6 | 7 | [![](https://www.r-pkg.org/badges/version/listdown?color=blue)](https://cran.r-project.org/package=listdown) 8 | [![R-CMD-check](https://github.com/kaneplusplus/listdown/workflows/R-CMD-check/badge.svg)](https://github.com/kaneplusplus/listdown/actions) 9 | [![Codecov test 10 | coverage](https://codecov.io/gh/kaneplusplus/listdown/branch/master/graph/badge.svg)](https://codecov.io/gh/kaneplusplus/listdown?branch=master) 11 | 12 | 13 | ## Overview 14 | 15 | The {listdown} package provides functions to programmatically create R 16 | Markdown files from named lists. It is intended for data analysis 17 | pipelines where the presentation of the results is separated from their 18 | creation. For this use case, a data processing (or analysis) is 19 | performed and the results are provided in a single named list, organized 20 | hierarchically. With the list and a {listdown} object a workflowr, pdf, 21 | word, or html page. List element names denote sections, subsections, 22 | subsubsection, etc. and the list elements contain the data structure to 23 | be presented including graphs and tables. The goal of the package is not 24 | to provide a finished, readable document. It is to provide a document 25 | with all tables and visualization that will appear (*computational* 26 | components). This serves as a starting point from which a user can 27 | organize outputs, describe a study, discuss results, and provide 28 | conclusions (*narrative* components). 29 | 30 | {listdown} provides a reproducible means for producing a document with 31 | specified computational components. It is most compatible with data 32 | analysis pipelines where the data format is fixed but the analyses are 33 | either being updated, which may affect narrative components including 34 | the result discussion and conclusion, or where the experiment is 35 | different, which affects all narrative components If the narrative 36 | components are not changing with the data being pushed through your 37 | analysis pipeline, then you may be better off writing the R Markdown 38 | code manually. 39 | 40 | ## Installation 41 | 42 | You can install the released version of listdown from 43 | [CRAN](https://CRAN.R-project.org) with: 44 | 45 | ``` r 46 | install.packages("listdown") 47 | ``` 48 | 49 | The development version of {listdown} can be installed from 50 | [GitHub](https://github.com/) with: 51 | 52 | ``` r 53 | # install.packages("devtools") 54 | devtools::install_github("kaneplusplus/listdown") 55 | ``` 56 | 57 | ## Example 58 | 59 | As a toy example, suppose we would like to create an html document 60 | plotting Anscombe’s quartet with each plot having it’s own section. To 61 | construct the document, we will need to two objects. The first is a 62 | presentation list, whose names indicate section (or subsection) titles 63 | and whose elements are the objects to present. The second is a 64 | `listdown` object, which describes how the object should be rendered in 65 | the document. 66 | 67 | ``` r 68 | library(listdown) 69 | library(ggplot2) 70 | 71 | data(anscombe) 72 | 73 | # Create the ggplot objects to display. 74 | pres_list <- list( 75 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point() + theme_bw(), 76 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point() + theme_bw(), 77 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point() + theme_bw(), 78 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + geom_point() + theme_bw()) 79 | 80 | # Save the pres_list object so that it can be used in the R Markdown document. 81 | saveRDS(pres_list, "pres-list.rds") 82 | 83 | # Create a listdown object. 84 | ld <- listdown(load_cc_expr = readRDS("pres-list.rds"), # The expression to load pres_list. 85 | package = "ggplot2") # The packages needed to render plots. 86 | 87 | # Output an html document to a string. 88 | doc <- c( 89 | as.character( 90 | ld_rmarkdown_header("Anscombe's Quartet", 91 | author = "Francis Anscombe", 92 | date = "1973")), 93 | ld_make_chunks(ld)) 94 | 95 | cat(paste(doc, collapse = "\n")) 96 | ``` 97 | 98 | #> --- 99 | #> title: Anscombe's Quartet 100 | #> author: Francis Anscombe 101 | #> date: '1973' 102 | #> output: html_document 103 | #> --- 104 | #> 105 | #> ```{r} 106 | #> library(ggplot2) 107 | #> 108 | #> cc_list <- readRDS("pres-list.rds") 109 | #> ``` 110 | #> 111 | #> # Linear 112 | #> 113 | #> ```{r} 114 | #> cc_list$Linear 115 | #> ``` 116 | #> 117 | #> # Non Linear 118 | #> 119 | #> ```{r} 120 | #> cc_list$`Non Linear` 121 | #> ``` 122 | #> 123 | #> # Outlier Vertical 124 | #> 125 | #> ```{r} 126 | #> cc_list$`Outlier Vertical` 127 | #> ``` 128 | #> 129 | #> # Outlier Horizontal 130 | #> 131 | #> ```{r} 132 | #> cc_list$`Outlier Horizontal` 133 | #> ``` 134 | 135 | The document can then be written to a file, rendered, and viewed with 136 | the following code. 137 | 138 | ``` r 139 | library(rmarkdown) 140 | 141 | writeLines(doc, file("anscombe.Rmd")) 142 | render("anscombe.Rmd") 143 | browseURL("anscombe.html") 144 | ``` 145 | 146 | 157 | 158 | ## Code of Conduct 159 | 160 | Please note that the {listdown} project is released with a [Contributor 161 | Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this project, 162 | you agree to abide by its terms. 163 | -------------------------------------------------------------------------------- /README.rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "listdown" 3 | output: 4 | md_document: 5 | variant: markdown_github 6 | --- 7 | 8 | 9 | 10 | ```{r, include = FALSE} 11 | knitr::opts_chunk$set( 12 | collapse = TRUE, 13 | comment = "#>", 14 | fig.path = "man/figures/README-", 15 | out.width = "100%" 16 | ) 17 | ``` 18 | 19 | # listdown 20 | 21 | 22 | [![](https://www.r-pkg.org/badges/version/listdown?color=blue)](https://cran.r-project.org/package=listdown) 23 | [![R-CMD-check](https://github.com/kaneplusplus/listdown/workflows/R-CMD-check/badge.svg)](https://github.com/kaneplusplus/listdown/actions) 24 | [![Codecov test coverage](https://codecov.io/gh/kaneplusplus/listdown/branch/master/graph/badge.svg)](https://codecov.io/gh/kaneplusplus/listdown?branch=master) 25 | 26 | 27 | ## Overview 28 | 29 | The {listdown} package provides functions to programmatically create R Markdown files from 30 | named lists. It is intended for data analysis pipelines where the presentation of the results 31 | is separated from their creation. For this use case, a data processing (or analysis) is performed 32 | and the results are provided in a single named list, organized hierarchically. With the list and a {listdown} object a workflowr, pdf, word, or html page. List element names denote sections, subsections, 33 | subsubsection, etc. and the list elements contain the data structure to be presented including 34 | graphs and tables. The goal of the package is not to provide a finished, readable document. It is to provide a document with all tables and visualization that will appear (_computational_ components). This serves as a starting point from which a user can organize outputs, describe a study, discuss results, and provide conclusions (_narrative_ components). 35 | 36 | {listdown} provides a reproducible means for producing a document with specified computational components. It is most compatible with data analysis pipelines where the data format is fixed but the analyses are either being updated, which may affect narrative components including the result discussion and conclusion, or where the experiment is different, which affects all narrative components If the narrative components are not changing with the data being pushed through your analysis pipeline, then you may be better off writing the R Markdown code manually. 37 | 38 | ## Installation 39 | 40 | You can install the released version of listdown from [CRAN](https://CRAN.R-project.org) with: 41 | 42 | ``` r 43 | install.packages("listdown") 44 | ``` 45 | 46 | The development version of {listdown} can be installed from [GitHub](https://github.com/) with: 47 | 48 | ``` r 49 | # install.packages("devtools") 50 | devtools::install_github("kaneplusplus/listdown") 51 | ``` 52 | 53 | ## Example 54 | 55 | As a toy example, suppose we would like to create an html document plotting Anscombe's quartet with 56 | each plot having it's own section. To construct the document, we will need to two objects. The first 57 | is a presentation list, whose names indicate section (or subsection) titles and whose elements are 58 | the objects to present. The second is a `listdown` object, which describes how the object should 59 | be rendered in the document. 60 | 61 | ```{r eval = FALSE} 62 | library(listdown) 63 | library(ggplot2) 64 | 65 | data(anscombe) 66 | 67 | # Create the ggplot objects to display. 68 | pres_list <- list( 69 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point() + theme_bw(), 70 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point() + theme_bw(), 71 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point() + theme_bw(), 72 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + geom_point() + theme_bw()) 73 | 74 | # Save the pres_list object so that it can be used in the R Markdown document. 75 | saveRDS(pres_list, "pres-list.rds") 76 | 77 | # Create a listdown object. 78 | ld <- listdown(load_cc_expr = readRDS("pres-list.rds"), # The expression to load pres_list. 79 | package = "ggplot2") # The packages needed to render plots. 80 | 81 | # Output an html document to a string. 82 | doc <- c( 83 | as.character( 84 | ld_rmarkdown_header("Anscombe's Quartet", 85 | author = "Francis Anscombe", 86 | date = "1973")), 87 | ld_make_chunks(ld)) 88 | 89 | cat(paste(doc, collapse = "\n")) 90 | ``` 91 | 92 | ```{r eval = TRUE, echo = FALSE} 93 | library(listdown) 94 | library(ggplot2) 95 | 96 | data(anscombe) 97 | 98 | # Create the ggplot objects to display. 99 | pres_list <- list( 100 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point() + theme_bw(), 101 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point() + theme_bw(), 102 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point() + theme_bw(), 103 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + geom_point() + theme_bw()) 104 | 105 | # Save the pres_list object so that it can be used in the R Markdown document. 106 | saveRDS(pres_list, "pres-list.rds") 107 | 108 | # Create a listdown object. 109 | ld <- listdown(load_cc_expr = readRDS("pres-list.rds"), # The expression to load pres_list. 110 | package = "ggplot2") # The packges needed to render plots. 111 | 112 | # Output an html document to a string. 113 | doc <- c( 114 | as.character( 115 | ld_rmarkdown_header("Anscombe's Quartet", 116 | author = "Francis Anscombe", 117 | date = "1973")), 118 | ld_make_chunks(ld)) 119 | 120 | cat(paste(doc, collapse = "\n")) 121 | ``` 122 | 123 | The document can then be written to a file, rendered, and viewed with the following code. 124 | 125 | ```{r message = FALSE, eval = FALSE} 126 | library(rmarkdown) 127 | 128 | writeLines(doc, file("anscombe.Rmd")) 129 | render("anscombe.Rmd") 130 | browseURL("anscombe.html") 131 | ``` 132 | 133 | ```{r cleanup, echo = FALSE, warning = FALSE, error = FALSE} 134 | unlink("pres-list.rds") 135 | ``` 136 | 137 | 147 | 148 | ## Code of Conduct 149 | 150 | Please note that the {listdown} project is released with a 151 | [Contributor Code of Conduct](CODE_OF_CONDUCT.md). 152 | By contributing to this project, you agree to abide by its terms. 153 | 154 | 155 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | cache: 14 | - C:\RLibrary 15 | 16 | environment: 17 | NOT_CRAN: true 18 | # env vars that may need to be set, at least temporarily, from time to time 19 | # see https://github.com/krlmlr/r-appveyor#readme for details 20 | # USE_RTOOLS: true 21 | # R_REMOTES_STANDALONE: true 22 | 23 | # Adapt as necessary starting from here 24 | 25 | build_script: 26 | - travis-tool.sh install_deps 27 | 28 | test_script: 29 | - travis-tool.sh run_tests 30 | 31 | on_failure: 32 | - 7z a failure.zip *.Rcheck\* 33 | - appveyor PushArtifact failure.zip 34 | 35 | artifacts: 36 | - path: '*.Rcheck\**\*.log' 37 | name: Logs 38 | 39 | - path: '*.Rcheck\**\*.out' 40 | name: Logs 41 | 42 | - path: '*.Rcheck\**\*.fail' 43 | name: Logs 44 | 45 | - path: '*.Rcheck\**\*.Rout' 46 | name: Logs 47 | 48 | - path: '\*_*.tar.gz' 49 | name: Bits 50 | 51 | - path: '\*_*.zip' 52 | name: Bits 53 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local R installation, R 4.0.6 3 | * ubuntu 16.04 (on travis-ci), R 4.0.6 4 | * win-builder (devel) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 1 note 9 | 10 | * This is a new release. 11 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page not found (404) • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | 118 | 119 | Content not found. Please use links in the navbar. 120 | 121 |
122 | 123 | 128 | 129 |
130 | 131 | 132 | 133 | 143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/CODE_OF_CONDUCT.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Contributor Code of Conduct • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | 118 | 119 |
120 | 121 |

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

122 |

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

123 |

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

124 |

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

125 |

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

126 |

This Code of Conduct is adapted from the Contributor Covenant (https://www.contributor-covenant.org), version 1.0.0, available at https://contributor-covenant.org/version/1/0/0/.

127 |
128 | 129 |
130 | 131 | 136 | 137 |
138 | 139 | 140 | 141 | 151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Articles • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | 118 | 119 |
120 |

All vignettes

121 |

122 | 123 |
124 |
The listdown Package
125 |
126 |
127 |
128 |
129 |
130 | 131 | 132 | 142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /docs/articles/listdown_files/header-attrs-2.7/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | 118 | 119 |
    120 |
  • 121 |

    Michael J. Kane. Author, copyright holder, maintainer. 122 |

    123 |
  • 124 |
125 | 126 |
127 | 128 |
129 | 130 | 131 | 132 | 142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body { 21 | position: relative; 22 | } 23 | 24 | body > .container { 25 | display: flex; 26 | height: 100%; 27 | flex-direction: column; 28 | } 29 | 30 | body > .container .row { 31 | flex: 1 0 auto; 32 | } 33 | 34 | footer { 35 | margin-top: 45px; 36 | padding: 35px 0 36px; 37 | border-top: 1px solid #e5e5e5; 38 | color: #666; 39 | display: flex; 40 | flex-shrink: 0; 41 | } 42 | footer p { 43 | margin-bottom: 0; 44 | } 45 | footer div { 46 | flex: 1; 47 | } 48 | footer .pkgdown { 49 | text-align: right; 50 | } 51 | footer p { 52 | margin-bottom: 0; 53 | } 54 | 55 | img.icon { 56 | float: right; 57 | } 58 | 59 | img { 60 | max-width: 100%; 61 | } 62 | 63 | /* Fix bug in bootstrap (only seen in firefox) */ 64 | summary { 65 | display: list-item; 66 | } 67 | 68 | /* Typographic tweaking ---------------------------------*/ 69 | 70 | .contents .page-header { 71 | margin-top: calc(-60px + 1em); 72 | } 73 | 74 | dd { 75 | margin-left: 3em; 76 | } 77 | 78 | /* Section anchors ---------------------------------*/ 79 | 80 | a.anchor { 81 | margin-left: -30px; 82 | display:inline-block; 83 | width: 30px; 84 | height: 30px; 85 | visibility: hidden; 86 | 87 | background-image: url(./link.svg); 88 | background-repeat: no-repeat; 89 | background-size: 20px 20px; 90 | background-position: center center; 91 | } 92 | 93 | .hasAnchor:hover a.anchor { 94 | visibility: visible; 95 | } 96 | 97 | @media (max-width: 767px) { 98 | .hasAnchor:hover a.anchor { 99 | visibility: hidden; 100 | } 101 | } 102 | 103 | 104 | /* Fixes for fixed navbar --------------------------*/ 105 | 106 | .contents h1, .contents h2, .contents h3, .contents h4 { 107 | padding-top: 60px; 108 | margin-top: -40px; 109 | } 110 | 111 | /* Navbar submenu --------------------------*/ 112 | 113 | .dropdown-submenu { 114 | position: relative; 115 | } 116 | 117 | .dropdown-submenu>.dropdown-menu { 118 | top: 0; 119 | left: 100%; 120 | margin-top: -6px; 121 | margin-left: -1px; 122 | border-radius: 0 6px 6px 6px; 123 | } 124 | 125 | .dropdown-submenu:hover>.dropdown-menu { 126 | display: block; 127 | } 128 | 129 | .dropdown-submenu>a:after { 130 | display: block; 131 | content: " "; 132 | float: right; 133 | width: 0; 134 | height: 0; 135 | border-color: transparent; 136 | border-style: solid; 137 | border-width: 5px 0 5px 5px; 138 | border-left-color: #cccccc; 139 | margin-top: 5px; 140 | margin-right: -10px; 141 | } 142 | 143 | .dropdown-submenu:hover>a:after { 144 | border-left-color: #ffffff; 145 | } 146 | 147 | .dropdown-submenu.pull-left { 148 | float: none; 149 | } 150 | 151 | .dropdown-submenu.pull-left>.dropdown-menu { 152 | left: -100%; 153 | margin-left: 10px; 154 | border-radius: 6px 0 6px 6px; 155 | } 156 | 157 | /* Sidebar --------------------------*/ 158 | 159 | #pkgdown-sidebar { 160 | margin-top: 30px; 161 | position: -webkit-sticky; 162 | position: sticky; 163 | top: 70px; 164 | } 165 | 166 | #pkgdown-sidebar h2 { 167 | font-size: 1.5em; 168 | margin-top: 1em; 169 | } 170 | 171 | #pkgdown-sidebar h2:first-child { 172 | margin-top: 0; 173 | } 174 | 175 | #pkgdown-sidebar .list-unstyled li { 176 | margin-bottom: 0.5em; 177 | } 178 | 179 | /* bootstrap-toc tweaks ------------------------------------------------------*/ 180 | 181 | /* All levels of nav */ 182 | 183 | nav[data-toggle='toc'] .nav > li > a { 184 | padding: 4px 20px 4px 6px; 185 | font-size: 1.5rem; 186 | font-weight: 400; 187 | color: inherit; 188 | } 189 | 190 | nav[data-toggle='toc'] .nav > li > a:hover, 191 | nav[data-toggle='toc'] .nav > li > a:focus { 192 | padding-left: 5px; 193 | color: inherit; 194 | border-left: 1px solid #878787; 195 | } 196 | 197 | nav[data-toggle='toc'] .nav > .active > a, 198 | nav[data-toggle='toc'] .nav > .active:hover > a, 199 | nav[data-toggle='toc'] .nav > .active:focus > a { 200 | padding-left: 5px; 201 | font-size: 1.5rem; 202 | font-weight: 400; 203 | color: inherit; 204 | border-left: 2px solid #878787; 205 | } 206 | 207 | /* Nav: second level (shown on .active) */ 208 | 209 | nav[data-toggle='toc'] .nav .nav { 210 | display: none; /* Hide by default, but at >768px, show it */ 211 | padding-bottom: 10px; 212 | } 213 | 214 | nav[data-toggle='toc'] .nav .nav > li > a { 215 | padding-left: 16px; 216 | font-size: 1.35rem; 217 | } 218 | 219 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 220 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 221 | padding-left: 15px; 222 | } 223 | 224 | nav[data-toggle='toc'] .nav .nav > .active > a, 225 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 226 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 227 | padding-left: 15px; 228 | font-weight: 500; 229 | font-size: 1.35rem; 230 | } 231 | 232 | /* orcid ------------------------------------------------------------------- */ 233 | 234 | .orcid { 235 | font-size: 16px; 236 | color: #A6CE39; 237 | /* margins are required by official ORCID trademark and display guidelines */ 238 | margin-left:4px; 239 | margin-right:4px; 240 | vertical-align: middle; 241 | } 242 | 243 | /* Reference index & topics ----------------------------------------------- */ 244 | 245 | .ref-index th {font-weight: normal;} 246 | 247 | .ref-index td {vertical-align: top; min-width: 100px} 248 | .ref-index .icon {width: 40px;} 249 | .ref-index .alias {width: 40%;} 250 | .ref-index-icons .alias {width: calc(40% - 40px);} 251 | .ref-index .title {width: 60%;} 252 | 253 | .ref-arguments th {text-align: right; padding-right: 10px;} 254 | .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} 255 | .ref-arguments .name {width: 20%;} 256 | .ref-arguments .desc {width: 80%;} 257 | 258 | /* Nice scrolling for wide elements --------------------------------------- */ 259 | 260 | table { 261 | display: block; 262 | overflow: auto; 263 | } 264 | 265 | /* Syntax highlighting ---------------------------------------------------- */ 266 | 267 | pre { 268 | word-wrap: normal; 269 | word-break: normal; 270 | border: 1px solid #eee; 271 | } 272 | 273 | pre, code { 274 | background-color: #f8f8f8; 275 | color: #333; 276 | } 277 | 278 | pre code { 279 | overflow: auto; 280 | word-wrap: normal; 281 | white-space: pre; 282 | } 283 | 284 | pre .img { 285 | margin: 5px 0; 286 | } 287 | 288 | pre .img img { 289 | background-color: #fff; 290 | display: block; 291 | height: auto; 292 | } 293 | 294 | code a, pre a { 295 | color: #375f84; 296 | } 297 | 298 | a.sourceLine:hover { 299 | text-decoration: none; 300 | } 301 | 302 | .fl {color: #1514b5;} 303 | .fu {color: #000000;} /* function */ 304 | .ch,.st {color: #036a07;} /* string */ 305 | .kw {color: #264D66;} /* keyword */ 306 | .co {color: #888888;} /* comment */ 307 | 308 | .message { color: black; font-weight: bolder;} 309 | .error { color: orange; font-weight: bolder;} 310 | .warning { color: #6A0366; font-weight: bolder;} 311 | 312 | /* Clipboard --------------------------*/ 313 | 314 | .hasCopyButton { 315 | position: relative; 316 | } 317 | 318 | .btn-copy-ex { 319 | position: absolute; 320 | right: 0; 321 | top: 0; 322 | visibility: hidden; 323 | } 324 | 325 | .hasCopyButton:hover button.btn-copy-ex { 326 | visibility: visible; 327 | } 328 | 329 | /* headroom.js ------------------------ */ 330 | 331 | .headroom { 332 | will-change: transform; 333 | transition: transform 200ms linear; 334 | } 335 | .headroom--pinned { 336 | transform: translateY(0%); 337 | } 338 | .headroom--unpinned { 339 | transform: translateY(-100%); 340 | } 341 | 342 | /* mark.js ----------------------------*/ 343 | 344 | mark { 345 | background-color: rgba(255, 255, 51, 0.5); 346 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 347 | padding: 1px; 348 | } 349 | 350 | /* vertical spacing after htmlwidgets */ 351 | .html-widget { 352 | margin-bottom: 10px; 353 | } 354 | 355 | /* fontawesome ------------------------ */ 356 | 357 | .fab { 358 | font-family: "Font Awesome 5 Brands" !important; 359 | } 360 | 361 | /* don't display links in code chunks when printing */ 362 | /* source: https://stackoverflow.com/a/10781533 */ 363 | @media print { 364 | code a:link:after, code a:visited:after { 365 | content: ""; 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent; 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.13' 2 | pkgdown: 1.6.1 3 | pkgdown_sha: ~ 4 | articles: 5 | listdown: listdown.html 6 | last_built: 2021-04-26T20:57Z 7 | 8 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/create_load_cc_expr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create an expression to load a Computational Component — create_load_cc_expr • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
    65 |
    66 | 111 | 112 | 113 | 114 |
    115 | 116 |
    117 |
    118 | 123 | 124 |
    125 |

    An expression to load a computational component can be either 126 | a raw expression, a variable holding the expression, or a string. The 127 | return is an unevaluated expression.

    128 |
    129 | 130 |
    create_load_cc_expr(load_cc_expr)
    131 | 132 |

    Arguments

    133 | 134 | 135 | 136 | 137 | 139 | 140 |
    load_cc_expr

    a string or expression that should be use to load 138 | the computational components.

    141 | 142 | 143 |
    144 | 149 |
    150 | 151 | 152 |
    153 | 156 | 157 |
    158 |

    Site built with pkgdown 1.6.1.

    159 |
    160 | 161 |
    162 |
    163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Function reference • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 108 | 109 | 110 | 111 |
    112 | 113 |
    114 |
    115 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 144 | 145 | 146 | 147 | 150 | 151 | 152 | 153 | 156 | 157 | 158 | 159 | 162 | 163 | 164 | 165 | 168 | 169 | 170 | 171 | 174 | 175 | 176 | 177 | 180 | 181 | 182 | 183 | 186 | 187 | 188 | 189 | 192 | 193 | 194 | 195 | 198 | 199 | 200 | 201 | 204 | 205 | 206 | 207 | 210 | 211 | 212 | 213 | 216 | 217 | 218 | 219 |
    130 |

    All functions

    131 |

    132 |
    142 |

    as_ld_yml()

    143 |

    Turn a Computational Component List into YAML with Class Information

    148 |

    create_load_cc_expr()

    149 |

    Create an expression to load a Computational Component

    154 |

    ld_build_html_site()

    155 |

    Build an html Site from listdown Document Bundles

    160 |

    ld_bundle_doc()

    161 |

    Create a `listdown` Document Bundle

    166 |

    ld_cc_dendro()

    167 |

    Show the list of Computational Components as a Dendrogram

    172 |

    ld_chunk_opts()

    173 |

    Apply Chunk Options to a Presentation Object

    178 |

    ld_create_doc()

    179 |

    Create a Document from a `listdown` Bundle

    184 |

    ld_make_chunks()

    185 |

    Write a listdown Object to a String

    190 |

    ld_rmarkdown_header()

    191 |

    Create an R Markdown Header

    196 |

    ld_site_yaml()

    197 |

    Create a Minimalist Site YAML List

    202 |

    ld_workflowr_header()

    203 |

    Create a workflowr Header

    208 |

    ld_write_file()

    209 |

    Write to an R Markdown File

    214 |

    listdown()

    215 |

    Create a listdown Object

    220 |
    221 | 222 | 227 |
    228 | 229 | 230 |
    231 | 234 | 235 |
    236 |

    Site built with pkgdown 1.6.1.

    237 |
    238 | 239 |
    240 |
    241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /docs/reference/ld_bundle_doc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create a `listdown` Document Bundle — ld_bundle_doc • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
    66 |
    67 | 112 | 113 | 114 | 115 |
    116 | 117 |
    118 |
    119 | 124 | 125 |
    126 |

    A page bundle encapsulates the computational components, 127 | R Markdown header, and listdown object. Together, these three objects 128 | are sufficient to create a document, which can be written with the 129 | `ld_create_document()` function.

    130 |
    131 | 132 |
    ld_bundle_doc(cc, header, ld)
    133 | 134 |

    Arguments

    135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 149 | 150 |
    cc

    the computational component list that will be presented.

    header

    a `list` with the header information for the document.

    ld

    a `listdown` object describing how to present the computational 148 | components.

    151 | 152 |

    See also

    153 | 154 |

    ld_create_document

    155 | 156 |
    157 | 162 |
    163 | 164 | 165 |
    166 | 169 | 170 |
    171 |

    Site built with pkgdown 1.6.1.

    172 |
    173 | 174 |
    175 |
    176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /docs/reference/ld_chunk_opts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Apply Chunk Options to a Presentation Object — ld_chunk_opts • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 110 | 111 | 112 | 113 |
    114 | 115 |
    116 |
    117 | 122 | 123 |
    124 |

    This function allows the user to set chunk options for 125 | individual elements of a presentation list.

    126 |
    127 | 128 |
    ld_chunk_opts(pres_obj, chunk_name = NULL, ..., chunk_opts = NULL)
    129 | 130 |

    Arguments

    131 | 132 | 133 | 134 | 135 | 137 | 138 | 139 | 140 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 151 | 152 |
    pres_obj

    the presentation list element whose chunk options should 136 | be modified.

    chunk_name

    the name of the chunk. By default this is NULL, 141 | corresponding to no chunk name.

    ...

    named chunk options and their values.

    chunk_opts

    list of chunk options can be specified. Takes priority 150 | over arguments provided to ...

    153 | 154 | 155 |
    156 | 161 |
    162 | 163 | 164 |
    165 | 168 | 169 |
    170 |

    Site built with pkgdown 1.6.1.

    171 |
    172 | 173 |
    174 |
    175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/reference/ld_make_chunks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Write a listdown Object to a String — ld_make_chunks • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
    66 |
    67 | 112 | 113 | 114 | 115 |
    116 | 117 |
    118 |
    119 | 124 | 125 |
    126 |

    After a presentation list and listdown object have been 127 | constructed the chunks can be rendered to a string, which can be appended 128 | to a file, with appropriate headers, resulting in a compilable R Markdown 129 | document.

    130 |
    131 | 132 |
    ld_make_chunks(ld, rmd_dir)
    133 | 134 |

    Arguments

    135 | 136 | 137 | 138 | 139 | 142 | 143 |
    ld

    the listdown object that provides 140 | information on how a presentation object should be displayed in the 141 | output.

    144 | 145 |

    See also

    146 | 147 | 148 | 149 |
    150 | 155 |
    156 | 157 | 158 |
    159 | 162 | 163 |
    164 |

    Site built with pkgdown 1.6.1.

    165 |
    166 | 167 |
    168 |
    169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /docs/reference/ld_rmarkdown_header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create an R Markdown Header — ld_rmarkdown_header • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 109 | 110 | 111 | 112 |
    113 | 114 |
    115 |
    116 | 121 | 122 |
    123 |

    Output an R Markdown header with specified parameters.

    124 |
    125 | 126 |
    ld_rmarkdown_header(
    127 |   title,
    128 |   author = NULL,
    129 |   date = NULL,
    130 |   output = c("html_document", "pdf_document", "word_document")
    131 | )
    132 | 133 |

    Arguments

    134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 152 | 153 |
    title

    the title of the page.

    author

    the author of the page. The default is NULL - no author.

    date

    the date for the page. The default is NULL - no date.

    output

    the output format of the page. If NULL then no output format. 151 | The default is an html document.

    154 | 155 | 156 |
    157 | 162 |
    163 | 164 | 165 |
    166 | 169 | 170 |
    171 |

    Site built with pkgdown 1.6.1.

    172 |
    173 | 174 |
    175 |
    176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /docs/reference/ld_site_yaml.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create a Minimalist Site YAML List — ld_site_yaml • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 109 | 110 | 111 | 112 |
    113 | 114 |
    115 |
    116 | 121 | 122 |
    123 |

    Create a Minimalist Site YAML List

    124 |
    125 | 126 |
    ld_site_yaml(site_name, tab_name, rmd_name, navbar_title = site_name)
    127 | 128 |

    Arguments

    129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 143 | 144 | 145 | 146 | 148 | 149 |
    site_name

    the name of the site.

    tab_name

    the name of the tabs on the site.

    rmd_name

    the name of the Rmarkdown files that will generate the 142 | respective tabs.

    navbar_title

    the title of the navigation bar (Default is the 147 | `site_name` argument.

    150 | 151 | 152 |
    153 | 158 |
    159 | 160 | 161 |
    162 | 165 | 166 |
    167 |

    Site built with pkgdown 1.6.1.

    168 |
    169 | 170 |
    171 |
    172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/reference/ld_workflowr_header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create a workflowr Header — ld_workflowr_header • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 109 | 110 | 111 | 112 |
    113 | 114 |
    115 |
    116 | 121 | 122 |
    123 |

    Output a workflowr R Markdown header with specified title.

    124 |
    125 | 126 |
    ld_workflowr_header(title, toc = FALSE)
    127 | 128 |

    Arguments

    129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
    title

    the title of the page.

    toc

    should the table of contents be generated? Default FALSE.

    140 | 141 | 142 |
    143 | 148 |
    149 | 150 | 151 |
    152 | 155 | 156 |
    157 |

    Site built with pkgdown 1.6.1.

    158 |
    159 | 160 |
    161 |
    162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /docs/reference/ld_write_file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Write to an R Markdown File — ld_write_file • listdown 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 110 | 111 | 112 | 113 |
    114 | 115 |
    116 |
    117 | 122 | 123 |
    124 |

    This function takes header information and a listdown 125 | object and writes to a specified file.

    126 |
    127 | 128 |
    ld_write_file(rmd_header, ld, file_name)
    129 | 130 |

    Arguments

    131 | 132 | 133 | 134 | 135 | 137 | 138 | 139 | 140 | 143 | 144 | 145 | 146 | 147 | 148 |
    rmd_header

    either a character or listdown_header with R Markdown 136 | header information.

    ld

    the listdown object that provides 141 | information on how a presentation object should be displayed in the 142 | output.

    file_name

    the output file to write to.

    149 | 150 | 151 |
    152 | 157 |
    158 | 159 | 160 | 170 |
    171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry(bibtype = "Article", 2 | title = "On the Programmatic Generation of Reproducible Documents", 3 | author = c(person(given = "Michael", 4 | family = "Kane", 5 | email = "michael.kane@yale.edu"), 6 | person(given = c("Xun", "(Tony)"), 7 | family = "Jiang", 8 | email = "xunj@amgen.com", 9 | comment = "Tony"), 10 | person(given = "Simon", 11 | family = "Urbanek", 12 | email = "s.urbanek@auckland.ac.nz")), 13 | journal = "Journal of Statistical Software", 14 | year = "2022", 15 | volume = "103", 16 | number = "8", 17 | pages = "1--15", 18 | doi = "10.18637/jss.v103.i08", 19 | header = "To cite listdown in publications use:" 20 | ) 21 | 22 | -------------------------------------------------------------------------------- /inst/jss/clean.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | rm -f *.aux 3 | rm -f *.bbl 4 | rm -f *.blg 5 | rm -f *.log 6 | rm -f *.out 7 | rm -rf kane-listdown_files 8 | -------------------------------------------------------------------------------- /inst/jss/cover-letter.txt: -------------------------------------------------------------------------------- 1 | Dear Editors, 2 | 3 | Please find the attached submission, "On the Programmatic Generation of Reproducible 4 | Documents," which explores the use and appropriateness of programmatically generating 5 | reproducible documents, identifies key concepts for understanding their use, and introduces a 6 | new R package, listdown, that implements the generation of R Markdown documents, and 7 | explores it's use in a clinical trial reporting context. 8 | 9 | We believe this paper provides a novel take on the relationship between reproducibility and 10 | automated reporting, and we expect that this article will see broad readership in this 11 | increasingly popular area of statistics and data science. 12 | 13 | The package's interface is now stable and the associated code is available on CRAN, it is being 14 | actively maintained, and it is also being used regularly. 15 | 16 | This manuscript has not been published elsewhere and neither of the authors have a conflict of 17 | interest to declare. 18 | 19 | Sincerely, 20 | 21 | Michael Kane and Simon Urbanek 22 | -------------------------------------------------------------------------------- /inst/jss/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/inst/jss/jsslogo.jpg -------------------------------------------------------------------------------- /inst/jss/listdown-jss.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/inst/jss/listdown-jss.pdf -------------------------------------------------------------------------------- /inst/jss/pre-review-response.md: -------------------------------------------------------------------------------- 1 | # Pre-comment response 2 | 3 | We would like to thank the editors for their comments and suggestions. We have made considerable changes to both the submission as well as the package based on the feedback provided. Below we address and discuss each of the issues provided. 4 | 5 | # Response to the general comments from the editorial team 6 | 7 | We have restructured the document and added text describing more specifically how a computational component list's structure maps to the that of an R Markdown document. We have also added an example of the `ld_cc_dendro()` function earlier in the document to illustrate the correspondence between the list and the document. 8 | 9 | The progression of the examples has also been revised so that the example builds progressively in complexity and sophistication. We hope that this change allows the reader to digest successively more elaborate concepts and functionality facilitated by the package. However, we would like to remind the reviewers that the goal of the package is to address the creation of the presentation of results in the context described. It is not meant to address how those results are derived. We have added emphasis to this in Section 5. 10 | 11 | The advantages and limitations of both the automated reproducible document generation and package are given in Section 1 and the discussion in Section 6. Section 5 and 6 describe those situations for which the package has been shown useful. 12 | 13 | The comment concerning the "monolithicness" of the presentation is somewhat difficult to understand. The package itself adrresses the problem creating reproducible documents via lists and, in this sense, the task is singular and perhaps this is the motivation for the comment. However, the conceptual contribution is the separation of narrtive from computational components along with the analysis and dicussion of this characterization and it's consequences. The technical contribution is the implementation of this capability in a way that is general, flexible, and easy to integrate into data processing pipelines. An earlier version of the manuscript was sufficient for analysts (intermediate R users) to create reproducible documents for reporting to clinicians with little to no extra instruction. The manuscript should be sufficent for the reader to understand the underlying concepts, understand how to automate R Markdown document generation for a variety of different types of documents and document types, and extend the use of the package to the users own needs. The paper is not meant to show readers how to create complete reports for a specific domain and the clinical trial example is only meant to illustrate one outlet for the package, which we have found useful. If there are specific suggestions for how else to address this issue, we would be happy to incorporate them. 14 | 15 | # Further comments 16 | 17 | The manuscript needs to be spell-checked and proofread. The manuscript in its current form is not suitable for review. 18 | 19 | - Hopefully it is in the current form. 20 | 21 | A print method should be added for listdown objects. 22 | 23 | - This is included in the newest revision of the package and is described in the paper. 24 | 25 | As replication material an R script, e.g., by purling the Rmd file and editing the R script output such that it is in a human readable form, needs to be provided. 26 | 27 | - This is included in the updated `supplemental-materials` directory. 28 | 29 | The submitted package version and the version on CRAN are out of sync. An updated version should be submitted to JSS. 30 | 31 | - We have uploaded version 0.2.21 to CRAN and included it in this submission. 32 | 33 | Appendix 1 can be omitted, but rather included in plain text form in a standalone file in the supplementary material. 34 | 35 | - Done, thanks for the suggestion. 36 | 37 | For referring to subsections, do not use Subsection x.y, just Section x.y. 38 | 39 | - This has been done. Please note that we do describe creating "subsections" and "subsubsection" in the text and that should be distinguished from the references. 40 | 41 | The code presented in the manuscript should not contain comments within the verbatim code. Instead the comments should be made in the normal LaTeX text. 42 | 43 | - Done. 44 | 45 | For the code layout in R publications, we typically distinguish input/output using Sinput/Soutput (or equivalently CodeInput/CodeOutput). Unless there are special reasons to format it differently, the input should use the text width (up to 76 or 77 characters) and be indented by two spaces, e.g., 46 | 47 | - Done. 48 | 49 | As a reminder, please make sure that \proglang, \pkg and \code have been used for highlighting throughout the paper (including titles and references), except where explicitly escaped. 50 | 51 | - Done. 52 | 53 | Springer-Verlag (not: Springer) ysis.” In Compstat, pp. 575–580. Springer. 54 | 55 | - Done. Thanks for pointing this out. 56 | 57 | Please make sure that all software packages are cite'd properly. 58 | 59 | - Done. 60 | 61 | All references should be in title style. 62 | 63 | - Done 64 | 65 | Please make sure that the files needed to replicate all code/examples within the manuscript are included in a standalone replication script 66 | 67 | - Done -------------------------------------------------------------------------------- /inst/jss/references.bib: -------------------------------------------------------------------------------- 1 | @Manual{R, 2 | title = {R: A Language and Environment for Statistical Computing}, 3 | author = {{R Core Team}}, 4 | organization = {R Foundation for Statistical Computing}, 5 | address = {Vienna, Austria}, 6 | year = {2012}, 7 | note = {{ISBN} 3-900051-07-0}, 8 | url = {http://www.R-project.org/}, 9 | } 10 | 11 | @article{ihaka:1996, 12 | Author = {Ihaka, Ross and Gentleman, Robert}, 13 | Journal = {Journal of Computational and Graphical Statistics}, 14 | Number = 3, 15 | Pages = {299--314}, 16 | Title = {R: A Language for Data Analysis and Graphics}, 17 | Volume = 5, 18 | Year = 1996} 19 | 20 | @article{gamma1995, 21 | title={Design Patterns: Elements of Reusable Object-Oriented Software}, 22 | author={Gamma, Erich and Helm, Richard and Johnson, Ralph and Vlissides, John}, 23 | journal={Addison Wesley Longman, Inc, January}, 24 | volume={1}, 25 | number={5}, 26 | pages={1}, 27 | year={1995} 28 | } 29 | 30 | @inproceedings{leisch2002, 31 | title={Sweave: Dynamic Generation of Statistical Reports using Literate Data Analysis}, 32 | author={Leisch, Friedrich}, 33 | booktitle={Compstat}, 34 | pages={575--580}, 35 | year={2002}, 36 | organization={Springer-Verlag} 37 | } 38 | 39 | @Manual{yaml, 40 | title = {yaml: Methods to Convert R Data to YAML and Back}, 41 | author = {Jeremy Stephens and Kirill Simonov and Yihui Xie and Zhuoer Dong and Hadley Wickham and Jeffrey Horner and {reikoch} and Will Beasley and Brendan O'Connor and Gregory R. Warnes}, 42 | year = {2020}, 43 | note = {R package version 2.2.1}, 44 | url = {https://CRAN.R-project.org/package=yaml}, 45 | } 46 | 47 | @Manual{purrr, 48 | title = {purrr: Functional Programming Tools}, 49 | author = {Lionel Henry and Hadley Wickham}, 50 | year = {2020}, 51 | note = {R package version 0.3.4}, 52 | url = {https://CRAN.R-project.org/package=purrr}, 53 | } 54 | 55 | @Manual{trelliscopejs, 56 | title = {trelliscopejs: Create Interactive Trelliscope Displays}, 57 | author = {Ryan Hafen and Barret Schloerke}, 58 | year = {2020}, 59 | note = {R package version 0.2.4}, 60 | url = {https://CRAN.R-project.org/package=trelliscopejs}, 61 | } 62 | 63 | @Manual{rmarkdownref, 64 | title = {The R Markdown Reference}, 65 | author = {RStudio}, 66 | year = {2020}, 67 | url = {https://rstudio.com/wp-content/uploads/2015/03/rmarkdown-reference.pdf}, 68 | } 69 | 70 | @article{knuth1984, 71 | title={Literate Programming}, 72 | author={Knuth, Donald Ervin}, 73 | journal={The Computer Journal}, 74 | volume={27}, 75 | number={2}, 76 | pages={97--111}, 77 | year={1984}, 78 | publisher={Oxford University Press} 79 | } 80 | 81 | @Book{rmarkdownbook, 82 | title = {R Markdown: The Definitive Guide}, 83 | author = {Yihui Xie and J.J. Allaire and Garrett Grolemund}, 84 | publisher = {Chapman and Hall/CRC}, 85 | address = {Boca Raton, Florida}, 86 | year = {2018}, 87 | note = {ISBN 9781138359338}, 88 | url = {https://bookdown.org/yihui/rmarkdown}, 89 | } 90 | 91 | @Book{knitrbook, 92 | title = {Dynamic Documents with {R} and knitr}, 93 | author = {Yihui Xie}, 94 | publisher = {Chapman and Hall/CRC}, 95 | address = {Boca Raton, Florida}, 96 | year = {2015}, 97 | edition = {2nd}, 98 | note = {ISBN 978-1498716963}, 99 | url = {https://yihui.org/knitr/}, 100 | } 101 | 102 | @article{baumer2014, 103 | title={R Markdown: Integrating a Reproducible Analysis Rool into Introductory Statistics}, 104 | author={Baumer, Ben and Cetinkaya-Rundel, Mine and Bray, Andrew and Loi, Linda and Horton, Nicholas J}, 105 | journal={arXiv preprint arXiv:1402.1894}, 106 | year={2014} 107 | } 108 | 109 | @Article{blischak2019, 110 | title = {Creating and Sharing Reproducible Research Code the Workflowr Way [version 1; peer review: 3 approved]}, 111 | author = {John D Blischak and Peter Carbonetto and Matthew Stephens}, 112 | journal = {F1000Research}, 113 | year = {2019}, 114 | volume = {8}, 115 | number = {1749}, 116 | doi = {10.12688/f1000research.20843.1}, 117 | url = {https://doi.org/10.12688/f1000research.20843.1}, 118 | } 119 | 120 | @Book{wickham2016, 121 | author = {Hadley Wickham}, 122 | title = {ggplot2: Elegant Graphics for Data Analysis}, 123 | publisher = {Springer-Verlag New York}, 124 | year = {2016}, 125 | isbn = {978-3-319-24277-4}, 126 | url = {https://ggplot2.tidyverse.org}, 127 | } 128 | 129 | @Manual{xie2020, 130 | title = {DT: A Wrapper of the JavaScript Library 'DataTables'}, 131 | author = {Yihui Xie and Joe Cheng and Xianying Tan}, 132 | year = {2020}, 133 | note = {R package version 0.12}, 134 | url = {https://CRAN.R-project.org/package=DT}, 135 | } -------------------------------------------------------------------------------- /inst/jss/supplemental-material/clean.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | rm -f *.rds 3 | rm -f *.pdf 4 | rm -f *.tex 5 | rm -f *.aux 6 | rm -f *.blg 7 | rm -f *.log 8 | rm -f *.out 9 | rm -f *.bbl 10 | rm -f *.html 11 | rm -f *.md 12 | rm -rf figure 13 | rm -f trial-report.rmd 14 | -------------------------------------------------------------------------------- /inst/jss/supplemental-material/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/inst/jss/supplemental-material/jsslogo.jpg -------------------------------------------------------------------------------- /inst/jss/supplemental-material/listdown-jss.R: -------------------------------------------------------------------------------- 1 | ## ----cc1---------------------------------------------------------------------- 2 | library("ggplot2") 3 | 4 | library("listdown") 5 | 6 | data(anscombe) 7 | 8 | computational_components <- list( 9 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 10 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 11 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + 12 | geom_point(), 13 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 14 | geom_point()) 15 | 16 | ld_cc_dendro(computational_components) 17 | 18 | 19 | ## ----------------------------------------------------------------------------- 20 | saveRDS(computational_components, "comp-comp.rds") 21 | 22 | ld <- listdown(load_cc_expr = readRDS("comp-comp.rds"), 23 | package = "ggplot2") 24 | 25 | ld 26 | 27 | 28 | ## ----eval = FALSE------------------------------------------------------------- 29 | ## ld_write_file(ld_rmarkdown_header("Anscombe's Quartet", 30 | ## author = "Francis Anscombe", 31 | ## date = "1973"), 32 | ## ld, 33 | ## "anscome-example.rmd") 34 | 35 | 36 | ## ----------------------------------------------------------------------------- 37 | ld <- listdown(load_cc_expr = readRDS("comp-comp.rds"), 38 | package = "ggplot2", 39 | echo = FALSE) 40 | 41 | ld_make_chunks(ld)[1:7] 42 | 43 | 44 | ## ----results="as.is"---------------------------------------------------------- 45 | computational_components$Data <- anscombe 46 | saveRDS(computational_components, "comp-comp.rds") 47 | ld_make_chunks(ld)[32:36] 48 | 49 | 50 | ## ----------------------------------------------------------------------------- 51 | ld <- listdown(load_cc_expr = readRDS("comp-comp.rds"), 52 | package = c("ggplot2", "DT"), 53 | decorator = list(data.frame = datatable)) 54 | 55 | ld_make_chunks(ld)[33:37] 56 | 57 | 58 | ## ----------------------------------------------------------------------------- 59 | comp_comp2 <- list( 60 | Iris = iris, 61 | Sepal.Length = list( 62 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 63 | geom_point(), 64 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 65 | geom_point(), 66 | Colored = list( 67 | Sepal.Width = ggplot(iris, 68 | aes(x = Sepal.Length, y = Sepal.Width, 69 | color = Species)) + geom_point(), 70 | Petal.Length = ggplot(iris, 71 | aes(x = Sepal.Length, y = Petal.Length, 72 | color = Species)) + geom_point()))) 73 | 74 | ld_cc_dendro(comp_comp2) 75 | 76 | 77 | ## ----------------------------------------------------------------------------- 78 | saveRDS(comp_comp2, "comp-comp2.rds") 79 | ld <- listdown(load_cc_expr = readRDS("comp-comp2.rds"), 80 | package = c("ggplot2", "DT", "purrr"), 81 | decorator = list(ggplot = identity, 82 | data.frame = datatable_no_search), 83 | setup_expr = knitr::opts_chunk$set(echo = FALSE), 84 | init_expr = { 85 | datatable_no_search <- partial(datatable, 86 | options = list(dom = 't')) 87 | }) 88 | 89 | ld_make_chunks(ld)[2:14] 90 | 91 | 92 | ## ----------------------------------------------------------------------------- 93 | ld <- listdown(load_cc_expr = readRDS("comp-comp2.rds"), 94 | package = c("ggplot2", "DT", "purrr"), 95 | decorator_chunk_opts = 96 | list(ggplot = list(fig.width = 100, 97 | fig.height = 200)), 98 | init_expr = { 99 | datatable_no_search <- partial(datatable, 100 | options = list(dom = 't')) 101 | }, 102 | echo = FALSE) 103 | 104 | ld_make_chunks(ld)[c(12:16, 19:24)] 105 | 106 | 107 | ## ----------------------------------------------------------------------------- 108 | comp_comp2$Iris <- ld_chunk_opts(comp_comp2$Iris, echo = TRUE) 109 | saveRDS(comp_comp2, "comp-comp2.rds") 110 | ld_make_chunks(ld)[12:16] 111 | 112 | 113 | ## ---- eval = TRUE, message=FALSE, warning=FALSE------------------------------- 114 | library("gtsummary") 115 | library("dplyr") 116 | library("survival") 117 | library("survminer") 118 | library("rmarkdown") 119 | 120 | make_surv_cc <- function(trial, treat, surv_cond_chars) { 121 | table_1 <- trial %>% 122 | tbl_summary(by = all_of(treat)) %>% 123 | gtsummary::as_flex_table() 124 | 125 | scs <- lapply(c("1", surv_cond_chars), 126 | function(sc) { 127 | sprintf("Surv(ttdeath, death) ~ %s + %s", treat, sc) %>% 128 | as.formula() %>% 129 | surv_fit(trial) %>% 130 | ggsurvplot() 131 | }) 132 | names(scs) <- c("Overall", tools::toTitleCase(surv_cond_chars)) 133 | list(`Table 1` = table_1, `Survival Plots` = scs) 134 | } 135 | 136 | surv_cc <- make_surv_cc(trial, treat = "trt", 137 | surv_cond_chars = c("stage", "grade")) 138 | 139 | ld_cc_dendro(surv_cc) 140 | 141 | 142 | ## ----eval = TRUE, message = FALSE, warning = FALSE---------------------------- 143 | class(surv_cc$`Survival Plots`$Overall) <- 144 | class(surv_cc$`Survival Plots`$Stage) <- 145 | class(surv_cc$`Survival Plots`$Grade) <- "list" 146 | 147 | names(surv_cc$`Survival Plots`) <- 148 | paste(names(surv_cc$`Survival Plots`), "{.tabset}") 149 | 150 | names(surv_cc$`Survival Plots`$`Overall {.tabset}`) <- 151 | names(surv_cc$`Survival Plots`$`Stage {.tabset}`) <- 152 | names(surv_cc$`Survival Plots`$`Grade {.tabset}`) <- 153 | c("Plot", "Data", "Table") 154 | 155 | saveRDS(surv_cc, "surv-cc.rds") 156 | 157 | ld_surv <- listdown(load_cc_expr = readRDS("surv-cc.rds"), 158 | package = c("gtsummary", "flextable", "DT", 159 | "ggplot2"), 160 | decorator_chunk_opts = 161 | list(gg = list(fig.width = 8, 162 | fig.height = 6)), 163 | decorator = list(data.frame = datatable), 164 | echo = FALSE, 165 | message = FALSE, 166 | warning = FALSE, 167 | fig.width = 7, 168 | fig.height = 4.5) 169 | 170 | writeLines( 171 | paste(c( 172 | as.character(ld_rmarkdown_header("Simple Trial Report")), 173 | ld_make_chunks(ld_surv))), 174 | "trial-report.rmd") 175 | 176 | render("trial-report.rmd", quiet = TRUE) 177 | browseURL("trial-report.html") 178 | 179 | -------------------------------------------------------------------------------- /inst/jss/supplemental-material/make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | Rscript -e "knitr::knit('listdown-jss.rmd', tangle = TRUE)" 4 | Rscript -e "rmarkdown::render('listdown-jss.rmd')" 5 | -------------------------------------------------------------------------------- /man/as_ld_yml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as-yml.r 3 | \name{as_ld_yml} 4 | \alias{as_ld_yml} 5 | \title{Turn a Computational Component List into YAML with Class Information} 6 | \usage{ 7 | as_ld_yml(x) 8 | } 9 | \arguments{ 10 | \item{x}{a named list of computational components.} 11 | } 12 | \description{ 13 | Create an object of type yaml::yml from a list of 14 | computational components. The function recursively descends into the list 15 | and when an element type is not a list the class information substituted 16 | for the object. 17 | } 18 | \examples{ 19 | if (require("ggplot2")) { 20 | 21 | cc_list <- list( 22 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 23 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 24 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 25 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 26 | geom_point()) 27 | 28 | as_ld_yml(cc_list) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /man/class_and_tag.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class-and-tag.r 3 | \name{class_and_tag} 4 | \alias{class_and_tag} 5 | \title{Prepend Class Information and Add Attributes} 6 | \usage{ 7 | class_and_tag(.x, new_class, ...) 8 | } 9 | \arguments{ 10 | \item{.x}{an object to add class and attribute information to.} 11 | 12 | \item{new_class}{the name of the class to be prepended to .x.} 13 | 14 | \item{...}{the attributes to attach to .x.} 15 | } 16 | \description{ 17 | listdown decorators map list element to functions. This 18 | function is provided for convenience to prepend a class and attributes, 19 | which can then be used by custom decorators to display those element. 20 | } 21 | -------------------------------------------------------------------------------- /man/create_load_cc_expr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/add-load-cc-expr.r 3 | \name{create_load_cc_expr} 4 | \alias{create_load_cc_expr} 5 | \title{Create an expression to load a Computational Component} 6 | \usage{ 7 | create_load_cc_expr(load_cc_expr) 8 | } 9 | \arguments{ 10 | \item{load_cc_expr}{a string or expression that should be use to load 11 | the computational components.} 12 | } 13 | \description{ 14 | An expression to load a computational component can be either 15 | a raw expression, a variable holding the expression, or a string. The 16 | return is an unevaluated expression. 17 | } 18 | -------------------------------------------------------------------------------- /man/ld_build_html_site.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/build-site.r 3 | \name{ld_build_html_site} 4 | \alias{ld_build_html_site} 5 | \title{Build an html Site from listdown Document Bundles} 6 | \usage{ 7 | ld_build_html_site( 8 | doc_bundles, 9 | site_yaml, 10 | site_dir = tempdir(), 11 | rmd_dir = file.path(site_dir, "rmarkdown"), 12 | data_dir = file.path(site_dir, "data"), 13 | html_dir = file.path(site_dir, "html"), 14 | render_site = TRUE, 15 | view = interactive(), 16 | make_data_dir = TRUE, 17 | make_rmd_dir = TRUE, 18 | ... 19 | ) 20 | } 21 | \arguments{ 22 | \item{doc_bundles}{a named list of document bundles. There can be up to one 23 | unnamed bundle, which will be assumed to correspond to an index.rmd file.} 24 | 25 | \item{site_yaml}{a list of site information, which will be written 26 | to the _site.yml file.} 27 | 28 | \item{site_dir}{the directory where the site (rmd, data, and html files) 29 | will be written to.} 30 | 31 | \item{rmd_dir}{the directory where the R Markdown files will reside. By 32 | default an "rmarkdown" file is written to `tempdir()`.} 33 | 34 | \item{data_dir}{the location where data can be found for each bundle. 35 | If the data is held in memory for a listdown document bundle, then it will 36 | be written to the specified directory. If mulitple directories are specified, 37 | then the directory is specified per bundle, with index recycling used if 38 | the number of directories is not the same as the number of bundles.} 39 | 40 | \item{html_dir}{the location of the rendered document, relative to the 41 | directory specified by `rmd_dir`. Note that this is an {{rmarkdown}} 42 | convention. By default a directory names "html" is created in the 43 | directory specified by `rmd_dir` and rendered documents are place there.} 44 | 45 | \item{render_site}{should the page be rendered? If not then the 46 | `html_dir` is not created.} 47 | 48 | \item{view}{should the output document be opened after rendering? By 49 | default, if `render_doc` is `TRUE` and this argument is `TRUE` then 50 | the browser will open for you to examine the output.} 51 | 52 | \item{make_data_dir}{if the `data_dir` directory is not present, should it 53 | be created? This can be set to `FALSE` when data already resides on disk 54 | to verify that it is not being created and written.} 55 | 56 | \item{make_rmd_dir}{if the `rmd_dir` directory is not present, should it 57 | be created? This can be set to `FALSE` when data already resides on disk 58 | to verify that it is not being created and written.} 59 | 60 | \item{...}{argument to be passed to the `rmarkdown::render_site()` function.} 61 | } 62 | \description{ 63 | This function creates an html website with each tab in the 64 | page being desribed by a listdown document bundle. 65 | } 66 | \seealso{ 67 | ld_bundle_doc ld_create_doc 68 | } 69 | -------------------------------------------------------------------------------- /man/ld_bundle_doc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/build-site.r 3 | \name{ld_bundle_doc} 4 | \alias{ld_bundle_doc} 5 | \title{Create a `listdown` Document Bundle} 6 | \usage{ 7 | ld_bundle_doc(cc, header, ld) 8 | } 9 | \arguments{ 10 | \item{cc}{the computational component list that will be presented.} 11 | 12 | \item{header}{a `list` with the header information for the document.} 13 | 14 | \item{ld}{a `listdown` object describing how to present the computational 15 | components.} 16 | } 17 | \description{ 18 | A page bundle encapsulates the computational components, 19 | R Markdown header, and listdown object. Together, these three objects 20 | are sufficient to create a document, which can be written with the 21 | `ld_create_document()` function. 22 | } 23 | \examples{ 24 | library(ggplot2) 25 | cc <- list( 26 | iris = iris, 27 | Sepal.Length = list( 28 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 29 | geom_point(), 30 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 31 | geom_point(), 32 | Colored = list( 33 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, 34 | color = Species)) + geom_point(), 35 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 36 | color = Species)) + geom_point()))) 37 | 38 | header <- ld_rmarkdown_header("Test header", author = "Some Dude", 39 | date = "2020") 40 | 41 | ld <- listdown(package = "ggplot2") 42 | 43 | ld_bundle_doc(cc, header, ld) 44 | } 45 | \seealso{ 46 | ld_create_document 47 | } 48 | -------------------------------------------------------------------------------- /man/ld_cc_dendro.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cc-dendro.r 3 | \name{ld_cc_dendro} 4 | \alias{ld_cc_dendro} 5 | \title{Show the list of Computational Components as a Dendrogram} 6 | \usage{ 7 | ld_cc_dendro(x) 8 | } 9 | \arguments{ 10 | \item{x}{a named list of computational components} 11 | } 12 | \description{ 13 | This function creates text dendrograms from 14 | a list of computational components. It is useful for 15 | creating a dendrogram of the the computational components of a listdown 16 | object allowing the user to view the components hierarchically. 17 | } 18 | \examples{ 19 | if (require("ggplot2")) { 20 | 21 | cc_list <- list( 22 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 23 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 24 | `Outlier Vertical`= ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 25 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 26 | geom_point()) 27 | 28 | ld_cc_dendro(cc_list) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /man/ld_chunk_opts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chunk-options.r 3 | \name{ld_chunk_opts} 4 | \alias{ld_chunk_opts} 5 | \title{Apply Chunk Options to a Presentation Object} 6 | \usage{ 7 | ld_chunk_opts(pres_obj, chunk_name = NULL, ..., chunk_opts = NULL) 8 | } 9 | \arguments{ 10 | \item{pres_obj}{the presentation list element whose chunk options should 11 | be modified.} 12 | 13 | \item{chunk_name}{the name of the chunk. By default this is NULL, 14 | corresponding to no chunk name.} 15 | 16 | \item{...}{named chunk options and their values.} 17 | 18 | \item{chunk_opts}{list of chunk options can be specified. Takes priority 19 | over arguments provided to ...} 20 | } 21 | \description{ 22 | This function allows the user to set chunk options for 23 | individual elements of a presentation list. 24 | } 25 | -------------------------------------------------------------------------------- /man/ld_create_doc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/build-site.r 3 | \name{ld_create_doc} 4 | \alias{ld_create_doc} 5 | \title{Create a Document from a `listdown` Bundle} 6 | \usage{ 7 | ld_create_doc( 8 | ldb, 9 | rmd_file_name = basename(tempfile(pattern = "rmarkdown", fileext = ".Rmd")), 10 | rmd_dir = tempdir(), 11 | output_dir = rmd_dir, 12 | render_doc = TRUE, 13 | cc_file_name = NULL, 14 | data_dir = ".", 15 | view = interactive(), 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{ldb}{a listdown doc bundle.} 21 | 22 | \item{rmd_file_name}{the name of the R Markdown file to create. By default, 23 | a temporary file is created.} 24 | 25 | \item{rmd_dir}{the directory where the output R Markdown file should be 26 | written to. By default, this is `tempdir()`.} 27 | 28 | \item{output_dir}{the location of the rendered document, relative to the 29 | directory specified by `rmd_dir`. Note that this is an {{rmarkdown}} 30 | convention. By default a directory names "pres" is created in the 31 | directory specified by `rmd_dir` and rendered documents are place there.} 32 | 33 | \item{render_doc}{should the page be rendered? If not then the 34 | `output_dir` is not created.} 35 | 36 | \item{cc_file_name}{the name of the list specifying the computational 37 | components. If this is `NULL` (the default) then the listdown bundle 38 | is checked to make sure it's `load_cc_expr` attribute has been specified. 39 | If it is specified, and the bundles `load_cc_expr` has not been specified, 40 | then it will be written to disk (in the corresponding data directory, 41 | specified by `data_dir`) and read via the `saveRDS()` function.} 42 | 43 | \item{data_dir}{the directory where data should be written. If the 44 | `cc_file_name` argument is `NULL` then this argument is ignored. If the 45 | `cc_file_name` argument is specfied but `data_dir` is not, then `tempdir()` 46 | is used.} 47 | 48 | \item{view}{should the output document be opened after rendering? By 49 | default, if `render_doc` is `TRUE` and this argument is `TRUE` then 50 | the browser will open for you to examine the output.} 51 | 52 | \item{...}{options to send to the rmarkdown::render() function.} 53 | } 54 | \description{ 55 | This function creates a document, defined by a listdown bundle 56 | in a specified location on disk and, optionally, opens the document in the 57 | browser. 58 | } 59 | \seealso{ 60 | ld_bundle_doc 61 | } 62 | -------------------------------------------------------------------------------- /man/ld_make_chunks.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chunk-writer.r 3 | \name{ld_make_chunks} 4 | \alias{ld_make_chunks} 5 | \title{Write a listdown Object to a String} 6 | \usage{ 7 | ld_make_chunks(ld, rmd_dir) 8 | } 9 | \arguments{ 10 | \item{ld}{the listdown object that provides 11 | information on how a presentation object should be displayed in the 12 | output.} 13 | 14 | \item{rmd_dir}{the R Markdown directory.} 15 | } 16 | \description{ 17 | After a presentation list and listdown object have been 18 | constructed the chunks can be rendered to a string, which can be appended 19 | to a file, with appropriate headers, resulting in a compilable R Markdown 20 | document. 21 | } 22 | \seealso{ 23 | \code{\link{listdown}} 24 | } 25 | -------------------------------------------------------------------------------- /man/ld_rmarkdown_header.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/headers.r 3 | \name{ld_rmarkdown_header} 4 | \alias{ld_rmarkdown_header} 5 | \title{Create an R Markdown Header} 6 | \usage{ 7 | ld_rmarkdown_header( 8 | title, 9 | author = NULL, 10 | date = NULL, 11 | output = c("html_document", "pdf_document", "word_document") 12 | ) 13 | } 14 | \arguments{ 15 | \item{title}{the title of the page.} 16 | 17 | \item{author}{the author of the page. The default is NULL - no author.} 18 | 19 | \item{date}{the date for the page. The default is NULL - no date.} 20 | 21 | \item{output}{the output format of the page. If NULL then no output format. 22 | The default is an html document.} 23 | } 24 | \description{ 25 | Output an R Markdown header with specified parameters. 26 | } 27 | -------------------------------------------------------------------------------- /man/ld_site_yaml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/build-site.r 3 | \name{ld_site_yaml} 4 | \alias{ld_site_yaml} 5 | \title{Create a Minimal Site YAML List} 6 | \usage{ 7 | ld_site_yaml(site_name, tab_name, rmd_name, navbar_title = site_name) 8 | } 9 | \arguments{ 10 | \item{site_name}{the name of the site.} 11 | 12 | \item{tab_name}{the name of the tabs on the site.} 13 | 14 | \item{rmd_name}{the name of the Rmarkdown files that will generate the 15 | respective tabs.} 16 | 17 | \item{navbar_title}{the title of the navigation bar (Default is the 18 | `site_name` argument.} 19 | } 20 | \description{ 21 | Create a Minimal Site YAML List 22 | } 23 | -------------------------------------------------------------------------------- /man/ld_workflowr_header.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/headers.r 3 | \name{ld_workflowr_header} 4 | \alias{ld_workflowr_header} 5 | \title{Create a workflowr Header} 6 | \usage{ 7 | ld_workflowr_header(title, toc = FALSE) 8 | } 9 | \arguments{ 10 | \item{title}{the title of the page.} 11 | 12 | \item{toc}{should the table of contents be generated? Default FALSE.} 13 | } 14 | \description{ 15 | Output a workflowr R Markdown header with specified title. 16 | } 17 | -------------------------------------------------------------------------------- /man/ld_write_file.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ld-write-file.r 3 | \name{ld_write_file} 4 | \alias{ld_write_file} 5 | \title{Write to an R Markdown File} 6 | \usage{ 7 | ld_write_file(rmd_header, ld, file_name) 8 | } 9 | \arguments{ 10 | \item{rmd_header}{either a character or listdown_header with R Markdown 11 | header information.} 12 | 13 | \item{ld}{the listdown object that provides 14 | information on how a presentation object should be displayed in the 15 | output.} 16 | 17 | \item{file_name}{the output file to write to.} 18 | } 19 | \description{ 20 | This function takes header information and a listdown 21 | object and writes to a specified file. 22 | } 23 | -------------------------------------------------------------------------------- /man/listdown.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chunk-writer.r 3 | \name{listdown} 4 | \alias{listdown} 5 | \title{Create a listdown Object} 6 | \usage{ 7 | listdown( 8 | package = NULL, 9 | decorator = list(), 10 | decorator_chunk_opts = list(), 11 | default_decorator = identity, 12 | setup_expr = NULL, 13 | init_expr = NULL, 14 | load_cc_expr = NULL, 15 | ..., 16 | chunk_opts = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{package}{a quoted list of package required by the outputted document.} 21 | 22 | \item{decorator}{a named list mapping the potential types of list elements 23 | to a decorator function.} 24 | 25 | \item{decorator_chunk_opts}{a named list mapping the potential types of list 26 | elements to chunk options that should be included for those types.} 27 | 28 | \item{default_decorator}{the decorator to use for list elements whose type 29 | is not inherited from the decorator list. If NULL then the those 30 | elements will not be included when the chunks are written. By default 31 | this is identity, meaning that the elements will be passed directly 32 | (through the identity() function).} 33 | 34 | \item{setup_expr}{an expression that is added before package are 35 | loaded. The expression is put into a chunk named `setup` with option 36 | `include = FALSE` and is intended for initializing the document. For 37 | example the expression `knitr::opts_chunk$set(echo = FALSE)` could be 38 | used to turn echo'ing off for the entire document.} 39 | 40 | \item{init_expr}{an initial expression that will be added to the outputted 41 | document after the libraries have been called. This expression appears 42 | after packages are loaded and before data is read.} 43 | 44 | \item{load_cc_expr}{either an unquoted expression or a character string 45 | that will be turned into an unquoted expression via str2lang to load the 46 | presentation list.} 47 | 48 | \item{...}{default options sent to the chunks of the outputted document.} 49 | 50 | \item{chunk_opts}{a named list of options sent to the chunks of outputted 51 | documents. Note: takes priority over argument provided to ...} 52 | } 53 | \description{ 54 | A listdown object provides information for how a presentation 55 | list should be used to create an R Markdown document. It requires an 56 | unquoted expression indicating how the presentation list will be loaded. 57 | In addition, libraries required by the outputted document and other 58 | parameters can be specified. 59 | } 60 | \examples{ 61 | library(ggplot2) 62 | cc <- list( 63 | iris = iris, 64 | Sepal.Length = list( 65 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 66 | geom_point(), 67 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 68 | geom_point(), 69 | Colored = list( 70 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, 71 | color = Species)) + geom_point(), 72 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 73 | color = Species)) + geom_point()))) 74 | 75 | header <- ld_rmarkdown_header("Test header", author = "Some Dude", 76 | date = "2020") 77 | 78 | ld <- listdown(package = "ggplot2") 79 | 80 | ld_bundle_doc(cc, header, ld) 81 | } 82 | -------------------------------------------------------------------------------- /tests/testthat.r: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(listdown) 3 | 4 | test_check("listdown") 5 | -------------------------------------------------------------------------------- /tests/testthat/reference-data/anscombe-quartet.rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Anscombe Quartet 3 | author: Francis Anscombe 4 | date: '1973' 5 | output: html_document 6 | --- 7 | 8 | ```{r} 9 | library(ggplot2) 10 | 11 | cc_list <- readRDS("cc-list.rds") 12 | ``` 13 | 14 | # Linear 15 | 16 | ```{r} 17 | cc_list$Linear 18 | ``` 19 | 20 | # Non Linear 21 | 22 | ```{r} 23 | cc_list$`Non Linear` 24 | ``` 25 | 26 | # Outlier Vertical 27 | 28 | ```{r} 29 | cc_list$`Outlier Vertical` 30 | ``` 31 | 32 | # Outlier Horizontal 33 | 34 | ```{r} 35 | cc_list$`Outlier Horizontal` 36 | ``` 37 | 38 | # a 39 | 40 | ## b 41 | 42 | ```{r} 43 | cc_list$a$b 44 | ``` 45 | 46 | ```{r} 47 | cc_list$a$`` 48 | ``` 49 | -------------------------------------------------------------------------------- /tests/testthat/reference-data/as-yml.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/as-yml.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/cc-dendro.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/cc-dendro.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/cc-list.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/cc-list.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/chunk-decorator-option-1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/chunk-decorator-option-1.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/chunk-option-1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/chunk-option-1.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/chunk-option-2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/chunk-option-2.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/chunk-option-3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/chunk-option-3.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/chunk-option-4.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/chunk-option-4.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/ld-cc-list-2-output.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/ld-cc-list-2-output.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/listdown-page-bundle-after-creation.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/listdown-page-bundle-after-creation.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/listdown-page-bundle.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/listdown-page-bundle.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/option-check.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/option-check.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/option-chunk-check.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/option-chunk-check.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/site_yaml.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/site_yaml.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-make-chunks-1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-make-chunks-1.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-make-chunks-2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-make-chunks-2.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-no-package.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-no-package.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-print-ld.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-print-ld.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-print-with-decorator.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-print-with-decorator.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-rmarkdown-header.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-rmarkdown-header.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-setup-expr.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-setup-expr.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test-workflowr-header.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test-workflowr-header.rds -------------------------------------------------------------------------------- /tests/testthat/reference-data/test_list.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/tests/testthat/reference-data/test_list.rds -------------------------------------------------------------------------------- /tests/testthat/reference.r: -------------------------------------------------------------------------------- 1 | make_reference <- FALSE 2 | 3 | write_if_make_reference <- 4 | function(object, file_name, reference_data_dir = "reference-data", 5 | write_reference = make_reference) { 6 | 7 | if (!dir.exists(reference_data_dir)) { 8 | dir.create(reference_data_dir) 9 | } 10 | 11 | if (write_reference) { 12 | saveRDS(object, file.path(reference_data_dir, file_name)) 13 | invisible(TRUE) 14 | } else { 15 | invisible(FALSE) 16 | } 17 | } 18 | 19 | read_reference <- function(file_name, reference_data_dir = "reference-data") { 20 | readRDS(file.path(reference_data_dir, file_name)) 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test-add-chunk-elem-option.r: -------------------------------------------------------------------------------- 1 | context("Decorator Chunk Option") 2 | 3 | test_that("Decorator chunk options work.", { 4 | 5 | source("reference.r") 6 | 7 | write_if_make_reference( 8 | list(iris = iris, mtcars = mtcars), 9 | "option-chunk-check.rds") 10 | 11 | expect_error( 12 | listdown(load_cc_expr = readRDS(file.path("reference-data", 13 | "option-chunk-check.rds")), 14 | package = "knitr", 15 | decorator = list(data.frame = kable), 16 | decorator_chunk_opts = 17 | list(data.frame = list("test_chunk", bunk = FALSE)))) 18 | 19 | ld <- listdown(load_cc_expr = readRDS(file.path("reference-data", 20 | "option-check.rds")), 21 | package = "knitr", 22 | decorator = list(data.frame = kable), 23 | decorator_chunk_opts = 24 | list(data.frame = list("test_chunk", echo = FALSE, 25 | results = "as.is"))) 26 | 27 | 28 | write_if_make_reference(ld_make_chunks(ld), "chunk-decorator-option-1.rds") 29 | write_if_make_reference(capture.output(print(ld)), 30 | "test-print-with-decorator.rds") 31 | 32 | expect_equal(ld_make_chunks(ld), 33 | read_reference("chunk-decorator-option-1.rds")) 34 | expect_equal(capture.output(print(ld)), 35 | read_reference("test-print-with-decorator.rds")) 36 | 37 | }) 38 | -------------------------------------------------------------------------------- /tests/testthat/test-add-chunk-option.r: -------------------------------------------------------------------------------- 1 | context("Chunk Options") 2 | 3 | source("reference.r") 4 | 5 | pres_list <- list(iris = iris, mtcars = mtcars) 6 | 7 | write_if_make_reference(pres_list, "option-check.rds") 8 | 9 | ld <- listdown(load_cc_expr = read_reference("option-check.rds"), 10 | package = "knitr", 11 | decorator = list(data.frame = kable)) 12 | 13 | test_that("Only listdown objects can be used to make chunks.", { 14 | expect_error(ld_make_chunks(letters, 1:10)) 15 | }) 16 | 17 | write_if_make_reference(ld_make_chunks(ld), "chunk-option-1.rds") 18 | 19 | test_that("Output with no options works.", { 20 | expect_equal(ld_make_chunks(ld), 21 | read_reference("chunk-option-1.rds")) 22 | }) 23 | 24 | pres_list$mtcars <- ld_chunk_opts(pres_list$mtcars, 25 | echo = FALSE, results = "as.is") 26 | 27 | write_if_make_reference(ld_make_chunks(ld), "chunk-option-2.rds") 28 | 29 | test_that("Chunk options can be added.", { 30 | expect_equal(ld_make_chunks(ld), 31 | read_reference("chunk-option-2.rds")) 32 | }) 33 | 34 | pres_list$iris <- ld_chunk_opts(pres_list$iris, chunk_name = "iris_chunk") 35 | 36 | write_if_make_reference(ld_make_chunks(ld), "chunk-option-3.rds") 37 | 38 | test_that("Chunk names can be added.", { 39 | expect_equal(ld_make_chunks(ld), 40 | read_reference("chunk-option-3.rds")) 41 | }) 42 | 43 | pres_list$iris <- ld_chunk_opts(pres_list$iris, echo = TRUE) 44 | 45 | write_if_make_reference(ld_make_chunks(ld), "chunk-option-4.rds") 46 | 47 | test_that("Chunks can have names and options.", { 48 | expect_equal(ld_make_chunks(ld), 49 | read_reference("chunk-option-4.rds")) 50 | }) 51 | 52 | test_that("Bad options can't be added.", { 53 | expect_error(ld_chunk_opts(pres_list$iris, no_way_jose = FALSE)) 54 | }) 55 | 56 | test_that("Options can be NULL", { 57 | plt <- ld_chunk_opts(pres_list$iris, results = NULL) 58 | expect_equal(attributes(plt)$listdown$results, NULL) 59 | }) 60 | 61 | test_that("Arg liststs can be created.", { 62 | chunk_opts <- list(echo = FALSE, eval = TRUE) 63 | plt <- ld_chunk_opts(pres_list$iris, chunk_opts = chunk_opts) 64 | attributes(plt)$listdown$chunk_name <- NULL 65 | expect_equal(attributes(plt)$listdown, list(echo = FALSE, eval = TRUE)) 66 | }) 67 | 68 | -------------------------------------------------------------------------------- /tests/testthat/test-as-yml.r: -------------------------------------------------------------------------------- 1 | context("As YML") 2 | 3 | library(ggplot2) 4 | 5 | test_that("Writing a yml file works.", { 6 | 7 | source("reference.r") 8 | 9 | cc_list <- list( 10 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + 11 | geom_point(), 12 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 13 | `Outlier Vertical` = ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 14 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 15 | geom_point(), 16 | a = list(b = 3, 4)) 17 | 18 | write_if_make_reference(as_ld_yml(cc_list), "as-yml.rds") 19 | 20 | expect_equal(as_ld_yml(cc_list), 21 | read_reference("as-yml.rds")) 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/test-cc-dendro.r: -------------------------------------------------------------------------------- 1 | context("Dendrogram") 2 | 3 | library(ggplot2) 4 | 5 | test_that("Dendrograms work.", { 6 | 7 | source("reference.r") 8 | 9 | cc_list <- 10 | list( 11 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 12 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 13 | `Outlier Vertical` = ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 14 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + 15 | geom_point() 16 | ) 17 | 18 | write_if_make_reference(ld_cc_dendro(cc_list), "cc-dendro.rds") 19 | 20 | expect_equal(ld_cc_dendro(cc_list), 21 | read_reference("cc-dendro.rds")) 22 | 23 | expect_error(ld_cc_dendro(exp)) 24 | 25 | ldc <- ld_cc_dendro(cc_list) 26 | 27 | pldc <- capture.output(print(ldc)) 28 | 29 | expect_equal(unclass(pldc), c("", unclass(ldc), "")) 30 | 31 | # Should there be a test here? 32 | 33 | pldc <- capture.output(ld_cc_dendro(list(3))) 34 | 35 | }) 36 | -------------------------------------------------------------------------------- /tests/testthat/test-chunk-opts.r: -------------------------------------------------------------------------------- 1 | 2 | context("Chunk Options") 3 | 4 | test_that("Bad chunk options fail.", { 5 | expect_error(listdown(readRDS(file.path("reference-data", 6 | "option-check.rds")), 7 | package = "knitr", 8 | decorators = list(data.frame = kable), 9 | bunk = letters)) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/test-create-doc.r: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | source("reference.r") 3 | 4 | cc <- list( 5 | iris = iris, 6 | Sepal.Length = list( 7 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 8 | geom_point(), 9 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 10 | geom_point(), 11 | Colored = list( 12 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, 13 | color = Species)) + geom_point(), 14 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 15 | color = Species)) + geom_point()))) 16 | 17 | header <- ld_rmarkdown_header("Test header", author = "Some Dude", 18 | date = "2020") 19 | 20 | ld <- listdown(package = "ggplot2") 21 | 22 | ldb <- ld_bundle_doc(cc, header, ld) 23 | 24 | write_if_make_reference(ldb, "listdown-page-bundle.rds") 25 | 26 | test_that("Create page bundle works", { 27 | expect_equal(ldb, read_reference("listdown-page-bundle.rds")) 28 | }) 29 | 30 | 31 | test_that("A document has been created", { 32 | ldcp <- expect_warning(ld_create_doc(ldb, view = FALSE, quiet = TRUE)) 33 | expect_s3_class(ldcp, "ld_page_bundle") 34 | }) 35 | 36 | # This isn't working. It's probably a path issue. 37 | #write_if_make_reference(ldcp, "listdown-page-bundle-after-creation.rds") 38 | # 39 | #test_that("Create page works.", { 40 | # expect_equal(ldcp, 41 | # read_reference("listdown-page-bundle-after-creation.rds")) 42 | #}) 43 | 44 | saveRDS(cc, "cc.rds") 45 | 46 | # This needs to be added correctly. 47 | cc_path <- file.path(getwd(), "cc.rds") 48 | #ldb <- ld_bundle_doc(readRDS(cc_path), header, ld) 49 | #ld_create_doc(ldb, view = FALSE) 50 | 51 | read_cc_path_str <- paste0('readRDS("', cc_path, '")') 52 | ld_bundle_doc(read_cc_path_str, header, ld) 53 | 54 | test_that("A document can be created.", { 55 | expect_warning(ld_create_doc(ldb, view = FALSE, quiet = TRUE)) 56 | }) 57 | 58 | unlink("cc.rds") 59 | -------------------------------------------------------------------------------- /tests/testthat/test-create-html-site.r: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | 3 | ld <- listdown(package = "ggplot2") 4 | 5 | iris_cc <- list( 6 | iris = iris, 7 | Sepal.Length = list( 8 | Sepal.Width = 9 | ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 10 | geom_point(), 11 | Petal.Length = 12 | ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 13 | geom_point(), 14 | Colored = list( 15 | Sepal.Width = 16 | ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, 17 | color = Species)) + 18 | geom_point(), 19 | Petal.Length = 20 | ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 21 | color = Species)) + 22 | geom_point()))) 23 | 24 | header <- ld_rmarkdown_header("Iris", author = "Some Dude", date = "2020") 25 | 26 | iris_page <- ld_bundle_doc(iris_cc, header, ld) 27 | 28 | anscombe_cc <- list( 29 | Linear = 30 | ggplot(anscombe, aes(x = x1, y = y1)) + 31 | geom_point() + 32 | theme_bw(), 33 | `Non Linear` = 34 | ggplot(anscombe, aes(x = x2, y = y2)) + 35 | geom_point() + 36 | theme_bw(), 37 | `Outlier Vertical`= 38 | ggplot(anscombe, aes(x = x3, y = y3)) + 39 | geom_point() + 40 | theme_bw(), 41 | `Outlier Horizontal` = 42 | ggplot(anscombe, aes(x = x4, y = y4)) + 43 | geom_point() + 44 | theme_bw()) 45 | 46 | header <- ld_rmarkdown_header("Anscombe", author = "Anscombe", date = "2020") 47 | 48 | anscombe_page <- ld_bundle_doc(anscombe_cc, header, ld) 49 | 50 | pages <- list(Anscombe = anscombe_page, Iris = iris_page) 51 | 52 | test_that("Site can be built.", { 53 | site_yaml <- 54 | ld_site_yaml( 55 | "Test Site", 56 | tab_name = names(pages), 57 | rmd_name = c("index.Rmd", "iris.Rmd")) 58 | 59 | site_path <- ld_build_html_site( 60 | pages, 61 | site_yaml, 62 | view = FALSE, 63 | quiet = TRUE) 64 | expect_equal(basename(site_path), "index.html") 65 | }) 66 | 67 | -------------------------------------------------------------------------------- /tests/testthat/test-headers.r: -------------------------------------------------------------------------------- 1 | context("Headers") 2 | 3 | source("reference.r") 4 | 5 | mdh <- ld_rmarkdown_header("Workflow R", author = "Some Dude", date = "2020") 6 | 7 | write_if_make_reference(mdh, "test-rmarkdown-header.rds") 8 | 9 | test_that("The R Markdown header hasn't changed.", { 10 | expect_equal(mdh, read_reference("test-rmarkdown-header.rds")) 11 | }) 12 | 13 | wfr <- ld_workflowr_header("Workflow R") 14 | 15 | write_if_make_reference(wfr, "test-workflowr-header.rds") 16 | 17 | test_that("The workflowrheader hasn't changed.", { 18 | expect_equal(wfr, read_reference("test-workflowr-header.rds")) 19 | }) 20 | -------------------------------------------------------------------------------- /tests/testthat/test-list.r: -------------------------------------------------------------------------------- 1 | context("Write file") 2 | 3 | library(ggplot2) 4 | 5 | source("reference.r") 6 | 7 | cc_list <- list( 8 | Linear = list( 9 | ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 10 | iris[1:10,])) 11 | 12 | rds_file <- "cc-list-2.rds" 13 | 14 | saveRDS(cc_list, file = rds_file) 15 | 16 | ld <- listdown(load_cc_expr = readRDS("cc-list-2.rds"), package = "ggplot2") 17 | 18 | test <- ld_make_chunks(ld) 19 | 20 | write_if_make_reference(test, "ld-cc-list-2-output.rds") 21 | 22 | expect_equal(test, read_reference("ld-cc-list-2-output.rds")) 23 | 24 | unlink("cc-list-2.rds") 25 | -------------------------------------------------------------------------------- /tests/testthat/test-make-chunks.r: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | library(DT) 3 | 4 | context("Make Chunks") 5 | 6 | source("reference.r") 7 | 8 | # The list we'll make an RMarkdown document from. 9 | test_list <- list( 10 | iris = iris, 11 | Sepal.Length = list( 12 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 13 | geom_point(), 14 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 15 | geom_point(), 16 | Colored = list( 17 | Sepal.Width = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, 18 | color = Species)) + geom_point(), 19 | Petal.Length = ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 20 | color = Species)) + geom_point()))) 21 | 22 | # The listdown object. It needs the libraries to load, the decorators, 23 | # and, coming soon, arbitrary code. 24 | # If it sees a ggplot object, it does nothing. If it sees a dataframe 25 | # it decorates with datatable from the DT package. 26 | 27 | write_if_make_reference(test_list, "test_list.rds") 28 | 29 | ld <- listdown(load_cc_expr = readRDS(file.path("reference-data", 30 | "test_list.rds")), 31 | package = c("ggplot2", "DT", "purrr"), 32 | decorator = list(ggplot = identity, 33 | data.frame = datatable), 34 | init_expr = { 35 | datatable <- partial(DT::datatable, 36 | options = list(ordering = FALSE)) 37 | add_one <- function(x) { 38 | x + 1 39 | } 40 | }) 41 | 42 | test_that("A listdown object can be created.", { 43 | expect_true(inherits(ld, "listdown")) 44 | }) 45 | 46 | # Create the RMarkdown string. 47 | 48 | write_if_make_reference(ld_make_chunks(ld), "test-make-chunks-1.rds") 49 | 50 | test_that("The listdown object is the same as before.", { 51 | expect_equal(ld_make_chunks(ld), 52 | read_reference("test-make-chunks-1.rds")) 53 | }) 54 | 55 | ld2 <- listdown(load_cc_expr = readRDS(file.path("reference-data", 56 | "test_list.rds")), 57 | package = c("ggplot2", "DT", "purrr"), 58 | decorator = list(data.frame = datatable), 59 | init_expr = { 60 | datatable <- partial(DT::datatable, 61 | options = list(ordering = FALSE)) 62 | }, 63 | echo = FALSE, 64 | warning = FALSE, 65 | message = FALSE) 66 | 67 | test_that("A listdown object with initial expression can be created.", { 68 | expect_true(inherits(ld2, "listdown")) 69 | }) 70 | 71 | # Create the RMarkdown string. 72 | 73 | write_if_make_reference(ld_make_chunks(ld2), "test-make-chunks-2.rds") 74 | 75 | test_that("The listdown object with init expr is the same as before.", { 76 | expect_equal(ld_make_chunks(ld2), 77 | read_reference("test-make-chunks-2.rds")) 78 | }) 79 | -------------------------------------------------------------------------------- /tests/testthat/test-no-list-decorators.r: -------------------------------------------------------------------------------- 1 | context("Not list decorators") 2 | 3 | expect_error(listdown(load_cc_expr = list(x = 1), 4 | setup_expr = knitr::opts_chunk$set(echo = FALSE), 5 | decorator = list(list = print))) 6 | 7 | -------------------------------------------------------------------------------- /tests/testthat/test-no-package.r: -------------------------------------------------------------------------------- 1 | context("No packages need to be specified.") 2 | 3 | source("reference.r") 4 | 5 | ld <- listdown(load_cc_expr = list(x = 1)) 6 | 7 | if (make_reference) { 8 | saveRDS(paste(ld_make_chunks(ld), collapse = "\n"), 9 | file.path("reference-data", "test-no-package.rds")) 10 | } 11 | 12 | write_if_make_reference(paste(ld_make_chunks(ld), collapse = "\n"), 13 | "test-no-package.rds") 14 | 15 | test_that("No packages need to be specified.", { 16 | expect_equal(paste(ld_make_chunks(ld), collapse = "\n"), 17 | read_reference("test-no-package.rds")) 18 | }) 19 | 20 | -------------------------------------------------------------------------------- /tests/testthat/test-setup-expr.r: -------------------------------------------------------------------------------- 1 | context("Setup expression.") 2 | 3 | source("reference.r") 4 | 5 | ld <- listdown(load_cc_expr = list(x = 1), 6 | setup_expr = knitr::opts_chunk$set(echo = FALSE)) 7 | 8 | write_if_make_reference(paste(ld_make_chunks(ld), collapse = "\n"), 9 | "test-setup-expr.rds") 10 | write_if_make_reference(capture.output(print(ld)), 11 | "test-print-ld.rds") 12 | 13 | expect_equal(paste(ld_make_chunks(ld), collapse = "\n"), 14 | read_reference("test-setup-expr.rds")) 15 | 16 | expect_equal(capture.output(print(ld)), 17 | read_reference("test-print-ld.rds")) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-site-yaml.r: -------------------------------------------------------------------------------- 1 | test_that("Basic site yaml list works.", { 2 | 3 | source("reference.r") 4 | 5 | site_name <- "A Test Site" 6 | tab_name <- c("Tab 1", "Tab 2") 7 | rmd_name <- c("file1.rmd", "file2.rmd") 8 | output_dir <- "../html" 9 | navbar_title <- "Study 1234" 10 | expect_error( 11 | ld_site_yaml(site_name, tab_name[-1], rmd_name, navbar_title)) 12 | 13 | site_yaml <- 14 | ld_site_yaml(site_name, tab_name, rmd_name, navbar_title) 15 | 16 | write_if_make_reference(site_yaml, "site_yaml.rds") 17 | 18 | expect_equal(site_yaml, read_reference("site_yaml.rds")) 19 | }) 20 | -------------------------------------------------------------------------------- /tests/testthat/test-write-file.r: -------------------------------------------------------------------------------- 1 | context("Write file") 2 | 3 | library(ggplot2) 4 | 5 | source("reference.r") 6 | 7 | test_that("Basic R Markdown file creation.", { 8 | cc_list <- list( 9 | Linear = ggplot(anscombe, aes(x = x1, y = y1)) + geom_point(), 10 | `Non Linear` = ggplot(anscombe, aes(x = x2, y = y2)) + geom_point(), 11 | `Outlier Vertical` = ggplot(anscombe, aes(x = x3, y = y3)) + geom_point(), 12 | `Outlier Horizontal` = ggplot(anscombe, aes(x = x4, y = y4)) + geom_point(), 13 | a = list(b = 3, 4)) 14 | 15 | rds_file <- "cc-list.rds" 16 | saveRDS(cc_list, file = rds_file) 17 | 18 | ld <- listdown(load_cc_expr = readRDS("cc-list.rds"), package = "ggplot2") 19 | 20 | ld_write_file( 21 | ld_rmarkdown_header(title = "The Anscombe Quartet", 22 | author = "Francis Anscombe", 23 | date = "1973"), 24 | ld, 25 | "anscombe-quartet.rmd") 26 | 27 | if (make_reference) { 28 | ld_write_file( 29 | ld_rmarkdown_header(title = "The Anscombe Quartet", 30 | author = "Francis Anscombe", 31 | date = "1973"), 32 | ld, 33 | file.path("reference-data", "anscombe-quartet.rmd")) 34 | } 35 | 36 | expect_equal(readLines("anscombe-quartet.rmd"), 37 | readLines(file.path("reference-data", "anscombe-quartet.rmd"))) 38 | 39 | unlink("anscombe-quartet.rmd") 40 | unlink("cc-list.rds") 41 | }) 42 | 43 | test_that("Basic R Markdown file errors.", { 44 | expect_error( 45 | ld_write_file(1:3, ld, file.path("reference-data", "anscombe-quartet.rmd"))) 46 | 47 | expect_error( 48 | ld_write_file(ld_rmarkdown_header(title = "test"), 1:3, "bunk")) 49 | }) 50 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/comp-comp.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaneplusplus/listdown/3de15bda61a032b0aaa004f9754850ecb66664ff/vignettes/comp-comp.rds --------------------------------------------------------------------------------