├── .Rbuildignore ├── .covrignore ├── .github ├── .gitignore └── workflows │ ├── auto-pkg-maintenance.yaml │ ├── check-standard.yaml │ └── pkgdown.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── addin.R ├── ipsum.R ├── lorem-package.R ├── render.R ├── sysdata.rda ├── utils.R └── zzz.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── data-raw └── words.R ├── inst └── rstudio │ └── addins.dcf ├── lorem.Rproj ├── man ├── as.tags.lorem.Rd ├── ipsum.Rd └── lorem-package.Rd └── tests ├── testthat.R └── testthat ├── _snaps ├── ipsum.md └── render.md ├── helpers.R ├── test-ipsum.R └── test-render.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^lorem\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^data-raw$ 4 | ^LICENSE\.md$ 5 | ^README\.Rmd$ 6 | ^_pkgdown\.yml$ 7 | ^docs$ 8 | ^pkgdown$ 9 | ^\.github$ 10 | ^\.covrignore$ 11 | ^cran-comments\.md$ 12 | ^CRAN-SUBMISSION$ 13 | -------------------------------------------------------------------------------- /.covrignore: -------------------------------------------------------------------------------- 1 | R/zzz.R 2 | R/addin.R 3 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/auto-pkg-maintenance.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | # pull_request_target: 3 | # types: [opened, synchronize, labeled] 4 | pull_request: 5 | push: 6 | branches: main 7 | 8 | name: Package Maintenance 9 | 10 | jobs: 11 | auto-pkg-maintenance: 12 | uses: rstudio/education-workflows/.github/workflows/auto-pkg-maintenance.yaml@v1 13 | with: 14 | extra-packages: deps::. 15 | install-local-package: true 16 | source-repository-owner: gadenbuie 17 | pandoc-version: 3.1.1 18 | -------------------------------------------------------------------------------- /.github/workflows/check-standard.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macOS-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v2 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: rcmdcheck 45 | 46 | - uses: r-lib/actions/check-r-package@v2 47 | 48 | - name: Update gadenbuie/status dashboard 49 | uses: gadenbuie/status/actions/status-update-rcmdcheck@main 50 | with: 51 | github-token-repo-scope: ${{ secrets.GADENBUIE_STATUS_TOKEN }} 52 | status-repo: gadenbuie/status 53 | 54 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Deploys pkgdown for Pull Requests, tags, and pushes to main branch 2 | # PRs are deployed to /preview/pr/ 3 | # Tags are deployed to // 4 | on: 5 | pull_request: 6 | branches: 7 | - main 8 | types: 9 | - opened 10 | - reopened 11 | - synchronize 12 | - closed 13 | paths: 14 | - 'man/**' 15 | - 'pkgdown/**' 16 | - 'vignettes/**' 17 | push: 18 | tags: 19 | - 'v[0-9]+.[0-9]+.[0-9]+' # build on version tags 20 | - '!v[0-9]+.[0-9]+.[0-9]+.[0-9]+' # but not if version involves a dev component 21 | branches: 22 | - main 23 | workflow_dispatch: 24 | inputs: 25 | tag: 26 | description: Tag to deploy 27 | required: true 28 | default: '' 29 | 30 | name: pkgdown 31 | 32 | jobs: 33 | pkgdown-build: 34 | runs-on: ubuntu-latest 35 | if: ${{ !(github.event_name == 'pull_request' && github.event.action == 'closed') }} 36 | env: 37 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 38 | steps: 39 | - uses: actions/checkout@v2 40 | 41 | - name: Configure git 42 | run: | 43 | git config --local user.name "$GITHUB_ACTOR" 44 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 45 | 46 | - uses: r-lib/actions/pr-fetch@v2 47 | if: ${{ github.event_name == 'pull_request' }} 48 | with: 49 | repo-token: ${{ github.token }} 50 | 51 | - uses: r-lib/actions/setup-pandoc@v2 52 | 53 | - uses: r-lib/actions/setup-r@v2 54 | with: 55 | use-public-rspm: true 56 | 57 | - uses: r-lib/actions/setup-r-dependencies@v2 58 | with: 59 | needs: | 60 | connect 61 | website 62 | extra-packages: | 63 | local::. 64 | any::pkgdown 65 | 66 | # If events is a PR, set subdir to 'preview/pr' 67 | - name: "[PR] Set documentation subdirectory" 68 | if: github.event_name == 'pull_request' 69 | run: | 70 | echo "subdir=preview/pr${{ github.event.number }}" >> $GITHUB_ENV 71 | 72 | # If event is a tag, set subdir to '' 73 | - name: "[tag] Set documentation subdirectory" 74 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') 75 | run: | 76 | echo "subdir=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV 77 | 78 | # If event is workflow_dispatch, set subdir to 'inputs.tag' 79 | - name: '[dispatch] Set documentation subdirectory' 80 | if: github.event_name == 'workflow_dispatch' 81 | run: | 82 | echo "subdir=${{ github.event.inputs.tag }}" >> $GITHUB_ENV 83 | 84 | - name: Deploy pkgdown site 85 | id: deploy 86 | shell: Rscript {0} 87 | run: | 88 | subdir <- "${{ env.subdir }}" 89 | pkg <- pkgdown::as_pkgdown(".") 90 | 91 | # Deploy pkgdown site to branch 92 | pkgdown::deploy_to_branch(subdir = if (nzchar(subdir)) subdir, clean = nzchar(subdir)) 93 | 94 | # Report deployed site URL 95 | deployed_url <- file.path(pkg$meta$url, subdir) 96 | cat(sprintf('url=%s', deployed_url), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) 97 | 98 | - name: Notify pkgdown deployment 99 | if: github.event_name == 'pull_request' 100 | uses: hasura/comment-progress@v2.2.0 101 | with: 102 | github-token: ${{ secrets.GITHUB_TOKEN }} 103 | repository: ${{ github.repository }} 104 | number: ${{ github.event.number }} 105 | id: pkgdown-deploy 106 | append: false 107 | message: > 108 | :book: ${{ steps.deploy.outputs.url }} 109 | 110 | Preview documentation for this PR (at commit ${{ github.event.pull_request.head.sha }}) 111 | 112 | pkgdown-clean: 113 | if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }} 114 | runs-on: ubuntu-latest 115 | env: 116 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 117 | steps: 118 | - uses: actions/checkout@v2 119 | with: 120 | ref: "gh-pages" 121 | 122 | - name: Clean up PR Preview 123 | run: | 124 | git config --local user.name "$GITHUB_ACTOR" 125 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 126 | 127 | preview_dir="preview/pr${{ github.event.pull_request.number }}" 128 | if [ -d "$preview_dir" ]; then 129 | git rm -r $preview_dir 130 | git commit -m "Remove $preview_dir (GitHub Actions)" || echo 'No preview to remove' 131 | git push origin || echo 'No preview to remove' 132 | else 133 | echo 'No preview to remove' 134 | fi 135 | 136 | - name: Notify pkgdown cleanup 137 | uses: hasura/comment-progress@v2.2.0 138 | with: 139 | github-token: ${{ secrets.GITHUB_TOKEN }} 140 | repository: ${{ github.repository }} 141 | number: ${{ github.event.number }} 142 | id: pkgdown-deploy 143 | message: | 144 | :closed_book: _Preview documentation for this PR has been cleaned up._ 145 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | docs 5 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: lorem 2 | Title: Generate Lorem Ipsum Text 3 | Version: 1.0.0.9000 4 | Authors@R: 5 | person("Garrick", "Aden-Buie", , "garrick@adenbuie.com", role = c("aut", "cre"), 6 | comment = c(ORCID = "0000-0002-7111-0077")) 7 | Description: Quickly generate lorem ipsum placeholder text. Easy to 8 | integrate in 'R Markdown' documents and 'Shiny' apps. Includes an 9 | 'RStudio' addin to insert lorem ipsum into the current document. 10 | License: MIT + file LICENSE 11 | URL: https://github.com/gadenbuie/lorem, 12 | http://pkg.garrickadenbuie.com/lorem/ 13 | BugReports: https://github.com/gadenbuie/lorem/issues 14 | Depends: 15 | R (>= 2.10) 16 | Imports: 17 | htmltools, 18 | knitr, 19 | stats 20 | Suggests: 21 | rstudioapi, 22 | testthat (>= 3.0.0), 23 | withr 24 | Config/Needs/website: gadenbuie/grkgdown 25 | Config/testthat/edition: 3 26 | Encoding: UTF-8 27 | Roxygen: list(markdown = TRUE) 28 | RoxygenNote: 7.2.3 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2023 2 | COPYRIGHT HOLDER: lorem authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2023 lorem authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.tags,lorem) 4 | S3method(format,lorem) 5 | S3method(knit_print,lorem) 6 | S3method(print,lorem) 7 | export(ipsum) 8 | export(ipsum_starts) 9 | export(ipsum_words) 10 | importFrom(htmltools,as.tags) 11 | importFrom(knitr,knit_print) 12 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # lorem (development version) 4 | 5 | 6 | # lorem 1.0.0 7 | 8 | The first official release of **lorem** on CRAN! A few small changes have happened in the package since it was first released on GitHub: 9 | 10 | - `lorem::ipsum()` now returns a `lorem` classed object that works in both knitr R chunks and htmltools tags. In htmltools, each paragraph is automatically wrapped in a `

