$$\newcommand{\n}{\hat{n}}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$

   

2nd dev sesh

First order of business is to sprint toward getting HTML documents fully rendered out of my markdeep .deep.md files that I've created 5 of already.

   

Today's roadblock

So it turns out markdeep was always designed to run in the browser. Luckily someone else has already run into this problem. I am going to need to dive into this to see if it is still functional 2 years later. It shouldn't be too bad because Markdeep has not seen significant changes in the past 2 years either.

I also did recently play with jsdom when I had a tool that I made for quickly rendering a js object into DOM structure (imagine it as taking arbitrary JSON ⟶ a ton of nested divs with some reasonably assigned class names). I modularized it to insert it into my typescript utils lib, but it wasn't until I couldn't build it that I realized my utils lib was node only. Well I added jsdom and I could unit test that in pure node, which worked out great!

Since this markdeep-offline repo looks soft-abandoned I'm just going to take the easy route and in-tree his code. It seems pretty simple and clean, and I'm going to go ahead and immediately convert it into typescript and ESM for farts and cackles. This also meant bringing in those deps it uses mentioned in the readme, highlight, jsdom, minimist.

Side note about highlight: it's certainly not the latest sexiest code highlighter package in the js ecosystem at this point in 2024, but this current approach would appear to give me about as good a chance as any to get my hands dirty to the right degree to potentially swap it out if i want. In my editor of choice (neovim) I already get treesitter based proper syntax highlighting in code blocks in markdown files right inside the editor...


I was actually able to get it working on my simple markdeep files but there are very strange issues happening when i test on more complete tests with the features.md.html and the themes files. It seems like I will have to make a more specialized simpler test case that exercises mainly the things I am interested in (math rendering, ascii diagrams and so on), because I can dispense with the section/toc handling stuff.

I tested here a rather large excerpt from Markdeep's features demo page, the section that includes diagrams and math. I'm pleasantly surprised here that it is all rendering properly, and even TOC stuff is also somehow working properly, which I did not expect.

I'm planning to delete this content copied from the markdeep demo doc, as it does not belong in my blog, but i'm keeping it in as a handy way to test this system as I continue to hack on it while I continue to write.

   

Diagrams

ServerDATACYCLESecurityFilePolicyManager Diagrams can be inserted alongside, as in this example, or between paragraphs of text as shown below.

The diagram parser leaves symbols used as labels unmodified, so characters like > and ( can appear inside of the diagram. In fact, any plain text may appear in the diagram. In addition to labels, any un-beautified text will remain in place for use as ASCII art. Thus, the diagram is rarely distored by the beautification process.

  ABoxRoundMixedRoundedDiagonals&SquareCornersSearchInteriorDiaglineif(a>b)Curvedlineobj->fcn()Done?JoinCurvedVertical3not:line'quotes'A||B*bold*NotadotAdash--isnotalineNor/isthis.

Figure 1: Diagrams can also have captions

Code with line-like symbols is allowed in diagrams and is parsed correctly so long as you make it unambiguous:

--x;x->y0__proto____FILE__<=a|bfooy--;x||ya+b

Here's a diagram on the left of some text:

Song of Myself: 35

Would you hear of an old-time sea-fight?
Would you learn who won by the light of the moon and stars?
List to the yarn, as my grandmother's father the sailor told it to me.

Walt Whitman

If there is no leading text on the left except for whitespace, a diagram may omit the asterisks on the right side for convenience:

Below are some more examples of diagrams.

   

Diagram Examples

   

Lines with Decorations

||

   

Graph with Large Nodes

A12483B5C67D

   

Graph with Small Nodes

A12483B5C67D

   

Flow Chart

STARTABCOMPLEXENDCHOICEPREPARATIONXPROCESSINPUTPROCESSPROCESSX

   

Line Ends

Tests for some tough cases:

   

Trees

111222333123412341234444

XYAYXCBCAB

XYAYXCBCAB

   

Digital Circuits

ABYC

   

Analog Circuits

kxmxd

   

Gantt Chart

PreproductionAlphaRC1StoryConceptArtModelingRiggingMechanicsEngineCodeGameCodeFreeze

   

Big Shapes

   

Small Shapes

   

Overlaps and Intersections

   

Big Grids

BABABA

   

Small Grids

bbababaa

   

Tiny Grids

   

Dot Grids

··································

   

Unicode in Diagram

x𝚺xt²dt

   

Simple Plot Diagram

UinUdcUdc_OK:::::500ms::Cpu.QonInactiveActive

   

Graphics Diagram

03PEye+y)Reflection12v0v347-+xXRefraction56+zv1v2

   

