BareGit
You are about to implement a markdown processor in C++ called
“MacroDown”. The main feature besides markdown is it will support
macros (TeX-like). The processor will output standard HTML.

The processor will implement the CommonMark syntax. Specifically you
should implement the parsing strategy outline in
https://spec.commonmark.org/0.31.2/#appendix-a-parsing-strategy.
However with this processor, you should convert all the all the syntax
elements (emphsized text, bold text, quotes, code, etc.) into macros,
and contruct a syntax tree. At the last step, evaluate the macros into
HTML. A macro is basically a function that can have arguments, and can
expand into text and more macros. For example, I can define a macro

```
%def[my_macro]{t1, t2}{It’s a %em{%t1} that is %t2.}
```

This code should define a macro called `my_macro`. It takes two
arguments, `t1` and `t2`, and it expand the body with these arguments.
If I write in my document `%my_macro{test}{good}`, it should expand
into `It’s a %em{test} that is good`, in which there’s another macro,
`em`, which will in turn expand into something else. Of course `def`
is a special case that is used to define macros.

In short, the syntax to define a macro should be
```
%def[name]{arg1, arg2, ...}{body}
```
The syntax to call a macro should be
```
%name{arg1}{arg2}...
```

In order for a CommonMark document to parse into HTML in this way, we
will need to have a “standard library” of macros that implements the
basic markdown constructs like headings, emphasis, etc.

Note that a MacroDown document will mostly look like a normal
CommonMark file, but a writer could also write macros definitions and
calls in it.

Naming style:

* `CapCase` for classes and types
* `snake_case` for variables
* `UPPER_CASE` for global constants
* `camelCase` for functions. If the function name is just one word,
  use lower case.
* All file names should be `snake_case`.

Unicode should be handled properly.

Use Cmake as the build system. Exmaple cmake file:
https://github.com/MetroWind/planck-blog/blob/master/CMakeLists.txt.

The syntax tree should have a function to iterate over all nodes.

The library should expose an interface that allows the user to render
a document with 2 steps: The first step will expose the syntax tree
(the root node), and the second step will render the syntax tree into
HTML.

## Custom markups

An interface for the user to define custom markup should be exposed.
The user will be able to define two kinds of markup:

1. A markup starts with a prefix. For example, the user can define `#`
   as a prefix, then in `It’s a #test.`, `#test` is the part that’s
   being marked up. In other words, for a prefix markup, the text
   that’s marked up begin with the prefix, and ends with any
   whitespace or punctuation (excluding the underscroe `_`, dash `-`,
   at-sign `@` and dot `.`).
2. A delimited markup. This kind of custom markup has starts with a
   character and ends with the same delimiting character. No
   whitespace or punctuation are allowed in between, except for the
   underscore `_` and the dash `-`. If whitespace or punctuation is
   found between the delimiting character, it’s not a markup. For
   example, suppose the user defines `:` to be a delimiter, then in
   `it’s a :test:.`, `:test:` is the part that’s being marked up;
   however in `it’s a :test.:`, nothing is marked up.

In both cases, the special character is a single unicode character,
which could be multi-byte. The markup is defined with a function, and
is converted into a macro with one argument, the argument being the
text being marked up, without the special character. The first kind is
defined with `definePrefixMarkup(const std::string& prefix, const
std::string& macro_name)`. The second kind is defined with
`defineDelimitedMarkup(const std::string& delimiter, const
std::string& macro_name)`. In the example with `#` defining a prefix
markup, the defining call would be

    definePrefixMarkup("#", "tag");

which would transform `#test` into a macro `%tag{test}`.