Compiling a tutorial from a Git repository¶
Structure of git repo¶
Each tutorial is in its own branch of the repo, and has its own top-level directory within the repo. We imagine such branches will very often have their history re-written as we think of clearer ways of structuring the development of the code.
The structure of the development of the code (its decomposition into
sections etc.) is provided by the tutorial.md
document.
To identify particular commits touching the code.py
file, the
author adds a slug to the commit message by starting the subject
with a string like:
{#fire-alien-missile}
To refer to such a commit in the tutorial text, and bring in an
interactive patch element to the presentation, the author writes a
paragraph consisting of just a particular shortcode into the
tutorial.md
file like:
{{< commit fire-alien-missile >}}
(These shortcodes are modelled on Hugo’s.)
Creating a new tutorial¶
There is an experimental tool for creating the necessary file and
repo structures for a new tutorial. Within the pytch-tutorials
repo, and assuming the pytch-build
repo is a sibling to the
pytch-tutorials
repo, run something like:
poetry run -P ../pytch-build \
pytchbuild-new-tutorial \
--tutorial-name="Collect the diamonds" \
--tutorial-branch=bn/collect-diamonds-01 \
--tutorial-slug=collect-diamonds
Where the three inputs give the short human-readable name, the branch name to be created, and the name of the directory to be created.
Structure of tutorial markdown file¶
Consists of front matter followed by chapters.
Front matter¶
Start with level-1 heading naming the project. Then whatever you like, then a horizonal rule. The rule marks the end of the front matter and does not appear in the rendered tutorial.
Typically the rendered front matter will include a try the project button, which is generated by the shortcode:
{{< run-finished-project >}}
It will also typically include credits, including perhaps by use of the shortcode:
{{< asset-credits >}}
which brings in the credit information from the messages of commits adding assets.
Chapters¶
After the horizontal rule, the markdown file should contain the chapters of the tutorial. Each chapter starts with a level-2 heading and continues until either the next level-2 heading or the end of the file. Within each chapter, level-3 or lower-level headings can be used, as can any other markdown features.
Showing patches¶
At a point where the tutorial wants to show the exact change to the
code required to do the next step of the project, the author can write
a paragraph consisting of a commit
shortcode:
{{< commit fire-alien-missile >}}
The compiler transforms this into a <div>
with a particular
structure which can be picked up by the front end, to add
interactivity features.
(Currently the complete text of the code.py
file as of that commit
is included as a data attribute. This was used for an experimental
make mine like this feature, but currently is unused. It bloats the
HTML fragment considerably. Remove it? Recover it from the sequence
of patches?)
Generating commit shortcodes for all code commits¶
The tool pytchbuild-emit-commit-slugs-markdown
will emit, to
stdout, markdown text consisting of a sequence of commit
shortcodes, one per code commit in the history. This can be copied
into the tutorial.md
file as a basis for writing the tutorial
text.
Project assets¶
The project will require graphics and maybe sound assets. These files should be added in standard git commits. More than one asset can be added in a single commit, but such commits should not include any other changes.
The commit message should include copyright and licence information,
for example creative commons, source attribution, etc. This is
free-form markdown, and the text is gathered by the tutorial-compiler
and made available via the asset-credits
shortcode.
Current thinking is that assets will be added and then left unchanged. Is there a use-case for modifying the graphics as part of the tutorial? If so, how to encode version information in the code?
Tutorial assets¶
Assets for use in the tutorial itself, for example screenshots, can be
included in a tutorial-assets
directory. Commits adding such
assets should have credits/licence information along the same lines as
the information given for project assets.
Tutorial summary file¶
The tutorial directory should also include a summary.md
file at
top-level (so next to the tutorial.md
file). It should start with
a screenshot image, created along the lines of:

and after that should have a H1 line, such as:
# Boing — a Pong-like game
and after that is free-form, but should be kept fairly short. One paragraph of a few lines is enough.
Output from compiler¶
Zipfile containing a single directory at top level, whose name is taken from the sole directoy at top-level in the repo (as of the tip of the branch containing that particular tutorial). Within that directory, the contents are:
tutorial.html
— HTML fragment suitable for loading by interactive tutorial mechanism in webapp.project-assets/
— Directory containing images and/or sounds as required by project which the tutorial explains. Within the tutorial Python, the URL is taken to refer to an object underproject-assets/
.
TODO: This information is independent of the fact that the zipfile
came from a git repo. Move it to the general
tutorial-structure.rst
file?
Internals¶
The following is cut/paste from an earlier version of the tool and needs revising:
We collect the tutorial into chapters; each chapter is a list of elements. An ‘interactive patch’ element gets turned into a DIV with the relevant patch as a table, as well as extra metadata. Each chapter starts with an H2 and continues until either the next H2 or the end of the whole document.
Outline design¶
Major pieces are:
- class Asset¶
Graphics or sound asset belonging to project
Distinction is (or will be) against tutorial asset, e.g., a screenshot to be included in the presentation.
Contains path (QN: relative to what?) and data-bytes. Relative to git root?
- class ProjectCommit¶
Individual commit from history
Construct from repo and commit-OID.
Different types of commit:
Identified commit belonging to project being developed: Expect this to be used in tutorial.
Addition of asset/s: E.g., adding a graphics file.
The unique base commit: How much code should there be in this? Just the
import
stuff at the top?Updates just to the raw markdown of the tutorial text: Ignored when generating tutorial.
TODO: Addition of tutorial assets, e.g., screenshots.
- added_assets¶
A list of
Asset
instances.QN: A given ProjectCommit might add more than one asset. We also have an explicit (but possibly redundant) tag in the commit message to flag a commit as adding assets. What if the tag and the actual commit disagree? Should it be possible to do
added_assets
on anyProjectCommit
? Should this return an empty list if there are no added assets? Emit a warning if it adds assets but doesn’t include theadd-project-assets
tag (or vice versa)? TODO: That tag is no longer used I think?
- maybe_identifying_slug¶
The text of the identifying slug, if one present, otherwise None.
- is_base: bool
Whether the commit message contains the magic ‘this is the base’ tag.
- modified_tutorial_text¶
Whether the commit updates just the
TOP-LEVEL-DIRECTORY/tutorial.md
file, and is not otherwise tagged.
- class ProjectHistory¶
Chain of git commits developing project from scratch.
Read in repo, starting at some commit and tracing back through first parent until a given end commit. Really just a list of ProjectCommit objects.
Ctor inputs:
Repo directory. Branch name with latest commit in history to process. (QN: Might one day want to support more than one ‘final’ branch, to support ‘now you try this’, or ‘alternatively we could have implemented this feature like this.)
Tip revision.
Which source to use for the tutorial text.
- class TutorialRawText¶
Document with tutorial text and DIVs for rich content
Read in tutorial text, break down into sections, identify pieces where augmentation from the git repo is required.
Ctor inputs:
Filename of markdown file.
Representation:
Soup? Whose job is it to manipulate the soup to add the attributes etc. to the DIVs for interactive commits? And who owns the soup? Probably OK for it to live in the TutorialRawText, but for the convention to be that when that TutorialRawText is handed over to the TutorialBundle ctor, the contained soup is available for the TutorialBundle to mutate.
- class TutorialBundle¶
Filesystem fragment (tutorial.html, assets/ directory)
Representation of everything needed to emit the tutorial bundle:
Raw text (TutorialRawText)
Git repo / project history (
ProjectHistory
)
Constructed from the above two things.
- write_new_zipfile(file_or_filename)¶
- write_to_zipfile(existing_open_zipfile)¶
TODOs¶
Validation and/or warnings would be nice, including:
each project asset has a path within the ‘project-assets/’ directory
exactly those commits tagged as adding project assets do in fact add project assets
all changes to the code file are tagged with identifier-slugs
all untagged commits are changes to the tutorial.md file
there is exactly one base in the history
the history has no merges