👨‍💻 about me home CV/Resume News 🖊️ Contact Github LinkedIn I’m a Haskeller 🏆 Best of LuaX hey bang ypp panda lsvg Fizzbuzz Calculadoira TPG todo pwd rrpi

Yet a PreProcessor

Yet a PreProcessor

ypp is yet another preprocessor. It’s an attempt to merge UPP and Panda. It acts as a generic text preprocessor as UPP and comes with macros reimplementing most of the Panda functionalities (i.e. Panda facilities not restricted to Pandoc but also available to softwares like Typst).

Ypp is a minimalist and generic text preprocessor using Lua macros.

It provides several interesting features:

Open source

ypp is an Open source software. Anybody can contribute on GitHub to:

Installation

ypp requires LuaX.

$ git clone https://github.com/CDSoft/luax.git && ninja -C luax install
...

# install ypp in ~/.local/bin
$ git clone https://github.com/CDSoft/ypp.git && ninja -C ypp install

ninja install installs ypp in ~/.local/bin. The PREFIX variable can be defined to install ypp to a different directory (e.g. PREFIX=/usr ninja install to install ypp in /usr/bin).

Precompiled binaries

In case precompiled binaries are needed (GNU/Linux, MacOS, Windows), some can be found at cdelord.fr/hey. These archives contain ypp as well as some other softwares more or less related to LuaX.

Test

$ make test

Usage

Usage: ypp [-h] [-v] [-l script] [-e expression] [-p path] [-o file]
       [-t {svg,pdf,png}] [--MT target] [--MF name] [--MD]
       [<input>] ...

ypp
Yet a PreProcessor

Arguments:
   input                 Input file

Options:
   -h, --help            Show this help message and exit.
   -v                    Show yyp version
   -l script             Execute a Lua script
   -e expression         Execute a Lua expression
   -p path               Add a path to package.path
   -o file               Redirect the output to 'file'
   -t {svg,pdf,png}      Set the default format of generated images
   --MT target           Add `name` to the target list (implies `--MD`)
   --MF name             Set the dependency file name (implies `--MD`)
   --MD                  Generate a dependency file

For more information, see https://github.com/CDSoft/ypp

Note for Windows users: since Windows does not support shebangs, ypp shall be explicitly launched with luax (e.g.: luax ypp). If ypp is not found, it is searched in the installation directory of luax or in $PATH.

Documentation

Lua expressions and chunks are embedded in the document to process. Expressions are introduced by @ and chunks by @@. Several syntaxes are provided.

The first syntax is more generic and can execute any kind of Lua expression or chunk:

The second one can be used to read a variable or execute a Lua function with a subset of the Lua grammar:

The expression grammar is:

expression ::= <identifier> continuation

continuation ::= '.' expression
               | ':' expression
               | '(' well parenthesized substring ')' continuation
               | '{' well bracketed substring '}' continuation
               | <single quoted string> continuation
               | <double quoted string> continuation
               | <long string> continuation
               | <empty string>

And the third one is an assignment to Lua variables:

The assignment grammar is:

assignment ::= <identifier> ('.' <identifier>)* '='
               ( <number>
               | 'true' | 'false'
               | '(' well parenthesized substring ')'
               | '{' well bracketed substring '}'
               | <single quoted string>
               | <double quoted string>
               | <long string>
               | expression
               )

Note: the number or equal signs in long strings is variable, as in Lua long strings

The special macro @/ is used to explicitly end an expression when the context is ambiguous.

The Lua code can be delimited with parentheses or long brackets. The code delimited with parentheses shall only contain well-balanced parentheses. The long bracket delimiters shall have the same number of equal signs (which can be null), similarly to Lua literal strings

A macro is just a Lua function. Some macros are predefined by ypp. New macros can be defined by loading Lua scripts (options -l and -e) or embedded as Lua chunks.

Expression and chunks can return values. These values are formatted according to their types:

For documentation purpose, ypp macros can be enable/disabled with the special ? macro:

Examples

Lua expression

The user's home is @(os.getenv "HOME").

$\sum_{i=0}^100 = @(F.range(100):sum())$

Lua chunk

