Skip to content

bootstrapworld/curriculum

Repository files navigation

READ ME

We describe here the directories and files in the curriculum directory, and how to use the programs provided.

For a generated document tree, please see https://bootstrapworld.org/materials/spring2023/en-us

Structure of the curriculum directory

The top directory contains a bunch of scripts and subdirectories.

The curriculum content is placed in the subdirectories lessons and pathways. lessons contains individual lessons, including the lesson plan, exercises, and printable pages. pathways contains pathway directories, each of which defines a collection of lessons. (It is possible for a lesson to occur in multiple pathways.)

The subdirectories lib and shared contain the components of the program used to generate web pages and PDFs from the lessons and pathways. For instance, lib contains a general glossary of terms used in the lessons: glossary-terms.json. shared contains directories named for the various natural languages used for instruction, e.g., en-us for US English, and es-mx for Mexican Spanish. Inside these dwell centralized educational-standards dictionaries, e.g., standards/standards-csta-dictionary.json is a list of standards defined by the CSTA.

The file Makefile is used (via make) to constructs the web pages and PDFs a directory called distribution.

Here is a skeleton of the curriculum tree, showing the salient files, with a sample lesson and sample pathway:

curriculum/
  Makefile
  lib/
    <language-independent implementation files>
    *.rkt
    *.css
    glossary-terms.json
    glossary-terms-ss.json
    maker/
      <build-related makefiles and helper scripts>
  shared/langs/
    en-us/
      <language-dependent implementation files, such as>
      *.rkt
      *.css
      Badges/*.{jpg,png}
      docroot/*.{html,png}
      images/*.png
      practices/*.json
      standards/*.json
      textbooks/*.json
  lessons/
    sample-lesson/
      langs/
        en-us/
          proglang.txt (optional)
          shadow-glossary.txt (optional)
          index.adoc
          slides.md
          images/
            *.{png,gif,jpg}
            lesson-images.json
          pyret/
          wescheme/
          pages/
            *.{adoc,pdf}
            workbook-pages.txt
            pyret/
            wescheme/
          solution-pages/
            *.{adoc,pdf}
            pyret/
            wescheme/
          xtra/
            *.{adoc,pdf}
            pyret/
            wescheme/
  pathways/
    sample-pathway/
      langs/
        en-us/
          proglang.txt (optional)
          index.adoc
          lesson-order.txt
          external-index.rkt
          images/
            *.{png,gif,jpg}
            lesson-images.json
          front-matter/
            pages/
              *.{adoc,pdf}
              workbook-pages.txt
            solution-pages/
              *.adoc
              workbook-pages.txt
          back-matter/
            pages/
            solution-pages/
          resources/
            index.adoc
            images/
              *.{png,gif,jpg}
              lesson-images.json
            pages/
              *.{adoc,pdf}
              workbook-pages.txt

Some standard subdirectory names are used to separate and shadow content based on (natural) language of instruction, the programming language used, or whether content is being built for student or teacher. Thus:

  • The langs subdirectory uses further subdirectories, e.g., en-us for US English, es-mx for Mexican Spanish, and fr for French. Source documents from the relevant natural language are chosen based on the value of the makefile variable $NATLANG during build. The default is en-us. In order to ease transition, if a language other than en-us is chosen, any content unavailable in the new language is filled in by what’s in en-us.

  • Some of the directories have pyret and wescheme subdirectories or both. These contain content that should shadow the default content (one directory level up) if that programming language is used.

  • The directory solution-pages is used to house source that will shadow pages, when the pages meant only for teacher use are created.

In all these cases, it is important that the shadowing content have the same file basename as the content that is being shadowed. Extensions can vary; thus it is possible for filename.pdf to shadow filename.adoc and vice versa.

Structure of a lesson directory

Each lesson has a subdirectory, e.g., sample-lesson, under the lessons directory.

A lesson plan is specified by an .adoc file in the language directory for that lesson, e.g., sample-lesson/langs/en-us/index.adoc. While the file basename doesn’t have to be index, ensure that there is only one .adoc file at this level.

Images are in subdirectory images.

Single printable and optionally printable pages are in subdirs pages and solution-pages (some of these can be static PDFs rather than adoc source files). (The solution- versions, as already explained, are meant to supply shadowing content intended for teacher-only documents.)

The file pages/workbook-pages.txt lists the pages — one per line — in the pages directory in the order in which they should show up in the final workbook. By default, these pages are rendered in portrait mode. If you desire a particular file file.adoc to be in landscape, its entry line in workbook-pages.txt should be file.adoc landscape rather than just file.adoc. (The entry file.adoc is convenient shorthand for file.adoc portrait.) (The words landscape and portrait may be in any case.) Supplementary adoc files used by these pages can be stored in subdirectories, typically named fragments.

Lesson pages are paginated by default when they show up in the workbook. If you don’t want a page to be populated, its entry line in workbook-pages.txt should be file.adoc portrait nopagenum. (The aspect should also be mentioned, even if it’s the default.)

(Any of the components in an entry line in workbook-pages.txt may be enclosed in double-quotes.)

The images/ subdirectory

As mentioned above, the images for a lesson are collected in a subdirectory called images. References to these images in the adoc files are of the form @image{path-to-image-file, width}, where the path-to-image-file is the relative pathname of the chosen image file in images, and the optional width is the desired width of the image.

The images also contains a lesson-images.json file that lists all the image files in the same directory with their associated metadata, i.e., caption, description, source, and license. The topmost JSON object in this file maps each image name to an object containing its metadata.

Here is an example:

"louis.png": {
  "caption": "Louis",
  "description": "A very good standard apricot poodle named Louis",
  "source": "Image from Louis's hooman",
  "license": "Creative Commons 4.0 - NC - SA"
}

Captions are optional and will print under the image on the webpage and printable exercises. They can be left out if no caption is desired.

Descriptions are for visually impaired folks using screenreaders so need to be detailed enough to allow students to engage with our materials. For example:

"description" : "pie chart: 44.6% white, 22.8% Black, 19.8% Hispanic/Latinx, 9.9% Asian, Small wedges for some other race alone and 2 or more races",

If an image is created by us, not derived from other work, and is not a data display, use

"source" : "Created by the Bootstrap Team.",
"license" : "Creative Commons 4.0 - NC - SA"

If an image is created by us and derived from other work, indicate that. Here’s an example of how we credit the data cycle images:

  "source" : "Created by the Bootstrap Team based on work from @link{http://introdatascience.org/, Mobilizing IDS project} and @link{https://www.amstat.org/asa/files/pdfs/GAISE/GAISEPreK12_Intro.pdf, GAISE}",
  "license" : "Creative Commons 4.0 - NC - SA"
},

If an image is a data display created by us using real data, please specify the source. For example:

  "source" : "Created by the Bootstrap Team using data from https://nces.ed.gov/Programs/Edge/ACSDashboard",
  "license" : "Creative Commons 4.0 - NC - SA"
},

If an image is a data display created using fictitious data, please indicate that.

"source" : "Created by the Bootstrap Team using contrived data",
"license" : "Creative Commons 4.0 - NC - SA"

The build will issue warnings for underdefined images when description, source, or license are missing. (You will get warnings even if the value is an empty string. However, for the moment, empty-string captions are ignored.)

The build process collects all the image descriptions into a single file images.js in distribution/en-us.

Structure of a pathway directory

Each pathway has a subdirectory, e.g., sample-pathway, under the pathways directory.

A pathway narrative is specified by an .adoc file in the language directory for that pathway, e.g., sample-pathway/langs/en-us/index.adoc. The file basename doesn’t have to be index, but there should be only one .adoc file in this directory.

There can also be a file external-index.rkt used to expand pointers to URLs in the pathway narrative (see below).

In the same directory, the file lesson-order.txt lists the names of the lessons (e.g., sample-lesson) that should be included in the pathway, in the order in which they should appear in the pathway workbook. (The filename can be enclosed in double-quotes.)

The pathway directory can also contains a resources subdirectory, where an .adoc file describes the “Teacher Resources” page. There should be only one such .adoc file, but it can be named anything (not necessarily index.adoc).

Building and deploying using the Makefile

The top dir contains Makefile. Type make to build the distribution, to populate the distribution/ directory with the built documentation.

make can take optional targets on the command line:

  • book — creates the PDF versions of the HTML files, as also the workbook PDFs. By default, these are not created as it is a relatively time-consuming process and is required only after the author is sure that the HTML conversions have been thoroughly debugged

  • clean — removes distribution/ so the next make builds from scratch. If this is the only option, there is no build done!

  • csv — makes a CSV version of the entire converted (en-us version only, for now) docs in distribution/en-us/curriculum.csv

  • deploy — deploys. (See section on "Deployment")

  • force — removes distribution/ and builds from scratch

  • help — displays a brief help message

  • linkcheck — checks the various internal and external links in the documents to ensure they are valid. By default, this check isn’t done to save time

make can take the following variable settings on the command line to guide the build:

  • NATLANG=lang — builds for the natural language lang. The default is en-us (English US) . Currently, the only other language that has significant support is es-mx (español mexicano)

  • SEMESTER=season — typically either fall or spring. The default is fall

  • YEAR=yyyy — typically the four-digit year of the Common Era. The default is the current year followed by -BETA

  • COURSE=p1,p2,... — if book is also specified, this makes the workbook PDFs and the related lesson PDFs only for the comma-separated pathways p1, p2, ... specified

  • DEBUGADOC=nonempty — this runs Asciidoctor individually on each file. This is slow as molasses, but helps locate any AsciiDoc syntax error such as unterminated table blocks, as opposed to preprocessing errors. nonempty is any non-empty alphanumeric string. Some mnemonic values are yes, y, true, t, 1.

  • TPC=n — We use puppeteer-cluster to generate the thousands of PDF files use in the student workbooks. By default, the cluster runs 2 tabs per core (TPC). This can be set to a higher number via this commandline argument, gaining speed at the cost of possible race-conditions.

Caution

NATLANG, SEMESTER, YEAR, COURSE, DEBUGADOC, and TPC are makefile variables, not shell environment variables! You cannot set them as environment variables and expect make to pick them up. To set, NATLANG, say, to es-mx, use

make NATLANG=es-mx

Calls such as

NATLANG=es-mx make
NATLANG=es-mx; make
export NATLANG=es-mx; make

will not work! This is intentional: to avoid the build picking up environment variables that were possibly set for other purposes.

The doctree for the built pathway (e.g., data-science) for the prose language en-us, resides in distribution/en-us/courses/. Thus:

distribution/
  en-us/
    courses/
      data-science/
        index.shtml
        workbook/
          workbook.pdf
          workbook-long.pdf
          opt-exercises.pdf
        resources/
          protected/
            workbook-sols.pdf
            workbook-long-sols.pdf
            opt-exercises-sols.pdf

Here index.shtml is the web page corresponding to the pathway narrative. The student workbooks in workbook/ are

  • workbook.pdf, the basic student workbook

  • workbook-long.pdf, above plus the optional exercises

  • opt-exercises.pdf, just the optional exercises

The teacher workbooks in resources/protected are

  • workbook-sols.pdf, the basic teacher workbook, i.e., with solutions

  • workbook-long-sols.pdf, above plus the optional exercises

  • opt-exercises-sols.pdf, just the optional exercises

These filenames are standard and do not vary with course. Their location identifies which course they describe.

Note that many workbook PDFs can be created: the students’ versions are created in the workbook directory; the teachers’ versions in the “protected” directory resources/protected.

Pages under resources/protected may prompt you for a teacher password, which is available on signing up with Bootstrapworld.

The lessons referred to by the various pathways reside in distribution/en-us/lessons/. Thus:

distribution/
  en-us/
    lessons/
      sample-lesson/
        index.shtml
        pages/
        solution-pages/

For slide generation, please see ./README-slides.adoc.

For more on the build process in general, see lib/maker/doc/index.adoc.

Sensible re-making

As expected of make, subsequent calls to it will only rebuild those files in the distribution/ that need to be updated, based on modifications to the source files in the repo.

However, if you haven’t changed the source docs, but there have been changes to the building programs themselves (in lib/), or the library/data files (in shared/), you will often need to regenerate the entire distribution/ from scratch.

You can manually delete the distribution directory and make again.

Alternatively, you can use the make target clean:

make clean

This deletes any existing distribution (it is not an error if it doesn’t exist). A subsequent make builds anew.

You can also use make force followed by any other options (if needed). This implicitly calls make clean before proceeding with the other options.

Remember, re-making the entire distribution takes time, and is often too drastic a step if you’re working on one or two lessons, are satisfied with local debugging, and immediate deployment is not the goal. In such cases, you can simply go into distribution/en-us/lessons and manually delete only those lessons that you want rebuilt. You can also manually delete pathways in distribution/en-us/courses to rebuild specific pathways. A subsequent make (even without force) will cleanly re-make just your desired lessons and/or pathways, leaving the rest of the distribution/ untouched.

Be careful while deleting stuff in distribution/ expecting them to be regenerated. Deleting at too fine a grain (just one file, say) may not always succeed in regenerating it. It’s best to stick to deleting whole lessons or pathways.

Deployment

(This section is relevant only to administrators.)

After making the distribution, it may be deployed to the web host using the make target deploy:

make deploy

We currently deploy to: https://www.bootstrapworld.org

A typical make deploy goes to something like https://www.bootstrapworld.org/materials/fall2023, assuming that the environment variables SEASON and YEAR are fall and 2023 respectively. These environment variables may be set at your OS command line or in your shell profile, or on the make command line, e.g.,

make SEASON=fall YEAR=2023 deploy
Important
If SEASON and YEAR are not set externally and are not supplied on the make command line, the default values of fall and yyyy-BETA (where yyyy is the current year) are used. This is to prevent inadvertently overwriting a currently active deployment. Always explicitly set SEASON and YEAR when deploying in earnest.

Deployment requires that you have enabled SSH access to the website machine, and that the environment variables HOSTINGER_IPADDR, HOSTINGER_USER, and HOSTINGER_PORT are set to the appropriate values.

Tip
You are allowed to set these environment variables as makefile variables, i.e., as options to make. However, it may be more convenient to store these as environment variables, as, once set, they are unlikely to change.

You will be prodded for your webhost password, once to copy the files over and another time to unpack them on the webhost machine.

Tip

Deployment uses SSH to interact with your webost. account. This can be slow. If you’re updating an already deployed doctree, you may set the variable SKIPLIB to save yourself the time taken to recopy the large mathjax library, since it’s unlikely to have changed:

make SKIPLIB=true deploy

Standards compliance

The standards compliance for the various lessons is documented in the directory `shared/langs/en-us/standards/'. In it are dictionaries for the various standards. For now, these are:

standards-cc-ela-dictionary.json
standards-cc-math-dictionary.json
standards-cc-states-dictionary.json
standards-csta-dictionary.json
standards-ia-dictionary.json
standards-k12cs-dictionary.json
standards-ma-dictionary.json
standards-ngss-dictionary.json
standards-ok-dictionary.json

Each dictionary entry associates an educational standard label with its description and all the lessons that comply with it. E.g., the following is an entry in the dictionary file standards-cc-math-dictionary.json

"6.EE.B": {
   "description": "Reason about and solve one-variable equations and inequalities.",
   "lessons": [
      "inequalities1-simple",
      "inequalities2-compound"
    ]
 }

It associates the label 6.EE.B with the description Reason about and solve one-variable equations and inequalities., and says that the two lessons inequalities1-simple and inequalities2-compound comply with it. As you create or modify lessons, add their names to the appropriate standard entries as appropriate.

The build process creates a menu for finding out the standards complied with by the lessons and the pathway. The lesson’s menu is embedded in the lesson plan, whereas the pathway’s (larger) menu is linked to.

Other compliances

Compliances with textbooks and practices are similarly documented in the subdirectories textbooks/ and practices/ of the shared/langs/en-us directory.

Lesson prerequisites

The directive @lesson-prereqs{} is used as a placeholder in a table for row(s) that include lesson prerequisites (if any) and standards. (The mode of inclusion may change in subsequent versions depending on how predictable lesson-plan formats become. For now, we need a placeholder.)

Git basics

Fork this repo to your GitHub account (say, jrandomuser). (This is done using obvious buttons on the GitHub page.)

In your terminal, clone your fork thusly:

git clone https://github.com/jrandomuser/curriculum

This will create a local repo where you can try things, change things, etc. But first, to retain connection with the original do:

git remote add upstream https://github.com/bootstrapworld/curriculum

Every time the original changes, update like so:

git fetch upstream
git merge upstream/master

You are probably in your own master branch. Even if you’re “branching out” to other new branches, the above merge will mostly work. “Mostly” because merge often triggers conflicts depending on how far you have diverged from the original. At the very least, make sure you’ve checked in all your changes that you care about, before you attempt a merge. For changes you aren’t ready to check in, save the concerned files somewhere else, and make sure there are no “modified” files in your directory.

Creating your private branch in the original repo

Alternatively — and this will work only for greenlisted members — clone the repo directly and add your own branch, e.g.,

git clone https://github.com/bootstrapworld/curriculum
cd curriculum
git checkout -b my-sandbox

You can pull and merge from master as needed:

git checkout master
git pull
git checkout my-sandbox
git merge master

If conflicts arise, you will be given a way to resolve them.

Prerequisites

The following is needed to construct documents from this repo:

  • A Unix-like environment.

    • If you’re already on some flavor of unix, you’re there! ✅

    • If you’re on Windows, you’ll want to install WSL2 to give yourself a Linux environment first (we recommend Ubuntu).

    • If you’re on MacOS, your environment is close but missing some Unix tools. You’ll want to install Homebrew first, then run the following command to add them:

      brew install gnu-sed curl make coreutils gnu-tar lua asciidoctor pkg-config cairo pango libpng jpeg giflib librsvg pixman
    • Mac users will also need to add these unix tools to their path. In the terminal, run open ~/.zshrc to edit your configuration file. Add the following, then save the file and restart your terminal:

      # add every gnu tool we have as a prefix to the path
      eval "$(/opt/homebrew/bin/brew shellenv)"
      if type brew &>/dev/null; then
        HOMEBREW_PREFIX=$(brew --prefix)
        for d in ${HOMEBREW_PREFIX}/opt/*/libexec/gnubin; do export PATH=$d:$PATH; done
      fi
  • Bash. Keeps all the scripts humming. (This is already available on Linux, macOS, and WSL) ✅

  • jq, used for checking correctness of JSON files

    Linux, macOS, and WSL users should already have this installed. If not, it can be installed via sudo apt install jq

  • Racket, to do pre-processing and other bookkeeping. Any version should do. We’re not using any bleeding-edge features of Racket. You’ll want to download and install DrRacket and make sure the racket binary is in your $PATH.

    On systems with apt (Ubuntu, WSL), the easiest way to install the latest Racket is:

    sudo apt-add-repository ppa:plt/racket
    sudo apt install racket

    or

    sudo snap install racket
  • Asciidoctor, a Ruby program, to generate HTML from AsciiDoc.

    • on Linux/WSL: sudo apt-get install asciidoctor

    • on macOS: (already installed from the list of brew packages above)

  • Lua, used for postprocessing.

    • on Linux/WSL: sudo apt-get install lua5.4

    • on macOS: (already installed from the list of brew packages above)

  • Node. The standard Node offered view your OS’s package manager may not be right: To get finer control on the Node version:

    • Install nvm, the Node Version Manager, by follow the instructions on https://github.com/nvm-sh/nvm/blob/master/README.md#installing-and-updating to install the Node Version Manager. (Use the curl as you’ve already installed curl.)

    • Do nvm install 20 followed by nvm use 20 to use version 20 - the most current version that we’ve confirmed works.

    • Note: the node canvas package is extremely finicky with versions of node. If you are getting installation errors about canvas or node-gyp, call Emmanuel!

  • Several node packages all of which are automatically installed by running npm install. (Note: you will need to be running Node v20!)

    • puppeter, and HTML → PDF generator that converts web pages into PDF documents

    • puppeteer-cluster to build the hundreds of pages we have in parallel.

    • pdf-lib, which handles collecting all the PDFs and adding page numbers

    • md2googleslides, which generates slide decks from markdown files in each of the lesson plans

    • mathjax, which generates beautifully formatted math output

  • sshpass (for deployment only)

    • on Linux/WSL: sudo apt-get install sshpass

    • on macOS: <insert>

