Slidoc: A slide-oriented document management system using Markdown

  • 1 Installation and dependencies
  • 2 Lecture management
  • 3 Slidoc document structure
  • 4 Concepts and Notes
  • 5 Slideshow mode and quick navigation
  • 6 Paced mode
  • 7 Answer tally and concept understanding analysis
  • 8 Concept dependency analysis
  • 9 Internal links and numbering
  • 10 Question slides
  • 11 Hiding and/or stripping solutions
  • 12 Converting to Jupyter Notebooks
  • 13 Managing images
  • 14 Viewing slides with reveal.js
  • 15 reveal.js shortcuts
  • 16 reveal.js presentation mode
  • 17 Printing slidoc documents
  • 18 Additional command line options
  • 19 Inline and block formulas
  • 20 Code snippets
  • 21 Slide with image
  • 22 Another slide with images
  • 23 Interactive multiple choice question
  • 24 Text response
  • 25 Simple function code (question)
  • 26 Tables (markdown extension)
  • 27 Open multiple choice question
  • 28 Open numeric response question
  • 29 Open text response question
  • 30 Linking Slidoc sessions a Google Docs spreadsheet
  • 31 Embed Jupyter Notebook
−Contents  −All Notes  Missed question concepts

Slidoc manages a collection of lectures written using Markdown, which is a very simple and popular markup syntax. The lectures can include text, images and interactive questions. Markdown files are plain text files saved using extension .md. They can be edited using text editors like Emacs, vi, Atom, and Sublime Text.

Slidoc publishes the Markdown files as static HTML files, reveal.js slideshows and Jupyter notebooks. It can also create a table of contents, generate an index, manage questions and analyze concept dependencies.

The HTML files generated by Slidoc can be shared via email or hosted using free resources such as public Dropbox folders, Github project web sites etc.

The design goals of Slidoc documents are:

  1. Easy to write.

  2. Easy to read.

  3. Easy to interact with.

  4. Track understanding of concepts.

This README.md provides documentation, examples and tests for Slidoc.


Using the widely-used Markdown file format, with some extensions, accomplishes the first goal. With this format, plain text editors and many other open source tools (such as pandoc) can be used to edit and process the files. Version control is easy and sites like GitHub can be used to store and share the files.

The remaining goals are achieved using plain vanilla HTML files with embedded Javascript allows easy navigation between slides and lectures. The format is mobile-friendly and allows "index navigation", i.e., scrolling through portions of different lectures that discuss same concept. The embedded Javascript also provides interactivity, allowing users to answer embedded questions, tallying scores and tracking understanding of concepts.

1 Installation and dependencies

Slidoc has minimal dependencies. All the Slidoc scripts are located in the src directory. The templates sub-directory is also needed. Download from Github and unzip/untar to install. To test, publish this README.md file in a temporary directory using the following command:

../src/slidoc.py --slides=black ../README.md

Open the toc.html file created by the above command in a browser.

Slidoc uses mistune for HTML exports, which is included in the src directory for convenience. HTML documents produced by Slidoc automatically load the Mathjax library to display equations and reveal.js for slideshows (except for presentation mode, which requires the notes plugin for reveal.js to be installed in a web-accessible directory).

2 Lecture management

Say the root directory is Course. Typically, all lectures would be stored in a Lectures subddirectory with ordered names like prefix-lecture01.md.

To export some or all lectures to html format for web publishing, create a sub-directory, say Publish. In that directory, type:

slidoc.py ../Lectures/prefix-lecture??.md

The above command will create files named prefix-lecture01.html and so on in that directory. Additionally, it will create two files, toc.html (table of contents) and ind.html (concept index). The files in the Publish directory can be served from a web server, say by renaming toc.html to index.html using the --toc=index.html option.

Alternatively, the --combine=all.html option can be added, which will combine all the lectures, table of contents and index into a single file all.html, which can be published or shared.

3 Slidoc document structure

Slidoc recognizes several extensions to standard Markdown to process slides in a lecture.


Any Level 1 header other than the first one will be treated like a Level 2 header.

4 Concepts and Notes

Two additional pieces of information may optionally be included in each slide: a list of concepts and additional notes. A concept list may appear anywhere in the slide, but notes can only appear at the very end of the slide.


Concepts: topic1, subtopic1; topic2; another topic, sub topic

Notes: Additional material

Concept lists are used generate an automatic concept index. Indexing is done separately for regular slides and question slides. Slidoc supports concept chain naviagtion. Starting from the index, you can easily navigate between all places in the document where a particular concept is discussed.


Concept lists are semicolon-separated and use the syntax topic, subtopic where topic/subtopic is a space-separated phrase and subtopic is optional. Concepts are not visible during a slideshow, but are displayed in the printed version of the lecture.

