Add documentation on external renderers

This commit is contained in:
Starbeamrainbowlabs 2019-10-26 15:19:05 +01:00
parent 34a86dbaec
commit 729af8205d
Signed by: sbrl
GPG Key ID: 1BE5172E637709C2
5 changed files with 121 additions and 4 deletions

View File

@ -0,0 +1,91 @@
# External Renderers
Pepperminty Wiki supports external renders, should you choose to enable with the `parser_ext_renderers_enabled` setting - though it's enabled by default. The way these function is very powerful - by registering an external renderer, a subshell will be spawned that will execute the given command, and serve the output back to the user as an image. Text is specified via code-fencing like so:
<pre><code>```language_code
insert text here
```</code></pre>
The output of external renderers is cached in the `render_ext` subdirectory of the main cache directory (usually called `._cache` in the data storage directory alongside your pages), to avoid the computational load of re-rendering things every time.
Note that anonymous users, by default, are not allowed to invoke external renderers, unless the `parser_ext_allow_anon` setting is set to `true` - though they can still recall pre-rendered items from the cache. This protects against potentially malicious content being rendered and causing nasty things like infinite loops.
If you've got anonymous edits enabled, you may want to carefully analyse the external renderers you've got enabled, as an anonymous user could save a malicious image to a page, which would then be unwittingly loaded a user at a later time.
External renderers are registered in an object map in the `parser_ext_renderers` setting, like so:
```json
{
"language_code": "definition_here",
"another_language_code": "definition_here"
}
```
...where `"definition_here"` is an object like this:
```json
{
"name": "nomnoml",
"description": "The nomnoml UML diagram renderer. Requires the 'nomnoml' npm package to be globally installed.",
"url": "http:\/\/nomnoml.com\/",
"cli": "nomnoml {input_file} {output_file} 0",
"cli_mode": "file",
"output_format": "image\/svg+xml",
"output_classes": [ "invert-when-dark" ]
}
```
Above is a definition for [nomnoml](http://nomnoml.com/), which is one of the 4 default external renderers registered. There's quite a lot here, so we'll look at each property in turn. First, the simpler properties:
- `name`: The pretty display name of the external renderer.
- `description`: A short description of the renderer.
- `url`: A link to a quick reference guide on how to format text that's passed to the renderer.
- `cli`: The command-line program to execute.
- `output_format`: The MIME type of the output format generated by the renderer - for example `image/png`, `image/svg+xml`, etc.
- `output_classes`: An array of classes to add to images generated by the renderer.
Although the output of external renderers is cached, the hash used as the filename in the cache is computed from not only the source text input, but a hash of the external renderer options too. If any of the options in the definition of the external renderer change, then the hash will be altered too and all previous cache entries automatically invalidated. In these instances it may be worth deleting the cache directory too, as it might get quite large if the external renderer definition is changed in between many invocations.
`cli_mode` requires additional explanation. It supports 3 values:
- `pipe`
- `substitution_pipe`
- `file`
Each value causes the command specified in `cli` to be executed slightly differently and the output of the command to be handled differently too. The intention here is to allow integration with the widest possible range of external programs without the need for a wrapper script.
## Pipe Mode
In pipe mode, the input source text is made available via the standard input, and everything on the standard output is considered to be the output image, which is both cached and sent to the user.
If the exit code of the command is non-zero, then the output on the standard error is converted into an error image and served instead. Example:
```bash
command
```
## Substitution-Pipe Mode
In substitution-pipe mode, the special token `{input_text}` in the `cli` that is to be executed is replaced with the shell-escaped text (using PHP's `escapeshellarg`) that should be rendered. The standard input is empty, and the standard output is treated as the output image, as in pipe mode. The standard error is handled as in pipe mode too.
Example:
```bash
command {input_text}
```
Note that `{input_text}` is not in quotes - these are added automatically. Care should be taken that the input text is note handled as an argument though, as this could cause unintended side-effects if the input text starts with a dash. Many commands support the double-dash syntax to stop parsing argument flags like so:
```bash
command --some-options -a -b -c 3 -- {input_text}
```
## File Mode
The last mode supported is file mode. Unlike the pipe and substitution-pipe modes, any content pushed to the standard output is ignored. The tokens `{input_file}` and `{output_file}` are replaced with the path to files that contain the input text and that the output should be written to respectively. If the exit code is non-zero, the standard error is handled as normal - just like pipe and substitution-pipe modes.
Example:
```bash
command --input {input_file} --output {output_file}
```
As with substitution-pipe mode, note that the tokens are not in quotes - these are added automatically.
As with substitution-pipe mode, care should be taken to ensure that the file paths aren't handled as arguments - but _Pepperminty Wiki_ will attempt to avoid this. The input file will be an absolute path to an empty file in the system's temporary directory, and the output file will be a file (that may or may not yet exist) in the external renderer cache directory.

View File

@ -10,6 +10,7 @@
* [Configuring your instance](06-Configuration.md)
* [Inter-wiki links](06.5-Interwiki-Links.md)
* [Custom Themes](06.7-Custom-Themes.md)
* [Custom Themes](06.8-External-Renderers.md)
* [Writing Modules](07-Writing-Modules.md)
* **References**
* [Configuration Settings](https://starbeamrainbowlabs.com/labs/peppermint/peppermint-config-info.php)

View File

@ -105,7 +105,7 @@
"version": "0.1.1",
"author": "Starbeamrainbowlabs",
"description": "Adds interwiki link support. Set the interwiki_index_location setting at an index file to activate support.",
"lastupdate": 1549840688,
"lastupdate": 1572089223,
"optional": false,
"extra_data": []
},
@ -337,7 +337,7 @@
"version": "0.10",
"author": "Emanuil Rusev & Starbeamrainbowlabs",
"description": "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https:\/\/github.com\/erusev\/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation.",
"lastupdate": 1572001815,
"lastupdate": 1572090277,
"optional": false,
"extra_data": {
"Parsedown.php": "https:\/\/raw.githubusercontent.com\/erusev\/parsedown\/fe7a50eceb4a3c867cc9fa9c0aa906b1067d1955\/Parsedown.php",

View File

@ -398,6 +398,31 @@ register_module([
<tr><td><code>{{{*}}}</code></td><td>Outputs a comma separated list of all the subpages of the current page.</td></tr>
<tr><td><code>{{{+}}}</code></td><td>Shows a gallery containing all the files that are sub pages of the current page.</td></tr>
</table>");
if($settings->parser_ext_renderers_enabled) {
$doc_help = "<p>$settings->sitename supports external renderers. External renderers take the content of a code fence block, like this:</p>
<pre><code>```language_code
Insert text here
```</code></pre>
<p>...and render it to an image. This is based on the <code>language_code</code> specified, as is done in the above example. Precisely what the output of a external renderer is depends on the external renderers defined, but $settings->sitename currently has the following external renderers registered:</p>
<table>
<tr><th>Name</th><th>Language code</th><th>Description</th><th>Reference Link</th></tr>
";
foreach($settings->parser_ext_renderers as $code => $renderer) {
$row = array_map("htmlentities", [
$renderer->name,
$code,
$renderer->description,
$renderer->url
]);
$row[3] = "<a href='$row[3]'>&#x1f517;</a>";
$doc_help .= "<tr><td>".implode("</td><td>", $row)."</td></tr>\n";
}
$doc_help .= "</table>
$settings->admindetails_name can register more external renderers - see the <a href='https://starbeamrainbowlabs.com/labs/peppermint/__nightdocs/06.8-External-Renderers.html'>documentation</a> for more information.</p>";
add_help_section("24-external-renderers", "External Renderers", $doc_help);
}
}
]);

View File

@ -51,8 +51,8 @@
},
"latexserver": {
"name": "Server-Side MathJax",
"description": "Client-side Mathjax via the 'enable_math_rendering' setting not your thing? Try it server-side instead! Requires the 'mathjax-node-cli' npm package to be globally installed.",
"url": "https:\/\/github.com\/mathjax\/mathjax-node-cli\/blob\/master\/package.json#L41",
"description": "Client-side Mathjax via the 'enable_math_rendering' setting not your thing? Try it server-side instead! Requires the 'mathjax-node-cli' npm package to be globally installed. Note that you obviously don't want to include the latex math inside dolar signs $$ as the reference link tells you to.",
"url": "https://math.meta.stackexchange.com/q/5020/221181",
"cli": "tex2svg -- {input_text}",
"cli_mode": "substitution_pipe",
"output_format": "image\/svg+xml",