` tag, or you can call `as.tags()` directly to provide your own `wrapper`. This change required `ipsum()` to return a list-like `lorem` class rather than a character vector; use `format()` or `as.character()` to retrieve standard character vectors. Thanks to @cpsievert for the suggestion (#7, #8). 11 | 12 | - `lorem::ipsum()` now includes punctuation like commas, colons, semi-colons and em dashes in the generated text (#4). 13 | -------------------------------------------------------------------------------- /R/addin.R: -------------------------------------------------------------------------------- 1 | ipsum_addin <- function() { 2 | if (!requireNamespace("rstudioapi", quietly = TRUE)) { 3 | stop("{rstudioapi} is required for ipsum_addin()") 4 | } else if (!rstudioapi::hasFun("showPrompt")) { 5 | stop("Did you call ipsum_addin() in RStudio?") 6 | } 7 | 8 | ctx <- rstudioapi::getSourceEditorContext() 9 | 10 | paras <- rstudioapi::showPrompt("lorem::ipsum", "Number of Paragraphs", 1) 11 | paras <- as.integer(paras) 12 | 13 | sents <- rstudioapi::showPrompt( 14 | title = "lorem::ipsum", 15 | message = paste( 16 | "Number of Sentences", 17 | if (paras > 1) paste( 18 | "Each\nMultiple values can be separated by commas:", 19 | paste(seq_len(min(c(6, paras))), collapse = ","), 20 | if (paras > 6) "..." 21 | ) 22 | ), 23 | default = 4) 24 | sents <- strsplit(sents, "\\s*,\\s*")[[1]] 25 | 26 | ipsum_text <- ipsum(paras, as.integer(sents)) 27 | 28 | ipsum_text <- paste(ipsum_text, collapse = "\n\n") 29 | 30 | rstudioapi::insertText(ctx$selection[[1]]$range, ipsum_text, id = ctx$id) 31 | 32 | invisible(ipsum_text) 33 | } 34 | -------------------------------------------------------------------------------- /R/ipsum.R: -------------------------------------------------------------------------------- 1 | #' Generate Lorem Ipsum Text 2 | #' 3 | #' @description 4 | #' Generates _lorem ipsum_ placeholder text for the requested number of 5 | #' sentences or paragraphs. You can control the number of sentences per 6 | #' paragraph and the average number of words per sentence, or simply enter the 7 | #' number of desired paragraphs for a completely random experience. 8 | #' 9 | #' `lorem::ipsum()` uses sampling and the random number generator and makes no 10 | #' effort to shield the placeholder text generation from the main script, so 11 | #' please only use this package for temporary placeholder text. 12 | #' 13 | #' @section Options: 14 | #' 15 | #' You can influence, to a degree, the amount of punctuation that is included 16 | #' in the output using the `lorem.punctuation_valence` option. This global 17 | #' option should be a number between 0 and 1, or `FALSE` to disable 18 | #' punctuation altogether. When the value is closer to 1, more punctuation is 19 | #' included in the sentences. When the value is closer to 0, less punctuation 20 | #' will be inserted. The default value is 0.4. 21 | #' 22 | #' @examples 23 | #' # 1 paragraph of text 24 | #' lorem::ipsum(1) 25 | #' 26 | #' # 2 paragraphs with 2 and 3 sentences each 27 | #' lorem::ipsum(2, sentences = c(2, 3)) 28 | #' 29 | #' # 2 paragraphs with short sentences 30 | #' lorem::ipsum(2, avg_words_per_sentence = 4) 31 | #' 32 | #' # 2 paragraphs with long sentences 33 | #' lorem::ipsum(2, avg_words_per_sentence = 20) 34 | #' 35 | #' @return A character vector of _lorem ispum_ placeholder text, where each 36 | #' element in the vector is a paragraph of text. 37 | #' 38 | #' @param paragraphs Number of paragraphs of text to generate. 39 | #' @param sentences Number of sentences per paragraph. If `NULL`, then a random 40 | #' number of sentences per paragraph (approximately 3-8) will be chosen. 41 | #' Alternatively, `sentences` can be a vector of integers representing the 42 | #' number of sentences per paragraph. 43 | #' @param avg_words_per_sentence Number of expected words per sentence. 44 | #' @name ipsum 45 | NULL 46 | 47 | #' @describeIn ipsum Generate paragraphs and sentences of _lorem ipsum_ text. 48 | #' @export 49 | ipsum <- function(paragraphs = 1, sentences = NULL, avg_words_per_sentence = 10) { 50 | # default to single paragraph 51 | paragraphs <- paragraphs %||% 1L 52 | stopifnot( 53 | "`paragraphs` must be a single integer" = length(paragraphs) == 1, 54 | "`paragraphs` must be an integer" = paragraphs %% 1 == 0, 55 | "`paragraphs` must be greater than 0" = paragraphs > 0, 56 | "`paragraphs` must be finite" = is.finite(paragraphs) 57 | ) 58 | 59 | # Pick number of sentences to be about 3-8 60 | if (!is.null(sentences)) { 61 | stopifnot( 62 | "`sentences` must be a vector of finite values" = all(is.finite(sentences)), 63 | "`sentences` must be a vector of integer values" = all(sentences %% 1 == 0), 64 | "`sentences` must be a vector of 1 or more integers greater than zero" = all(sentences > 0) 65 | ) 66 | } else { 67 | sentences <- stats::rbinom(paragraphs, 10, 0.45) 68 | sentences[sentences < 1] <- 1L 69 | } 70 | 71 | if (length(sentences) == 1 && paragraphs > 1) { 72 | sentences <- rep(sentences, paragraphs) 73 | } 74 | 75 | if (paragraphs != length(sentences)) { 76 | stop( 77 | "`sentences` must be a single integer ", 78 | "or have the same length as the number of `paragraphs`." 79 | ) 80 | } 81 | 82 | # check punctuation valence so we can warn about bad values 83 | get_punctuation_valence(warn = TRUE) 84 | 85 | # roughly 10 words per sentence per paragraph 86 | words <- stats::rbinom(paragraphs, avg_words_per_sentence * sentences * 2, 0.5) 87 | 88 | # generate words 89 | text <- v_char(1:paragraphs, function(i) ipsum_words(words[i])) 90 | text <- paste(ipsum_starts(paragraphs), text) 91 | 92 | # break into sentences 93 | ret <- pv_char(break_sentences, text = text, n = sentences) 94 | structure(as.list(ret), class = "lorem") 95 | } 96 | 97 | #' @describeIn ipsum Generate _lorem ipsum_ words, without punctuation. 98 | #' @param n Number of words to generate 99 | #' @param collapse Should the words be collapsed into a single string, separated 100 | #' by spaces (default)? If `FALSE`, the chosen words are returned as a 101 | #' character vector. 102 | #' @export 103 | ipsum_words <- function(n, collapse = TRUE) { 104 | words <- sample(words$word, n, replace = TRUE) 105 | if (collapse) paste(words, collapse = " ") else words 106 | } 107 | 108 | #' @describeIn ipsum Generate _lorem ipsum_ starting words. 109 | #' @export 110 | ipsum_starts <- function(n) { 111 | sample(words$start, n, replace = TRUE) 112 | } 113 | 114 | break_sentences <- function(text, n = NULL) { 115 | n <- n %||% default_n_sentences(text) 116 | 117 | v_char(text, break_sentence, n = n) 118 | } 119 | 120 | break_sentence <- function(text, n) { 121 | if (n == 1) { 122 | return(as_sentence(text)) 123 | } 124 | 125 | # sentences of approx 10 words each 126 | words <- stats::rbinom(n = n - 1, 20, 0.5) 127 | text <- strsplit(text, " ", fixed = TRUE)[[1]] 128 | if (words[1] >= length(text)) { 129 | return(as_sentence(text)) 130 | } 131 | while (sum(words) > length(text)) { 132 | longest <- which(words == max(words))[1] 133 | words[longest] <- words[longest] - 1L 134 | } 135 | words <- c(cumsum(words), length(text)) 136 | 137 | sentences <- list() 138 | for (i in seq_along(words)) { 139 | from <- if (i == 1) 1L else words[i-1] + 1 140 | to <- words[i] 141 | subtext <- text[from:to] 142 | sentences <- c(sentences, list(subtext)) 143 | } 144 | sentences <- v_char(sentences, as_sentence) 145 | paste0(sentences, collapse = " ") 146 | } 147 | 148 | as_sentence <- function(x) { 149 | x <- insert_punctuation(x) 150 | x <- paste(x, collapse = " ") 151 | x <- to_sentence_case(x) 152 | ending <- sample(c(".", "!", "?"), 1, prob = c(0.7, 0.15, 0.15)) 153 | paste0(x, ending) 154 | } 155 | 156 | insert_punctuation <- function(x) { 157 | valence <- get_punctuation_valence() 158 | if (identical(valence, FALSE)) return(x) 159 | 160 | idxs <- seq_along(x) 161 | 162 | # draw at most n_words/3 samples from normal distribution 163 | r_normal <- stats::rnorm(ceiling(length(x) / 3), mean(idxs), sd = sqrt(length(x))) 164 | 165 | # discard first and last word 166 | r_normal <- r_normal[r_normal > 2 & r_normal < (length(x) - 2)] 167 | 168 | # keep only the indexes that are within 0.2 of a sample 169 | within_thresh <- vapply(r_normal, FUN.VALUE = logical(1), function(r) { 170 | any(abs(r - idxs) < valence / 2) 171 | }) 172 | idxs <- as.integer(round(r_normal[within_thresh], 0)) 173 | 174 | if (!length(idxs)) return(x) 175 | 176 | r_punct <- random_punctuation(length(idxs)) 177 | 178 | if (all(c(":", ";") %in% r_punct)) { 179 | # don't allow both : and ; in the same sentence 180 | discard <- sample(c(":", ";"), 1) 181 | r_punct[r_punct == discard] <- "" 182 | } 183 | 184 | # at most one colon per sentence 185 | for (colon in c(":", ";")) { 186 | if (length(r_punct[r_punct == colon]) > 2) { 187 | idx_colon <- which(r_punct == colon) 188 | discard_colon <- sample(idx_colon, size = length(idx_colon) - 1) 189 | r_punct[discard_colon] <- "" 190 | } 191 | } 192 | 193 | x[idxs] <- paste0(x[idxs], r_punct) 194 | x 195 | } 196 | 197 | random_punctuation <- function(n) { 198 | sample( 199 | x = c(",", ":", ";", " \u2013"), 200 | prob = c(0.7, 0.1, 0.1, 0.1), 201 | size = n, 202 | replace = TRUE 203 | ) 204 | } 205 | 206 | get_punctuation_valence <- function(warn = FALSE) { 207 | valence <- getOption("lorem.punctuation_valence", 0.4) 208 | if (identical(valence, FALSE)) return(FALSE) 209 | if (identical(valence, TRUE)) return(0.4) 210 | 211 | if (!is.numeric(valence) || valence > 1 || valence < 0) { 212 | if (isTRUE(warn)) { 213 | warning( 214 | "The `lorem.punctuation_valence` option should be a numeric value ", 215 | "between 0 and 1, not ", 216 | valence, 217 | ". Using the default value of 0.2.", 218 | call. = FALSE, 219 | immediate. = TRUE 220 | ) 221 | } 222 | valence <- 0.4 223 | } 224 | valence 225 | } 226 | 227 | default_n_sentences <- function(text) { 228 | n_words <- count_words(text) 229 | 230 | x <- round(n_words / 10, 0) 231 | x[x < 1] <- 1L 232 | x 233 | } 234 | 235 | count_words <- function(x) { 236 | x <- strsplit(x, " ", fixed = TRUE) 237 | vapply(x, function(y) length(y), integer(1)) 238 | } 239 | 240 | to_sentence_case <- function(x) { 241 | x <- tolower(x) 242 | first <- v_char(x, function(y) substr(y, 1, 1)) 243 | rest <- v_char(x, function(y) substr(y, 2, nchar(y))) 244 | first <- toupper(first) 245 | paste0(first, rest) 246 | } 247 | -------------------------------------------------------------------------------- /R/lorem-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | ## usethis namespace: start 5 | ## usethis namespace: end 6 | NULL 7 | -------------------------------------------------------------------------------- /R/render.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | format.lorem <- function(x, ...) { 3 | paste(unlist(x), collapse = "\n\n") 4 | } 5 | 6 | #' @export 7 | print.lorem <- function(x, ...) { 8 | text <- strwrap(format(x)) 9 | cat("\n", paste(text, collapse = "\n"), sep = "") 10 | invisible(x) 11 | } 12 | 13 | #' @importFrom knitr knit_print 14 | #' @export 15 | knit_print.lorem <- function(x, ...) { 16 | knitr::asis_output(format(x)) 17 | } 18 | 19 | #' Render placeholder text as HTML tags 20 | #' 21 | #' Renders [lorem::ipsum()] placeholder text as HTML tags using 22 | #' [htmltools::as.tags()]. By default, paragraphs are rendering `

