-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
61 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,104 @@ | ||
.\" Automatically generated by Pandoc 3.1.2 | ||
.\" Automatically generated by Pandoc 3.1.7 | ||
.\" | ||
.\" Define V font for inline verbatim, using C font in formats | ||
.\" that render this, and otherwise B font. | ||
.ie "\f[CB]x\f[]"x" \{\ | ||
. ftr V B | ||
. ftr VI BI | ||
. ftr VB B | ||
. ftr VBI BI | ||
.\} | ||
.el \{\ | ||
. ftr V CR | ||
. ftr VI CI | ||
. ftr VB CB | ||
. ftr VBI CBI | ||
.\} | ||
.TH "DJOT" "1" "" "djot 0.2.3" "" | ||
.hy | ||
.TH "DJOT" "1" "" "djot 0.2.4" "" | ||
.SH NAME | ||
.PP | ||
djot \[en] converts djot markup. | ||
.SH SYNOPSIS | ||
.PP | ||
djot options [file..] | ||
.SH DESCRIPTION | ||
.PP | ||
djot is a command-line parser for djot markup (https://djot.net). | ||
It can produce | ||
.IP \[bu] 2 | ||
an HMTL document (default behavior or \f[V]-t html\f[R]) | ||
an HMTL document (default behavior or \f[CR]-t html\f[R]) | ||
.IP \[bu] 2 | ||
a stream of annotated tokens with byte offsets (\f[V]-t events\f[R]) | ||
a stream of annotated tokens with byte offsets (\f[CR]-t events\f[R]) | ||
.IP \[bu] 2 | ||
an AST in either human-readable or JSON form (\f[V]-t ast\f[R], | ||
\f[V]-t astpretty\f[R]). | ||
an AST in either human-readable or JSON form (\f[CR]-t ast\f[R], | ||
\f[CR]-t astpretty\f[R]). | ||
.IP \[bu] 2 | ||
a djot document (\f[V]-t djot\f[R]) | ||
a djot document (\f[CR]-t djot\f[R]) | ||
.IP \[bu] 2 | ||
a pandoc AST serialized to JSON (\f[V]-t pandoc\f[R]), which can be read | ||
by pandoc (version >= 3) and converted to many other formats | ||
a pandoc AST serialized to JSON (\f[CR]-t pandoc\f[R]), which can be | ||
read by pandoc (version >= 3) and converted to many other formats | ||
.PP | ||
It can also read a JSON-serialized djot AST (\f[V]-f ast\f[R]) or a | ||
pandoc AST serialized to JSON (\f[V]-f pandoc\f[R]), allowing conversion | ||
from many other formats. | ||
It can also read a JSON-serialized djot AST (\f[CR]-f ast\f[R]) or a | ||
pandoc AST serialized to JSON (\f[CR]-f pandoc\f[R]), allowing | ||
conversion from many other formats. | ||
.PP | ||
Finally, it can apply \f[I]filters\f[R] that modify the parsed AST | ||
between the parsing and rendering steps. | ||
This is the primary way in which djot syntax can be customized. | ||
.SH OPTIONS | ||
.TP | ||
\f[V]--to,-t\f[R] \f[I]FORMAT\f[R] | ||
\f[CR]--to,-t\f[R] \f[I]FORMAT\f[R] | ||
Specify format to convert to. | ||
Valid values are \f[V]html\f[R] (the default), \f[V]ast\f[R] | ||
(JSON-formatted AST), \f[V]astpretty\f[R] (human-readable AST), | ||
\f[V]events\f[R] (JSON array of events produced by the tokenizer), | ||
\f[V]djot\f[R] (djot markup), or \f[V]pandoc\f[R] (JSON serialized | ||
Valid values are \f[CR]html\f[R] (the default), \f[CR]ast\f[R] | ||
(JSON-formatted AST), \f[CR]astpretty\f[R] (human-readable AST), | ||
\f[CR]events\f[R] (JSON array of events produced by the tokenizer), | ||
\f[CR]djot\f[R] (djot markup), or \f[CR]pandoc\f[R] (JSON serialized | ||
pandoc AST). | ||
.TP | ||
\f[V]--from,-f\f[R] \f[I]FORMAT\f[R] | ||
\f[CR]--from,-f\f[R] \f[I]FORMAT\f[R] | ||
Specify format to convert from. | ||
Valid values are \f[V]djot\f[R] (the default), \f[V]ast\f[R] | ||
(JSON-formatted AST), and \f[V]pandoc\f[R] (JSON serialized pandoc AST). | ||
Valid values are \f[CR]djot\f[R] (the default), \f[CR]ast\f[R] | ||
(JSON-formatted AST), and \f[CR]pandoc\f[R] (JSON serialized pandoc | ||
AST). | ||
.TP | ||
\f[V]--filter\f[R] \f[I]FILE\f[R] | ||
\f[CR]--filter\f[R] \f[I]FILE\f[R] | ||
Read a filter from \f[I]FILE\f[R] and apply it to the parsed AST prior | ||
to rendering. | ||
This option may be used multiple times; the filters will be applied in | ||
the order specified on the command line. | ||
See FILTERS below for details. | ||
.TP | ||
\f[V]--compact\f[R] | ||
\f[CR]--compact\f[R] | ||
Use compact JSON for the AST, with no extra spacing for readbility. | ||
.TP | ||
\f[V]--width,-w\f[R] \f[I]NUMBER\f[R] | ||
Text width to which to wrap output of \f[V]-t djot\f[R]. | ||
\f[CR]--width,-w\f[R] \f[I]NUMBER\f[R] | ||
Text width to which to wrap output of \f[CR]-t djot\f[R]. | ||
If \f[I]NUMBER\f[R] is 0, no wrapping will be done, and line breaks in | ||
the input will be preserved in the output. | ||
If it is -1, no wrapping will be done, and line breaks in the input will | ||
be treated as spaces. | ||
.TP | ||
\f[V]--sourcepos,-p\f[R] | ||
\f[CR]--sourcepos,-p\f[R] | ||
Include information about the start and end positions of elements in the | ||
HTML and AST. | ||
Source positions include the line number, column number (counting UTF-16 | ||
code units, which might not accord with visible columns), and character | ||
offset in the entire document (again, in UTF-16 code units). | ||
.TP | ||
\f[V]--time\f[R] | ||
\f[CR]--time\f[R] | ||
Print timings for parsing, filtering, and rendering to stderr. | ||
.TP | ||
\f[V]--quiet\f[R] | ||
\f[CR]--quiet\f[R] | ||
Suppress warnings. | ||
.TP | ||
\f[V]--version\f[R] | ||
\f[CR]--version\f[R] | ||
Print version | ||
.TP | ||
\f[V]--help,-h\f[R] | ||
\f[CR]--help,-h\f[R] | ||
Print this message. | ||
.SH FILTERS | ||
.PP | ||
Filters are JavaScript programs that modify the parsed document prior to | ||
rendering. | ||
Here is an example of a filter that capitalizes all the content text in | ||
a document: | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// This filter capitalizes regular text, leaving code and URLs unaffected | ||
return { | ||
str: (el) => { | ||
el.text = el.text.toUpperCase(); | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
Save this as \f[V]caps.js\f[R] use tell djot to use it using | ||
Save this as \f[CR]caps.js\f[R] use tell djot to use it using | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
djot --filter caps input.js | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
Note: never run a filter from a source you don\[cq]t trust, without | ||
inspecting the code carefully. | ||
|
@@ -132,42 +110,39 @@ document. | |
This filter doesn\[cq]t alter the document at all; it just prints the | ||
list to stderr. | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
return { | ||
link: (el) => { | ||
process.stderr:write(el.destination + \[dq]\[rs]n\[dq]) | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
A filter walks the document\[cq]s abstract syntax tree, applying | ||
functions to like-tagged nodes, so you will want to get familiar with | ||
how djot\[cq]s AST is designed. | ||
The easiest way to do this is to use \f[V]djot --ast\f[R] or | ||
\f[V]djot --astpretty\f[R]. | ||
The easiest way to do this is to use \f[CR]djot --ast\f[R] or | ||
\f[CR]djot --astpretty\f[R]. | ||
.PP | ||
By default filters do a bottom-up traversal; that is, the filter for a | ||
node is run after its children have been processed. | ||
It is possible to do a top-down travel, though, and even to run separate | ||
actions on entering a node (before processing the children) and on | ||
exiting (after processing the children). | ||
To do this, associate the node\[cq]s tag with a table containing | ||
\f[V]enter\f[R] and/or \f[V]exit\f[R] functions. | ||
The \f[V]enter\f[R] function is run when we traverse \f[I]into\f[R] the | ||
node, before we traverse its children, and the \f[V]exit\f[R] function | ||
\f[CR]enter\f[R] and/or \f[CR]exit\f[R] functions. | ||
The \f[CR]enter\f[R] function is run when we traverse \f[I]into\f[R] the | ||
node, before we traverse its children, and the \f[CR]exit\f[R] function | ||
is run after we have traversed the node\[cq]s children. | ||
For a top-down traversal, you\[cq]d just use the \f[V]enter\f[R] | ||
For a top-down traversal, you\[cq]d just use the \f[CR]enter\f[R] | ||
functions. | ||
If the tag is associated directly with a function, as in the first | ||
example above, it is treated as an \[ga]exit\[cq] function. | ||
.PP | ||
The following filter will capitalize text that is nested inside | ||
emphasis, but not other text: | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// This filter capitalizes the contents of emph | ||
// nodes instead of italicizing them. | ||
let capitalize = 0; | ||
|
@@ -187,14 +162,12 @@ return { | |
} | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
Here is a simple filter that changes letter enumerated lists to | ||
roman-numbered: | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// Changes letter-enumerated lists to roman-numbered | ||
return { | ||
list: (e) => { | ||
|
@@ -205,14 +178,12 @@ return { | |
} | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
A single filter may return a table with multiple tables, which will be | ||
applied sequentially: | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// This filter includes two sub-filters, run in sequence | ||
return [ | ||
{ // first filter changes (TM) to trademark symbol | ||
|
@@ -226,22 +197,20 @@ return [ | |
} | ||
} | ||
] | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
The filters we\[cq]ve looked at so far modify nodes in place by changing | ||
one of their properties (\f[V]text\f[R]). | ||
one of their properties (\f[CR]text\f[R]). | ||
Sometimes we\[cq]ll want to replace a node with a different kind of | ||
node, or with several nodes, or to delete a node. | ||
In these cases we can end the filter function with a \f[V]return\f[R]. | ||
In these cases we can end the filter function with a \f[CR]return\f[R]. | ||
If a single AST node is returned, it will replace the element the filter | ||
is processing. | ||
If an array of AST nodes is returned, they will be spliced in to replace | ||
the element. | ||
If an empty array is returned, the element will be deleted. | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// This filter replaces certain Symb nodes with | ||
// formatted text. | ||
const substitutions = { | ||
|
@@ -258,38 +227,33 @@ return { | |
} | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
// This filter replaces all Image nodes with their descriptions. | ||
return { | ||
image: (e) => { | ||
return e.children; | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.PP | ||
It is possible to inhibit traversal into the children of a node, by | ||
having the \f[V]enter\f[R] function return an object with the property | ||
\f[V]stop\f[R]. | ||
The contents of \f[V]stop\f[R] will be used as the regular return value. | ||
having the \f[CR]enter\f[R] function return an object with the property | ||
\f[CR]stop\f[R]. | ||
The contents of \f[CR]stop\f[R] will be used as the regular return | ||
value. | ||
This can be used, for example, to prevent the contents of a footnote | ||
from being processed: | ||
.IP | ||
.nf | ||
\f[C] | ||
.EX | ||
return { | ||
footnote: { | ||
enter: (e) => { | ||
return {stop: [e]}; | ||
} | ||
} | ||
} | ||
\f[R] | ||
.fi | ||
.EE | ||
.SH AUTHORS | ||
.PP | ||
John MacFarlane (<[email protected]>). |