Phil's Musings notes from a peripatetic programmer

Openstax Textbooks Reader on GitHub using Kramdown

Over the weekend I converted all of our popular textbooks from our new HTML format to kramdown (a Markdown variant that allows classes) and tossed it on GitHub.

Since gh-pages automatically converts kramdown files to HTML using jekyll, I also created a tiny book reader and linked to it in the book. Click the screenshot to read all the books!

image Bonus Features

By using a Markdown variant instead of HTML, there are several things GitHub provides for free.

  • repo pages will render instead of just showing the markup
  • links between pages just work
  • diffs and Pull Requests render and add changebars/colors to make the changes clearer

Clickable Table of Contents


Note: {: ...} is kramdown’s way of adding classes

The markup:

layout: page

1.  {: .preface} [Preface](contents/
2.  {: .part} Unit 1: Levels of Organization
    1.  {: .chapter} [An Introduction to the...](contents/
        1. [Overview of Anatomy and Physiology](contents/
        2. [Structural Organization of the...](contents/
        3. [Functions of Human Life](contents/

    2.  {: .chapter} [The Chemical Level of...](contents/
        1. [Elements and Atoms: The Building...](contents/
        2. [Chemical Bonds](contents/
        3. [Chemical Reactions](contents/

Rendering in normal

The markdown files render on repo pages (see example page on GitHub)


and the raw kramdown:

title: "Anatomy of Selected Synovial Joints"
layout: page

<div data-type="abstract" markdown="1">
By the end of this section, you will be able to:

* Describe the bones that articulate together to form selected...
* Discuss the movements available at each joint
* Describe the structures that support and prevent excess movements


# Articulations of the Vertebral Column

In addition to being held together by the intervertebral discs,
vertebrae also articulate with each other at synovial joints formed
between the superior and inferior articular processes called
**zygapophysial joints**{: data-type="term" :} (facet joints) (see
[link text]( These are
plane joints that provide for only limited motions between the
vertebrae. The orientation of the articular processes at these joint
varies in different regions of the vertebral column and serves to
determine the types of motions available in each vertebral region.
The cervical and lumbar regions have the greatest ranges of motions.

![Figure alt text](../resource/fig1.jpg "Figure caption"){: data-title="Figure Title" .half-page :}

Rendered Changes

GitHub will also render the changes of kramdown files instead of showing a diff (see example of deleting a chapter)



  • unobtrusive design
  • big next/prev buttons
  • reading progress bar
  • keyboard left/right buttons work
  • Table of Contents shows pages you have read
  • spinner shows when page is loading
  • just 300 lines of code
  • works on any book hosted on too! Examples of all the Openstax College books
  • search button reuses the Table of Contents
  • does not require building the files for gh-pages (unlike GitBook)

Book Reader Links


  • the reader works even if files are stored in places other than /contents (thanks to URI.js)
  • kramdown does not support <figure> (unless you HTML escape it) so I added attributes to the <img> tag (for the title) and JS converts them to a <figure>
  • internal links do not work on the OSC books because I ran out of time and used <base href="">
  • Jekyll requires all Markdown that is converted to HTML must have a YAML header
  • I removed autogenerated ids on paragraphs and lists so the kramdown is cleaner (id="fs-id*")