MINT

5 min read Original article ↗

MINT Is Not TeX

MINT is a document markup language designed to be extensible and informative for humans.

As in LaTeX, grouping of text in MINT is done using braces. However, unlike TeX, the special character in MINT is not \ but @. Therefore, every command starts with @.

MINT doesn’t have any predefined commands. Even basic document commands like those for paragraphs, titles, or text decorations are not predefined. Commands can be defined by the user in a (YAML) schema file.

Why

I tried many systems for writing and publishing content: TeX and TeX like languages, markup languages (with Pandoc and filters), static site generators, etc... Without doubt, each solution I tried had some benefits, but each was hard to work with when I wanted to implement custom processing. Each solution required from me to learn a new programming language, or to get acquainted with all quirks in the system (cough, cough, Hugo).

When I started writing my programming book, I reconsidered many options, and in the end decided it would be easiest to define my own markup language, with commands designed specifically for the content of my book. It may sound like a lot of work, but AST traversal in favorite language is much simpler than spending hours reading documentation and forum posts looking for a solution of a simple problem.

No matter which system you use, with a project large enough, some of the processing will have to be done with custom scripts. Instead seeking for a declarative system that will cover all use cases, why not let users implement all processing logic in the language they know the best? MINT will provide just the most boring part: a parser.

Of course, MINT is not the first markup language that requires author to program the document. I know that Pollen has similar ideas as MINT. However, it is tied to Racket programming language, and MINT is independent from programming languages. Other difference is that MINT explictly avoids mixing markup and processing code.

Syntax

document := element*
element := text | command
  • text := (textChar | escapedChar)+
    • textChar := CHAR - ("@" | "{" | "}")
    • escapedChar := "@@" | "@{" | "@}"
  • command := "@" label id? argument*
    • label := ALPHA (ALPHANUM | "_" | "-")*
    • id := "#" label
    • argument := "{" element* "}"

Simple grammar allows for easy implementation of fast parsers.

Example

Following example illustrates how Euclid's Elements could be written in MINT so semantics of the text is preserved. Example has one definition, and one proposition that references that definition. Arguably, the schema for this example could define more or fewer commands. We could replace multiple commands with a single command for math expressions, or we could add commands for proof statements. This demonstrates the strength of MINT, the user defines only the commands they need.

@title{Triangles}

@definition#triangles{Of trilateral figures, an @term{equilateral triangle} is that which has its three sides equal, an @term{isosceles triangle} that which has two of its sides alone equal, and a @term{scalene triangle} that which has its three sides unequal.}

@proposition{
To construct an equilateral triangle on a given finite straight line.
}{
Let @line{AB} be the given finite straight line. It is required to construct an equilateral triangle on the straight line @line{AB}.

Describe the circle @circle{BCD} with center @point{A} and radius @segment{AB}. Again describe the circle @circle{ACE} with center @point{B} and radius @line{BA}. Join the straight lines @segment{CA} and @segment{CB} from the point @point{C} at which the circles cut one another to the points @point{A} and @point{B}.

Now, since the point @point{A} is the center of the circle @circle{CDB}, therefore @segment{AC} equals @segment{AB}. Again, since the point @point{B} is the center of the circle @circle{CAE}, therefore @segment{BC} equals @segment{BA}.

But @segment{AC} was proved equal to @segment{AB}, therefore each of the straight lines @segment{AC} and @segment{BC} equals @segment{AB}.

And things which equal the same thing also equal one another, therefore @segment{AC} also equals @segment{BC}.

Therefore the three straight lines @segment{AC}, @segment{AB}, and @segment{BC} equal one another.
@reference{triangles}

Therefore the triangle @triangle{ABC} is equilateral, and it has been constructed on the given finite straight line @segment{AB}.
}

You can also look at example with schema in the project's repository

Content written with MINT

MINT is created for producing Programming in Haskell book (source). The first MINT compiler was written exclusively for this purpose. It is implemented in Haskell and supports a fixed schema.

This website is also written in MINT.

Status of the projects

MINT is currently in heavy alpha, which means that a working Go program exists that loads MINT files and a YAML schema, and outputs a textual format generated by simple substitutions. It can also export the parsed file to JSON. A parser generator is not yet implemented, nor are any language bindings.

If you like the idea behind MINT, feel free to reach out via GitHub or email (mint at ubavic dot rs). Your interest will motivate me to continue working on this project.

MINT's code is hosted on GitHub.