[TOC]
----------------------------------------------------------------------------------------------------
# About plugins
Plugins automate and simplify typical tasks and make the documentation more structural and easy
to use.
The main approach used by this program is no interference in the Markdown syntax. So the
documentation content must be readable in plain text even without processing by this program.
Plugins provide extra possibilities for the templates processing and visualization.
See [here](#argument_file_example) for an example of how plugins are defined in
the *argument file*.
----------------------------------------------------------------------------------------------------
# "relative-paths" plugin
**Motivation**
The program generates static HTML pages that reference other pages and resources like CSS and
pictures. The generated HTML pages may be located in different places of the project structure,
so the same resources must be referenced differently from different pages.
In the following example:
````shell
$ tree -L 2 --charset=ascii --dirsfirst
.
|-- doc
| |-- about.html
| `-- styles.css
|-- pict
| `-- logo.png
`-- readme.html
````
the reference to `styles.css` is:
- `doc/styles.css` from the `readme.html` page;
- and `styles.css` from the `about.html` page.
This plugin automatically recalculates relative paths for certain pages depending on their location
and avoids manual definition of these paths for every page individually. It also allows
substitution of such paths inside the documents.
**Definition**
Here's an example of the plugin definition:
````json
{
"documents": [
{ "input": "readme.txt", "output": "readme.html", "title": "Home" },
{ "input": "doc_src/about.txt", "output": "doc/about.html", "title": "About" }
],
"plugins": {
"relative-paths": {
"markers": ["path"],
"paths": {
"resource_path": "doc/",
"pict": "doc/pict/"
}
}
}
}
````
This is the new syntax. The previous syntax (that doesn't support substitution inside documents)
is also supported:
````json
"relative-paths": { "resource_path": "doc/" }
````
In this example, `resource_path` and `pict` are path *codes*, and the corresponding values are
paths themselves.
The plugin considers the paths and the current page location being relative to the
same location, that is the program invocation current directory in this case. When it
calculates the path with the code `resource_path` then:
- for the page `readme.html`, it'll return `doc/`;
- for the page `doc/about.html` it'll return `""` (empty path, as they are located in the same
directory).
**Usage**
Include the following _tag_ to the template:
````html
````
That's it. When a document using this template is generated, this tag will be replaced with
the desired path.
For substitution inside a document insert the text like this:
````

````
After the page is generated this fragment will look like this:
For page `readme.html` | For page `doc/about.html`
------------------------|--------------------------
`` | ``
----------------------------------------------------------------------------------------------------
# "page-flows" plugin
**Motivation**
Sidebar provides quick access to different project pages. It's often very helpful to put a
sequence of pages that are intended to be read in order. Doing it manually is pretty
cumbersome and error-prone.
This plugin defines such pages sequences and and provides them for easy manipulation in templates.
**Definition**
!!! note
You may want to also look at the new syntax described
[here](#page_flows_new_syntax).
In the `"plugins"` sections:
````json
{
"documents": [
{ "input": "page1.txt", "output": "page1.html", "title": "Page 1" },
{ "input": "page2.txt", "output": "doc/page2.html", "title": "Page 2" },
{ "input": "page3.txt", "output": "doc/page3.html", "title": "Page 3" }
],
"plugins": {
"page-flows": {
"sidebar": [
{ "link": "page1.html", "title": "Page 1" },
{ "link": "doc/page2.html", "title": "Page 2", "class": "align_right" },
{ "link": "doc/page3.html", "title": "Page 3", "highlight": true },
{ "link": "www.google.com", "title": "Search", "external": true }
]
}
}
}
````
Here we see the page flow `sidebar` that contains four link definitions. Each link definition
has main attributes `link`, `title`, `external`. Also other arbitrary attributes (like `class`
and `highlight`) may be added and then used in the templates (will be discussed below).
In the above example the three pages are defined twice. To avoid such repetition the page flows
may be defined directly in the `"documents"` section:
````json
{
"documents": [
{ "input": "page1.txt", "title": "Page 1", "page-flows": ["sidebar"] },
{ "input": "page2.txt", "title": "Page 2", "page-flows": ["sidebar"] },
{ "input": "page3.txt", "title": "Page 3", "page-flows": ["sidebar"] }
],
"plugins": {
"page-flows": {}
}
}
````
But the plugin itself must be activated to make it work. So even if all page flows are defined
in the `"documents"` section the plugin empty definition must be added to the `"plugins"`
section.
The `"page-flows"` document definition may be carried out to the `"default"` section (not
demonstrated here). Several page flows may be defined and a single page may be a part of several
page flows.
**Usage**
In a template, each page flow is accessible by its name (`sidebar` in this example) and
provides the following structured data:
Field | Description
----- | -----
`{{sidebar}}` | Iterable, returns [pages](#page_flow_page_structure)
`{{sidebar.previous}}` | Previous [page](#page_flow_page_structure) if exists
`{{sidebar.current}}` | Current [page](#page_flow_page_structure) if exists
`{{sidebar.next}}` | Next [page](#page_flow_page_structure) if exists
`{{sidebar.has_navigation}}` | Boolean, `true` if ether previous or next page exist
`{{sidebar.not_empty}}` | Boolean, `true` if contains at least one page
The page has the following structure:
Field | Description
----- | -----
`{{link}}` | The link that references the page. Recalculated for the current page
`{{title}}` | The title of the page
`{{external}}` | Boolean, external pages can never be current
`{{first}}` | Boolean, `true` if this is the first page in the sequence
`{{last}}` | Boolean, `true` if this is the last page in the sequence
`{{class}}` | Example of a custom arbitrary attribute
This data is calculated for every page that uses this template. So for the current page we can
know the previous and the next pages and render the navigations. Here's a simple example:
````
{{#sidebar.previous}}[PREVIOUS]{{/sidebar.previous}}
{{#sidebar.next}}[NEXT]{{/sidebar.next}}
````
!!! tip "Explanation"
`{{#sidebar.previous}}...{{/sidebar.previous}}` means that if `sidebar.previous` value
exists then the enclosed content is rendered. `sidebar.previous` value is a page and has
attribute `link` that is used in the rendered block.
Also for the current page we have the whole page sequence of the page flow and can render this
list in the sidebar. As we know which page or pages are current, we can highlight this links.
Here's a simplified example of how the sidebar items may be rendered:
````
````
!!! tip "Explanation"
`{{#sidebar}}...{{/sidebar}}` means that for each item in the `sidebar` value (that is
iterable) render the enclosed content. The items are pages and their attributes `link`,
`title` and `current` are used in the rendered block.
This documentation demonstrates pretty typical usage of this plugin. Also see the template
`doc_src/templates/multipage.html` and the _argument file_ `md2html_args.json` for more
understanding of correspondence between the plugin's definition and usage.
**New syntax**
In version 1.0.3 new syntax was introduced. The following example demonstrates the differences:
````json
. . .
"plugins": {
"page-flows": {
"sections": { "groups": ["sidebar"] },
"header": [
{ "link": "readme.html", "title": "Home" },
{ "link": "doc/content/sections/installation.html", "title": "Installation" },
{ "link": "doc/content/sections/usage.html", "title": "Usage" }
],
"useful_links": { "title": "Useful links", "groups": ["sidebar"], "items": [
{ "link": "https://mustache.github.io/", "title": "Mustache", "external": true },
{ "link": "https://json.org/", "title": "JSON", "external": true }
]}
},
}
. . .
````
The `useful_links` *page flow* is defined using the full syntax. The *page flow* has a title, a list
of groups and the content defined by the `items` attributes. The content definition is a list of
the pages just the same way as in the old syntax.
The `sections` *page flow* defines only the necessary attributes. The title is an empty string by
default. The content is empty initially and it may be defined in the `documents` section.
The `header` *page flow* uses the old syntax. Two syntaxes may be used in the same argument file
that makes the previously written documentation compatible with the new version of the program.
The purpose of this change is to remove specific elements from the
[templates]() and to avoid boilerplates. Now sidebar *page flows* may be
defined solely in the argument file and the template file in the documentation project
may be updated with the other one taken from the outside without subsequent customization.
Here's a sidebar block that may be defined for the above argument file fragment:
````html
{{#sidebar}}
{{#title}}
{{.}}
{{/title}}
{{#.}}{{title}}
{{/.}}
{{/sidebar}}
````
The `sidebar` variable contains a list of *page flows* for which it's defined (here there are
two such *page flows*). As each *page flow* now has a title then this title may be conditionally
rendered using the Mustache syntax. Elements `{{#.}}` and `{{/.}}` represent a current
*page flow* that here is represented as a number of links. Current links are highlighted
with the `selected` CSS class.
----------------------------------------------------------------------------------------------------
# "page-variables" plugin
**Motivation**
This plugin extracts variables from document source texts and provides these variables to be
used in the template.
**Definition**
````json
"plugins": {
"page-variables": {"variables": {"only-at-page-start": true} }
}
````
This means that variables will be extracted from the _page metadata_ blocks with marker
`variables` and only from those blocks that are the first non-blank text on the page.
This is the definition of the default marker so it may be simplified to `"page-variables": {}`,
and this is the recommended form.
**Usage**
For the above plugin definition the metadata blocks may look like:
````
````
The marker is `variables` and it is case insensitive. The variables are `title` and `noPageTitle`
and the tags `{{title}}` and `{{noPageTitle}}` will be replaced with the defined values when
this page is processed.
The _page metadata_ blocks will be removed from the source text if they are recognized and
processed by the defined markers.
The metadata content must be a valid JSON [].
!!! Note
Opening `` must not be used inside the metadata
section. Also consecutive hyphens `--` inside HTML comments may probably be a problem in some
browsers. In JSON strings, Unicode entities may be used to resolve these issues, i.e. string
`""` will be interpreted as `""`. Still, depending on the
page content and the context, opening and closing markers, even when escaped in JSON, may
cause unexpected result. Check it first if you really need to use these symbols.
----------------------------------------------------------------------------------------------------
# "variables" plugin
**Motivation**
This plugin defines variables that are not bound to certain pages. Actually such values may be
included directly into the template with no need of using this plugin. But when the same template
is used by several projects it may be convenient to define some template variable parts that
different projects may substitute using their _argument files_.
**Definition**
````json
"variables": {"logo": "" }
````
**Usage**
Tag (or tags) `{{{logo}}}` in the template will be substituted in the template. (Note that in
this case three pairs of curly braces are used to avoid HTML-escaping on substitution.)
----------------------------------------------------------------------------------------------------
# "index" plugin
**Motivation**
Some terms, abbreviations and other kind of keywords may be defined, described and mentioned
in different pages within the documentation. Searching such keywords may be hard,
especially if the documentation is large. This plugin allows marking such points on the pages
as _index entries_ and then collects these entries and put them together on a separate
_index page_. See the [index page](../index_page.html) of this documentation as an example.
**Definition**
````json
"plugins": {
"index": {"index": {"output": "index_page.html", "title": "Index", "index-cache": "index_cache.json",
"index-cache-relative": true, "letters": true, "letters-block": true }
}
}
````
This example defines one index with marker `index`. It's possible to define several indexes with
different markers.
All possible properties are listed in the table below. They are mostly the same as those
of the [`documents` section](#documents_section) so see that section for the
absent descriptions.
Name | Type | Required | Default | Description
---- | ---- | :----: | ---- | ----
output-root | string | No | | |
output | string | Yes | | Index page that must be created: absolute or relative to the `output-root` property value
title | string | No | | |
template | string | No | | |
link-css | array of string | No | | |
include-css | array of string | No | | |
no-css | boolean | No | | |
add-link-css | array of string | No | | |
add-include-css | array of string | No | | |
page-flows | array of string | No | | |
add-page-flows | array of string | No | | |
verbose | boolean | No | | |
report | boolean | No | | |
index-cache | string | Yes | | Index cache file (see the note below)
index-cache-relative | boolean | No | false | `true` means that the index cache file location is defined relative to the index page location
letters | boolean | No | false | `true` means that the index page content will be divided by the terms first letters
letters-block | boolean | No | false | `true` means that all terms first letters will be listed at the top of the index page
!!! note "Index cache file"
_Index page_ is generated using the entries from all the documents but
the program may regenerate the documentation project partially, i.e. it may regenerate
only those documents that were changed or added since the previous program run.
In order to always generate a complete index page the program uses an _index cache file_
that keeps the collected index entries between the runs.
In some cases a forceful full regeneration (with `-f` flag or `"force": true` option,
see [here]() for more details) is required, for example, if the "index" plugin is
activated on an existing project or if the index cache file is deleted.
Index cache file is a generated artifact so in case of any problem it may be manually deleted
and the further forceful full documents regeneration may resolve the problem.
**Usage**
Index entries may be added in two different ways:
- using a single-term entry like ``;
- using a multiple-term entry like ``.
The `index` marker is case-insensitive. If the above two entries are added then the index page
will be generated with terms "term 1", "Term 2" and "term 3" in the sorted order.
In the index page, the term list will be included into a `
` element.
The term first letter delimiters will look like this:
````html
A
````
The terms themselves will look like this:
````html
````
The above information allows define desirable styling with CSS.
----------------------------------------------------------------------------------------------------
# "page-links" plugin {#page_links_plugin}
**Motivation**
HTML pages inside documentation usually reference each other using links. A link specifies its
target relative to the page where it's placed. When the target page is moved or renamed the link
need to be modified accordingly, otherwise it won't work. And what's worse, all pages that
reference the relocated page need to be found and modified. This plugin automatically calculates
link target pages location thus eliminating the need of specifying them manually.
**Definition**
To make this plugin work the target document must have a `code`. Here is an example of an argument
file that uses this plugin:
````json
{
"documents": [
{ "input": "page1.txt", "code": "p1" },
{ "input": "subdir/page2.txt", "code-from-variable": "code" }
],
"plugins": {
"page-variables": {},
"page-links": { "markers": ["page"] }
}
}
````
The first page has a code `p1` specified in the document definition. The second page has a code
(let's say `p2`) specified in the page _metadata_ (see the
["page-variables" plugin](#page_variables_plugin)), variable `code`. If page _metadata_ is used
then "page-variables" plugin must be activated.
_Marker_ `page` is defined in the "page-links" plugin. There may be several markers.
**Usage**
On the page `page1.txt` the following link to the page `subdir/page2.txt` may be added:
`[](#some_anchor)` and the plugin will convert it to
`[](subdir/page2.html#some_anchor)`. Consequently link `[]()` on the second page will
become `[](../page1.html)`.
!!! attention
1. If a page is moved or renamed, some other pages may need to be regenerated to reflected this
change. But those pages may be up-to-date, so a forceful full regeneration may be required
(with `-f` flag or `"force": true` option, see [here]() for more details).
2. Changing a page's `code` will invalidate all links that reference this page by its `code`.
----------------------------------------------------------------------------------------------------
# "ignore" plugin {#ignore_plugin}
**Motivation**
Different plugins fulfill page metadata substitution. But sometimes it's required to show a
metadata block without substitutions. To achieve that, there are methods that use direct HTML
inclusions and masking, but they are quite tedious and cumbersome. This plugin gives an easy
way of doing that.
**Definition**
Here is an example of an *argument file* that uses this plugin:
````json
{
"documents": [
{ "input": "page1.txt" }
],
"plugins": {
"ignore": { "markers": ["ignore"] }
}
}
````
The example shows the default *marker* usage, so the other, and recommended, way is the following
definition: `"ignore": { }`. There may be several markers if required.
**Usage**
Let's consider two different code blocks:
````

````
and
````

````
In the first block the source text is `` and substitution
is fulfilled, while in the second block the source text is
`` so substitution is omitted.
----------------------------------------------------------------------------------------------------
# "wrap-code" plugin
**Motivation**
Pages may contain links to source code files like Java (\*.java), Python (\*.py), XML (\*.xml),
and so on. When viewing such pages locally (as HTML files) the linked files are often opened by
browsers as text. When the page is published and is viewed by URL, the browsers will often
offer downloading the linked files that's very inconvenient and significantly slows down the
documentation usage.
The "wrap-code" plugin wraps source code files into HTML pages and provides links to these
wrapping pages.
**Definition**
The plugin definition may look like this:
````json
"plugins": {
. . .
"wrap-code": {
"wrap_java": {"style": "code", "input-root": "projects/", "output-root": "doc/code",
"template": "doc_src/templates/code.html", "variables": {"noPageTitle": true}},
"wrap_xml": {"style": "xml", "input-root": "projects/", "output-root": "doc/code",
"template": "doc_src/templates/code.html", "variables": {"noPageTitle": true}}
}
. . .
}
````
In this example `wrap_java` and `wrap_xml` are markers to be used in the placeholders (see below).
The markers define the wrapping HTML page generation options: where to take the source code files,
where to place the wrapping HTML pages, which rendering style and template to use.
!!! note
The `style` parameter may be defined directly per each page metadata, see below. So just one
`wrap-code` definition may be used and customized directly in place.
All possible properties are listed in the table below. They are mostly the same as those
of the [`documents` section](#documents_section) so see that section for the
absent descriptions.
Name | Type | Required | Default | Description
---- | ---- | :----: | ---- | ----
input-root | string | No | | |
output-root | string | No | | |
template | string | No | | |
link-css | array of string | No | | |
include-css | array of string | No | | |
no-css | boolean | No | | |
add-link-css | array of string | No | | |
add-include-css | array of string | No | | |
verbose | boolean | No | | |
report | boolean | No | | |
style | string | No | *empty string* | style, like `code`, `shell`, etc. |
variables | object | No | *empty* | additional variables to be used in the template |
**Usage**
Let's say there's the file `projects/hello/Main.java` with some content. To link this file in
a source text, use something like this:
````
The main class is [here]().
````
The alternative form is:
````
The main class is [here]().
````
As the result, the new file `doc/code/hello/Main.java.html` will be generated based on the
following transformed content:
````code
````
The source text will be transformed like this:
````
The main class is [here]().
````
An example may be viewed [here](). Also see the argument file
`md2html_args.json` in this project.
The following additional variables may be used in the template:
Variable | Description
----- | -----
`{{wrap_code_path}}` | Path to the wrapped file
`{{wrap_code_file_name}}` | The wrapped file name
!!! note
The wrapping HTML file will be generated (or regenerated) only if the source text is processed.
To assure regeneration, use `-f` flag or `"force": true` option (see [here]()
for more details).
----------------------------------------------------------------------------------------------------
# "include-file" plugin {#include_file_plugin}
**Motivation**
When writing and running program code, it may be desired to place some source code into the
documentation. Just copy-pasting will require updating documentation each time the source code
is changed. ["wrap-code" plugin](#wrap_code_plugin) may help by generating a separate page
for this code. But if the source text is small it may be better to show it directly in the text
where it's described. This plugin does such kind of inclusion.
**Definition**
The plugin is defined the following way:
````json
"plugins": {
. . .
"include-file": [
{ "markers": ["include_code"], "root-dir": "sample_code/", "trim": "all" },
{ "markers": ["include_text1", "include_text2"], "root-dir": "sample_text/",
"recursive": true, "start-with": "", "end-with": "",
"start-marker": "// INCLUDE FROM HERE", "end-marker": "// INCLUDE UP TO HERE" }
],
. . .
}
````
In this example:
- there are two inclusion definitions;
- `include_code` is the marker to be used in the placeholders (see below);
There may be several markers;
- `sample_code/` and `sample_text/` define the places where to take the source code files;
- `"trim": "all"` defines whether to trim leading and trailing white spaces (`all` by default).
Other options are `empty-lines` and `none`;
- `"recursive": true` (`false` by default) means that if the included file content contains
*metadata* blocks, like ``, then these *metadata* blocks will be
processed;
- partial inclusion. Not only the whole file may be included but also a fragment of it:
- `start-with` and `start-marker` parameters specify the text that will be the fragment start.
The `start-with` text will be present in the included fragment while the `start-marker`
text will not be included. The first of these markers will be used. If ether of these
parameters are specified and they are not found in the file then nothing will be included;
- `end-with` and `end-marker` specify the text that will be the fragment end. If no text
defined by these parameters are found then the fragment will be to the end of the file.
**Usage**
By adding the following content on the page:
`````
````code
````
`````
we will get the following output:
````code
````
For a certain file, custom parameters may be defined the following way:
`````
````code
````
`````
The result will look like this:
````code
````
----------------------------------------------------------------------------------------------------
# "replace" plugin
**Motivation**
This plugin makes replacements by template. It may be helpful for contracting long and recurring
fragments. Probably, long and cumbersome HTML inclusions are the first fragments that
may be addressed by this plugin.
!!! important
This plugin must be used with care. When used too much, it may become a replacement for
the Markdown syntax, and that, in its turn, may significantly reduce the documents
readability and compatibility in source text.
**Definition**
The plugin is defined the following way:
````json
"plugins": {
. . .
"replace": [
{ "markers": ["red"], "replace-with": "${1}" },
{ "markers": ["blue"], "replace-with": "${1}" },
{ "markers": ["pict"], "replace-with": "", "recursive": true }
],
. . .
}
````
In this example:
- there are several replacement definitions;
- `red`, `blue` and `pict` are the marker to be used in the placeholders (see below).
There may be several markers in one replacement definition;
- the `replace-with` attributes define the templates to be extended;
- `${1}`, `${2}`, `${3}`, etc. are the placeholders that will be replaced in the template.
To add a dollar sign `$` it must be doubled. So `$${4}` will be interpreted as `${4}`.
There's a need for this doubling only if a dollar sign if followed by a curly brace.
So `$3` will be taken literary as `$3`;
- if the `recursive` flag is set to `true` then the resulting text (after the template is
extending) will be considered as containing metadata blocks. In the replacement definition
with marker `pict` the fragment `` will be processed and replaced if
the marker `path` is defined.
**Usage**
The content may be added the following ways:
- `` --- using a string, only one value may be specified;
- `` --- using a list. Unused items will be
ignored.
The output will be the same in both cases:
````code
some text
````
This result may look like this: .
If there are not enough values provided for the template, the missing positions will be replaced
with empty strings.