` tags with 23 | #' [htmltools::p()], but you may provide your own paragraph `wrapper` function. 24 | #' In general, you won't need to manually call this function, instead you can 25 | #' just drop [lorem::ipsum()] text into another [htmltools::tag()]. 26 | #' 27 | #' @name as.tags.lorem 28 | #' @rdname as.tags.lorem 29 | #' 30 | #' @examples 31 | #' htmltools::div( 32 | #' lorem::ipsum(paragraphs = 3) 33 | #' ) 34 | #' 35 | #' htmltools::tags$ul( 36 | #' htmltools::as.tags( 37 | #' lorem::ipsum(paragraphs = 3, sentences = 1), 38 | #' wrapper = htmltools::tags$li 39 | #' ) 40 | #' ) 41 | #' 42 | #' @inheritParams htmltools::as.tags 43 | #' @param wrapper A function that takes a character string of a paragraph or 44 | #' chunk of placeholder text and returns an [htmltools::tag()]. By default, 45 | #' lorem ipsum text is wrapped in [htmltools::p()]. 46 | #' 47 | #' @return Returns an [htmltools::tagList()]. 48 | #' 49 | #' @importFrom htmltools as.tags 50 | #' @export 51 | as.tags.lorem <- function(x, wrapper = NULL, ...) { 52 | if (is.null(wrapper)) { 53 | wrapper <- function(x, ...) htmltools::p(x, .noWS = "inside") 54 | } 55 | htmltools::tagList(lapply(x, wrapper, ...)) 56 | } 57 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gadenbuie/lorem/79113db73d002a0f486f3670881fe5e03a7e88da/R/sysdata.rda -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | `%||%` <- function(x, y) if (is.null(x)) y else x 2 | 3 | v_char <- function(x, .f, ...) { 4 | vapply(x, .f, ..., FUN.VALUE = character(1), USE.NAMES = FALSE) 5 | } 6 | 7 | pv_char <- function(.f, ...) { 8 | z <- mapply(.f, ..., SIMPLIFY = FALSE, USE.NAMES = FALSE) 9 | v_char(z, paste) 10 | } 11 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | register_s3_method <- function(pkg, generic, class, fun = NULL) { 2 | stopifnot(is.character(pkg), length(pkg) == 1) 3 | stopifnot(is.character(generic), length(generic) == 1) 4 | stopifnot(is.character(class), length(class) == 1) 5 | 6 | if (is.null(fun)) { 7 | fun <- get(paste0(generic, ".", class), envir = parent.frame()) 8 | } else { 9 | stopifnot(is.function(fun)) 10 | } 11 | 12 | if (pkg %in% loadedNamespaces()) { 13 | registerS3method(generic, class, fun, envir = asNamespace(pkg)) 14 | } 15 | 16 | # Always register hook in case package is later unloaded & reloaded 17 | setHook( 18 | packageEvent(pkg, "onLoad"), 19 | function(...) { 20 | registerS3method(generic, class, fun, envir = asNamespace(pkg)) 21 | } 22 | ) 23 | } 24 | 25 | .onLoad <- function(libname, pkgname, ...) { 26 | register_s3_method("knitr", "knit_print", "lorem") 27 | register_s3_method("htmltools", "as.tags", "lorem") 28 | 29 | invisible() 30 | } 31 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | set.seed(424342) 15 | ``` 16 | 17 | # lorem::ipsum() 18 | 19 | 20 | [![CRAN status](https://www.r-pkg.org/badges/version/lorem)](https://CRAN.R-project.org/package=lorem) 21 | [![lorem r-universe badge](https://gadenbuie.r-universe.dev/badges/lorem)](https://gadenbuie.r-universe.dev/lorem) 22 | [![R-CMD-check](https://github.com/gadenbuie/lorem/actions/workflows/check-standard.yaml/badge.svg)](https://github.com/gadenbuie/lorem/actions/workflows/check-standard.yaml) 23 | 24 | 25 | * Quickly generate lorem ipsum placeholder text with `lorem::ipsum()`. 26 | 27 | * Easy to integrate in RMarkdown documents. 28 | 29 | * Includes an RStudio addin to insert *lorem ipsum* into the current document. 30 | 31 | ## Installation 32 | 33 | You can install the latest released version of lorem from CRAN 34 | 35 | ``` r 36 | install.packages("lorem") 37 | ``` 38 | 39 | or the current development version of lorem from GitHub or r-universe 40 | 41 | ``` r 42 | # GitHub 43 | # install.packages("remotes") 44 | rmeotes::install_github("gadenbuie/lorem") 45 | 46 | # R Universe 47 | install.packages('lorem', repos = c('https://gadenbuie.r-universe.dev', 'https://cloud.r-project.org')) 48 | ``` 49 | 50 | ## Usage 51 | 52 | ### RStudio Addin 53 | 54 | **lorem** includes a simple addin for RStudio that 55 | adds placeholder _lorem ipsum_ text to the current source document. 56 | The addin allows you to specify the number of desired paragraphs and sentences. 57 | 58 | ### R Markdown 59 | 60 | Another way to generate _lorem ipsum_ placeholder text is to call 61 | `lorem::ipsum()` in an inline R chunk in R Markdown. 62 | 63 | ```markdown 64 | `r knitr::inline_expr("lorem::ipsum(paragraphs = 2)")` 65 | ``` 66 | 67 | `r paste(">", lorem::ipsum(2), collapse = "\n>\n")` 68 | 69 | You can control the number of `paragraphs` and `sentences` per paragraph. 70 | 71 | ```markdown 72 | `r knitr::inline_expr("lorem::ipsum(paragraphs = 3, sentences = c(1, 2, 3))")` 73 | ``` 74 | 75 | `r paste(">", lorem::ipsum(3, 1:3), collapse = "\n>\n")` 76 | 77 | You can also adjust the `avg_words_per_sentence` to create long or short paragraphs. 78 | 79 | ```markdown 80 | `r knitr::inline_expr("lorem::ipsum(2, avg_words_per_sentence = 3)")` 81 | ``` 82 | 83 | `r paste(">", lorem::ipsum(paragraphs = 2, avg_words_per_sentence = 3), collapse = "\n>\n")` 84 | 85 | 86 | ```markdown 87 | `r knitr::inline_expr("lorem::ipsum(1, avg_words_per_sentence = 20)")` 88 | ``` 89 | 90 | `r paste(">", lorem::ipsum(1, 2, avg_words_per_sentence = 20), collapse = "\n>\n")` 91 | 92 | ### Everywhere Else 93 | 94 | Generate _lorem ipsum_ anywhere else using `lorem::ipsum()` or `lorem::ipsum_words()`. 95 | 96 | ```{r results='asis'} 97 | ipsum_items <- replicate(5, lorem::ipsum_words(5)) 98 | cat(paste("-", ipsum_items), sep = "\n") 99 | ``` 100 | 101 | ## Ipsum gratiam 102 | 103 | Thank you to 104 | [Luke Haas](https://getlorem.com) 105 | for the node module 106 | [getlorem](https://github.com/lukehaas/getlorem) 107 | and for providing the lorem ipsum word list used in this package. 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # lorem::ipsum() 5 | 6 | 7 | 8 | [![CRAN 9 | status](https://www.r-pkg.org/badges/version/lorem)](https://CRAN.R-project.org/package=lorem) 10 | [![lorem r-universe 11 | badge](https://gadenbuie.r-universe.dev/badges/lorem)](https://gadenbuie.r-universe.dev/lorem) 12 | [![R-CMD-check](https://github.com/gadenbuie/lorem/actions/workflows/check-standard.yaml/badge.svg)](https://github.com/gadenbuie/lorem/actions/workflows/check-standard.yaml) 13 | 14 | 15 | - Quickly generate lorem ipsum placeholder text with `lorem::ipsum()`. 16 | 17 | - Easy to integrate in RMarkdown documents. 18 | 19 | - Includes an RStudio addin to insert *lorem ipsum* into the current 20 | document. 21 | 22 | ## Installation 23 | 24 | You can install the latest released version of lorem from CRAN 25 | 26 | ``` r 27 | install.packages("lorem") 28 | ``` 29 | 30 | or the current development version of lorem from GitHub or r-universe 31 | 32 | ``` r 33 | # GitHub 34 | # install.packages("remotes") 35 | rmeotes::install_github("gadenbuie/lorem") 36 | 37 | # R Universe 38 | install.packages('lorem', repos = c('https://gadenbuie.r-universe.dev', 'https://cloud.r-project.org')) 39 | ``` 40 | 41 | ## Usage 42 | 43 | ### RStudio Addin 44 | 45 | **lorem** includes a simple addin for RStudio that adds placeholder 46 | *lorem ipsum* text to the current source document. The addin allows you 47 | to specify the number of desired paragraphs and sentences. 48 | 49 | ### R Markdown 50 | 51 | Another way to generate *lorem ipsum* placeholder text is to call 52 | `lorem::ipsum()` in an inline R chunk in R Markdown. 53 | 54 | ``` markdown 55 | `r lorem::ipsum(paragraphs = 2)` 56 | ``` 57 | 58 | > Sit nunc at convallis fringilla semper. Penatibus vivamus eget 59 | > malesuada cursus fames magnis potenti. Venenatis ligula enim conubia 60 | > laoreet orci, class ligula. Massa sem sed enim risus ut mattis 61 | > inceptos nisl elementum mattis. Nostra ultricies habitant donec vitae 62 | > luctus proin gravida placerat ac libero imperdiet! Auctor habitasse 63 | > faucibus ultricies purus eget sociis ultrices habitasse: nec ad aptent 64 | > lectus rutrum proin potenti, montes, sodales, posuere convallis tempor 65 | > erat, egestas magna lectus sociis mollis purus. 66 | > 67 | > Dolor turpis euismod himenaeos interdum felis dictum tempus euismod 68 | > tortor aliquam! Eget interdum vehicula laoreet quam mollis, justo 69 | > cursus ad blandit feugiat pulvinar? Sem sodales bibendum leo leo magna 70 | > pulvinar metus lacinia nam. Fringilla maecenas duis dis suscipit 71 | > aenean natoque sem metus, quam risus sagittis convallis primis sociis 72 | > id dictumst. 73 | 74 | You can control the number of `paragraphs` and `sentences` per 75 | paragraph. 76 | 77 | ``` markdown 78 | `r lorem::ipsum(paragraphs = 3, sentences = c(1, 2, 3))` 79 | ``` 80 | 81 | > Amet cras primis at ac neque primis dui scelerisque massa inceptos 82 | > massa. 83 | > 84 | > Adipiscing netus cursus – vivamus est aliquam mauris pharetra: nostra 85 | > ornare. Tristique ad consequat sagittis montes sociis, ut cursus 86 | > tincidunt vitae sagittis netus! 87 | > 88 | > Adipiscing aptent libero vitae etiam tristique commodo iaculis erat 89 | > mattis tempor convallis. Porta aenean natoque, feugiat himenaeos – ac 90 | > accumsan mollis torquent in ut maecenas congue vulputate nulla! 91 | > Interdum fames. 92 | 93 | You can also adjust the `avg_words_per_sentence` to create long or short 94 | paragraphs. 95 | 96 | ``` markdown 97 | `r lorem::ipsum(2, avg_words_per_sentence = 3)` 98 | ``` 99 | 100 | > Elit facilisis curae pharetra quisque per? Euismod risus phasellus 101 | > euismod velit, orci platea? Na platea. 102 | > 103 | > Amet posuere habitasse imperdiet. Porta tempor felis morbi. Est nam 104 | > nisl litora viverra? Accumsan feugiat volutpat cubilia purus. Na 105 | > purus. 106 | 107 | ``` markdown 108 | `r lorem::ipsum(1, avg_words_per_sentence = 20)` 109 | ``` 110 | 111 | > Elit venenatis tincidunt urna sagittis integer posuere dignissim. Dui 112 | > tellus massa nam suspendisse venenatis dui nec imperdiet donec magna 113 | > libero elementum euismod nibh ligula conubia vitae, ad egestas dis 114 | > himenaeos ligula urna, dui parturient lacus montes semper ultricies 115 | > euismod non condimentum porta sem luctus porttitor platea hac 116 | > sagittis! 117 | 118 | ### Everywhere Else 119 | 120 | Generate *lorem ipsum* anywhere else using `lorem::ipsum()` or 121 | `lorem::ipsum_words()`. 122 | 123 | ``` r 124 | ipsum_items <- replicate(5, lorem::ipsum_words(5)) 125 | cat(paste("-", ipsum_items), sep = "\n") 126 | ``` 127 | 128 | - purus enim pellentesque blandit facilisis 129 | - elementum interdum suscipit enim urna 130 | - urna elementum nec vitae scelerisque 131 | - scelerisque faucibus dignissim urna interdum 132 | - curabitur porttitor dui in euismod 133 | 134 | ## Ipsum gratiam 135 | 136 | Thank you to [Luke Haas](https://getlorem.com) for the node module 137 | [getlorem](https://github.com/lukehaas/getlorem) and for providing the 138 | lorem ipsum word list used in this package. 139 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: http://pkg.garrickadenbuie.com/lorem/ 2 | 3 | template: 4 | package: grkgdown 5 | 6 | reference: 7 | - title: Generate Placeholder Text 8 | contents: 9 | - ipsum 10 | - as.tags.lorem 11 | 12 | -------------------------------------------------------------------------------- /data-raw/words.R: -------------------------------------------------------------------------------- 1 | # https://github.com/lukehaas/getlorem/blob/e845157641ddb7e4696dd2666c92a8165e407f1b/lib/getlorem.js#L37-L81 2 | words <- list( 3 | start = c( 4 | 'lorem', 'ipsum', 'dolor', 'sit', 5 | 'amet', 'consectetur', 'adipiscing', 'elit' 6 | ), 7 | word = c( 8 | 'a', 'ac', 'accumsan', 'ad', 9 | 'aenean', 'aliquam', 'aliquet', 'ante', 10 | 'aptent', 'arcu', 'at', 'auctor', 11 | 'augue', 'bibendum', 'blandit', 'class', 12 | 'commodo', 'condimentum', 'congue', 'consequat', 13 | 'conubia', 'convallis', 'cras', 'cubilia', 14 | 'cum', 'curabitur', 'curae', 'cursus', 15 | 'dapibus', 'diam', 'dictum', 'dictumst', 16 | 'dignissim', 'dis', 'donec', 'dui', 17 | 'duis', 'egestas', 'eget', 'eleifend', 18 | 'elementum', 'enim', 'erat', 'eros', 19 | 'est', 'et', 'etiam', 'eu', 20 | 'euismod', 'facilisi', 'facilisis', 'fames', 21 | 'faucibus', 'felis', 'fermentum', 'feugiat', 22 | 'fringilla', 'fusce', 'gravida', 'habitant', 23 | 'habitasse', 'hac', 'hendrerit', 'himenaeos', 24 | 'iaculis', 'id', 'imperdiet', 'in', 25 | 'inceptos', 'integer', 'interdum', 'justo', 26 | 'lacinia', 'lacus', 'laoreet', 'lectus', 27 | 'leo', 'libero', 'ligula', 'litora', 28 | 'lobortis', 'luctus', 'maecenas', 'magna', 29 | 'magnis', 'malesuada', 'massa', 'mattis', 30 | 'mauris', 'metus', 'mi', 'molestie', 31 | 'mollis', 'montes', 'morbi', 'mus', 32 | 'nam', 'nascetur', 'natoque', 'nec', 33 | 'neque', 'netus', 'nibh', 'nisi', 34 | 'nisl', 'non', 'nostra', 'nulla', 35 | 'nullam', 'nunc', 'odio', 'orci', 36 | 'ornare', 'parturient', 'pellentesque', 'penatibus', 37 | 'per', 'pharetra', 'phasellus', 'placerat', 38 | 'platea', 'porta', 'porttitor', 'posuere', 39 | 'potenti', 'praesent', 'pretium', 'primis', 40 | 'proin', 'pulvinar', 'purus', 'quam', 41 | 'quis', 'quisque', 'rhoncus', 'ridiculus', 42 | 'risus', 'rutrum', 'sagittis', 'sapien', 43 | 'scelerisque', 'sed', 'sem', 'semper', 44 | 'senectus', 'sociis', 'sociosqu', 'sodales', 45 | 'sollicitudin', 'suscipit', 'suspendisse', 'taciti', 46 | 'tellus', 'tempor', 'tempus', 'tincidunt', 47 | 'torquent', 'tortor', 'tristique', 'turpis', 48 | 'ullamcorper', 'ultrices', 'ultricies', 'urna', 49 | 'ut', 'varius', 'vehicula', 'vel', 50 | 'velit', 'venenatis', 'vestibulum', 'vitae', 51 | 'vivamus', 'viverra', 'volutpat', 'vulputate' 52 | ) 53 | ) 54 | 55 | usethis::use_data(words, internal = TRUE) 56 | -------------------------------------------------------------------------------- /inst/rstudio/addins.dcf: -------------------------------------------------------------------------------- 1 | Name: Insert Lorem Ipsum... 2 | Description: Insert Placeholder Lorem Ipsum Text 3 | Binding: ipsum_addin 4 | Interactive: false 5 | -------------------------------------------------------------------------------- /lorem.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/as.tags.lorem.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/render.R 3 | \name{as.tags.lorem} 4 | \alias{as.tags.lorem} 5 | \title{Render placeholder text as HTML tags} 6 | \usage{ 7 | \method{as.tags}{lorem}(x, wrapper = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object to be converted.} 11 | 12 | \item{wrapper}{A function that takes a character string of a paragraph or 13 | chunk of placeholder text and returns an \code{\link[htmltools:builder]{htmltools::tag()}}. By default, 14 | lorem ipsum text is wrapped in \code{\link[htmltools:builder]{htmltools::p()}}.} 15 | 16 | \item{...}{Any additional parameters.} 17 | } 18 | \value{ 19 | Returns an \code{\link[htmltools:tagList]{htmltools::tagList()}}. 20 | } 21 | \description{ 22 | Renders \code{\link[=ipsum]{ipsum()}} placeholder text as HTML tags using 23 | \code{\link[htmltools:as.tags]{htmltools::as.tags()}}. By default, paragraphs are rendering \verb{

} tags with 24 | \code{\link[htmltools:builder]{htmltools::p()}}, but you may provide your own paragraph \code{wrapper} function. 25 | In general, you won't need to manually call this function, instead you can 26 | just drop \code{\link[=ipsum]{ipsum()}} text into another \code{\link[htmltools:builder]{htmltools::tag()}}. 27 | } 28 | \examples{ 29 | htmltools::div( 30 | lorem::ipsum(paragraphs = 3) 31 | ) 32 | 33 | htmltools::tags$ul( 34 | htmltools::as.tags( 35 | lorem::ipsum(paragraphs = 3, sentences = 1), 36 | wrapper = htmltools::tags$li 37 | ) 38 | ) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /man/ipsum.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ipsum.R 3 | \name{ipsum} 4 | \alias{ipsum} 5 | \alias{ipsum_words} 6 | \alias{ipsum_starts} 7 | \title{Generate Lorem Ipsum Text} 8 | \usage{ 9 | ipsum(paragraphs = 1, sentences = NULL, avg_words_per_sentence = 10) 10 | 11 | ipsum_words(n, collapse = TRUE) 12 | 13 | ipsum_starts(n) 14 | } 15 | \arguments{ 16 | \item{paragraphs}{Number of paragraphs of text to generate.} 17 | 18 | \item{sentences}{Number of sentences per paragraph. If \code{NULL}, then a random 19 | number of sentences per paragraph (approximately 3-8) will be chosen. 20 | Alternatively, \code{sentences} can be a vector of integers representing the 21 | number of sentences per paragraph.} 22 | 23 | \item{avg_words_per_sentence}{Number of expected words per sentence.} 24 | 25 | \item{n}{Number of words to generate} 26 | 27 | \item{collapse}{Should the words be collapsed into a single string, separated 28 | by spaces (default)? If \code{FALSE}, the chosen words are returned as a 29 | character vector.} 30 | } 31 | \value{ 32 | A character vector of \emph{lorem ispum} placeholder text, where each 33 | element in the vector is a paragraph of text. 34 | } 35 | \description{ 36 | Generates \emph{lorem ipsum} placeholder text for the requested number of 37 | sentences or paragraphs. You can control the number of sentences per 38 | paragraph and the average number of words per sentence, or simply enter the 39 | number of desired paragraphs for a completely random experience. 40 | 41 | \code{lorem::ipsum()} uses sampling and the random number generator and makes no 42 | effort to shield the placeholder text generation from the main script, so 43 | please only use this package for temporary placeholder text. 44 | } 45 | \section{Functions}{ 46 | \itemize{ 47 | \item \code{ipsum()}: Generate paragraphs and sentences of \emph{lorem ipsum} text. 48 | 49 | \item \code{ipsum_words()}: Generate \emph{lorem ipsum} words, without punctuation. 50 | 51 | \item \code{ipsum_starts()}: Generate \emph{lorem ipsum} starting words. 52 | 53 | }} 54 | \section{Options}{ 55 | 56 | 57 | You can influence, to a degree, the amount of punctuation that is included 58 | in the output using the \code{lorem.punctuation_valence} option. This global 59 | option should be a number between 0 and 1, or \code{FALSE} to disable 60 | punctuation altogether. When the value is closer to 1, more punctuation is 61 | included in the sentences. When the value is closer to 0, less punctuation 62 | will be inserted. The default value is 0.4. 63 | } 64 | 65 | \examples{ 66 | # 1 paragraph of text 67 | lorem::ipsum(1) 68 | 69 | # 2 paragraphs with 2 and 3 sentences each 70 | lorem::ipsum(2, sentences = c(2, 3)) 71 | 72 | # 2 paragraphs with short sentences 73 | lorem::ipsum(2, avg_words_per_sentence = 4) 74 | 75 | # 2 paragraphs with long sentences 76 | lorem::ipsum(2, avg_words_per_sentence = 20) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /man/lorem-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lorem-package.R 3 | \docType{package} 4 | \name{lorem-package} 5 | \alias{lorem} 6 | \alias{lorem-package} 7 | \title{lorem: Generate Lorem Ipsum Text} 8 | \description{ 9 | Quickly generate lorem ipsum placeholder text. Easy to integrate in 'R Markdown' documents and 'Shiny' apps. Includes an 'RStudio' addin to insert lorem ipsum into the current document. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://github.com/gadenbuie/lorem} 15 | \item \url{http://pkg.garrickadenbuie.com/lorem/} 16 | \item Report bugs at \url{https://github.com/gadenbuie/lorem/issues} 17 | } 18 | 19 | } 20 | \author{ 21 | \strong{Maintainer}: Garrick Aden-Buie \email{garrick@adenbuie.com} (\href{https://orcid.org/0000-0002-7111-0077}{ORCID}) 22 | 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/tests.html 7 | # * https://testthat.r-lib.org/reference/test_package.html#special-files 8 | 9 | library(testthat) 10 | library(lorem) 11 | 12 | test_check("lorem") 13 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/ipsum.md: -------------------------------------------------------------------------------- 1 | # lorem::ipsum() 1-sentence paragraphs 2 | 3 | Code 4 | lorem::ipsum(paragraphs = 1, sentences = 1) 5 | Output 6 | 7 | Consectetur iaculis tellus lacus sociis porta euismod primis etiam 8 | cubilia interdum nec mauris ut. 9 | 10 | --- 11 | 12 | Code 13 | lorem::ipsum(paragraphs = 2, sentences = 1) 14 | Output 15 | 16 | Sit iaculis tellus lacus sociis porta euismod primis etiam cubilia 17 | interdum nec mauris ut. 18 | 19 | Elit nunc consequat tempor parturient odio purus elementum mauris curae 20 | urna nullam aenean ultrices. 21 | 22 | --- 23 | 24 | Code 25 | lorem::ipsum(paragraphs = 3, sentences = 1) 26 | Output 27 | 28 | Ipsum tellus lacus sociis porta euismod primis etiam cubilia interdum 29 | nec mauris ut nunc! 30 | 31 | Elit consequat tempor parturient odio purus elementum mauris curae urna 32 | nullam aenean ultrices molestie. 33 | 34 | Sit nisi accumsan fusce enim cubilia tortor erat sem suscipit. 35 | 36 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/render.md: -------------------------------------------------------------------------------- 1 | # as.tags.lorem() makes htmltools tags 2 | 3 | Code 4 | htmltools::div(p3) 5 | Output 6 |