Authoring guidelines

The .adoc files peppering this curriculum repo are written in general-purpose AsciiDoc overlaid with some preprocessing directives written in Racket that are available only in our documentation base.

AsciiDoc is a plain-text-based markup that is converted by the Asciidoctor program into HTML.

A brief introduction to AsciiDoc

An AsciiDoc source file typically has the extension .adoc, at least in our setup.

A title (aka “level 0”) header has its line preceded by a single equal sign.

Level 1 headers (“sections”) are preceded by two equal signs. Similarly for “subsections” at level 2, 3, 4, 5.

= Title at level 0
== Section at level 1
=== Subsection at level 2
==== Header at level 3
===== Header at level 4
====== Header at level 5

(That’s it. Headers of level 6+ are not provided.)

Tip
By convention, the level of a section is one less than the number of = signs used to specify it.

Itemized lists have each item paragraph preceded by a * or - and space.

Emphasized text is set within underscores: _emphasized text_.

Bold text is set within stars: *bold text*.

In-text code fragments are set within backticks: `code fragment`.

Code displays are on contiguous lines that are indented (amount of indentation doesn’t matter as long it’s non-0).

Once you’re ready to learn a bit more, see the Writer’s Guide.

For a full description of all the bells and whistles, see the AsciiDoc Language Documentation.

