Intro to ottrpal

ottrpal converts a Bookdown repository into a Leanpub-ready set of files. The output rendered files from this package can be published using the Github writing mode on Leanpub.

If you aren’t familiar with Bookdown you may want with their tutorials.

Installing ottrpal:

You can install ottrpal from GitHub with:

You will need to use the remotes package (and will need to install it if you don’t have it).

if (!("remotes" %in% installed.packages())) {
  install.packages("remotes")
}
if (!("ottrpal" %in% installed.packages())) {
  remotes::install_github("jhudsl/ottrpal")
}

Required files:

Before you are ready to run ottrpal, you will need the following files (which are standard in a Bookdown repository):
- a _bookdown.yml file which lists the .Rmd files that are to be rendered in a rmd: category (see example file). - .Rmd files which contain the chapter content (including your index.Rmd file which Bookdown has). - an images directory that contains any images that are referenced in the chapters. - .bib file(s) to complete any citation renders (see example file).

Optionally:. - a Book.txt file which lists the order of the chapters/quiz files (this can be autogenerated with ottrpal) (see example file).
- a directory containing quizzes in the form of .md files which have been written using the Markua formatting specifications (see example folder).

Here’s an example of what the Bookdown file set up (which ottrpal will look for) might be set up like:

A_Bookdown_Repo
├── _bookdown.yml
├── index.Rmd
├── 01-chapter_one.Rmd
├── docs
│   └── ...
├── references.bib
├── quizzes
│   ├── quiz_1.md
│   └── ...
├── resources/images
│   ├── some-figures.png
│   └── ...
└── Book.txt

Set up example data

If you’d like to use our example repository you can fork it on Github and clone it to your own computer Follow these instructions to fork and then you can clone it using a command line.

But for the purposes of this example we will download a zip file of the files we need and set those up using this function:

# Run this to get the files we need
example_files <- ottrpal::example_repo_setup()

Each of your Rmds needs to have a chunk of code with this at the beginning of the file: ottrpal::set_knitr_image_path()

This will ensure that the images are stored in the correct place and will be rendered correctly both in Bookdown and in Leanpub.

Running ottrpal

The ottrpal package converts your files using this main function (which we won’t run just yet).

ottrpal::bookdown_to_leanpub()

By default, ottrpal will re-run a bookdown::render_book("index.Rmd") rendering of your chapters first before converting the files to the Leanpub ready format. It will only process the Rmd files that are listed in the _bookdown.yml file. However, if you wish to skip this step, you can set render = FALSE when running the ottrpal::bookdown_to_leanpub() function.

About the output files

Leanpub’s Github writing mode will look for a directory called manuscript to publish from. You should not edit the files in manuscript/ by hand since a re-run of ottrpal will cause your changes to be overwritten.

About the Book.txt file:

Leanpub requires a Book.txt file to know what order the chapters/quizzes should be published.

By default, your Book.txt file will not be autogenerated but ottrpal will look in your given directory for an existing Book.txt file which it will copy over to the output directory.

You can create a Book.txt file manually, or if your quizzes and chapters are numbered, ottrpal can create the Book.txt file based on the numbers going from low to high and quizzes following chapters of the same number. (e.g. quiz_03.md will be placed after 03-some_chapter_file.Rmd).

To have ottrpal attempt to autogenerate this file with the main function you can set make_book_txt to TRUE. If no Book.txt file is found and make_book_txt is set to FALSE (this is the default setting), ottrpal will fail.

So to run the main function and also have it make a Book.txt file for us, we can run the following:

ottrpal::bookdown_to_leanpub(make_book_txt = TRUE)
## Looking for bookdown file in /home/rstudio/GitRepos/ottrpal/vignettes
## Processing these files: 
## index.Rmd
## 01-intro.Rmd
## 02-example-chapter.Rmd
## Rendering the Book
## index_file is /home/rstudio/GitRepos/ottrpal/vignettes/index.Rmd
## Warning in bookdown::render_book(input = index_file, output_format =
## output_format, : The argument 'clean_envir' has been deprecated and will be
## removed in future versions of bookdown.
## /usr/lib/rstudio-server/bin/pandoc/pandoc +RTS -K512m -RTS Course_Name.md --to html4 --from markdown+autolink_bare_uris+tex_math_single_backslash --output Course_Name.html --lua-filter /usr/local/lib/R/site-library/bookdown/rmarkdown/lua/custom-environment.lua --lua-filter /usr/local/lib/R/site-library/rmarkdown/rmarkdown/lua/pagebreak.lua --lua-filter /usr/local/lib/R/site-library/rmarkdown/rmarkdown/lua/latex-div.lua --metadata-file /tmp/RtmptI3G0C/file4ac41729876 --wrap preserve --citeproc --standalone --section-divs --table-of-contents --toc-depth 3 --template /usr/local/lib/R/site-library/bookdown/templates/gitbook.html --highlight-style pygments --number-sections --citeproc --include-in-header /tmp/RtmptI3G0C/rmarkdown-str4ac73aeac9e.html --mathjax
## 
## Output created: docs/index.html
## Copying Resources
## Copying Docs folder
## Copying bib files
## Autogenerated Book.txt saved to: manuscript/Book.txt
## Leanpub ready files are saved to manuscript Go to https://leanpub.com/ to publish them using the GitHub writing mode.

Alternatively, we could run bookdown_to_book_txt() function on its own:

## Autogenerated Book.txt saved to: manuscript/Book.txt

Also note that any index.Rmd will always be placed first and any about.Rmd file will be placed last.

We can take a peek at what the autogenerated file looks like. By default the Book.txt file is saved to the manuscript directory along with all the other Leanpub-ready files.

readLines(file.path("manuscript", "Book.txt"))
## [1] "index.Rmd"              "01-intro.Rmd"           "02-example-chapter.Rmd"

Setting up quizzes:

First, we will set up a directory to put our quizzes in.

quiz_dir <- "quizzes"
if(!dir.exists(quiz_dir)) {
  dir.create(quiz_dir)
}

By default, ottrpal will look for a folder called quizzes/ to find your quiz .md files. If your quizzes are located somewhere else, you will need to use the quiz_dir argument to specify that:

ottrpal::bookdown_to_leanpub(quiz_dir = "some_other_directory")

Leanpub can be very particular about the formatting of the quizzes, so there are funtions to help you check the formatting of your quiz.

In the main argument, you can set run_quiz_checks to TRUE (the default is FALSE).

ottrpal::bookdown_to_leanpub(run_quiz_checks = TRUE)

But the quiz checks can also be run separately using the check_quizzes() function. It will again assume you have a directory called quizzes unless you specify otherwise:

We can take a look at how check_quizzes() runs using a quiz examples: one that passes the checks and one that fails.

# Set up an good example quiz
good_quiz_path <- ottrpal::good_quiz_path()

dest_quiz_path <- file.path("quizzes", basename(good_quiz_path))
              
if (!file.exists(dest_quiz_path)){         
  file.copy(from = good_quiz_path, 
            to = dest_quiz_path)
}
## [1] TRUE

Run check_quizzes() to check all quizzes in the directory.

quiz_checklist <- ottrpal::check_quizzes(quiz_dir = "quizzes")
## 
##  Checking quiz: quizzes/quiz_good.md
## Checking question: First question to as ... in quiz: quiz_good.md
## Checking question: Example without choo ... in quiz: quiz_good.md
## Checking question: Question example wit ... in quiz: quiz_good.md
## Checking question: A more complicated e ... in quiz: quiz_good.md
## 
##  No question errors to report!

We can take a look at what a typical quiz format looks like:

quiz_lines <- readLines(dest_quiz_path)
head(quiz_lines)
## [1] ""                                                                                           
## [2] "{quiz, id: quiz_name_here, attempts: 10}"                                                   
## [3] ""                                                                                           
## [4] "## Template quiz"                                                                           
## [5] ""                                                                                           
## [6] "Put any other instructions your quiz takers need to know here like, Choose the best answer."

Now let’s add in a bad quiz and see how the report changes.

# Set up an good example quiz
bad_quiz_path <- ottrpal::bad_quiz_path()

dest_quiz_path <- file.path("quizzes", basename(bad_quiz_path))

if (!file.exists(dest_quiz_path)){                
  file.copy(from = bad_quiz_path, 
            to = dest_quiz_path)
}
## [1] TRUE

Let’s re-run check_quizzes().

quiz_checklist <- ottrpal::check_quizzes(quiz_dir = "quizzes")
## 
##  Checking quiz: quizzes/quiz_bad.md
## Checking question: It would be a shame  ... in quiz: quiz_bad.md
## Warning in FUN(X[[i]], ...): Colon detected in question on lines: 7 in question
## starting with:It would be a shame ... in quiz: quiz_bad.md
## Checking question: What a shame if we p ... in quiz: quiz_bad.md
## Checking question: Shame shame if we sa ... in quiz: quiz_bad.md
## Checking question: What if we don't put ... in quiz: quiz_bad.md
## Warning in FUN(X[[i]], ...): No correct answers provided for What if we don't
## put ... in quiz: quiz_bad.md
## Checking question: What if only give co ... in quiz: quiz_bad.md
## Warning in FUN(X[[i]], ...): No incorrect answer options provided for What if
## only give co ... in quiz: quiz_bad.md
## 
##  Checking quiz: quizzes/quiz_good.md
## Checking question: First question to as ... in quiz: quiz_good.md
## Checking question: Example without choo ... in quiz: quiz_good.md
## Checking question: Question example wit ... in quiz: quiz_good.md
## Checking question: A more complicated e ... in quiz: quiz_good.md
## 
##  Question error report saved to 'question_error_report.tsv'

We have some warning messages about various items and the errors have been saved to 'question_error_report.tsv' which we can read in and check out. Each line shows an error detected, what quiz file it was detected in, the line it’s roughly associated with and the warning message which explains what the problem is.

error_df <- readr::read_tsv("question_error_report.tsv")
## 
## ── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## cols(
##   question_names = col_character(),
##   quiz = col_character(),
##   warning_msg = col_character(),
##   related_index = col_double()
## )
error_df
## # A tibble: 3 x 4
##   question_names                quiz   warning_msg                 related_index
##   <chr>                         <chr>  <chr>                               <dbl>
## 1 It would be a shame if we pu… quiz_… Colon detected in question…             7
## 2 What if we don't put a corre… quiz_… No correct answers provide…            31
## 3 What if only give correct an… quiz_… No incorrect answer option…            38

Now you would just need to go into each of those files and fix the stated problem. Then you can re-run check_quizzes() and see if the warning is resolved.