Appendix A — Code Markdown

Bulk of this book is code snippets extracted from source files. Instead of entire files, sections of sources are extracted but printed with line numbers so that they could be traced in the original sources. The snippets solve specific problems in implementation or illustrate a technique or otherwise are interesting.

The snippet extraction and printout is performed by a tool codemd. With a simple markup language embedded in source code, the tool prepares source code for an expository presentation.

A.1 Learning Objectives

  • Another pattern matching application

A.2 Snippet Extraction

A.2.1 Code Markdown

Inspired by tools such as Doxygen and of late, the more ubiquitous markdown approaches, this tool supports few keywords:

codemd: begin segment=<segment name> caption=<A caption>
codemd: end

The above identifies a segment of code to extract and printout along with line numbers.

codemd: skipbegin
codemd: skipend

This pair enables some section embedded within the basic begin/end pair to be skipped. Typically uninteresting parts of a lengthy segment are skipped to keep the output somewhat manageable.

A.2.2 Patterns of interest

The above specifications are translated into regular patterns using the package GNAT.Regpat as follows:

~/bin/codemd ../../codemd/src/impl.adb -x patterns -l
0015 |    cmdid      : constant String          := "codemd" & ":";
0016 |    beginpat   : constant Pattern_Matcher :=
0017 |      Compile
0018 |        (cmdid & " +begin" & " +segment=([a-zA-Z0-9]+)" &
0019 |         " +caption=([a-zA-Z0-9 \-]+)");
0020 |    endpat     : constant Pattern_Matcher := Compile (cmdid & " +end");
0021 |    skippat    : constant Pattern_Matcher := Compile (cmdid & " +skipbegin");
0022 |    skipendpat : constant Pattern_Matcher := Compile (cmdid & " +skipend");

Each line of the source file is scanned and pattern matched to direct the actions:

~/bin/codemd ../../codemd/src/impl.adb -x Process -l
0093 |       Put_Line(inputfilename);
0094 |       Open (inpfile, In_File, inputfilename);
0095 |       while not End_Of_File (inpfile) loop
0096 |          Get_Line (inpfile, inpline, inplinelen);
0097 |          lineno := lineno + 1;

...

0110 |       end loop;
0111 |       Close (inpfile);

As seen above, the markdown directives can be embedded in any language source file. All languages provide a way to separate comment lines from code which is leveraged by codemd.

A.3 Stretch

  • More language aware output e,g. keywords in bold

  • Ability to render the snippets prettier

A.4 Sample Implementation

Repository: codemd