It’s quite possible, and encouraged, to write decent AsciiDoc documents without knowing all of its syntax. Learn just the bare minimum to get started writing, and then learn more as needed, either from the online manual, or by bugging me. (If something seems too tedious to learn or input, I could perhaps implement a simpler Racket directive.)

If your Asciidoctor version is at least 2.0.0, you can type

asciidoctor --help syntax

to get a brief reference guide to the syntax. To create a browsable HTML file, do

asciidoctor --help syntax | asciidoctor - -o help.html

and open help.html in your browser.

Racket preprocessing

The .adoc files we author can contain some additional markup, which we shall call directives. All directives begin with an @, and, if they take arguments, the latter are encased in braces ({}). Here are all the directives:

Glossary

Glossary items are annotated with the directive @vocab. E.g.,

@vocab{function}

In a lesson plan, such items are searched in the main glossary file, lib/glossary-terms.json, and are inserted as lists at the head of the document.

For a pathway narrative, the glossary items from all its constituent lessons are collected into a file pathway-standards.shtml that is linked to in the narrative page.

There can be auxiliary glossary files in lib/ that can be used to shadow the main glossary for particular lessons. For now, the only such shadowing glossary file is glossary-terms-ss.json, used for Social-Studies lessons.

In order for a lesson lessonA to use a shadowing glossary, its directory, i.e., lessons/lessonA/langs/en-us, should contain a file shadow-glossary.txt that contains the name of the shadowing glossary file.

