Repository: benmarwick/wordcountaddin Branch: master Commit: 99e222cfd964 Files: 25 Total size: 53.8 KB Directory structure: gitextract_4xsqdf0n/ ├── .Rbuildignore ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ └── bug_report.md │ ├── ISSUE_TEMPLATE.md │ └── workflows/ │ └── R-CMD-check.yaml ├── .gitignore ├── .travis.yml ├── CONDUCT.md ├── CONTRIBUTING.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R/ │ ├── hello.R │ └── utils.R ├── README.Rmd ├── README.md ├── codecov.yml ├── inst/ │ └── rstudio/ │ └── addins.dcf ├── man/ │ ├── text_stats.Rd │ └── wordcountaddin.Rd ├── tests/ │ ├── testthat/ │ │ ├── test_wordcountaddin.R │ │ ├── test_wordcountaddin.Rmd │ │ └── test_wordcountaddin.docx │ └── testthat.R └── wordcountaddin.Rproj ================================================ FILE CONTENTS ================================================ ================================================ FILE: .Rbuildignore ================================================ ^.*\.Rproj$ ^\.Rproj\.user$ ^\.travis\.yml$ ^README\.Rmd$ ^README-.*\.png$ ^CONDUCT\.md$ ^CONTRIBUTING.md$ ^codecov\.yml$ ^wordcountaddin\.Rcheck$ ^wordcountaddin.*\.tar\.gz$ ^wordcountaddin.*\.tgz$ .github/ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Please include a minimal reproducible example (AKA a reprex). If you've never heard of a [reprex](http://reprex.tidyverse.org/) before, start by reading . **Expected behavior** A clear and concise description of what you expected to happen. **Session Info** Output of `sessionInfo()` on your device so we can see what packages and version numbers you have ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Please wait for some discussion of your report before making a Pull Request.** **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Please include a minimal reproducible example (AKA a reprex). If you've never heard of a [reprex](http://reprex.tidyverse.org/) before, start by reading . Describe the steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Session Info** Output of `sessionInfo()` on your device so we can see what packages and version numbers you have ================================================ FILE: .github/workflows/R-CMD-check.yaml ================================================ name: R CMD CHECK on: [push] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y libcurl4-openssl-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev libtiff-dev libjpeg-dev libwebp-dev pkg-config shell: bash - name: Install dependencies run: | install.packages(c("pak", "devtools", "testthat")) pak::local_install_deps() shell: Rscript {0} - name: Run tests run: devtools::test() shell: Rscript {0} ================================================ FILE: .gitignore ================================================ .Rproj.user .Rhistory .RData wordcountaddin.Rcheck/ wordcountaddin*.tar.gz wordcountaddin*.tgz ================================================ FILE: .travis.yml ================================================ # Sample .travis.yml for R projects language: r warnings_are_errors: false sudo: required r_github_packages: - jimhester/covr after_success: - Rscript -e 'covr::codecov()' ================================================ FILE: CONDUCT.md ================================================ # Contributor Code of Conduct 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. 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. 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. 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. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/ ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing Guidelines ## Pull requests Requirements for making a pull request: * Some knowledge of [git]() * Some knowledge of [GitHub]() Read more about pull requests on GitHub at [https://help.github.com/articles/using-pull-requests/](https://help.github.com/articles/using-pull-requests/). If you haven't done this before, Hadley Wickham provides a nice overview of git (), as well as best practices for submitting pull requests (). Then: * Fork the repo to your GitHub account * Clone the version on your account down to your machine from your account, e.g,. `git clone git@github.com:benmarwick/.git` * Make sure to track progress upstream (i.e., on our version of the package at `benmarwick/`) by doing `git remote add upstream git@github.com:benmarwick/.git`. Each time you go to make changes on your machine, be sure to pull changes in from upstream (aka the ropensci version) by doing either `git fetch upstream` then merge later or `git pull upstream` to fetch and merge in one step * Make your changes (we prefer if you make changes on a new branch) * Ideally included in your contributions: * Well documented code in roxygen docs * If you add new functions or change functionality, add one or more tests. * Make sure the package passes `R CMD CHECK` on your machine without errors/warnings * Push up to your account * Submit a pull request and participate in the discussion. ## Documentation contributions Documentation contributions are surely much needed in every project as each could surely use better instructions. If you are editing any files in the repo, follow the above instructions for pull requests to add contributions. However, if you are editing the wiki, then you can just edit the wiki and no need to do git, pull requests, etc. All of the function documentation is generated automatically. Please do not edit any of the documentation files in man/ or the NAMESPACE. Instead, construct the appropriate roxygen2 documentation in the function files in R/ themselves. The documentation is then generated by running the document() function from the devtools package. Please consult the Advanced R programming guide if this workflow is unfamiliar to you. Note that functions should include examples in the documentation. Please use \dontrun for examples that take more than a few seconds to execute or require an internet connection. Likewise, the README.md file in the base directory should not be edited directly. This file is created automatically from code that runs the examples shown, helping to ensure that they are functioning as advertised and consistent with the package README vignette. Instead, edit the README.Rmd source file in manuscripts and run make to build the README. ## Repository structure This repository is structured as a standard R package following the conventions outlined in the Writing R extensions manual. A few additional files are provided that are not part of the built R package and are listed in .Rbuildignore, such as .travis.yml, which is used for continuous testing and integration. ## Code All code for this package is found in R/, (except compiled source code, if used, which is in /src). All functions should be thoroughly documented with roxygen2 notation; see Documentation. Bug reports _must_ have a [reproducible example](http://adv-r.had.co.nz/Reproducibility.html) and include the output of `devtools::session_info()` (instead of `sessionInfo()`). We recommend using Hadley Wickham's style guide when writing code (). ## Testing Any new feature or bug-fix should include a unit-test demonstrating the change. Unit tests follow the testthat framework with files in tests/testthat. Please make sure that the testing suite passes before issuing a pull request. This can be done by running check() from the devtools package, which will also check for consistent documentation, etc. This package uses the travis continuous testing mechanism for R to ensure that the test suite is run on each push to Github. An icon at the top of the README.md indicates whether or not the tests are currently passing. ## Questions or comments? Do not hesitate to open an issue in the issues tracker to raise any questions or comments about the package or these guidelines. ================================================ FILE: DESCRIPTION ================================================ Package: wordcountaddin Type: Package Title: Word counts and readability statistics in R markdown documents Version: 0.3.0.9000 Authors@R: c(person("Ben", "Marwick", email = "benmarwick@gmail.com", role = c("aut", "cre")), person("JooYoung", "Seo", email = "jooyoung@psu.edu", role = "ctb", comment = c(ORCID = "0000-0002-4064-6012")), person("Henrik", "Bengtsson", email = "henrik.bengtsson@gmail.com", role = "ctb"), person("Florian S.", "Schaffner", email = "florian.schaffner@outlook.com", role = "ctb"), person("Matthew T.", "Warkentin", email = "warkentin@lunenfeld.ca", role = "ctb"), person("Luke A.", "McGuinness", email = "luke.a.mcguinness@gmail.com", role = "ctb", comment = c(ORCID = "0000-0001-8730-9761"))) Maintainer: Ben Marwick Description: An addin for RStudio that will count the words and characters in a plain text document. It is designed for use with RMarkdown documents and will exclude YAML header content, code chunks and inline code from the counts. It also computes readability statistics so you can get an idea of how easy or difficult your text is to read. License: MIT + file LICENSE LazyData: TRUE Imports: fs, knitr, koRpus, koRpus.lang.en, miniUI (>= 0.1.1), purrr, rstudioapi (>= 0.5), shiny (>= 0.13), stringi, sylly, sylly.en Encoding: UTF-8 RoxygenNote: 7.1.1 Suggests: covr, testthat ================================================ FILE: LICENSE ================================================ YEAR: 2017 COPYRIGHT HOLDER: Ben Marwick ================================================ FILE: NAMESPACE ================================================ # Generated by roxygen2: do not edit by hand export(readability) export(readability_chr) export(text_stats) export(text_stats_chr) export(text_stats_fn_) export(word_count) import(koRpus) import(purrr) import(stringi) ================================================ FILE: NEWS.md ================================================ # wordcountaddin 0.3.0 NEW FEATURES * Count words from Rmd filename and get scalar as output (#20) MINOR IMPROVEMENTS * make the functions more DRY by adding some unexported fns * Expanded readme slightly * Added more tests # wordcountaddin 0.2.0 NEW FEATURES * Count words from Rmd filename without using RStudio (#3) * Count words in active Rmd in RStudio without making text selection (#3) * Count words in character string from command line (without Rmd or RStudio) (#2) MINOR IMPROVEMENTS * Added a `NEWS.md` file to track changes to the package. * Expanded readme * Added more tests BUG FIXES * Fixed inaccurate count when
present (#1) DEPRECATED AND DEFUNCT NA # wordcountaddin 0.1.0 Initial release ================================================ FILE: R/hello.R ================================================ #' wordcountaddin #' #' This packages is an addin for RStudio that will count the words and characters in a plain text document. It is designed for use with R markdown documents and will exclude YAML header content, code chunks and inline code from the counts. It also computes readability statistics so you can get an idea of how easy or difficult your text is to read. #' #' @name wordcountaddin #' @docType package #' @import purrr stringi koRpus NULL # global things md_file_ext_regex <- paste( "\\.markdown$", "\\.mdown$", "\\.mkdn$", "\\.md$", "\\.mkd$", "\\.mdwn$", "\\.mdtxt$", "\\.mdtext$", "\\.rmd$", "\\.Rmd$", "\\.RMD$", "\\.Rmarkdown$", "\\.qmd$", sep = "|") #------------------------------------------------------------------- # fns for working with selected text in an active Rmd #' Get text stats for selected text (excluding code chunks and inline code) #' #' Call this addin to get a word count and some other stats about the text #' @param filename Path to the file on which to compute text stats. #' Default is the current file (when working in RStudio) or the file being #' knit (when compiling with \code{knitr}). #' #' @export #' @examples #' md <- system.file(package = "wordcountaddin", "NEWS.md") #' text_stats(md) #' word_count(md) #' \dontrun{ #' readability(md) #' } text_stats <- function(filename = this_filename()) { text_to_count_output <- text_to_count(filename) text_stats_fn(text_to_count_output) } #' @rdname text_stats #' @description Get a word count as a single integer #' @export word_count <- function(filename = this_filename()){ text_to_count_output <- text_to_count(filename) word_count_output <- text_stats_fn_(text_to_count_output) word_count_output$n_words_korp } #' @rdname text_stats #' @description Get readability stats for selected text (excluding code chunks) #' @param quiet Logical. Should task be performed quietly? #' #' @details Call this addin to get readbility stats about the text #' #' @export readability <- function(filename = this_filename(), quiet = TRUE) { text_to_count_output <- text_to_count(filename) readability_fn(text_to_count_output, quiet = TRUE) } #--------------------------------------------------------------- # directly work on a character string in the console #' @rdname text_stats #' @description Get text stats for selected text (excluding code chunks and inline code) #' #' @details Use this function with a character string as input #' #' @export text_stats_chr <- function(text) { text <- paste(text, collapse="\n") text_stats_fn(text) } #' @rdname text_stats #' @description Get readability stats for selected text (excluding code chunks) #' #' @details Use this function with a character string as input #' #' @param text a character string of text, length of one #' #' @export readability_chr <- function(text, quiet = TRUE) { text <- paste(text, collapse = "\n") readability_fn(text, quiet = TRUE) } #----------------------------------------------------------- # helper fns, not exported text_to_count <- function(filename){ # selected text takes precedence over the filename argument: # if text is selected, it is used. Otherwise, the text in filename is used if (rstudioapi::isAvailable()) { context <- rstudioapi::getActiveDocumentContext() selection_text <- unname(unlist(context$selection)["text"]) text_is_selected <- nchar(selection_text) > 0 } else { # if not running in RStudio, assume no text is selected text_is_selected <- FALSE } if (text_is_selected) { text <- selection_text } else { # if no text is selected, read text from "filename" as character vector is_extension_invalid <- !grepl(md_file_ext_regex, filename) if (is_extension_invalid) { stop(paste("The supplied file has an extension which is not associated with markdown.", "This function only works with markdown or R markdown files.", sep = "\n ")) } text <- paste(scan(filename, 'character', quiet = TRUE), collapse = " ") } text } prep_text <- function(text){ # remove lines starting with ::: # we do this before removing line breaks so $ matches end of line text <- gsub("(?m)^:::.*$", "", text, perl = TRUE) # remove all line breaks, http://stackoverflow.com/a/21781150/1036500 text <- gsub("[\r\n]", " ", text) # don't include yaml front matter three_dashes <- unlist(gregexpr('---', text)) if (three_dashes[1]==1L) { yaml_end <- three_dashes[2] + 2L text <- substr(text, yaml_end + 1L, nchar(text)) } else { text } # don't include text in code chunks: https://regex101.com/#python text <- gsub("```\\{.+?\\}.+?```", "", text) # don't include text in in-line R code text <- gsub("`r.+?`", "", text) # don't include HTML comments text <- gsub("", "", text) # don't include LaTeX comments # how to do this? %% # don't include images with captions text <- gsub("!\\[.+?\\]\\(.+?\\)\\{.+?\\}", "", text) text <- gsub("!\\[.+?\\]\\(.+?\\)", "", text) # don't include inline markdown URLs text <- gsub("\\(http.+?\\)", "", text) # don't include # for headings text <- gsub("#*", "", text) # don't include opening html tags # (source: https://www.w3schools.com/TAGS/default.ASP) tags <- paste0("!DOCTYPE|a|abbr|acronym|address|applet|area|article|aside|", "audio|b|base|basefont|bdi|bdo|big|blockquote|body|br|button|", "canvas|caption|center|cite|code|col|colgroup|data|datalist|", "dd|del|details|dfn|dialog|dir|div|dl|dt|em|embed|fieldset|", "figcaption|figure|font|footer|form|frame|frameset|h1 to h6|", "head|header|hr|html|i|iframe|img|input|ins|kbd|label|legend|", "li|link|main|map|mark|meta|meter|nav|noframes|noscript|", "object|ol|optgroup|option|output|p|param|picture|pre|", "progress|q|rp|rt|ruby|s|samp|script|section|select|small|", "source|span|strike|strong|style|sub|summary|sup|svg|table|", "tbody|td|template|textarea|tfoot|th|thead|time|title|tr|", "track|tt|u|ul|var|video|wbr") text <- gsub(paste0("<\\s*(",tags,")[^>]*>"),"", text) # don't include closing html tags text <- gsub("", "", text) # don't include greater/less than signs because they trip up koRpus text <- gsub("<|>", "", text) # don't include percent signs because they trip up stringi text <- gsub("%", "", text) # don't include figures and tables inserted using plain LaTeX code text <- gsub("\\\\begin\\{figure\\}(.*?)\\\\end\\{figure\\}", "", text) text <- gsub("\\\\begin\\{table\\}(.*?)\\\\end\\{table\\}", "", text) # don't count abbreviations as multiple words, but leave # the period at the end in case it's the end of a sentence text <- gsub("\\.(?=[a-z]+)", "", text, perl = TRUE) # don't include LaTeX \eggs{ham} # how to do? problem with capturing \x if(nchar(text) == 0){ stop("You have not selected any text. Please select some text with the mouse and try again") } return(text) } prep_text_korpus <- function(text){ lengths <- unlist(strsplit(text, " ")) no_long_one <- paste0(ifelse(nchar(lengths) > 30, substr(lengths, 1, 10), lengths), collapse = " ") tokenize_safe <- purrr::safely(koRpus::tokenize) k1 <- tokenize_safe(no_long_one, lang = 'en', format = 'obj') k1 <- k1$result return(k1) } # These functions do the actual work #' @rdname text_stats #' @export text_stats_fn_ <- function(text){ # suppress warnings oldw <- getOption("warn") options(warn = -1) text <- prep_text(text) require("koRpus.lang.en", quietly = TRUE) # stringi methods n_char_tot <- sum(stri_stats_latex(text)[c(1,3)]) n_words_stri <- unname(stri_stats_latex(text)[4]) #korpus methods k1 <- prep_text_korpus(text) korpus_stats <- sylly::describe(k1) k_nchr <- korpus_stats$all.chars k_wc <- korpus_stats$words k_sent <- korpus_stats$sentences k_wps <- k_wc / k_sent # reading time # https://en.wikipedia.org/wiki/Words_per_minute#Reading_and_comprehension # assume 200 words per min wpm <- 200 reading_time_korp <- paste0(round(k_wc / wpm, 1), " minutes") reading_time_stri <- paste0(round(n_words_stri / wpm, 1), " minutes") return(list( # make the names more useful n_char_tot_stri = n_char_tot, n_char_tot_korp = k_nchr, n_words_korp = k_wc, n_words_stri = n_words_stri, n_sentences_korp = k_sent, words_per_sentence_korp = k_wps, reading_time_korp = reading_time_korp, reading_time_stri = reading_time_stri )) # resume warnings options(warn = oldw) } text_stats_fn <- function(text){ l <- text_stats_fn_(text) results_df <- data.frame(Method = c("Word count", "Character count", "Sentence count", "Reading time"), koRpus = c(l$n_words_korp, l$n_char_tot_korp, l$n_sentences_korp, l$reading_time_korp), stringi = c(l$n_words_stri, l$n_char_tot_stri, "Not available", l$reading_time_stri) ) results_df_tab <- knitr::kable(results_df) return(results_df_tab) } readability_fn_ <- function(text, quiet = TRUE){ text <- prep_text(text) oldw <- getOption("warn") options(warn = -1) require("koRpus.lang.en", quietly = TRUE) # korpus methods k1 <- prep_text_korpus(text) k_readability <- koRpus::readability(k1, quiet = TRUE) return(k_readability) # resume warnings options(warn = oldw) } readability_fn <- function(text, quiet = TRUE){ # a more condensed overview of the results k_readability <- readability_fn_(text, quiet = TRUE) readability_summary_table <- knitr::kable(summary(k_readability)) return(readability_summary_table) } ================================================ FILE: R/utils.R ================================================ # Get the filename of the current file, or # the file being rendered this_filename <- function() { if (interactive()) { filename <- rstudioapi::getSourceEditorContext()$path } else { filename <- knitr::current_input() } return(fs::path(filename)) } ================================================ FILE: README.Rmd ================================================ --- output: md_document: variant: markdown_github --- ```{r, echo = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "README-" ) ``` # wordcountaddin [![Last-changedate](https://img.shields.io/badge/last%20change-`r gsub('-', '--', Sys.Date())`-brightgreen.svg)](https://github.com/benmarwick/wordcountaddin/commits/master) [![minimal R version](https://img.shields.io/badge/R%3E%3D-`r as.character(getRversion())`-brightgreen.svg)](https://cran.r-project.org/) [![Licence](https://img.shields.io/github/license/mashape/apistatus.svg)](http://choosealicense.com/licenses/mit/) [![Travis-CI Build Status](https://travis-ci.org/benmarwick/wordcountaddin.png?branch=master)](https://travis-ci.org/benmarwick/wordcountaddin) [![codecov.io](https://codecov.io/github/benmarwick/wordcountaddin/coverage.svg?branch=master)](https://codecov.io/github/benmarwick/wordcountaddin?branch=master) [![ORCiD](https://img.shields.io/badge/ORCiD-0000--0001--7879--4531-green.svg)](http://orcid.org/0000-0001-7879-4531) This R package is an [RStudio addin](https://rstudio.github.io/rstudioaddins/) to count words and characters in text in an [R markdown](http://rmarkdown.rstudio.com/) document. It also has a function to compute readability statistics so you can get an indication of how easy or difficult your document is to read. You can count words in your Rmd file in three ways: - In a selection of text in your active Rmd, by selecting some text with your mouse in RStudio and using the Wordcount Addin - All the words in your active Rmd in RStudio, by using the Wordcount Addin with no text selected - All the words in an Rmd file, directly using the `word_count` function from the console or command line (RStudio not required), and specifiying the filename as an argument to the function (e.g. `wordcountaddin::word_count("my_file.Rmd")`). This will give you a single integer result, rather than the Markdown table that the other functions return. Independent of an Rmd file, you can also count words in a character vector from the console using the `text_stats_chr` function (and there is `readability_chr` for readability). ## Word count When counting words in the text of your Rmd document, these things will be ignored: - YAML front matter - code chunks and inline code - text in HTML comment tags: `` - HTML tags in the text: `
`, `
` - inline URLs in this format: `[text of link](url)` - images with captions in this format: `![this is the caption](/path/to/image.png)` - header level indicators such as `#` and `##`, etc. And because my regex is quite simple, the word count function may also ignore parts of your actual text that resemble these things. The word count will include text in headers, block quotations, verbatim code blocks, tables, raw LaTeX and raw HTML. In general, there are numerous ways to count words, with no widely accepted standard method. The variety of methods is due to differences in the definitions of a word and a sentence. Run `?stringi::stri_stats_latex` and `?koRpus::describe` to learn more about the word counting methods. For this addin I've included two methods, mostly out of curiosity to see how they differ from each other. I use functions from the [stringi](https://cran.r-project.org/web/packages/stringi/index.html) and [koRpus](https://cran.r-project.org/web/packages/koRpus/index.html) packages. If you're curious, you can compare the results you get with this addin to an online tool such as . The output of the `Word count` function is a markdown table in your R console that might look like this: ``` |Method |koRpus |stringi | |:---------------|:-----------|:-------------| |Word count |107 |104 | |Character count |604 |603 | |Sentence count |10 |Not available | |Reading time |0.5 minutes |0.5 minutes | ``` If you want to reuse these results in other R functions, you can use an unexported function like this `wordcountaddin:::text_stats_fn_(text)`, where `text` is a character vector of your text (with length one, ie. all your text in a single character string). The output will be a list object, and will include several other items not shown in the markdown table. ## Readability The readability function ignores all the same parts of the text as the word count function, and then computes the values of a bunch of [readability statistics](https://en.wikipedia.org/wiki/Readability_test). Most of these readability measurements aim to approximate the years of education required to understand your text. They look at the number of characters and syllables per word, the number of words per sentence, and so on. They don't analyse the meaning of the words. A score of around 10-12 is roughly the reading level on completion of high school in the US. These stats are computed by the [koRpus](https://cran.r-project.org/web/packages/koRpus/index.html) package. There about 27 measurements that this readability function returns (depending on how long your text is), including the Automated Readability Index (ARI), Coleman-Liau, th Flesch-Kincaid Grade Level, and the Simple Measure of Gobbledygook (SMOG). For the full list of readability measurements that are returned by the readability function, run `?koRpus::readability`. That help page also shows the formulae and citations for each statistic (and an additional 20-odd other readability statistics not used here). Readability stats are, of course, no substitute for critical self-reflection on the effectiveness of your writing at communicating ideas and information. To help with that, read [_Style: Toward Clarity and Grace_](http://www.amazon.com/dp/0226899152). The output of the `readability` function is a markdown table in your R console that might look like this: ``` |index |flavour |raw |grade |age | |:---------------------|:-----------|:-----|:-----|:----| |ARI | | |2.31 | | |Coleman-Liau | |66 |4.91 | | |Danielson-Bryan DB1 | |6.46 | | | |Danielson-Bryan DB2 | |60.39 |6 | | |Dickes-Steiwer | |53.07 | | | |ELF | |1.83 | | | |Farr-Jenkins-Paterson | |66.81 |8-9 | | |Flesch |en (Flesch) |69.57 |8-9 | | |Flesch-Kincaid | | |4.85 |9.8 | |FOG | | |7.84 | | |FORCAST | | |10.28 |15.3 | |Fucks | |23.38 |4.83 | | |Linsear-Write | | |2.35 | | |LIX | |32.41 |< 5 | | |nWS1 | | |4.19 | | |nWS2 | | |4.72 | | |nWS3 | | |4.14 | | |nWS4 | | |3.64 | | |RIX | |1.42 |5 | | |SMOG | | |8.08 |13.1 | |Strain | |2.44 | | | |TRI | |-94 | | | |Tuldava | |2.57 | | | |Wheeler-Smith | |18.33 |2 | | ``` Similar to the `word count` function, if you want to reuse these results in other R functions, you can use an unexported function like this `wordcountaddin:::readability_fn_(text)`, where `text` is a character vector of your text (with length one, ie. all your text in a single character string). The output will be a list object with slightly more detail than the summary table above. Inspiration for this addin came from [jadd](https://github.com/jennybc/jadd) and [WrapRmd](https://github.com/tjmahr/WrapRmd). ## How to install Install with `devtools::install_github("benmarwick/wordcountaddin", type = "source", dependencies = TRUE)` Go to `Tools > Addins` in RStudio to select and configure addins. ## How to use 1. Open a Rmd file in RStudio. 2. Select some text, it can include YAML, code chunks and inline code 3. Go to `Tools > Addins` in RStudio and click on `Word count` or `Readability`. Computing `Readability` may take a few moments on longer documents because it has to count syllables for some of the stats. 4. Look in the console for the output ## Feedback, contributing, etc. Please [open an issue](https://github.com/benmarwick/wordcountaddin/issues/new) if you find something that doesn't work as expected. Note that this project is released with a [Guide to Contributing](CONTRIBUTING.md) and a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. ================================================ FILE: README.md ================================================ wordcountaddin ===================================================================== [![Last-changedate](https://img.shields.io/badge/last%20change-2019--01--09-brightgreen.svg)](https://github.com/benmarwick/wordcountaddin/commits/master) [![minimal R version](https://img.shields.io/badge/R%3E%3D-3.5.2-brightgreen.svg)](https://cran.r-project.org/) [![Licence](https://img.shields.io/github/license/mashape/apistatus.svg)](http://choosealicense.com/licenses/mit/) [![Travis-CI Build Status](https://travis-ci.org/benmarwick/wordcountaddin.png?branch=master)](https://travis-ci.org/benmarwick/wordcountaddin) [![codecov.io](https://codecov.io/github/benmarwick/wordcountaddin/coverage.svg?branch=master)](https://codecov.io/github/benmarwick/wordcountaddin?branch=master) [![ORCiD](https://img.shields.io/badge/ORCiD-0000--0001--7879--4531-green.svg)](http://orcid.org/0000-0001-7879-4531) This R package is an [RStudio addin](https://rstudio.github.io/rstudioaddins/) to count words and characters in text in an [R markdown](http://rmarkdown.rstudio.com/) document. It also has a function to compute readability statistics so you can get an indication of how easy or difficult your document is to read. You can count words in your Rmd file in three ways: - In a selection of text in your active Rmd, by selecting some text with your mouse in RStudio and using the Wordcount Addin - All the words in your active Rmd in RStudio, by using the Wordcount Addin with no text selected - All the words in an Rmd file, directly using the `word_count` function from the console or command line (RStudio not required), and specifiying the filename as an argument to the function (e.g. `wordcountaddin::word_count("my_file.Rmd")`). This will give you a single integer result, rather than the Markdown table that the other functions return. Independent of an Rmd file, you can also count words in a character vector from the console using the `text_stats_chr` function (and there is `readability_chr` for readability). Word count ---------- When counting words in the text of your Rmd document, these things will be ignored: - YAML front matter - code chunks and inline code - text in HTML comment tags: `` - HTML tags in the text: `
`, `
` - inline URLs in this format: `[text of link](url)` - images with captions in this format: `![this is the caption](/path/to/image.png)` - header level indicators such as `#` and `##`, etc. And because my regex is quite simple, the word count function may also ignore parts of your actual text that resemble these things. The word count will include text in headers, block quotations, verbatim code blocks, tables, raw LaTeX and raw HTML. In general, there are numerous ways to count words, with no widely accepted standard method. The variety of methods is due to differences in the definitions of a word and a sentence. Run `?stringi::stri_stats_latex` and `?koRpus::describe` to learn more about the word counting methods. For this addin I’ve included two methods, mostly out of curiosity to see how they differ from each other. I use functions from the [stringi](https://cran.r-project.org/web/packages/stringi/index.html) and [koRpus](https://cran.r-project.org/web/packages/koRpus/index.html) packages. If you’re curious, you can compare the results you get with this addin to an online tool such as http://wordcounttools.com/. The output of the `Word count` function is a markdown table in your R console that might look like this: |Method |koRpus |stringi | |:---------------|:-----------|:-------------| |Word count |107 |104 | |Character count |604 |603 | |Sentence count |10 |Not available | |Reading time |0.5 minutes |0.5 minutes | If you want to reuse these results in other R functions, you can use an unexported function like this `wordcountaddin:::text_stats_fn_(text)`, where `text` is a character vector of your text (with length one, ie. all your text in a single character string). The output will be a list object, and will include several other items not shown in the markdown table. Readability ----------- The readability function ignores all the same parts of the text as the word count function, and then computes the values of a bunch of [readability statistics](https://en.wikipedia.org/wiki/Readability_test). Most of these readability measurements aim to approximate the years of education required to understand your text. They look at the number of characters and syllables per word, the number of words per sentence, and so on. They don’t analyse the meaning of the words. A score of around 10-12 is roughly the reading level on completion of high school in the US. These stats are computed by the [koRpus](https://cran.r-project.org/web/packages/koRpus/index.html) package. There about 27 measurements that this readability function returns (depending on how long your text is), including the Automated Readability Index (ARI), Coleman-Liau, th Flesch-Kincaid Grade Level, and the Simple Measure of Gobbledygook (SMOG). For the full list of readability measurements that are returned by the readability function, run `?koRpus::readability`. That help page also shows the formulae and citations for each statistic (and an additional 20-odd other readability statistics not used here). Readability stats are, of course, no substitute for critical self-reflection on the effectiveness of your writing at communicating ideas and information. To help with that, read [*Style: Toward Clarity and Grace*](http://www.amazon.com/dp/0226899152). The output of the `readability` function is a markdown table in your R console that might look like this: |index |flavour |raw |grade |age | |:---------------------|:-----------|:-----|:-----|:----| |ARI | | |2.31 | | |Coleman-Liau | |66 |4.91 | | |Danielson-Bryan DB1 | |6.46 | | | |Danielson-Bryan DB2 | |60.39 |6 | | |Dickes-Steiwer | |53.07 | | | |ELF | |1.83 | | | |Farr-Jenkins-Paterson | |66.81 |8-9 | | |Flesch |en (Flesch) |69.57 |8-9 | | |Flesch-Kincaid | | |4.85 |9.8 | |FOG | | |7.84 | | |FORCAST | | |10.28 |15.3 | |Fucks | |23.38 |4.83 | | |Linsear-Write | | |2.35 | | |LIX | |32.41 |< 5 | | |nWS1 | | |4.19 | | |nWS2 | | |4.72 | | |nWS3 | | |4.14 | | |nWS4 | | |3.64 | | |RIX | |1.42 |5 | | |SMOG | | |8.08 |13.1 | |Strain | |2.44 | | | |TRI | |-94 | | | |Tuldava | |2.57 | | | |Wheeler-Smith | |18.33 |2 | | Similar to the `word count` function, if you want to reuse these results in other R functions, you can use an unexported function like this `wordcountaddin:::readability_fn_(text)`, where `text` is a character vector of your text (with length one, ie. all your text in a single character string). The output will be a list object with slightly more detail than the summary table above. Inspiration for this addin came from [jadd](https://github.com/jennybc/jadd) and [WrapRmd](https://github.com/tjmahr/WrapRmd). How to install -------------- Install with `devtools::install_github("benmarwick/wordcountaddin", type = "source", dependencies = TRUE)` Go to `Tools > Addins` in RStudio to select and configure addins. How to use ---------- 1. Open a Rmd file in RStudio. 2. Select some text, it can include YAML, code chunks and inline code 3. Go to `Tools > Addins` in RStudio and click on `Word count` or `Readability`. Computing `Readability` may take a few moments on longer documents because it has to count syllables for some of the stats. 4. Look in the console for the output Feedback, contributing, etc. ---------------------------- Please [open an issue](https://github.com/benmarwick/wordcountaddin/issues/new) if you find something that doesn’t work as expected. Note that this project is released with a [Guide to Contributing](CONTRIBUTING.md) and a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. ================================================ FILE: codecov.yml ================================================ comment: false ================================================ FILE: inst/rstudio/addins.dcf ================================================ Name: Word count Description: Counts words and characters (excluding code chunks, inline code, etc.) Binding: text_stats Interactive: true Name: Readability Description: Computes readability statistics (excluding code chunks, inline code, etc.) Binding: readability Interactive: true ================================================ FILE: man/text_stats.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/hello.R \name{text_stats} \alias{text_stats} \alias{word_count} \alias{readability} \alias{text_stats_chr} \alias{readability_chr} \alias{text_stats_fn_} \title{Get text stats for selected text (excluding code chunks and inline code)} \usage{ text_stats(filename = this_filename()) word_count(filename = this_filename()) readability(filename = this_filename(), quiet = TRUE) text_stats_chr(text) readability_chr(text, quiet = TRUE) text_stats_fn_(text) } \arguments{ \item{filename}{Path to the file on which to compute text stats. Default is the current file (when working in RStudio) or the file being knit (when compiling with \code{knitr}).} \item{quiet}{Logical. Should task be performed quietly?} \item{text}{a character string of text, length of one} } \description{ Call this addin to get a word count and some other stats about the text Get a word count as a single integer Get readability stats for selected text (excluding code chunks) Get text stats for selected text (excluding code chunks and inline code) Get readability stats for selected text (excluding code chunks) } \details{ Call this addin to get readbility stats about the text Use this function with a character string as input Use this function with a character string as input } \examples{ md <- system.file(package = "wordcountaddin", "NEWS.md") text_stats(md) word_count(md) \dontrun{ readability(md) } } ================================================ FILE: man/wordcountaddin.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/hello.R \docType{package} \name{wordcountaddin} \alias{wordcountaddin} \title{wordcountaddin} \description{ This packages is an addin for RStudio that will count the words and characters in a plain text document. It is designed for use with R markdown documents and will exclude YAML header content, code chunks and inline code from the counts. It also computes readability statistics so you can get an idea of how easy or difficult your text is to read. } ================================================ FILE: tests/testthat/test_wordcountaddin.R ================================================ library(wordcountaddin) context("Word count") test_that("Word count is correct for short simple sentence", { # short sentence eleven_words <- "here are exactly eleven words of fairly boring and unpunctuated text" short_stats <- text_stats_fn_(eleven_words) # qdap cannot manage without final punct. n_words_stri_11 <-short_stats$n_words_stri n_words_korp_11 <- short_stats$n_words_korp n_char_tot_stri_11 <- short_stats$n_char_tot_stri n_char_tot_korp_11 <- short_stats$n_char_tot_korp expect_equal(n_words_stri_11, 11) expect_equal(n_words_korp_11, 11) expect_equal(n_char_tot_stri_11, 68) expect_equal(n_char_tot_korp_11, 69) }) test_that("Word count is correct for moderately complex sentences", { # Moderate: Harvard sentences, https://en.wikipedia.org/wiki/Harvard_sentences moderately_complex <- "The birch canoe slid on the smooth planks. Glue the sheet to the dark blue background. It's easy to tell the depth of a well. These days a chicken leg is a rare dish. Rice is often served in round bowls. The juice of lemons makes fine punch. The box was thrown beside the parked truck. The hogs were fed chopped corn and garbage. Four hours of steady work faced us. Large size in stockings is hard to sell." moderately_complex_stats <- text_stats_fn_(moderately_complex) n_char_tot_stri_mc <- moderately_complex_stats$n_char_tot_stri n_char_tot_korp_mc <- moderately_complex_stats$n_char_tot_korp n_words_stri_mc <- moderately_complex_stats$n_words_stri n_words_korp_mc <- moderately_complex_stats$n_words_korp n_sentences_korp_mc <- moderately_complex_stats$n_sentences_korp expect_equal(n_char_tot_stri_mc, 406) expect_equal(n_char_tot_korp_mc, 407) expect_equal(n_words_stri_mc, 80) # MS Word says 79 expect_equal(n_words_korp_mc, 80) expect_equal(n_sentences_korp_mc, 10) }) test_that("Word count is correct for complex sentences in filler text", { # Filler text with various punctuation filler <- "Lorem ipsum dolor sit amet, ea debet error sensibus vix, at esse decore vivendo vim, rebum aliquip an cum? His ea agam novum dissentiet! At mel audire liberavisse, mundi audiam quaeque sea ne. In eam error habemus delectus, audiam ocurreret ne sit, sit ei salutandi liberavisse! Ut vix case corpora. Posse malorum ponderum in qui, et eum dicam disputando, an vix quaestio scripserit. Falli veniam tamquam id mei. Modo sumo appetere cu mea, mutat possim rationibus ius id. Sed nominati antiopam cu, cu prima mandamus vim. Eos cu exerci consul! Nam case atomorum suavitate cu? No quo inermis necessitatibus, eos ne essent scripta vivendum, ea euismod quaestio qui? Per minim tation accusamus eu, audire dolores nam an. Vel vocent inimicus ut, eu porro libris argumentum quo. Vim no solet tempor, aperiam habemus assueverit ea usu: sea ut quodsi gloriatur! Eum te laudem aliquid inciderint, mollis prodesset mea ad. Dico definiebas efficiendi id usu. No bonorum suavitate adolescens per, ius oratio pericula ut, at mel porro vocibus scriptorem. Sea incorrupte definitiones necessitatibus in, cu ancillae conclusionemque duo. Ex vix dolore propriae principes, ius in augue ludus? Solet copiosae ea sed, at assum - dolore delenit has, ex aperiam honestatis mei. No legere nemore nonumes mel. Eu ullum accusata nam, an sea wisi rebum. Ei homero equidem sea! Sed erat augue eripuit et, ea vim altera eirmod labores, ad noster veritus nec. Ut porro sententiae vis, debet affert eligendi id eam! In, nominati, pertinacia has, sea admodum dissentiunt eu! Volumus appellantur ex eos. Ei duo movet scripta aliquid, ea blandit explicari consectetuer eos. Ne cibo ornatus vituperata pri. Soleat populo fierent ne sed, vel congue consequat temporibus in. Pro eu nostro inermis sadipscing, ne pri possim lobortis! Sea sonet nihil accusata no. Mei virtute noluisse pericula ex, aliquid mandamus inimicus quo ex. Esse patrioque at qui, cum sanctus; consequuntur conclusionemque cu? Ut summo oportere appellantur mel, ex per tale semper appellantur. Usu ea alia insolens sadipscing, eu aeterno persius vix. Agam prodesset interpretaris at ius, ne est malis signiferumque, illum soluta albucius mei an. Ex error tollit recusabo est, ut prompta consectetuer per. Dicam numquam eum id, brute mollis nam cu! Ei vis discere interesset! Mutat 'option' qualisque ius te, sea deserunt lobortis voluptatum at. Qui et impedit accumsan atomorum, nam dicat possit ornatus an? Eu mei aperiri discere, sea veri homero ad, stet dolore putant mei in. Eu pri debet populo luptatum, eos te nominati concludaturque. Tota veritus similique ne per, eam fastidii voluptatum eu. Sea tale mandamus suscipiantur ex. Ullum ullamcorper consequuntur et cum, aeque fuisset ut sea! Mea graecis pertinax explicari ne, pri tale hinc no? Eu vidisse nominati eum, et eam hendrerit voluptatum assueverit, qui ne munere recusabo democritum." filler_stats <- text_stats_fn_(filler) n_char_tot_stri_f <- filler_stats$n_char_tot_stri n_char_tot_korp_f <- filler_stats$n_char_tot_korp n_words_stri_f <- filler_stats$n_words_stri n_words_korp_f <- filler_stats$n_words_korp n_sentences_korp_f <- filler_stats$n_sentences_korp expect_equal(n_char_tot_stri_f, 2896) expect_equal(n_char_tot_korp_f, 2897) expect_equal(n_words_stri_f, 450) expect_equal(n_words_korp_f, 450) # MS Word says 442 expect_equal(n_sentences_korp_f, 52) }) test_that("Word count is correct for rmd text", { # text with code chunks, etc. rmd_text <- " --- title: 'Untitled' output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` ## Heading This is an [R markdown](http://rmarkdown.rstudio.com/) document. ```{r cars} summary(cars) # Lines line this have caused problems ----------------------------------------- ``` `r 2+2` `r nrow(cars)` ## Plots You can also embed plots, for example: ```{r pressure, echo=FALSE} plot(pressure) ``` ![this is the caption](/path/to/image.png) " rmd_stats <- text_stats_fn_(rmd_text) n_char_tot_stri_r <- rmd_stats$n_char_tot_stri n_char_tot_korp_r <- rmd_stats$n_char_tot_korp n_words_stri_r <- rmd_stats$n_words_stri n_words_korp_r <- rmd_stats$n_words_korp n_sentences_korp_r <- rmd_stats$n_sentences_korp expect_equal(n_char_tot_stri_r, 159) expect_equal(n_char_tot_korp_r, 159) expect_equal(n_words_stri_r, 20) expect_equal(n_words_korp_r, 20) expect_equal(n_sentences_korp_r, 4) }) test_that("we can ignore
and
", { # test for
string_with_br <- "Hi, I have
in the
string" string_with_br_stats <- text_stats_fn_(string_with_br) n_char_tot_stri_r <- string_with_br_stats$n_char_tot_stri n_char_tot_korp_r <- string_with_br_stats$n_char_tot_korp n_words_stri_r <- string_with_br_stats$n_words_stri n_words_korp_r <- string_with_br_stats$n_words_korp n_sentences_korp_r <- string_with_br_stats$n_sentences_korp expect_equal(n_char_tot_stri_r, 26) expect_equal(n_char_tot_korp_r, 27) expect_equal(n_words_stri_r, 6) expect_equal(n_words_korp_r, 6) expect_equal(n_sentences_korp_r, 0) }) test_that("we can ignore HTML tags but keep greater/less", { string_gr_ls <- "Hi,
I am <20 but >10 years old" expect_equal(prep_text(string_gr_ls), "Hi, I am 20 but 10 years old") }) test_that("Word count is correct for rmd file", { # test that we can word count on a file the_rmd_file_stats <- text_stats(filename = test_path("test_wordcountaddin.Rmd")) # Values updated to reflect correct Quarto block handling expect_equal(the_rmd_file_stats[3], "|Word count |117 |118 |") expect_equal(the_rmd_file_stats[4], "|Character count |733 |732 |") expect_equal(the_rmd_file_stats[5], "|Sentence count |27 |Not available |") expect_equal(the_rmd_file_stats[6], "|Reading time |0.6 minutes |0.6 minutes |") }) test_that("Word count is correct for cmd line", { # command line fns text_on_the_command_line <- "here is some text" text_stats_chr_out <- text_stats_chr(text_on_the_command_line) expect_equal(text_stats_chr_out[3], "|Word count |4 |4 |") expect_equal(text_stats_chr_out[4], "|Character count |18 |17 |") expect_equal(text_stats_chr_out[5], "|Sentence count |0 |Not available |") expect_equal(text_stats_chr_out[6], "|Reading time |0 minutes |0 minutes |") }) test_that("readability is correct for cmd line", { text_on_the_command_line <- "here is some text" expect_output( expect_warning( readability_chr_out <- readability_chr(text_on_the_command_line) ) ) expect_length(readability_chr_out, 27) }) test_that("Word count is correct for text with % sign", { # test for escaping the percent sign in plain text text_with_percent_sign <- "Here is some % text with percent % signs in it." text_stats_percent_chr_out <- text_stats_chr(text_with_percent_sign) expect_equal(text_stats_percent_chr_out[3], "|Word count |9 |9 |") }) test_that("Word count is correct for text with figures included using LaTeX code", { # test for escaping the percent sign in plain text text_with_figures <- "One \\begin{figure} \\caption{text} \\label{text} \\includegraphics[width=\\textwidth]{figure.png} \\end{figure} Two \\begin{figure} \\caption{text} \\label{text} \\includegraphics[width=\\textwidth]{figure.png} \\end{figure} Three" text_stats_percent_chr_out <- text_stats_chr(text_with_figures) expect_equal(text_stats_percent_chr_out[3], "|Word count |3 |3 |") }) test_that("Word count is a single integer for a Rmd file when using word_count", { # test that we can word count on a file the_rmd_word_count <- word_count(filename = test_path("test_wordcountaddin.Rmd")) expect_equal(the_rmd_word_count, 117L) }) test_that("We can handle very long strings, like citation keys", { expect_output( expect_warning( # test that we can word count on a file long_string_read <- readability_chr("it's a long string right at the end here because a tiny fraction of the refreneces have crazy long keys. Why do they do that? It's autogenerated. Why does this give so many warnings when testing. It's a puzzle. [@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa].", quiet = TRUE))) expect_equal( attr(long_string_read, 'format'), "pipe") }) test_that("don't count abbreviations as multiple words", { # test that we can word count on a file words_with_abbv <- "zero .o.n.e .t.wo." abbrev_count <- text_stats_chr(words_with_abbv) expect_equal( abbrev_count[3], "|Word count |3 |3 |") }) test_that("text_to_count reads file contents as character vector", { contents <- text_to_count(test_path("test_wordcountaddin.Rmd")) expect_type(contents, "character") expect_length(contents, 1) }) test_that("text_to_count raises an error for invalid file types", { expect_error(text_to_count("invalid.tif"), regexp = "works with markdown") }) test_that("Quarto ::: blocks do not break word count", { quarto_text <- " Here is some text which adds up to 10 words. ::: {#fig-1} plot(iris$Sepal.Length) ::: Here is more text which adds up to 10 words. Here is more text which adds up to 10 words. " stats <- text_stats_fn_(quarto_text) # Total words should be around 30. # Before fix, it will be around 10. expect_gt(stats$n_words_stri, 25) expect_gt(stats$n_words_korp, 25) }) ================================================ FILE: tests/testthat/test_wordcountaddin.Rmd ================================================ --- title: "rmd_test_file.rmd" output: word_document: default html_document: default --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` ## R Markdown This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see . When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this: ```{r cars} summary(cars) # Lines line this have caused problems ----------------------------------------- ``` ## Including Plots You can also embed plots, for example: ```{r pressure, echo=FALSE} plot(pressure) ``` Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot. ```{r} # context <- rstudioapi::getActiveDocumentContext() ``` This Markdown file contains `r wordcountaddin::word_count()` words: ```{r, message=FALSE, echo=FALSE, error=TRUE} wordcountaddin::text_stats() ``` ::: {.cell layout-align="center"} ::: ::: {.cell layout-align="center"} ::: {.cell-output-display} ::: ::: ================================================ FILE: tests/testthat.R ================================================ library(testthat) library(wordcountaddin) test_check("wordcountaddin") ================================================ FILE: wordcountaddin.Rproj ================================================ Version: 1.0 RestoreWorkspace: Default SaveWorkspace: Default AlwaysSaveHistory: Default EnableCodeIndexing: Yes UseSpacesForTab: Yes NumSpacesForTab: 2 Encoding: UTF-8 RnwWeave: knitr LaTeX: XeLaTeX AutoAppendNewline: Yes StripTrailingWhitespace: Yes BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source PackageRoxygenize: rd,collate,namespace