Annotated Table Diagram

AAABasis16491-210X8520140-1

   

Icon Diagram

ServerCloudDatabaseInternetWiFiBluetooth####LANWindowsOSXiOSUbuntuUbuntu//\\//\\Laptop1Laptop2Tablet1DedicatedServerRack

   

Styling Diagrams

You can use CSS to style all diagrams or individual diagrams. For example, the following has light lines on a dark background:

   

Horizontal Rules

Following the CommonMark specification, any of these patterns can be used (and extended across a whole line, of course) to produce a horizontal rule:

-----

- - -

_____

_ _ _

*****

* * *

Example:







   

Embedded Math

Markdeep automatically includes MathJax if your document contains equations and you have an Internet connection. That means you get the full power of LaTeX, TeX, MathML, and AsciiMath notation. Just put math inside single or double dollar signs.

$$ \Lo(X, \wo) = \Le(X, \wo) + \int_\Omega \Li(X, \wi) ~ f_X(\wi, \wo) ~ | \n \cdot \wi | ~ d\wi $$

You can also use LaTeX equation syntax directly to obtain numbered equations:

\begin{equation}
e^{i \pi} + 1 = 0
\end{equation}

\begin{equation}
\label{linear}
\mathbf{A}^{-1}\vec{b} = \vec{x}
\end{equation}

\begin{equation} e^{i \pi} + 1 = 0 \end{equation}

\begin{equation} \label{linear} \mathbf{A}^{-1}\vec{b} = \vec{x} \end{equation}

You can then reference those equations by name in the same way as figures, tables, and listings: See eqn. [linear] ⇒ See eqn. \ref{linear}.

If you don't have equations in your document, then Markdeep won't connect to the MathJax server. Either way, it runs MathJax after processing the rest of the document, so there is no delay.

Markdeep is smart enough to distinguish non-math use of dollar signs, such as $2.00 and $4.00, US$5, and 3$. Inline math requires consistent spaces (or punctuation) either outside or inside of the LaTeX dollar signs to distinguish them from regular text usage. Thus, the following all work:

Unless you've changed out the default MathJax processor, you can define your own LaTeX macros by executing \newcommand within dollar signs, just as you would in LaTeX. Markdeep provides a handful of commands defined this way by default because they're things that I frequently need:

Code Symbol
\O(n) \(\O(n)\)
\mathbf{M}^\T \(\mathbf{M}^\T\)
45\degrees \(45\degrees\)
x \in \Real \(x \in \Real\)
x \in \Integer \(x \in \Integer\)
x \in \Boolean \(x \in \Boolean\)
x \in \Complex \(x \in \Complex\)
\n \(\n\)
\w \(\w\)
\wo \(\wo\)
\wi \(\wi\)
\wh \(\wh\)
\Li \(\Li\)
\Lo \(\Lo\)
\Lr \(\Lr\)
\Le \(\Le\)
\thetai \(\thetai\)
\thetao \(\thetao\)
\int x^2 ~\d{x} \(\int x^2~\d{x}\)
10\un{m/s^2} \(10\un{m/s^2}\)

   

ATX Headers

In addition to the underlined headers, you can also use ATX-style headers, with multiple # signs:

   

H2

   

H3

   

H4

   
H5
   
H6

Although: do you really need six levels of subsection nesting?!

You can also create unnumbered sections that will not appear in the table of contents using parentheses around the pound signs:

Unnumbered H2
   

Well then...

I think this is more than enough exploration of markdeep. Being able to render it out from markdown in a backend process will be a big step toward productionizing it in the sense that the reader never has to run the code on their browser, and only in rare situations will I want this level of control. I'm also going to note that as impressive as it is, there are still many tradeoffs and some solutions are quite janky looking. The breadth and flexibility is impressive of course. Once I get the markdeep confirmed working I'm likely going to be setting up a more traditional markdown implementation and just using that for 98% of post files.