Syntax of the glossary-terms.json file

The glossary-terms.json file (and any shadowing files) defines a JSON object that is a list of glosses. Each gloss is an object with keys for the various natural languages in use (for now, "en-us" and "es-mx"). The value for each such natlang is an object with the following mappings:

  • "keywords", which specifies a list of sublists, each sublist listing grammatically-related strings. Any of these can be used in the source (whatever fits the prose flow), but the item in the generated glossary will be the first string in the sublist.

    An example value could be [ ["mean"], ["average" "ave" "avg"] ]. The word in the source is used to find the relevant sublist, and its first item is used in the generated glossary.

  • "description", the definition for the glossed item.

Tip

As a convenience, it is not necessary to specify simple grammatical declensions in the glossary file. Thus, in the glossary entry for "coordinate" you don’t need to tack on "coordinates", although you can call @vocab on either term in your source with the assurance that they will both refer to "coordinate".

For English (en-us), this convenience covers:

  • "-s", "-es", "-y/-ies" plurals and singular present tense, e.g., "cars" maps to "car", "boxes" to "box", "stories" to "story", "applies" to "apply"

  • "-d", "-ed", "y/-ied" preterites, e.g., "saved" maps to "save", "turned" to "turn", "applied" to "apply"

  • "-ing" gerunds, e.g., "applying" maps to "apply"