@@[[
    local sum = 0
    for i = 1, 100 do
        sum = sum + i
    end
    return sum
]]

$\sum_{i=0}^100 = @sum$

Builtin ypp functions

ypp

Builtin ypp modules

atexit

comment

E.g.:

@comment [===[
This paragraph is a comment
and is not part of the output document.
]===]

convert

This function requires a Pandoc Lua interpreter. The conversion is made by Pandoc itself.

The opts parameter is optional. By default Pandoc converts documents from and to Markdown and the header level is not modified.

The convert macro can also be called as a curried function (arguments can be swapped). E.g.:

@convert {from="csv"} (script.python [===[
# python script that produces a CSV document
]===])

Notice that convert can be implicitely called by include or script by giving the appropriate options. E.g.:

@script.python {from="csv"} [===[
# python script that produces a CSV document
]===]

doc

The doc macro can also be called as a curried function (arguments can be swapped). E.g.:

@doc "file.c" {pattern="///(.-)///"}

image

The render parameter is a string that defines the command to execute to generate the image. It contains some parameters:

Images are generated in a directory given by:

If source starts with a @ (e.g. "@filename") then the actual image source is read from the file filename.

The image link in the output document may have to be different than the actual path in the file system. This happens when the documents are not generated in the same path than the source document. Brackets can be used to specify the part of the path that belongs to the generated image but not to the link in the output document in YPP_IMG. E.g. if YPP_IMG=[prefix]path then images will be generated in prefix/path and the link used in the output document will be path.

The file format (extension) must be in render, after the %o tag (e.g.: %o.png).

If the program requires a specific input file extension, it can be specified in render, after the %i tag (e.g.: %i.xyz).

Some render commands are predefined. For each render X (which produces images in the default format) there are 3 other render commands X.svg, X.png and X.pdf which explicitely specify the image format. They can be used similaryly to image: X(source).

An optional table can be given before source to set some options:

Image engine ypp function Example
Asymptote asy image.asy(source)
Blockdiag actdiag image.actdiag(source)
Blockdiag blockdiag image.blockdiag(source)
Blockdiag nwdiag image.nwdiag(source)
Blockdiag packetdiag image.packetdiag(source)
Blockdiag rackdiag image.rackdiag(source)
Blockdiag seqdiag image.seqdiag(source)
Graphviz circo image.circo(source)
Graphviz dot image.dot(source)
Graphviz fdp image.fdp(source)
Graphviz neato image.neato(source)
Graphviz osage image.osage(source)
Graphviz patchwork image.patchwork(source)
Graphviz sfdp image.sfdp(source)
Graphviz twopi image.twopi(source)
Mermaid mmdc image.mmdc(source)
PlantUML plantuml image.plantuml(source)
ditaa ditaa image.ditaa(source)
gnuplot gnuplot image.gnuplot(source)
lsvg lsvg image.lsvg(source)
octave octave image.octave(source)

Example:

![ypp image generation example](@image.dot [===[
digraph {
    rankdir=LR;
    input -> ypp -> output
    ypp -> image
}
]===])

is rendered as

ypp image generation example

include

The include macro can also be called as a curried function (arguments can be swapped). E.g.:

@include "file.csv" {from="csv"}
@include {from="csv"} "file.csv"

q

script

script also predefines shortcuts for some popular languages:

Example:

$\sum_{i=0}^100 = @script.python "print(sum(range(101)))"$

is rendered as

$\sum_{i=0}^100 = 5050$

when

E.g.:

@when(lang=="en")
[===[
The current language is English.
]===]

file

LuaX modules

ypp is written in Lua and LuaX. All Lua and LuaX libraries are available to ypp.

LuaX is a Lua interpreter and REPL based on Lua 5.4, augmented with some useful packages.

LuaX comes with a standard Lua interpreter and provides some libraries (embedded in a single executable, no external dependency required). Here are some LuaX modules that can be useful in ypp documents:

More information here: http://cdelord.fr/luax

License

Ypp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Ypp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ypp.  If not, see <https://www.gnu.org/licenses/>.

For further information about ypp you can visit
http://cdelord.fr/ypp

Feedback

Your feedback and contributions are welcome. You can contact me at cdelord.fr.