1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
.TH SMP 1 2024-06-08
.SH name
Skaldpress Macro Processor \- Macro processor
.SH SYNOPSIS
.B smp [OPTION]... [\fIinput_file\fB]
.SH DESCRIPTION
.B smp
smp is a macro processor, made specifically for a usecase when doing templating of websites.
.SS Macros
.IP "\fBinclude(<file>)\fR"
Includes a file in-place, performing macro-expansion on it.
NOTE, THERE IS NO LOOP PROTECTION HERE!
.IP "\fBinclude_varbatim(<file>)\fR"
Same as \fBinclude\fR, but does not expand macros.
.IP "\fBdefine(<macro_name> [, <macro content>])\fR"
This defines a macro, optionally with some content.
The optional content will be expanded immediately,
and later the already processed content will be included in the output.
.IP "\fBundefine(<macro_name>)\fR"
Delete the macro.
.IP "\fBifdef(<macro_name>, <output if defined> [, <output if not defined>])\fR"
.IP "\fBifndef(<macro_name>, <output if not defined> [, <output if defined>])\fR"
.IP "\fBifeq(<arg1>, <arg2>, <output if equal> [, <output if not equal>])\fR"
.IP "\fBifneq(<arg1>, <arg2>, <output if not equal> [, <output if equal>])\fR"
.IP "\fBshell(<command>)\fR"
Runs command on shell, and includes the command output in the output
.IP "\fBeval(<python>)\fR"
Run a python command, write return value to output.
.IP "\fBexpr(<arg1>, <arg2>, ..., <argN>)\fR"
Shorthand for running the expr command, expands all arguments, and executes it on the shell.
.IP "\fBdefine_array(<macro_name>)\fR"
Defines a macro as a array, this can later be used with macros like \fBarray_push\fR and \fBarray_each\fR.
.IP "\fBarray_push(<macro_name>, <value>[, <additional value(s)>])\fR"
On a macro that is defined as a array, this will add one or more elements.
.IP "\fBarray_each(<macro_name>, <template macro>])\fR"
Push any arguments to array macro
Process each element in a array as a macro-invokation on the second argument
Not the best way to do this, it is not sensibly recursive.
.IP "\fBarray_size(<macro_name>)\fR"
Will return number of elements in a macro array.
.IP "\fBexplode(<array_name>, <delimiter>, <input>)\fR"
Explode a input into individual array elements.
.IP "\fBformat_time(<format>, <time>)\fR"
Format a RFC3339-timestamp to the specified format. Format is similar to strftime.
Only available if the \fBtime\fR-feature was enabled during compilation.
.IP "\fBhtml_from_markdown(<markdown>)\fR"
If compiled with \fBmarkdown\fR, this macro will convert it's argument from markdown to html.
It will process it's input twice before actually doing the conversion. This is to remove the outer quotes of a argument.
So you should probably always quote arguments to this.
.IP "\fBwodl(<url>)\fR"
This macro will always return it's argument.
But it will also perform a request to the link, and emit a warning if it it doesn't return HTTP 200 OK.
This will significantly slow down compile times!
.IP "\fBtemplate(<filename>, <content>)\fR"
Will read the file in \fIfilename\fR, and process it replacing \fBCONTENT\fR with the \fIcontent\fR.
.IP "\fBiftruthy(<content>)\fR"
Returns python True if content is evaluated to \fItruthy\fR.
.IP "\fBindent(<spaces>, <content>)\fR"
Indents each line of the \fIcontent\fR with \fIspaces\R spaces.
.IP "\fBdumpenv\fR"
Debugging macro for printing smp internals.
.SS "\fBSpecial macros\fR"
There is a syntax for special macros, which takes more data in once.
.IP "\fB@template \fI<template>\fR"
Passes the rest of the file as content to the \fBtemplate\fR-macro.
.IP "\fB@html_from_markdown\fR"
Passes the rest of the file as content to the \fBhtml_from_markdown\fR-macro.
.SS "\fBStrings\fR"
This macro processor is generally recursive, meaning all macros will process it's arguments normally before using them.
To make this easier to deal with, strings are differentiated between opening and closing.
Opening is \fB%"\fR, closing is \fB"%\fR.
.SS "\fBCode\fR"
You can run arbitrary (python) code in the files, which operates in the same environment as the macros.
This means you can from the python code call all builtin macros directly (you will need to manually provide the macro_processor reference).
It also means all definitions you make, are available outside as macro tokens.
Code blocks are opened with \fB%(\fR and closed with \fB)%\fR.
.PP
.nf
.RS
%(
def A():
return "test"
)%
A
%"A"%
.RE
.fi
.PP
Returns
.PP
.nf
.RS
test
A
.RE
.fi
.PP
.SS "\fBBuiltin macro options\fR"
There are some macros flags that can enable/disable features,
They will be prefixed by `smp_` if \fB-P\fR is set.
.IP "\fBparse_file_yaml\fR" 2
\fB\fItruthy\fR\fB by default\fR.
If set to a truthy value, metadata blocks in the start of files will be parsed, otherwise it will be treated as normal input.
.IP "\fBdraft\fR" 2
\fB\fIfalsy\fR\fB by default\fR.
If set to a truthy value, some macros may skip expensive steps to save compilation time (e.g. network calls).
.IP "\fBtemplate_prefix\fR" 2
\fB\fItemplates/\fR\fB by default\fR.
The path to search for templates in, this affects metadata wrapping, as well as macros using the template macro.
.IP "\fBmetadata_prefix\fR" 2
\fB\fIMETADATA_\fR\fB by default\fR.
The prefix used for defining metadata for macros defined in blocks.
.IP "\fBsmp_debug\fR" 2
\fB\fI4\fR\fB by default\fR.
Sets the debug level for the parser, higher number means more verbosity.
Level 1 and 2 is the most basic error messaging, 5 and up will print parser internals.
.IP "\fBsynclines\fR" 2
\fB\fIfalsy\fR\fB by default\fR.
If truthy, synclines will be included in output, along with filename.
.SS Metadata block
All input files can have a metadata-block at the beginning.
Any keys will be defined as macros as \fBMETADATA_<key>\fR.
There are a few special keys which has a specific effect:
.IP "\fBtarget_filename\fR"
By default, a file will have the same name in the \fIoutput\fR-directory (unless a template has a different extension).
This overrides the output-filename, but it keeps the file in the same directory, and it will not affect the extension.
.IP "\fBtemplate\fR"
If specified, the file will be compiled using a template.
In the template, all \fBMETADATA_<key>\fR macros will be available,
additionally templates can use the \fBCONTENT\fR-macro to get the expanded content of the file.
This is recursive, meaning that templates can use other templates, with their own metadata-block,
since it is recursive, any metadata in templates will overwrite any metadata from their children,
but will keep metadata that is not overwritten.
This means templates can add additional context.
.IP "\fBkeep_states\fR"
List or string where every listed state/variable will be kept for subsequenct compilations.
Meaning that you can e.g. construct a array in the first compilation, which is then used the second time around.
Setting this, means that the file will always be recompiled, regardeless of other instances (unless a \fB--filter\fR is set).
.SH OPTIONS
.IP "\fBinput_file\fR
If a input file is provided, that will be processed.
If it is `-`, or not specified and something is piped, it will process stdin.
.IP "\fB-D, --define\fR \fIkey\fR=\fIvalue\fR
Define macros, these will be interpreted as strings.
.IP "\fB-P, --prefix-builtins\fR
Prefix all builtin macros with `smp_`
.IP "\fB-U, --unsafe\fR
If specified, arbitrary code execution will be allowed.
It is most likely possible anyway.
.SH SEE ALSO
skaldpress(1)
|