Turn code samples into an executable book with Jupyter-book.
Documentation is complex and challenging. So challenging that people have a big hope for AI models and have been trying to generate docs from code for a few decades. Java docs and code annotations, and much more. This type of docs is functional but boring and hard to read. I was keen to create executable documentation that allowed users to play with code and allow me to explain code samples better.
I am a big fan of literate programming.
Org-mode times
First time I discover it on my emacs and org-mode times. Babel and org-mode allow you to combine different code parts, results of the execution, and visual elements like charts and diagrams into one document that you can convert to slides.
You can find more about org-mode in my old post
I learned that org-mode is old fashion and quite challenging to share and cooperate with, but I was impressed with the idea of executable cell codes and executable logic.
IPython is not only python. Run Typescript notebooks
I fail in love with python and python notebooks while working and Tomtom and did a lot of data and traffic data analysis. I even build a reporting system on top of it.
Notebooks follow the same idea as an org-mode babel. You could mix text, code, and execution results to unable doc and allow folks to play with it.
In the case of my task, I need some Ipython kernel that can run Typescript natively as far as my code samples and library is Typescript based. It was a bit of a challenge i tried a few approaches:
- https://github.com/n-riesco/ijavascript — didn't work well and works with js only
- https://vatlab.github.io/sos-docs/notebook.html — SOS notebooks allow to mix kernels and use multiple languages, but i found a few bugs and limitations
- https://github.com/pixiedust/pixiedust_node — quite promising, so you stay with python kernel and run js inside. Still, unfortunately, i didn't manage to make it work well.
- https://github.com/yunabe/tslab — was my last hope and love. It gives you a TS kernel and makes Ts a native notebook citizen.
You could simply run a docker image that has all tools needed
docker run -p 8888:8888 -v <working-folder>:/opt/app/data jdelemar/jupyterlab
Diagrams with Plant Uml and C4 model
Next challenge — diagrams. I struggle with visual editors and prefer DSLs and code for them.
Plant UML and GraphViz are pretty old and mature tooling. Don't be scared with the UML part.
For architecture, I prefer simple C4 models. You could find an amazing project that allows building C4 diagrams as a PlantUML.
But how to glue all this with a typescript notebook?
const plantumlEncoder = require('plantuml-encoder')
const tslab = require("tslab");
const encodedTriangle = plantumlEncoder.encode(`
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Boundary(b1,"Presentation exchange") {
Person(holder, "Holder", $sprite="person2")
Person(verifier, "Verifier")
}
Rel(verifier, holder, "1 ask for VCs", "Presentation Definition")
Rel(holder, holder, "2 filter and select VC to share acconding to definition", "VCs", $sprite = "&envelope-closed")
Rel(holder, verifier, "3 issue signed VP", "VP with a submission", $sprite = "&envelope-closed")
Rel(verifier, verifier, "4 verify vp over definition", "VP with submission & definition")
@enduml
`)
const urlTriangle = 'http://www.plantuml.com/plantuml/svg/' + encodedTriangle
tslab.display.html(`<img src="${urlTriangle}"/>`)
As a result, we get SVG. We could convert it to png and cache an effect or use it as is
Let's make a book
Oki, now we have a few cool things
- we could run typescript code
- write a documentation
- add diagrams and architecture models
But still, to make it available for the regular user, we should force folks to run a docker image. it is not so user-friendly.
Over time I accumulated a few notebooks with code samples, and my repo got a bit big, and it was hard to navigate. Github does an excellent job and even has a jupyter-friendly viewer, but still, it was rad to share a result with not technical folks.
I got a lot of inspiration from a book about ocaml
Folks heavily use Jupyter-book project
It is a fantastic tool that allows turning your notebooks or markdown files into a book or website.
What did I make? So I create a custom docker image that allows me to run tooling
FROM jdelemar/jupyterlab
RUN apk add --update git ssh
RUN pip install -U jupyter-book ghp-import
RUN mkdir -p /opt/app/book
Now with a few simple commands and just following a guide i was able to convert notebooks into a website
The source code is here
Hosting on GitHub
The simplest way to host a result is a git hub page. Just use ghp-import for it.
pip install ghp-import
ghp-import -n -p -f _build/html
Tadam, our book is ready.