7 |

Elit tellus lacus.

8 |

Adipiscing sociis porta.

9 |

Elit euismod!

10 |
11 | 12 | --- 13 | 14 | Code 15 | htmltools::tags$ul(as.tags(p3, htmltools::tags$li)) 16 | Output 17 |
    18 |
  • Elit tellus lacus.
  • 19 |
  • Adipiscing sociis porta.
  • 20 |
  • Elit euismod!
  • 21 |
22 | 23 | -------------------------------------------------------------------------------- /tests/testthat/helpers.R: -------------------------------------------------------------------------------- 1 | expect_n_sentences <- function(lorem, n) { 2 | x <- format(lorem) 3 | paras <- unlist(strsplit(x, "\n\n")) 4 | sentences <- strsplit(paras, " ") 5 | 6 | for (i in seq_along(sentences)) { 7 | words <- sentences[[i]] 8 | n_sentences <- sum(grepl("[.!?]", words)) 9 | n_expected <- as.integer(n[[i]]) 10 | expect_equal(n_sentences, n_expected) 11 | } 12 | 13 | invisible(lorem) 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/test-ipsum.R: -------------------------------------------------------------------------------- 1 | test_that("lorem::ipsum() produces lorem characters", { 2 | x <- lorem::ipsum() 3 | expect_s3_class(x, "lorem") 4 | }) 5 | 6 | test_that("lorem::ipsum() 1-sentence paragraphs", { 7 | withr::with_seed( 8 | seed = 42, 9 | expect_snapshot(lorem::ipsum(paragraphs = 1, sentences = 1)) 10 | ) 11 | p1 <- lorem::ipsum(1, 1) 12 | expect_length(p1, 1) 13 | expect_n_sentences(p1, 1) 14 | 15 | withr::with_seed( 16 | seed = 42, 17 | expect_snapshot(lorem::ipsum(paragraphs = 2, sentences = 1)) 18 | ) 19 | p2 <- lorem::ipsum(2, 1) 20 | expect_length(p2, 2) 21 | expect_n_sentences(p2, c(1, 1)) 22 | 23 | withr::with_seed( 24 | seed = 42, 25 | expect_snapshot(lorem::ipsum(paragraphs = 3, sentences = 1)) 26 | ) 27 | p3 <- lorem::ipsum(3, 1) 28 | expect_length(p3, 3) 29 | expect_n_sentences(p3, c(1, 1, 1)) 30 | }) 31 | 32 | test_that("lorem::ipsum() n-sentence paragraphs", { 33 | withr::local_seed(42) 34 | 35 | expect_n_sentences(lorem::ipsum(1, 1), 1L) 36 | expect_n_sentences(lorem::ipsum(1, 2), 2L) 37 | expect_n_sentences(lorem::ipsum(1, 3), 3L) 38 | expect_n_sentences(lorem::ipsum(1, 10), 10L) 39 | }) 40 | 41 | test_that("lorem::ispum() catches bad `paragraph` input", { 42 | expect_error(ipsum(-1)) 43 | expect_error(ipsum(1:2)) 44 | expect_error(ipsum(1.5)) 45 | expect_error(ipsum(Inf)) 46 | expect_error(ipsum(NA)) 47 | }) 48 | 49 | test_that("lorem::ispum() catches bad `sentences` input", { 50 | expect_error(ipsum(1, -1)) 51 | expect_error(ipsum(1, 1:2)) 52 | expect_error(ipsum(1, 1.5)) 53 | expect_error(ipsum(2, c(1, 1.5))) 54 | expect_error(ipsum(2, c(1, Inf))) 55 | expect_error(ipsum(2, c(1, -1))) 56 | expect_error(ipsum(2, c(1, NA))) 57 | }) 58 | 59 | test_that("lorem::ipsum() warns about bad punctuation valence", { 60 | withr::with_options( 61 | list(lorem.punctuation_valence = 100), 62 | expect_warning(ipsum()) 63 | ) 64 | }) 65 | 66 | test_that("get_punctuation_valence()", { 67 | withr::with_options( 68 | list(lorem.punctuation_valence = 0.8), 69 | expect_equal(get_punctuation_valence(), 0.8) 70 | ) 71 | 72 | withr::with_options( 73 | list(lorem.punctuation_valence = FALSE), 74 | expect_false(get_punctuation_valence()) 75 | ) 76 | 77 | withr::with_options( 78 | list(lorem.punctuation_valence = TRUE), 79 | expect_equal(get_punctuation_valence(), 0.4) 80 | ) 81 | 82 | withr::with_options( 83 | list(lorem.punctuation_valence = 100), 84 | expect_warning(expect_equal(get_punctuation_valence(warn = TRUE), 0.4)) 85 | ) 86 | }) 87 | -------------------------------------------------------------------------------- /tests/testthat/test-render.R: -------------------------------------------------------------------------------- 1 | test_that("as.tags.lorem() makes htmltools tags", { 2 | withr::local_seed(42) 3 | 4 | p3 <- lorem::ipsum(3, 1, 1) 5 | expect_s3_class(as.tags(p3), "shiny.tag.list") 6 | 7 | expect_snapshot(htmltools::div(p3)) 8 | expect_snapshot(htmltools::tags$ul(as.tags(p3, htmltools::tags$li))) 9 | }) 10 | --------------------------------------------------------------------------------