Latin (the aforementioned "axis"/"axes") and Old English plurals ("child"/"children") need explicit entries however; sorry!

Spanish (es-mx) has its own set of declension detection mechanisms ("-iones" to "-ión", "-ques" to "-c", "-gues" to "-g", "-ces" to "-z", "-es" to "").

Lesson descriptions and dependencies

Each lesson plan is strongly advised to start out with a

@description{A brief paragraph describing the lesson.}

The description is displayed in the lesson plan, but is also part of the autogenerated thumbnails used by the pathway narrative for each of its lessons.

A lesson can optionally include a set of keywords, which are used when searching for lesson content. While the title, description, and standards alignment are already included in the search, occasionally there are search terms a user might employ which are not reflected in any part of the lesson (e.g., “PEMDAS”, “GEMDAS”). These keywords can be added anywhere in the lesson with the keywords directive: @keywords{PEMDAS, GEMDAS}. Multiple keywords are comma-separated.

Callout Boxes

Strategy boxes

Use

@strategy{This is the title}{

  This is some _body_ text.

}

to generate a “strategy box”, a boxed text with a blue border.

Lesson "Points"

Use

@lesson-point{
  This is an important point!
}

to generate letterboxed text to emphasize critical points.

Lesson Instruction

Use

@lesson-instruction{
- Do this first
- Then this
- And finally this
}

