MarkAPL for Programmers

1. Overview

This document is of interest only if you use MarkAPL within an APL application as an APL programmer.

If you use it implicitly, say by editing a Markdown file with Meddy[1], then the cheat cheet and the MarkAPL reference document should suffice.

2. How to

First of all, you can bring the document you are reading right now into view by executing MarkAPL.Reference 0. Viewing the file “MarkAPL.html” has the same effect.

You can view the cheat sheet by calling MarkAPL.Help 0. Viewing the file “MarkAPL_CheatSheet.html” has the same effect.

One way to study how to make use of MarkAPL is to trace through the method MarkAPL.Help. This should clarify the principles.

Another way is to look at the test cases named Test_Examples_01 etc. in #.TestCases in the workspace MarkAPL.DWS. You can execute them with:

TestCases.RunThese 'Examples'

You can trace through them with

TestCases.RunThese 'Examples' (-⍳1000)

The numbers select the test cases of the given group (here “Examples”) to be executed. ⍳1000 is just a fancy way to make sure that you catch all of them.

Negative numbers tell the test framework to stop right before a particular test function is going to be executed. That gives you the opportunity to trace through that function without tracing through the actual test framework.

3. Methods

Note that all helpers are discussed separately.

3.1. ConvertMarkdownFile

Takes a filename as right argument. The file is expected to hold Markdown. By default a fully-fledged HTML page is created from that Markdown file with exactly the same filename except that the file extension is .html rather than .md.

However, instead of accepting the defaults one can create a parameter namespace with:

parms←MarkAPL.CreateParms

and then specify different parameters within parms. That parameter space parms then needs to be passed as left argument to the ConvertMarkdownFile method.

Note that inputFilename must not be specified, otherwise an error is signalled. This is because the input file is already defined by the right argument.

3.2. CreateParms

Niladic function that returns a namespace populated with parameters carrying their default values. CreateParms tries to find for every parameter a value from the command line or environment variables. If it cannot find them it will establish a default value.

The namespace returned by the CreateParms method has a built-in method ∆List which is niladic and will return a matrix with two columns, the parameter name in the first column and the default value in the second column.

Note that a value of ¯1 means that there is not really a default available but a reasonable value will be determined at a later stage.

3.3. CreateHelpParms

Niladic function that returns a namespace populated with parameters carrying their default values. Internally it calls CreateParms and then adds some parameters that are needed by the Help and Reference methods.

3.4. Execute

This function is used exclusively by test cases.

3.5. Help

The function takes a Boolean right argument:

You might specify an optional left argument: a parameter space, typically created by calling the CreateHelpParms method. This allows creating a document with non-default parameters. Of course this has only an effect when the right argument is a 1.

Note that the file “MarkAPL_CheatSheet.html” carries several embedded parameters — those cannot be overridden by a parameter namespace unless you assign a 1 to ignoreEmbeddedParms.

