marky
Quickstart Source2021-09-09
Abstract – This is the source code of the
marky
Documentation. This document represents themarky
source code before processing python code embedded into the document itself. For documentation and download please refer to themarky
repository.
---
title: marky Documentation
author: lehmann72021-09-09
date: -citations: true
link/marky.bib
bibliography: data-includes--pdf: >
header\hypersetup{colorlinks=false,
={0 0 0},
allbordercolors={/S/U/W 1}}
pdfborderstyle-includes--html: >
header<style>* { box-sizing: border-box; }</style>
-cleveref: true
xnos-capitalise: true
xnos11pt
fontsize: 10,8]
figsize: [300
figdpi:
version: undefined
---
!!! ../Makefile aux
!!! ../marky.py aux
!!
```import subprocess
= "Markdown"
MD = "`marky`"
M = "`Makefile`"
MF = "`marky.py`"
MP = "marky.py"
Mp = "`pandoc`"
P = "`numpy`"
NU = "`matplotlib`"
PL = "RMarkdown"
R = "Quarto"
Q = "`"
BT = "`_()`"
P1= "`__()`"
P2= subprocess.check_output(["python", "marky.py",
version "--version"]).decode("utf-8").strip()
```
---
> **Abstract** -- `!M` is a preprocessor for `!MD` using Python.
> `!M` is inspired by [pandoc](https://www.pandoc.org/),
> [`!R`](https://rmarkdown.rstudio.com/), [`!Q`](https://quarto.org/).
> This document is created using `!M` (Version `!version`) and
> contains examples which illustrate the generation of
> document content for `html` and `pdf` and the dynamical adjustment
> of `!MD` text during preprocessing based on `python` code.
> The full raw `!M` source code of this documentation appended at
> the end. The `marky` source code of this document can be read
> [here](marky-src.html).
> For more information please refer to the
> [`marky` repository](https://github.com/lehmann7/marky),
> [`marky` quickstart](quickstart.html) or the
> simple [`marky` example](example.html).
---
# Introduction
!M` is a `!MD` preprocessor which transforms a `!MD` document
`!M` implements new markup which controls the execution
using python. `and the generation and manipulation of `!MD` text.
of python code !M` quickstart can be found [here](quickstart.html) and a very
The `!M` example can be found [here](example.html).
simple `
!M` only depends on `!P` and `pyyaml`. `!P` is used for rendering
`!MD` into `html` and `pdf`. `!P` supports various `!MD`
the `for scientific writing using equations, figures,
extensions allowing and corresponding referencing mechanism for the latter.
tables, citations is used for parsing meta data in the front matter of the
`pyyaml` !MD` text if it is present.
`
for creating `html` or `pdf` using `!M`
Workflow
1. user writes a `!MD` text file and places it in `md/*.md`
with the extension `.md`. the `!MD` text contains
directory !M` markup which executes python code and manipulates
special `!MD` text.
the `
2. `!M` transforms the files in `md/*.md` into regular `!MD` text
and places the transformed files in `build/*.md`. The transformed text
!MD`, and placeholders for format dependent
only contains regular `for `html` and `pdf`.
output
3. before rendering `!M` replaces placeholders for format dependent
with content creating a temporary file which only contains
output !MD` text for `html` and `pdf` documents according to
regular `!P` `!MD` specification.
`
4. the regular `!MD` text in the files `build/*.md` is rendered into
and `pdf` using `!P`.
`html`
in `!MP` and a `!MF`. The
The three steps are implemented !M` markup and shows
following document describes the special `!MP` and the `!MF`.
how to use `
---
# Related Work {#sec:related}
and writing usually typesetting systems or
For scientific reporting
complicted WYSIWYG editors are used. In order to simplify the writingand frameworks have been developed.
different approaches
* [`!P`](https://www.pandoc.org/),
* [`!R`](https://rmarkdown.rstudio.com/)
* [Quarto](https://quarto.org/)
* [Scientific `!MD`](https://jaantollander.com/post/scientific-writing-with-markdown/)
* [Technical `!P`](https://lee-phillips.org/panflute-gnuplot/)
!P` as an underlying framework for document
All of those approaches use `!P` is a powerful framework for conversion between different
conversion. `!M`, `html` and `pdf`. `!P` implements an
document formats including `in which different document formats can be imported and
own internal AST, !P` allows
exported. Using this intermediate document representation, `
to modify document using filters, which operate on the AST. Filtersin [`haskell`](https://pandoc.org/filters.html),
can be written //pandoc.org/lua-filters.html) and
[`lua`](https://pandoc.org/filters.html#but-i-dont-want-to-learn-haskell).
[`python`](https:
as `!R` and `!Q` are integrated frameworks, which additionally
Where !M` depends on `!P` and `pyyaml`
depend on `knitr`, `RStudio`, `Jupyter`, `!M` natively only supports executable python code blocks, however,
only. `for
other languages can be executed using wrappers, which are available
other languages.
---
# `!M` Features {#sec:features}
!M` implements following features using an simple `!MD`-style syntax.
`
1. read `!MD` meta data from front matter,
@sec:metadata
see
```md---
<key>: <value>
---
```
2. execute and hide/show python code blocks inside `!MD` text,
@sec:block
see
```md!BT*3`!
`<python_code_shown>
!BT*3`
`
!BT*3`!!
`<python_code_hidden>
!BT*3`
`
```
3. generate `!MD` text using python code, see @sec:mdprint
```md!BT*3`!
`"<markdown_text>")
_("""
__( <markdown_text>
<markdown_text>
<markdown_text>
""")
!BT*3`
`
```
4. format output of python variables into `!MD` text,
@sec:format
see
```md\!<python_variable>`
Output into text: `
```
5. output the result of python expressions into `!MD` text,
@sec:inline
see
```md\!<python_expression>`
Output into text: `
```
6. include `!MD` text, make dependencies and forward meta data,
@sec:include and !@sec:incmeta.
see
```md!!! include_file.mdi
```
7. format links in `html` and `pdf` documents for
format,
referencing external documents of the same @sec:formlink.
see
```md/pdf document](path/to/file.???)
[Format Link to html
```
8. use format codes in order to inject format specific
in `html` and `pdf` documents,
code @sec:formcode.
see
```md!BT*3`!
`class myfmt(fmtcode):
def html(self):
"<HTML_CODE>")
_(return """
<MORE_CODE>
<MORE_CODE>
<MORE_CODE>
"""
def pdf(self):
"""
__( {TEX_CODE}
{TEX_CODE}
{TEX_CODE}
""")
= myfmt()
fmtc !BT*3`
`
\!fmtc()`
Format dependent output: `
```
---
# Scientific Writing in `!MD` {#sec:panmd}
!MD`](https://pandoc.org/MANUAL.html#pandocs-markdown) is a markup
[`for technical writing, with emphasis on readability. `!MD`
language in many formats including `html` and `pdf` by using
can be rendered !P`](https://pandoc.org/) for example.
[`
!MD` extensions of `!P` a sufficient structure for
Using various `!MD` syntax.
writing scientific documents can be reflected using `!M` uses the following `!P` `!MD` extensions.
`* parsing extensions
* [all_symbols_escapable](https://pandoc.org/MANUAL.html#extension-all_symbols_escapable)
* [intraword_underscores](https://pandoc.org/MANUAL.html#extension-intraword_underscores)
* [escaped_line_breaks](https://pandoc.org/MANUAL.html#extension-escaped_line_breaks)
* [space_in_atx_header](https://pandoc.org/MANUAL.html#extension-space_in_atx_header)
* [lists_without_preceding_blankline](https://pandoc.org/MANUAL.html#extension-lists_without_preceding_blankline)
* styling extensions
* [inline_code_attributes](https://pandoc.org/MANUAL.html#extension-inline_code_attributes)
* [strikeout](https://pandoc.org/MANUAL.html#extension-strikeout)
* structuring extensions
* [yaml_metadata_block](https://pandoc.org/MANUAL.html#extension-yaml_metadata_block)
* [pipe_tables](https://pandoc.org/MANUAL.html#extension-pipe_tables)
* [line_blocks](https://pandoc.org/MANUAL.html#extension-line_blocks)
* [implicit_figures](https://pandoc.org/MANUAL.html#extension-implicit_figures)
* [abbreviations](https://pandoc.org/MANUAL.html#extension-abbreviations)
* [inline_notes](https://pandoc.org/MANUAL.html#extension-inline_notes)
* code injection
* [raw_html](https://pandoc.org/MANUAL.html#extension-raw_html)
* [raw_tex](https://pandoc.org/MANUAL.html#extension-raw_tex)
!P` supports
`//pandoc.org/MANUAL.html#extension-tex_math_dollars)
[equations](https:and single-line in tex-style using `$...$` and `$$...$$`,
rendered inline //pandoc.org/MANUAL.html#citations)
[bibliography](https:--citeproc` option,
using the `//pandoc.org/MANUAL.html#extension-header_attributes)
[section numbering](https:--number-sections` option and
using the `//pandoc.org/MANUAL.html#option--toc)
[table of contents](https:--table-of-contents` option.
using the `
!P` supports [`xnos`](https://github.com/tomduck/pandoc-xnos) filters
`for referencing document content like
//github.com/tomduck/pandoc-fignos#usage),
[figures](https://github.com/tomduck/pandoc-eqnos#usage),
[equations](https://github.com/tomduck/pandoc-tablenos#usage),
[tables](https://github.com/tomduck/pandoc-secnos#usage)
[sections](https:--filter pandoc-xnos` option.
by using the `"Fig.", "Sec.", "Eq."
`xnos` integrates clever references, which means and "Tab." are added automatically to the corresponding element.
is to be omitted, the reference can be written as
If the prefix \!@ref:label`.
`
**Example**
```md## Referenced Section {#sec:label}
is a reference to @sec:label.
This
{#fig:label}
xgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg
is a reference to @fig:label.
This
|B |C |D
A ---|---|---|---
000|111|444|555
222|333|666|777
is the caption {#tbl:label}
Table: This
is a reference to @tbl:label.
This
\mbox{e}^{\mbox{i}\pi}+1=0$${#eq:label}
$$
is a reference to @eq:label.
This
is a citation [@Muller1993].
This
```
file `marky.bib` is specified in the meta data in the front
The !MD` text and contains the following article.
matter of the `
```bibtex!!! ../data/marky.bib raw
```
**Output**
## Referenced Section {#sec:label}
is a reference to @sec:label.
This
{#fig:label}
is a reference to @fig:label.
This
|B |C |D
A ---|---|---|---
000|111|444|555
222|333|666|777
is the caption. {#tbl:label}
Table: This
is a reference to @tbl:label.
This
\mbox{e}^{i\pi}+1=0$${#eq:label}
$$
is a reference to @eq:label.
This
is a citation [@Muller1993].
This
---
# `!MP` Command-Line Usage
## `!MP` Script Usage
!M` is supplied as a single-file script which contains the `!M`
`!MF` as well as the `!M` documentation `marky.md`, `marky.mdi`
`and `marky.bib`.
!MP` the script needs to be placed in a project
After downloading `
working directory `working_dir`. The script can be invoked using!Mp` or it can be executed using a
a python interpreter `python` `
shell:
```bash> cd working_dir
> chmod +x marky.py
> ./marky.py
```
is initialized in the `working_dir` using the `--init`
A new project !M` creates a directory tree for the project, which is
option. `in detail in @sec:project. The `!M` `!MF` and
explained and `marky.bib` are auto-generated
documentation `marky.md`, `marky.mdi` and placed inside the subdirs `md/` and `data/` in `working_dir`
accordingly.
```bash> cd working_dir
> ./marky.py --init
/Makefile
WRITE ./md/marky.md
WRITE ./md/marky.mdi
WRITE ./data/marky.bib
WRITE .
USAGE1. `make help`
2. `make all-html httpd`
3. `make all-pdf`
```
!M` renders the documentation using `!P` into `html` and
`and `pdf` documents can be rendered after
`pdf` using `make all`. `html` -pyyaml`, `pandoc` and `pandoc-xnos`
installing the dependencies `python-fignos`, `pandoc-secnos`, `pandoc-eqnos`, `pandoc-tablenos`).
(`pandocin the `!MF` help message in @sec:makefile.
The details are shown
## `!M` Project Structure {#sec:project}
!M` project has the following structure, which is auto-generated
A `in the project directory `working_dir` after invocation of
!Mp` `--init`.
`!!
```= ""
text for i in subprocess.check_output(["make",
"tree"]).decode("utf-8").split("\n"):
if i.startswith("#"):
+= i + "\n"
text
```
```!text`
`
```
all files `md/*.md` are transformed
By invoking `make all` /*.html` and `pdf/*.pdf` files. By
into corresponding `htmlis started in `html/`.
invoking `make httpd` a python web server
-generated project content goes into `md/*.md(i)` for
All user!MD` text and `!MD` include files and `data/*` for images,
`
bibliography, videos, html frames, etc...
**ATTENTION:** The files in the directories `build/*.md` are
**auto-generated**. All user-generated content `*.md` and `*.mdi`
/`. Invoking `make clean`
has to be placed inside the directory `mdall files in `html/`, `build/` and `pdf/`.
will delete
## `!M` Makefile Usage {#sec:makefile}
or `make help` in the project `working_dir` the
By running `make` !MF` help is shown.
`!!
```= ""
text for i in subprocess.check_output(["make",
"help"]).decode("utf-8").split("\n"):
if i.startswith("#"):
+= i + "\n"
text
```
```!text`
`
```
## `!M` Cheat Sheet
in the project `working_dir` the `!M` cheat
By running `make cheat` is shown, which presents a quick overview of `!M` special
sheet for execution of python code and manipulation of `!MD` text,
markup in @sec:features.
according to the features describes !!
```= ""
text for i in subprocess.check_output(["make",
"cheat"]).decode("utf-8").split("\n"):
if i.startswith("#"):
= i.replace(r".???", r".\???")
i = i.replace(r".html", r".???")
i += i + "\n"
text
```
```!text`
`
```
---
# `!M` Preprocessor Markup
## Yaml Meta Data in Front Matter {#sec:metadata}
is annotated in the front matter of a `!MD` text document.
Meta data in the first line with `---` and precedes all
The front matter must start ---`. The meta data is in `yaml` format.
other text being fenced by `is parsed using `python-pyyaml`. By default all meta
The `yaml` block is imported into the preprocessed document. If a meta
data with `-` the key is not exposed into the resulting
data key starts
front matter of the preprocessed document. All meta data keys will beas a local variable, unless the variable
exposed into the python scope all keys except
already exists. In the following exmample and `version` are copied into the preprocessed
`figsize`, `figdpi` !MD` document.
`
**Example**
```yaml
---
!title`
title: `
date: `Date`
author: `Author`-citations: `!link_citations`
link!bibliography`
bibliography: `-includes--pdf: >
header\hypersetup{
=false,
colorlinks={0 0 0},
allbordercolors={/S/U/W 1}}
pdfborderstyle-includes--html: >
header<style>* { box-sizing: border-box; }</style>
-cleveref: `!xnos_cleveref`
xnos-capitalise: `!xnos_capitalise`
xnos!fontsize`
fontsize: `!version`
version: `!figsize`
figsize: `!figdpi`
figdpi: `
---
```
The meta data fields//pandoc.org/MANUAL.html#metadata-variables),
[`title`, `date`, `author`](https:-citations`](https://pandoc.org/MANUAL.html#other-relevant-metadata-fields),
[`link//pandoc.org/MANUAL.html#citation-rendering) and
[`bibliography`](https:-includes`](https://pandoc.org/MANUAL.html#variables-set-automatically)
[`header!P` during document rendering. `fontsize` adjusts the
are processed by `in [`html`](https://pandoc.org/MANUAL.html#variables-for-html)
font size and [`pdf`](https://pandoc.org/MANUAL.html#variables-for-latex) documents.
-includes` field is used for underlining links in `pdf`
The `headerand `html` documents. The `xnos-cleveref` and `xnos-capitalise`
-xnos`](https://github.com/tomduck/pandoc-xnos)
fields are used by the [`pandocfor referencing
extensions //github.com/tomduck/pandoc-fignos#customization),
[figures](https://github.com/tomduck/pandoc-tablenos#customization),
[tables](https://github.com/tomduck/pandoc-secnos#customization) and
[sections](https://github.com/tomduck/pandoc-eqnos#customization).
[equations](https:
-includes` ends with `--pdf` and `--html`, which
The field `headerfor generation of `pdf` and `html`
specifies corresponding options !M` scans all meta data fields, and
documents. During make, `with `--pdf` and `--html` are selected and forwarded
fields which end !P` based on the format to be rendered. This was format dependent
to `in `!M` Markdown text.
meta data can be specified
is a user-defined field
The `version` field *`!version`*. `figsize` and
which shows the version of this document: in this document to control the figure size and
`figdpi` are used in the `!NU` and `!PL` example, see @sec:examples. The font
resolution is `!fontsize` and the @fig:figure1, !@fig:figure2_1,
size !@fig:figure2_2, !@fig:figure2_3 and !@fig:figure2_4 have a size of
!"x".join(str(i) for i in figsize)`cm. The font size applies to
`and figure text.
both document text
The values of meta data fields can be manipulated during include-` or `--`, as described in @sec:incmeta.
when being preceeded by `
## Python Code Blocks inside `!MD` Text {#sec:block}
!MD` text.
Python code can be executed during transformation of the `is directly written inside the `!MD` text and is fenced
Python code !BT*3` `` statement. The block needs to start with either
using the `` `\!` or `\!!`.
`* `\!`: The python code is executed and **shown** in the output.
* `\!!`: The python code is executed and **hidden** in the output.
```md!BT*3`!
`<python_code_shown>
!BT*3`
`
!BT*3`!!
`<python_code_hidden>
!BT*3`
`
```
from `!MD` front matter can be used as local variables in
Meta data in python code
python code blocks. The `import` statement can be used in order to access installed python packages. All code blocks
blocks for sharing functions and local variables.
span one large scope
Using the `print()` function the text will be printed to the consoleand **not** inside the resulting `!MD` text. In order to modify
!MD` text using `!M` during preprocessing, the `!P1` statement
the `@sec:mdprint.
has to be used, see
**Example**
!
```import numpy as np
def get_x(a=0):
return np.array([41 + a])
= 1
y
```
is a paragraph.
This
!
```= get_x(y)
x print("Hello Console! x is", x)
```
## Generation of `!MD` Text using Python Code {#sec:mdprint}
### The `!P1` Statement
Using the `print()` statement the text will be printed to the console.!P1` and `!P2` statements new `!MD` text can be
When using the `
inserted dynamically into the document during preprocessing.
**`!P1` Statement**
* `_(*args, sep=" ")`:
1. convert arguments to string
2. join arguments using `sep`
* `_(_, *args )`: append to previous output
* `_(_, *args, _)`: append to previous output and append next output
* `_( *args, _)`: append next output to this output
**`!P2` Statement**
* `__(arg, crop=True, shift="")`:
1. convert `arg` to string
2. crop and prepend `shift` string to each line
* `__(arg, _)`: append next output to this output
**Crop and Shift**
```pydef test():
"""
__( * List Level 1
* List Level 1
""")
"""
__( * List Level 2
* List Level 2
* List Level 3
""", shift=" "*4)
```
```md* List Level 1
* List Level 1
* List Level 2
* List Level 2
* List Level 3
```
**Example**
!
```+= 1
y f"""
__( * This is `marky` Version *{version}*.
* This is `marky` Version *{version}*.
""")
f"""
__( 1. This is `marky` Version *{version}*.
2. This is `marky` Version *{version}*.
""", shift=" "*4)
```
!
```"This", _)
_("is")
_(" one", _)
_(_, "line! not ending with \\")
_("this?")
_(
```
!
```f"Hello Markdown! x is **{x}** and y is *{y}*")
_(
```
### Indentation of the `!P1` Statement
!P1` statement needs to be indented according to the python program
The `and
flow (`for`, `while`, `if`, `else`, `try`, `with`, `def`, `class`) !MD` text into the document based
supports dynamic insertion of `and conditions.
on loops
**Example 1**
!
```"This is the **generated output**:")
_("")
_("> This is a *listing*:")
_(= ["zero", "one", "two", "three"]
text for i in range(10):
if i < 2:
f"> {i}")
_(elif i == 2:
= text[i]
j f"> {j}")
_(elif i == 3:
"")
_(elif i < 7:
f">> {' '*(i-4)}* {i}")
_(elif i == 7:
"")
_(else:
= i - 7
j = text[j]
k f"> {j}. {k}")
_(
```
**Example 2**
@tbl:table1 is generated using the following python clode block.
!
```= 13
n = ["*%s*", "**%s**", "~~%s~~", "`%s`",
dec r"$\times^%s$", "$\infty_%s$"]
"|".join("X"*n) + "\n" + "|".join("-"*n))
_(for i in range(n):
= [chr(ord("A")+(2*i+3*k)%26) for k in range(i+1)]
fill = [dec[(l+i)%len(dec)]%k for l, k in enumerate(fill)]
fill = list("0")*n
text >>1)-(i>>1):(n>>1)+(i>>1)] = fill
text[(n"|".join(text))
_(
```
is generated using code and the `!P1` statement. {#tbl:table1}
Table: Table
## Formatted Output of Python Variables {#sec:format}
!M` can output python variables inline into `!MD` text using
`\!VARIABLE` `` statement. `VARIABLE` can be any python variable
the `` `from a python code block or meta data field. The output can be
\!VARIABLE[:FORMAT]` `` statement according
formatted using the `` `<variable>[:<format>]}` implemented in the
to the python operator `{format()`](https://docs.python.org/3/library/string.html#formatstrings)
[`str.\!VARIABLE` `` statement is escaped
specification. The `` `\\!VARIABLE` ``.
using `` `
**Example**
!
```= int(1)
x = float(2.3)
y = 0
z = [1, 2, 3]
a = (4, 5)
b
```
```mdis a paragraph and x is `\!x:03d` and y is `\!y:.2f`.
This is: `\!a`, `\!b` and escaping works: `\\!z`.
Other content
```
is a paragraph and x is `!x:03d` and y is `!y:.2f`.
This is: `!a`, `!b` and escaping works: `\!z`.
Other content
## Output Results of Python Expressions {#sec:inline}
!M` outputs results of python expressions inline into `!MD` text
`\!EXPRESSION` `` statement. `EXPRESSION` can be any python
using the `` `
expression. The output can be formatted using the python\!EXPRESSION[:FORMAT]` `` statement according to the python operator
`` `<expression>[:<format>]}` implemented in the python
`{-strings](https://docs.python.org/3/reference/lexical_analysis.html#f-strings)
[`f`\!EXPRESSION` `` statement is escaped
specification. The `` `\\!EXPRESSION` ``.
using `` `
**Example**
```mdis a list with the numbers `\!", ".join([str(i) for i in a])`.
This is `\!get_x()` and escaping
The result of the function `get_x` \\!get_x(b[1])[0]`.
works: `
```
is a list with the numbers `!", ".join([str(i) for i in a])`.
This is `!get_x()` and escaping
The result of the function `get_x` \!get_x(b[1])[0]`.
works: `
## Include Statement and Make Dependencies {#sec:include}
!M` supports include of `!MD` text using the `\!!!` statement.
`\!!!` statement must be on a single line and follows the path
The `file. The path of the include file is relative to
of the include !MD` document which is processed. The paths of all
the root `and a `!MF` rule is created and
included files are collected in a file (path of output `!MD` text appended with `.mk`).
stored
\!!!` statement is escaped using `\\!!!`.
The `**cannot** be used in code blocks. `!M` `!MD`
The include statement and include files must have the
text must have the extension `.md`
extension `.mdi`
for parsing the include file.
The include statement supports flags
```md\!!! PATH/FILE.mdi FLAGS
```
**Flags**
* `aux`: reference as Makefile dependency, but do not process
* `nodep`: do not reference this file as Makefile dependency
* `raw`: the file is included as-is without any parsing
* `nometa`: meta data in front matter is skipped during parsing
* `nobody`: all Markdown text is skipped during parsing
* `nomarky`: include the `!MD` text without any `!M` processing
* `code`: only include hidden code blocks
* `code!`: include all code blocks
* `>>N`: increase the indentation using `N` tabs
* `>N`: increase the indentation using `N` spaces
* `#+N`: increase the level of ATX headings `#`. The headings are
!P` extensions
parsed according to `//pandoc.org/MANUAL.html#extension-blank_before_header),
([blank_before_header](https://pandoc.org/MANUAL.html#extension-space_in_atx_header))
[space_in_atx_header](https:
**Example**
```md\!!! marky.mdi #+2
file was included: `\!included` and $x=`\!x`$ and $y=`\!y`$.
The
```
!!! marky.mdi #+2
file was included: `!included` and $x=`!x`$ and $y=`!y`$.
The
file `marky.mdi` was loaded with shifting ATX headings by 2 which
The ##` has been added to the included section. The file contains:
means `
```md!!! marky.mdi raw >>1
```>>1`.
The unmodified source was loaded using the flags `raw
file `marky.md.mk` contains:
The
```Makefile/marky.md: \
build/marky.mdi
md
-marky
.PHONY: md-marky: build/marky.md
md
-marky
.PHONY: html-marky: html/marky.html
html
-marky
.PHONY: pdf-marky: pdf/marky.pdf
pdf
```
## Include Statement and Meta Data Import {#sec:incmeta}
\!!!` loads and parses an `*.mdi` include file.
The include statement `in the front matter of the document also is loaded
The `yaml` meta data and parsed if the `nometa` flag is not specified in the include
and the included document have the
statement. Assuming the root document
following meta data.
**Root Document**
```yaml
---
10
width: 20
height:
serial: none
parameter: value
text: abc
---
\!!! include.mdi
```
**Included Document**
```yaml
---
30
depth: -: A
serial--: default
parameterdef
text:
---
```
By default the values of meta data keys are appended. When a metais preceded by `-` the included key replaces the present
data key if it is preceded by `--` the included key is skipped if the
key, is present in the root document.
meta data key already in
Given the example above, the resulting meta data !MD` text looks as follows.
the front matter of the preprocessed `
**Preprocessed Document**
```yaml
---
10
width: 20
height: 30
depth:
serial: A
parameter: value|
text:
abcdef
---
```
## Format Links for `html` and `pdf` Documents {#sec:formlink}
When writing multiple documents, often documents are referenced
between each other using links. In order to refer to externaland `pdf` documents the `!MD` link statement is used.
`html`
```md/to/file.html)
[Link Caption](path/to/file.pdf)
[Link Caption](path
```
in the URL, the documents can be referenced
When using relative paths !M` `!MD` text
according to the directory tree of the source `/*/*.md`. However, the resulting link will be a path relative
`md/` for `html` documents and relative to `pdf/`
to the directory `htmlfor `pdf` documents. As all `html` and `pdf` documents are kept in
for rendering
separate directories, one link statement cannot be used and `pdf` with consistent paths in the link statement.
`html`
!M` format link statement `.???`, the file extension
By using the `in the links is replaced depending on the output format
in consistent links for `html` and `pdf`
resuling format link statement can be escaped using `.\???`.
documents. The
**Example**
```md
[Link to this Document](marky.???)
```
[Link to this Document](marky.html)
## Format Codes for `html` and `pdf` Documents {#sec:formcode}
for `html` and `pdf` documents, the
Often when writing markdown format needs to be adjusted according to the format. `!P` `!MD`
all common Markdown into `html` and `pdf`.
already renders !M` supports format specific tweaking using format codes.
`
format specific code, `html` code or `tex` code
In order to inject for `pdf` documents, the `fmtcode` class is used. The `fmtcode` class
-operator `()` and `attr`-forwarding to the
implements the `call`class members `html` and `pdf`. Each call to the `fmtcode` class
is disptached inttoo the `html` and `pdf` members, which either can
or class methods.
be member variables
!M` processes all format codes for each
During preprocessing, `format `html` and `pdf` and caches the output. When rendering
in one particular format using `!P`, `!M` only uses
the Markdown format.
the results of the corresponding for `pdf` as well as
Additional `tex` packages have to be included and style sheets for `html` using the
JavaScript -includes--pdf` and `header-includes--html`
meta data fields `header
respectively.
format specific code, either the `!P1` statement can
For returning the @sec:mdprint **or** the `return` statement can be used.
be used
If both statements are mixed, the output which had been returnedwith the `!P1` statement.
will be appended to the text generated
**Example: Functions and Variables**
!
```class fmt_test1(fmtcode):
def html(self):
"<sup>HTML in")
_(return "superscript</sup>"
def pdf(self):
r"""
__( ${}_{\mbox{PDF in subscript}}$
""")
= fmt_test1()
test1 = fmtcode(
test2 ="<sub>HTML in subscript</sub>",
html=r"${}^{\mbox{PDF in superscript}}$"
pdf
)= fmtcode(html="HTML", pdf="PDF")
test3
```
```mdformat code `\\!test3()` returns the format of
The \!test3()`.
the document: `* `\!test1()`
* `\!test2()`
```
format code `\!test3()` returns the format of
The !test3()`.
the document: `* `!test1()`
* `!test2()`
**Example: Classes**
!
```class html:
def test1(self):
"<sup>HTML in")
_(return "superscript</sup>"
def test2(self):
return "<sub>HTML in subscript</sub>"
def test3(self):
return "HTML"
class pdf:
def test1(self):
r"""
__( ${}_{\mbox{PDF in subscript}}$
""")
def test2(self):
return r"${}^{\mbox{PDF in superscript}}$"
def test3(self):
return "PDF"
= fmtcode(html=html(), pdf=pdf())
fmtc
```
```mdformat code `\\!fmtc.test3()` returns the format of
The \!fmtc.test3()`.
the document: `* `\!fmtc.test1()`
* `\!fmtc.test2()`
```
format code `\!fmtc.test3()` returns the format of
The !fmtc.test3()`.
the document: `* `!fmtc.test1()`
* `!fmtc.test2()`
---
# `!M` `!MD` Examples {#sec:examples}
## JavaScript in `html` and Placeholder in `pdf`
!MD` text for `html` output, the user often wants
When creating `
interactivity using widgets like sliders, check boxes, drop down boxes
etc. However, when exporting into `pdf` those elements need to bewith non-interactive placeholders. In order to develop a single
replaced !MD` document, which can be rendered in `html` with interactive
`and into `pdf` with placeholder, the `!M` format codes can be
elements @sec:formcode. The following example defines a
used, see <input type="range">` and two `<spans>` with `id="myval"` and
`="myres"`, in order to update the value of $y=sin(x)$ in `html`. For
`idand the value range is shown.
`pdf` output the equation
**Example**
!
```class Range(fmtcode):
def html(self):
"""
__( $x\in [0$ <input type='range' value='0' min='0' max='100'
onchange="
document.getElementById('myval').innerHTML = this.value;
document.getElementById('myres').innerHTML =
Math.sin(this.value);"> $100]$
""")
def pdf(self):
return "$x\in[0,100]$"
class Formula(fmtcode):
def html(self):
"""
__( $y=sin(x)=$ <span id="myres">0.000</span>
with $x=$ <span id="myval">0</span>
""")
def pdf(self):
return "$y=sin(x)$"
= Range()
Ra = Formula()
Fo
```
```mdand $y$ are related to each other by `\!Fo()`.
$x$
in the range `\!Ra()`.
$x$ must be
```
and $y$ are related to each other by `!Fo()`.
$x$
in the range `!Ra()`.
$x$ must be
## Generate a Figure on-the-fly during Preprocessing
This section illustrates how python modules can be used to createis placed inside the `data/`
document content. Document content !M`
directory of the current project working directory (refer to `@sec:project)
project structure,
{#fig:figure1}
`
!NU`](https://www.numpy.org) and [`!PL`](https://www.matplotlib.org)
[`for mathematical computing and plot
are powerful python modules @fig:figure1
generation. The following example shows how to generate !NU` and `!PL` and include it into the document.
using `
**Example**
!
```import numpy as np
import matplotlib.pyplot as plt
= lambda A: chr(ord(u"\u0391") + ord(A) - ord("A"))
GREEK = lambda a: chr(ord(u"\u03b1") + ord(a) - ord("a"))
greek = lambda xy: tuple(i/2.54 for i in xy)
cm2inch = int(fontsize[:-2]) # convert to int
fontsize = cm2inch(figsize) # convert from cm to inch
figsize = {
params 'figure.figsize': figsize,
'legend.fontsize': fontsize,
'axes.labelsize': fontsize,
'axes.titlesize': fontsize,
'xtick.labelsize': fontsize,
'ytick.labelsize': fontsize,
'font.family': 'Times New Roman'
}
plt.rcParams.update(params)= np.random.rand(50)
x = np.random.rand(50)
y
plt.figure()="Random Coordinates")
plt.scatter(x, y, label= "".join([greek(i) for i in ["a", "b", "c", "d"]])
text =(0.5,0.5), xytext=(0.25,0.25),
plt.annotate(text, xy=dict(arrowstyle='->',lw=1.5))
arrowprops"Two Random Datasets")
plt.title(r"Data #1 - $\mathdefault{%s_1}$" % GREEK("C"))
plt.xlabel(r"Data #2 - $\mathdefault{%s_2}$" % GREEK("D"))
plt.ylabel(
plt.grid()
plt.legend()
plt.tight_layout()"build/figure1.png", dpi=figdpi)
plt.savefig("all")
plt.close(
```
```md{#fig:figure1}
```
## Generate a Sequence of Figures on-the-fly
complex figures can be
This section illustrates how a sequence of !NU` and `!PL` and how the figures are formatted
generated using `and referenced using `!M`.
using python
in four different setups with
Suppose one experiment which can be run for $\lambda=$
different values !", ".join(["(%d) $%.2f$nm"%(k, 125.33*k) for k in range(1, 5)])`.
`1)--(4), two additional
Each run of the experiment using setup (\varepsilon$ and $\alpha$ are varried between
parameters $10.2\ldots30.6\%$ and $0.1\ldots0.3$Hz respectively.
$
for the setups (1)--(4) are summarized
The results of the experiments in the @fig:figure2_1, !@fig:figure2_2, !@fig:figure2_3 and
!@fig:figure2_4.
**Example**
!
```= 100
n = u"\u03b1"
alpha = u"\u03b5"
epsilon = u"\u03bb"
lamda = lambda x, a, b: a*(np.sqrt(x)+b*np.sin(x*b))
f = lambda x, a ,b, c: np.fabs(f(x, a, b) - f(c, a, b)) + c
g = np.zeros((n-1, 3, 3, 4), dtype=np.float32)
dat = ["red", "green", "blue"]
cols = ["o", "x", "<"]
mark = np.array([50.*x/n for x in range(1, n)], dtype=np.float32)
x for k, c in enumerate([10., 20., 30., 40.]):
for i, a in enumerate([1, 2, 4]):
for j, b in enumerate([0.2, 0.4, 0.6]):
= g(x, a, b, c)
dat[:, i, j, k]
plt.figure()for j in range(3):
for i in range(3):
= "%s=%.1f%%" % (epsilon, (i+1)*10.2) \
label_i if j == 0 else None
= "%s=%.1fHz" % (alpha, (j+1)/10.) \
label_j if i == 0 else None
= dat[:, i, j, k].flatten()
y =cols[i], lw=0.75, label=label_i)
plt.plot(x, y, color1::4], y[1::4], color="black",
plt.scatter(x[=mark[j], lw=0.5, s=5, label=label_j)
marker= k + 1
k = k*125.33
kval "Experiment Setup #%d: %s=%.2fnm" % (k, lamda, kval))
plt.title("Time [s]")
plt.xlabel("Intensity [kg/s³]")
plt.ylabel(
plt.grid()
plt.legend()
plt.tight_layout()"build/figure2-%d.png" % k, dpi=figdpi)
plt.savefig("all")
plt.close(f"""
__( {{#fig:figure2_{k}}}
""")
```
---
*Thanks for reading, please try `marky`.*
---
# References