to generate a list of instructions, inside a box with the "letterhead" of a teacher at a whiteboard.

Exercises

Exercise files are typically recipes and have calls to one of two directives

@design-recipe-exercise{...}
@assess-design-recipe{...}

The former is used to specify a correct recipe; the latter to introduce a recipe that needs to be debugged. For examples of such recipes, please see the .adoc files in the various fragments subdirectories in the repo.

Calling preproc routines directly

Some files are more elaborate than recipes and contain sketches of solutions and tables that need to be filled. These use some extra directives like @do, @show, @showsoln, and @code that then use raw Racket code to format the exercise. Examples of these can be found in the Supplemental lesson.

Code fragments

@show can call the preproc procedure code to typeset code fragments. The code fragment is specified in s-expression format, and gets converted to the appropriate format based on the prevailing programming lang, e.g., s-exp for WeScheme and in-fix for Pyret.

@show{(code '(+ 1 2))}
Circles of Evaluation (CoEs)

@show can invoke the procedure coe to typeset a circle of evaluation (CoE):

@show{(coe '(+ 1 2))}

Sometimes portions of the code are left blank as an exercise. Use (?ANS suggested-solution) in place of such portions. In student-facing pages, this shows up as a blank. In solutions mode, the suggested solution is inserted. E.g.,

@show{(coe '(+ (?ANS 1) 2))}
Contracts

Sometimes, just a contract (part of a recipe) needs to be shown in the text. Use @show to call the Racket procedures contract (for a single contract) or contracts (for multiple).

@show{(contract "/" '("Number" "Number") "Number")}

Strings may drop the double-quotes (i.e., become symbols) as long as they’re quoted somehow. Thus, the above contract is equivalent to:

@show{(contract "/" '(Number Number) "Number")}
@show{(contract '/ '(Number Number) 'Number)}

This states that the function name is /, its domain list is ("Number" "Number") and its range is "Number".

@show{(contract "/" '("Number" "Number") "Number"
  "divides one number by another")}

adds an optional fourth argument stating the function’s purpose.

You can add parameter names for each function argument:

@show{(contract "/" '(("dividend" "Number") ("divisor" "Number"))
  "Number")}

This adds the parameter names (dividend, divisor) as annotations under the corresponding type names.

To show multiple contracts,

@show{(contracts
  '("/" ("Number" "Number") "Number" "divides one number by another")
  '("*" ("Number" "Number") "Number" "multiples one number by another")
 }

Note that contracts takes a list of arguments. Also note that quoting each such argument removes the need to quote the domain-list argument.

The directive @showsoln is similar to @show but renders only in solution pages.

The directive @do passes its argument to Racket, and renders the standard output thereof. It is a general-purpose trapdoor into Racket for things that are too difficult to do using regular AsciiDoc and the standard directives. (That said, we haven’t had occasion to need it so far.)

Cross-references and pagination

There are a clutch of directives to allow easy cross-referencing between pages in the converted document base.

The directive @printable-exercise is used to refer to pages that are part of the workbook, e.g.,

@printable-exercise{lessonA/pages/page.adoc, link text}

If , link text is not supplied, the title of the page is used. The first and second components of the pathname may be dropped in certain cases: lessonA/ may be dropped if the reference is made within the same lesson. In that case, the second component, if pages/, may also be dropped. (The only other possible second component is solution-pages/, which cannot be dropped.) The third component may have extension .pdf, .html, or .adoc. If .adoc, it is resolved to .html.

The directives @opt-printable-exercise and @handout are called the same way, and are applied to exercise pages not mentioned in the lesson’s page list. (The two are categorized differently in the collections appearing in the pathway narrative.)

The directive @lesson-link{…​} is a general-purpose link to any pages within lessons, and uses pathnames relative to the distribution/<natlang>/lessons/ directory.

The directive @dist-link{…​} uses pathnames relative to the distribution/<natlang>/

Use @link{URL, link-text} to refer to a generic URL not part of the curriculum hierarchy. The second argument for the link text is optional.

Images

Use @image{images/pic.png} to insert the image images/pic.png.

An optional second argument gives the preferred width of the image. Additional information about the image is retrieved from the images/lesson-images.json file.

Comments

Comments can be inserted anywhere in the .adoc file as

@comment{A comment}

Note that such comments will be seen in the HTML source, which may be exactly what you want, either for documentation or debugging.

If you don’t want your comments to survive into the HTML, you may use AsciiDoc’s own commenting mechanism with // and //// (see manual). While these work mostly, their text is unfortunately subject to preprocessing for directives, which may have consequences. To have truly inert comments, use

@scrub{Everything within these braces is thoroughly scrubbed}

@scrub's argument can contain plausible directives — the only requirement is that any braces within it should be paired. (This is obviously needed to keep the extent of @scrub's argument recognizable.)

Conditional text

We sometimes need the same document to generate differing content in different contexts, e.g., different target programming languages; whether the page is in student- or solutions-mode; whether the page is being converted into slide. We have a bunch of directives starting with @if…​ that makes specifying this variation easier.

Programming-language specific text

Use the @ifproglang directive to conditonally include a fragment text for a specific programming language. E.g.,

@ifproglang{pyret}{
This text occurs in the Pyret version of this document.
}
@ifproglang{wescheme}{
This text occurs in the WeScheme version of this document.
}
Slide-specific text

Lesson plan files are autoconverted to Google slides. To specify that content should not be part of the slide:

@ifnotslide{This content should not show up in the slide}

To specify that it should show up only in the slide:

@ifslide{This content is slide-specific}

The slide converter will use the content of the lesson text to infer the slide layout to use. While these heuristics may vary slightly over time, the general rules are:

  • The slide layout will be partially determined by whether the text occurs within a Launch, Investigate, or Synthesize section

  • @teacher{…​} and "Common Misconceptions" will be auto converted into slide notes

  • If the text has a right-aligned image, one of the "R" templates will be used

  • If the text has a center-aligned image, one of the "C" templates will be used

  • If the text has no image, one of the standard full-text templates will be used

Student- vs solution mode

As described above, workbook pages get converted to both student and solution versions. For content that should show up only in the student version, use @ifnotsoln. For content that should show up only in solutions mode, use @ifsoln.

We often have situations where a choice of answers is presented to the reader, but the correct answer is identified only in solutions mode. Use @ifsoln-choice to enclose this correct answer.

Pathway-specific text

As described above, a lesson can be picked up by different pathways. Parts of a lesson file may be relevant only for certain pathways. Use

@ifpathway{p1,p2,...}{text}

to specify that text should only be used for the comma-separated list of pathways p1, p2, …​.

To specify that something should be used only for pathways that are not p1, p2, …​, use

@ifnotpathway{p1,p2,...}{text}
Reusable text

When using @if…​ and @ifnot…​ pairs of conditional text, we may often find that the controlled text nevertheless contains commonalities that may be too tedious and/or error-prone to repeat. In such cases use the @define directive to save reusable text in a dynamic directive, and use call the directive (rather than repeat the reusable text) whenever it needs to be used. E.g.,

@define{savedtext}{... long piece of text ...}
@ifslide{... slide-specific text containing @savedtext ...}
@ifnoslide{.. non-slide text, also containing @savedtext ...}

Adding custom CSS classes

Some standard CSS classes to emphasize certain regions of text.

Add the class .physics-table to a table attribute to generate a single-arg function table, e.g., one that maps miles driven to cost.

You can add your own CSS classes or IDs. Classes are specified with an initial dot and IDs with an initial #. Note that at most one ID is meaningful, although any number of classes may be specified. A combination of classes and ID are simply strung together, e.g.,

[.class1.class2.class3#onlyid]

The above works for blocks. Use @span{classes and id}{text} to enclose CSS classes and/or an ID around arbitrary (i.e., in-line) text. @spans may be nested. @span’s first argument of classes and ID is specified in the same way as for blocks, without the brackets.