In order to enable Help to find the file “Markdown_CheatSheet.html” (in case the defaults don't work) you must create a parameter space and then set homeFolder accordingly.

3.6. Init

Takes a two-item-vector as right argument:

  1. A parameter namespace, typically created by calling CreateParms.
  2. A vector of character vectors: the Markdown.

Returns The “ns” namespace.

3.7. MakeHTML_Doc

Takes HTML, typically created by calling Process, and makes it a fully fledged HTML document by adding <body>, <head> — with <title> — and <html> with the DocType.

3.8. MarkDown2HTML

This ambivalent function requires some Markdown as right argument.

It returns (since version 1.7.0) a two-item vector (shy):

Without an — optional — left argument it creates just the HTML from the Markdown.

However, you can also create a parameter space by calling CreateParms and set outputFilename. In that case it will create a fully-fledged HTML page from the Markdown and write it to that file. The generated page is also returned as result.

Finally one can also set the inputFilename parameter. This trumps the right argument: it reads the input file, expecting it to be Markdown, creates HTML5 from it and write it to the output file. Again the HTML is also returned as result.

Internally it calls Init & Process & MakeHTML_Doc.

Note that in case the parameter createFullHtmlPage is ¯1 (the default value which means “undefiend”) the default behaviour of MarkDown2HTML is defined by the setting of the parameter outputFilename: if outputFilename is not empty then createFullHtmlPage will default to 1, otherwise to 0, and that's what Markdown2HTML will take into account.

3.9. Process

This function takes — and returns — an ns namespace which was typically created by calling Init.

3.10. Reference

The function takes a Boolean right argument:

You might specify an optional left argument: a parameter space, typically created by calling the CreateHelpParms method. This allows creating a help file with non-default parameters. Of course this has only an effect when the right argument is a 1.

Note that the file “MarkAPL.html” carries several embedded parameters — those cannot be overridden by a parameter namespace unless you assign a 1 to ignoreEmbeddedParms.

In order to enable Reference to find the file “MarkAPL.html” (in case the defaults don't work) you must create a parameter space and then set homeFolder.

3.11. Version

Returns the name, the version number — including the built-ID — and the version date of MarkAPL.

4. Parameters

In order to specify parameters follow these steps:

      parms←MarkAPL.CreateParms''
      parms.∆List   ⍝ lists all parameters with their defaults
 bookmarkLink                                                    6
 bookmarkMayStartWithDigit                                       1
 charset                                                     utf-8
 checkFootnotes                              ⍝ defaults to "debug"
 checkLinks                                  ⍝ defaults to "debug"
 collapsibleTOC                                                  0
 compileFunctions                                                1
 compressCSS                                                     1
 createFullHtmlPage                                              0
 cssURL                                                         ¯1
 debug                                 ⍝ 0 in Runtime, 1 otherwise
 div_h_tag                                                       1
 enforceEdge                                                     1
 footnotesCaption                                      'Footnotes'
 head                                                           ''
 homefolder                                                     ¯1
 inputFilename
 lang                                                         "en"
 leanpubExtensions                                               0
 leanpubIconsUrl    'https://download.aplwiki.com/LeanPub/Images/'
 lineNumberOffset                                                0
 linkToCSS                                                       0
 markdownStrict                                                  0
 noCSS                                                           0
 numberHeaders                                                   0
 outputFilename
 printCSS                                        MarkAPL_print.css
 reportLinks                                                     0
 reportLinksCaption                                  'Link report'
 screenCSS                                      MarkAPL_screen.css
 subTocs                                                         1
 syntaxSugar                                                     1
 title                                                     MarkAPL
 toc                                                             0
 verbose                                                         1
 width                                                       900px

The function ∆List lists all the variables in the parameter space with their corresponding values.

After making amendments the parameter space can be passed as the first argument to the MarkAPL.Init function. See How-to for details.

The parameters themselves are discussed in the MarkAPL reference.

5. Function calls

It is possible to embed APL function calls in your Markdown document. The simplest way to call a function #.foo is:

This: ⍎⍎#.foo⍎⍎ is the result.

Given a function #.foo←{'FOO'} this will be the result:

This: FOO is the result.

The main purpose of this feature is to either inject simple text or one or more HTML blocks.

Notes:

You may specify something to the right as in this example:

This: ⍎⍎#.foo 1 2 'hello'⍎⍎ is the result.

The array 1 2 'hello' is however passed as left argument since ns is always passed as the right argument.

The result of such an embedded function must be one of:

However, mixing Markdown and HTML blocks is not permitted.

In case the function returns an HTML block the function call must stand on its own on a line.

If an HTML block is returned then the function is responsible for the correct formatting. In particular a <pre> block must look like this otherwise you might not get the desired result:

<pre><code>Line 1
Line 2
Last line
</code></pre>

Notes:

6. The ns namespace.

6.1. Overview

The ns namespace is returned (created) by the Init method and modified by the Process method. It contains both input and output variables.

Before Process is run the variables emptyLines, leadingChars, markdown, markdownLC and withoutBlanks hold data that is extracted from the Markdown. When Process is running block by block is processed and removed from these variables. At the same time the variable parms.html is collecting the resulting html. Other variables (abbreviations, data, footnoteDefs, headers, linkRefs, parms, subToc and toc) may or may not collect data in the process as well.

The two variables report and lineNumber are special, see there.

6.2. The ns namespace in detail

The namespace contains the following variables:

6.2.1. abbreviations

A (possibly empty) vector of two-item-vectors. The first item holds the abbreviation, the second item the explanation or comment.

6.2.2. emptyLines

A vector of Booleans indicating which lines in markdown are empty. Lines consisting of white-space characters only are considered empty.

6.2.3. embeddedParms

A matrix with two columns and as many rows as there are embedded parameters.

This document for example carries these embedded parameters:

      ns.embeddedParms
 toc                            2 3
 numberHeaders            2 3 4 5 6
 bookmarkLink                     6
 viewInBrowser                    1
 collapsibleTOC                   1
 title            MarkAPL Reference
 width                         1100
 reportLinks                      1

6.2.4. footnoteDefs

A matrix that carries all footnote definitions found in markdown. The matrix has these columns:

  1. Running number, starting from 1.
  2. Bookmark name.
  3. Caption.

6.2.5. headerLineNos

An integer vector that carries the line numbers of headers.

6.2.6. headers

A matrix that carries all headers defined in markdown.

The matrix has three or four columns:

  1. The level of the header, starting with 0.
  2. The anchor-ready version of the caption.
  3. The caption.
  4. The tiered number of the header.

Naturally the last column does not exist in case numberHeaders is 0.

6.2.7. html

After having created the ns namespace by calling Init this variable is empty. By running the Process method this variable will be filled up.

6.2.8. leadingChars

After having created the ns namespace by calling Init this variable contains a limited number of characters from markdown. Leading white-space is removed. This increases performance for many of the checks to be carried out by Process.

6.2.9. lineNumbers

After having created the ns namespace by calling Init this variable contains a vector of integers representing line numbers in markdown. This allows the current line number to be reported in case there is a problem like odd number of double quotes, invalid internal links etc. Note that function calls (See “Embedded APL function calls” in the MarkAPL reference) can access the line numbers as well.

Note that line numbers refer to the MarkDown rather than the HTML.

See also the parameter lineNumberOffset in the MarkAPL reference.

6.2.10. linkRefs

A vector of vectors holding information regarding all link references (see the MarkAPL reference for details regarding link references):

  1. id
  2. url
  3. alt text or empty
  4. special attributes or empty

6.2.11. markdown

This variable holds the Markdown to be processed by Process.

6.2.12. markdownLC

Same as markdown but all in lower case. That speeds things up at the expense of memory.

6.2.13. noOf

The number of lines processed in the next (or current) step.

6.2.14. parms

The parameters that were passed to Init.

6.2.15. report

After having created the ns namespace by calling CreateParms this variable is empty. The Process method might add remarks to this variable in case it finds something to complain about or comment on.

Some methods print what they assign to report also to the session in case the parameter verbose is 1.

6.2.16. subToc

This is a vector of two-item vectors:

  1. The level of the header, starting with 1.
  2. The caption of the header as displayed.

6.2.17. toc

This is a vector of four three-item vectors:

  1. The level of the header, starting with 1.
  2. The caption of the header as displayed.
  3. The internal link name.

Note that prior to version 2.8 there was a forth column (4. The type of the header: 1 = SeText, 2 = ATX.) which was removed then.

6.2.18. withoutBlanks

Same as markdown but without any blanks. This speeds things up at the expense of memory.

7. Helpers

This chapter comprises all methods that help converting APL arrays into Markdown.

7.1. Matrix2MarkdownList

This helper method takes an APL matrix and converts it to a list definition in Markdown.

Note that the table must have three columns:

  1. List type. A 0 defines a bulleted list. Any positive integer starts an ordered list, and defines at the same time the starting point.
  2. Nesting level. The first row must start with nesting level 0 or 1.
  3. Either a text vector or a vector of text vectors.

Example; this:

 m←''
 m,←⊂0 1 'Level 1 a bull'
 m,←⊂2 2 'Level 2 a num'
 m,←⊂2 2('Level 2 b num' '' 'Another para' '' '~~~' '{+⌿⍵}' '~~~')
 m,←⊂2 2 'Level 2 c num'
 md←MarkAPL.Matrix2MarkdownList⊃m
 ns←MarkAPL.Init''md
 ns←MarkAPL.Process ns

leads to this list:

7.2. Matrix2MarkdownTable

This helper method takes an APL matrix and converts it to a table definition in Markdown.

Without a left argument there are no column headers, and alignment is ruled by data type: strictly numeric columns are right-aligned, everything else is left-aligned:

      M←('APL' 99 'Really great')('Python' 70 'Nice')('Cobol' 1 'Oh dear')
      ⎕←MarkAPL.Matrix2MarkdownTable M
|-|-:|-|
| APL | 99 | Really great |
| Python | 70 | Nice |
| Cobol | 1 | Oh dear |

This results in this:

APL 99 Really great
Python 70 Nice
Cobol 1 Oh dear

You can specify column headers via the left argument. Naturally the length of the left argument must match the number of columns in the matrix. You can use leading and trailing : in order to define column alignment.

Note that any | in the matrix is automatically escaped except when it appears in code:

      ch←'Lang' 'Prod:Rank' ':Comment:'
      M←('APL' 99 'Really great')('Python' 70 'Nice')('Cobol' 1 'Oh|dear')
      ⎕←MarkAPL.Matrix2MarkdownTable M
| Lang | Prod:Rank | Comment |
|-|-:|:-:|
| APL | 99 | Really great |
| Python | 70 | Nice `|`|
| Cobol | 1 | Oh\|dear |

This results in this:

Lang Prod:Rank Comment
APL 99 Really great
Python 70 Nice |
Cobol 1 Oh|dear

Notes:

8. Problems

8.1. Bugs

Please report any bugs to kai@aplteam.com. I appreciate:

8.2. Unexpected results

Before reporting a bug please check carefully your Markdown. More often than not mistakes in the Markdown are causing the problem.

If you cannot work out why it goes wrong report it to me – see the previous topic for how to report a problem.

This document refers to version 5.0.0 of MarkAPL.

Kai Jaeger ⋄ APL Team Ltd ⋄ 2018-10-17


Footnotes

  1. The Markdown editor Meddy on GitHub:
    https://github.com/aplteam/Meddy

  2. Wikipedia definition of abandonware:
    https://www.wikiwand.com/en/Abandonware

  3. The CommonMark specification:
    http://spec.commonmark.org/