The first concept in the list is assumed to be the primary concept relevant to the slide. If there is no primary concept, then the special concept null should be specified as the first concept. Additional concepts are treated as secondary concepts.

Notes are additional material that are displayed in the printed version of the lecture. For normal slideshows, notes are not visible in the main slide, but are normally displayed in vertical slides below the main slide. (The separator -- may be used to generate multiple Notes slides in the vertical.)

An alternative presentation mode, with two views, is also available for slideshows. In this case, notes are not displayed in the normal view but only displayed in the presenter view.

5 Slideshow mode and quick navigation

Slidoc features a built-in "slideshow" mode, allowing you to switch seamlessly between scroll view and slide view anywhere in the document. Slide view is enabled by clicking on the square () icon on the bottom left. The Escape key may also be used to enter/exit slide mode. Pressing ? during a slideshow displays a list of keyboard shortcuts.

The slideshow mode can be used for quick navigation around the document:


Unlike a true slideshow, vertical scrolling is permitted in each slide, allowing essentially unlimited supporting material such as Notes.

6 Paced mode

Slidoc supports a restrictive type of slideshow mode known as the paced mode, where the user is forced to view the document as a sequence of slides. Information about the state of a paced slideshow is saved in the persistent local storage of the browser, using the filename as the key. It is enabled by the option:


The Notes portion of a question slide is hidden until a correct response is received or all tries are exhausted.


Slides can normally be advanced only one at a time in paced mode. This means that "slide skipping", i.e., forward slide navigation through internal links is disabled. However, if a set of consecutive questions is answered correctly, forward slide navigation is enabled until the next question slide is reached. Thus, a forward slide link could be included in the Notes portion of the final question in a sequence (or the following non-question slides) to enable adaptive testing. If you answer the sequence of questions correctly, you can skip the next several slides, which may contain additional questions aimed at those who failed to answer correctly.

7 Answer tally and concept understanding analysis

8 Concept dependency analysis

To analyze concept dependency for lectures and exercises delivered, create a temporary subdirectory and use a command like:

slidoc.py --qindex=qind.html --crossref=xref.html ../Lectures/prefix-lecture0[1-6].md ../Lectures/prefix-exercise0[123].md

This will generate the concept dependency analysis for the first six lectures and the first three exercises in the files index.html (concepts index), qind.html (questions index), and xref.html (cross-referencing info).

The qind.html file has a map analyzing each question for all the concepts it covers, and relating it to other questions which cover a subset of these concepts.

Slidoc supports internal links that refer to other slides using a # in the reference syntax:


If header is the same as text, a simpler notation may be used:


Headers (at all levels) are automatically referrable. For example, see another answer or Simple function code answer.

If the header name is too long to be conveniently linked, a shorter reference can be appended to the header using the notation:

## header {#short-ref}

like the one that links to this slide. Short references may only contain letters, digits, underscores, hyphens and dots.


To refer to an arbitrary portion of non-header text, define the reference using the notation:


This phrase can be referred to elsewhere as phrase:


Double hash ## links may be used to refer to concept index entries, like markdown or multiple-choice questions:

[markdown](##) OR [multiple-choice questions](##questions, multiple choice)

Link prefixes of the form #: may be used to append automatically generated counter values, like figure numbers:

[Figure ]{#:my_figure}. Figure caption

Figure 1 can then can be referred to elsewhere as

[Figure ](#:my_figure)

Look at Figure 1. For figure numbers with sections (e.g., 1.2), use #::my_sectional_figure.

For references, the above syntax allows for two options:

[Newton (1687)](#ref-newton1687)

[]{#ref-newton1687} Newton, I., 1687: ... 

for author-based references like Newton (1687)

Newton, I., 1687: ...



[]{#:ref-einstein1905}. Einstein, A., 1905: ... 

for numeric references[1].

1. Einstein, A., 1905: ...

10 Question slides

Slidoc distinguishes between normal slides and slides with questions. Questions are slides of the form:

Question statement

Answer: X

Concepts: ...

where X can be a, b, etc. for multiple-choice questions, a number for numeric answers, or some text for open-ended answers. For unspecified answers, X should be choice, number, or text. Correct text answers with markup, or spanning multiple lines, can be provided as Notes or in the next slide with a Level 3 header containing the word answer.

The optional concepts list for questions is analyzed by Slidoc for dependencies.

Slide with answer

11 Hiding and/or stripping solutions

By specifying a match pattern (regex) for slide titles, answers in question slides and text slides containing answers can be hidden at first glance. Clicking on the answer prefix or the slide title will reveal the answers. The following command will hide all slides with the string Answer or answer in the title (as well as answers specified in question slides).

slidoc.py --hide=[Aa]answer ... 

The following command

slidoc.py --hide=[Aa]answer --strip=hidden ... 

will strip answers completely from the printable .html files.

12 Converting to Jupyter Notebooks

Lecture files may be converted to Jupyter notebooks by specifying the --notebook option to slidoc.py. By default, concept lists are stripped during this conversion process.

Alternatively, to simply convert to notebooks, use the md2nb.py command:

md2nb.py ../Lectures/prefix-lecture03.md ../Lectures/prefix-lecture04.md

By default, all fenced code blocks are converted to code cells. Specifiying the --indented option also converts indented code blocks to code cells. Use the -h option to list all command options.

The reverse conversion, from notebook to Markdown format, can be accomplished using nb2md.py. Another script, md2md.py, can be used to transform Markdown documents by removing concept lists, embedding/exporting images etc.

13 Managing images

Handling images is a bit hard when using Markdown. For Slidoc, the convention is to use web URLs or to store images in a local subdirectory named images and include references of the form

![alt text](images/figure1.png)

The script md2md.py can be used to apply several Markdown tranformations as follows:

md2md.py --strip=concepts,notes doc.md

The above example creates a new file doc-modified.md with concept lists and notes stripped out.


Other supported operations include:

  • --fence|--unfence: Convert fenced code to indented code and vice versa

  • --images=check,web: Check that all image references in the document are valid, including web references.

  • --images=copy --dest_dir=...: Copy all image references to destination

  • --images=import,web: Import all image references into the document as data URLs (including web URLs)

  • --images=import,web,embed --combine=all.html: Import all image references, embed them as data URLs and create a single, large, self-contained HTML document.

  • --images=export,embed: Export all data URLs from document as local files, and convert all Markdown image references to HTML <img> tags.

  • --strip=extensions: Strip slidoc-specific extensions.

14 Viewing slides with reveal.js

Slidoc supports creating slideshows using reveal.js. To enable it, specify --slides=THEME,CODE_THEME,FSIZE,NOTES_PLUGIN the option. This will create a *-slides.html file will be created for each source file.

a. THEME: Text theme for reveal.js, e.g., black, white, (more)

b. CODE_THEME: Code theme for highlight.js, e.g., github, zenburn, (more)

c. FSIZE: Font size, e.g., 200%

d. NOTES_PLUGIN: Local directory where the notes plugin is installed (for presentation mode, see below)

Any of the above can be a null string, or be omitted, e.g. --slides=, or --slides=,,190%


To customize the presentation further, edit the templates/reveal_template.html template file.

15 reveal.js shortcuts

In a reaveal.js slideshow, the following keyboard shortcuts may be useful:

16 reveal.js presentation mode

reveal.js has a presentation mode which displays a timer, notes for the current slide, as well as a preview of the next slide. This mode requires the installation of the notes plugin files in a local subdirectory where the contents files are located (symlinking should also work).

If the plugin is installed in reveal.js/plugin/notes, use the command

slidoc.py --slides=,,,reveal.js/plugin/notes

to generate the slides file.

When viewing slides, type s to open a new browser window with the presentation mode. Turn off any mirroring of displays. Display the standard window on the projected window and the presentation window in the desktop/laptop window.

17 Printing slidoc documents

Although slidoc are best viewed as HTM documents, sometime you may need to print them or save them as PDF files.

You can create a single document from a set of Markdown files using the --combine= option, open it in the browser, and select the Show all chapters option. You can then print it or save it as PDF. (The --printable option can be used to preserve internal links when printing, but it should not be used for web view.)

To customize what appears in the document, you can use the --strip option. It accepts a list of comma-separated values from the list answers,chapters,concepts,contents,hidden,navigate,notes,rule,sections

You can also specity --strip=all or --strip=all,but,...


18 Additional command line options

The slidoc.py supports several additional command line options. Use the following command to display them:

slidoc.py -h

These options include:

Default options for the slidoc.py command can be specified in the first line of the first file using the following format:

<!--slidoc-defaults --hide="[Aa]nswer" --features=equation_number -->

The above line appears as the first line of this README file. (These options can be overridden by explicity specifying options in the command line.)

The remaining slides are example slides used to illustrate the Markdown slide format and to test slidoc.py

19 Inline and block formulas

Inline Latex-style formulas are supported via the backtick-dollar ... dollar-backtick syntax. For example,

`$ \alpha = \beta *\gamma* \delta $`

renders inline as `$\alpha = \beta *\gamma* \delta$`

Block equations are also supported using the double-dollar syntax:

\alpha = \beta *\gamma* \delta

renders as

$$ \alpha = \beta *\gamma* \delta $$

Can also use Latex-style equation blocks:

   E = mc^2

which renders as

\begin{equation} \label{eq:a} E = mc^2 \end{equation}

Using the --features=equation_number option for automatic equation numbering, you can refer to the above equation inline as


which renders as (`$\ref{eq:a}$`)



Equations are also allowed in notes: `$\alpha = \omega$`

(The -- separator below can be used to create additional vertical slides containing notes in reveal.js.)

Use double backticks (or multiple lines) for inline code with dollar signs at beginning/end: $ beginning dollar, ending dollar $)

20 Code snippets

Code snippets can be included using the fenced syntax or the 4-space indented syntax.

Fenced code snippet

def func(a):
    return a**2

When converting to notebook format, fenced code is converted to a code cell.

Indented code snippet

def func2(b):
    return b**2

When converting to notebook format, indented code is not converted to a code cell (unless explicitly requested).

Slide with no header

Slides with no header are omitted from the table of contents.

21 Slide with image

Flowchart example of image (Image 1) inserted using Markdown syntax:

El Nino time series

Image 1: El Nino time series

Alternatively, an internal image reference can be used:

El Nino time series

Image 2: Another El Nino time series

The reference blank.gif can be defined elsewhere in the document. The definition can be a web URL or a data URL:

[blank.gif]: data: URL "title height=100"

22 Another slide with images

Images can also be inserted directly as HTML tags (allowing control over height/width)

<img height=100 src="http://upload.wikimedia.org/wikipedia/commons/d/d6/FlowchartExample.png">

Image 3: Flowchart

Slidoc also supports an extension to the Markdown title syntax that embeds attributes align, height, and width in the title of an image (either in the link itself or in the definition, in case of a reference)


Image 4: Resized image

23 Interactive multiple choice question

Slidoc supports a simple format for framing multiple-choice questions, similar to the Aiken format used by Learning Management Systems like Moodle.

The next slide contains a multiple choice question that uses the A.. notation allowing interactive response. (The space after the .. is required.) Click on a choice to view the correct answer.

In Shakespeare's play Hamlet, the protagonist agonizes over answering a multiple-choice question. What choice does he agonize over?

A. Letter A

B. Letter B

C. Letter C

D. Letter D


This is a question with a numeric response (no header)

What is the square root of 6.25?


24 Text response

The dinosaur named tyrant lizard is more commonly known as?


25 Simple function code (question)

Write a python function to add two numbers.



Simple function code answer

26 Tables (markdown extension)

Item Value Qty
Computer $1600 5
Phone $12 12
Pipe $1 234

27 Open multiple choice question

What is the best way to deal with climate change?

A. Mitigation

B. Adaptation

C. Geoengineering

D. Move to Mars



28 Open numeric response question

What number is the answer to the Ultimate Question of Life, the Universe and Everything?



29 Open text response question

To be or note to be-that is the question. What is the answer?



Open text response question answer

30 Linking Slidoc sessions a Google Docs spreadsheet

Slidoc paced sessions may be linked to a Google Docs spreadsheet. The spreadhseet will be updated with information for each user such as the last access time, slides viewed, questions answered etc. To create the link you will need to attach the script scripts/slidoc_sheet.js to your Google Docs spreadsheet using the Tools->Script Editor... menu item. Instructions are provided in the comments section of slidoc_sheet.js and additional information may be found in this blog post. After attaching the script, you can use the Current web app URL for the spreadsheet in the command line to generate the HTML documents:

slidoc.py --google_docs=spreadsheet_url ... 

By default, users will use a unique name or other identifier when they start a paced session. If you want the users to authenticate using their Google account, additional steps are necessary as described in the Notes below.


You will need to create a Web Application attached to your Google account, obtain its ClientID and API key and use it as follows:

slidoc.py --google_docs=spreadsheet_url,client_id,apiKey ...

Getting access keys for your application: To get access keys, go to the Google Developers Console and specify your application's name and the Google APIs it will access. For simple access, Google generates an API key that uniquely identifies your application in its transactions with the Google Auth server.

For authorized access, you must also tell Google your website's protocol and domain. In return, Google generates a client ID. Your application submits this to the Google Auth server to get an OAuth 2.0 access token.

31 Embed Jupyter Notebook

A Jupyter Notebook can be embedded in a slide. To enable that, copy the Slidoc-generated README.html version of this file to a subdirectory files of the notebook server working directory. The start the server as follows:

jupyter notebook --NotebookApp.extra_static_paths='["./files"]'

The notebook server will then statically serve the HTML file from the following link: http://localhost:8888/static/README.html

Within the slide, include the following iframe HTML element:

<iframe src="http://localhost:8888/notebooks/README.ipynb" style="width:720px; height:600px;"></iframe>