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.
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") }
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
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.
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.
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.
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:
ottrpal::bookdown_to_book_txt()
## 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.
## [1] "index.Rmd" "01-intro.Rmd" "02-example-chapter.Rmd"
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:
## [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.