YapTeX
April 9, 2026 · View on GitHub
YapTeX is a Markdown and plain text state of the shitpost preprocessor.
It's the very cool and simply overcomplicated solution.
Features
- Build targets
- Markdown
- HTML
- Cross-platform (WallHoles, Penguins, and that inconsitent HalfEatenAppleOS™!)
- Only pip dependencies
- Macros and variables
- Customization
- Font management
Usage
Usual markdown headers are not considered as directives.
When using directives the # symbol must be the first symbol of the line.
If you want to start your line with directive-like entry, you will have to escape the special char by using a backslash (e.g. \#).
Similarly, variables and macros can be escaped.
CLI
Building a document
You can ivoke the installed module simply by running a command in terminal.
yaptex <input-file>
For more info use help flag:
yaptex -h
rargs are renderer arguments.
Each of them have identifier of the renderer they belong to as a prefix.
Value is speciefied after an equls sign and you can separate them with a semicolon like so: id:arg1=value;id:arg2=other
Example to tell html renderer to use Roboto as font family for body of the output document.
yaptex <input-file> --target html --rargs "html:font_family=Roboto"
Note
HTML renderer is used as a middle step when targeting PDF.
Fonts
You can download more fonts from Google Fonts using the following command.
yaptex-font pull <font-family>
To see all installed fonts use:
yaptex-font list
Basic Directives
#include "<filepath>"
Includes another file.
#include "some/other/file.md"
#embed "<filepath>"
Includes another file raw without processing it.
#embed "some/other/file.txt"
#region "<name>"
Creates a section. Sections are converted into headers with regard to depth. You of course must end it.
#region "Hello"
Wolrd
#endregion
If you want to dynamically select the current depth of a title you can use -#
-# Hello
#define <NAME>[(<ARG>...)]
Using this directive you can create macros.
#define MACRO Hello World!
To evaluate it use ?.
?MACRO
You can also pass in arguments to make it even more dynamic!
#define GREET(NAME; LASTNAME) Hello %NAME %LASTNAME!
?GREET(Bingus; Dingus)
For multiline ones escape the new line.
#define GIB_LIST \
- A\
- B\
- C
?GIB_LIST
You can also remove defines.
#undef HELLO
#pagebreak
Insert page breaking feature.
#pagebreak
Variable Directives
#set <VARIABLE> {"<value>",<number>}
Sets a custom variable
#set NUMERIC_VAR 0
#set NUMERIC_VAR=0
#set NUMERIC_VAR = 0
#set TEXT_VAR "text"
#set TEXT_VAR="text"
#set TEXT_VAR = "text"
#inc <VARIABLE> [by]
Increments a given variable by specified amount (default is 1).
#inc HELLO_VAR 1
#dec <VARIABLE> [by]
Decrements a given variable by specified amount (default is 1).
#dec HELLO_VAR 1
Advanced Directives
#copy "<what>" "<where>"
Copies a given file into directory that is relative to output directory. Mostly used for asset management.
#copy "images/memisek.jpg" "assets"
`#if
Includes content if variable is defined and isn't empty (or not zero). Also needs to be ended like other block directives.
#if HELLO
HELLO set
#elif BYE
BYE set
#else
I have no idea what's going on...
#endif
#ifdef <DEFINE>
Includes content if defined and not empty (or not zero). Needs end directive like other block directives.
#ifdef HELLO
HELLO set
#elifdef BYE
BYE set
#else
I have no idea what's going on...
#endif
Also #ifndef and #elifndef can be used with inverted evaluation.
Some boolean operator can be used.
#ifdef HELLO && BYE
What's going on
#endif
#ifndef HELLO || BYE
Nothing is defined :(
#endif
#warning "<message>"
Prints a message while building.
#warning "We are doing number of cool things..."
#error "<message>"
Prints a message and stops the build.
#error "Whoops..."
Using Variables
Varibles can be placed anywhere using the % symbol as a prefix.
%HELLO
There are multiple variable formatting options while pasting. You can access them by prefixing the prefix symbol.
- Basic
l: convert to lower caseu: convert to upper caset: convert to title case
- Files
bn: filepath basenamedn: filepath dirname
- Special
html: html escape given valueslug: slufifyesc: escape special characters (eg.")
%{HELLO:l} -> c:/users/fafa/je "cyp"?.txt
%{HELLO:u} -> C:/USERS/FAFA/JE "CYP"?.TXT
%{HELLO:t} -> C:/Users/Fafa/Je "Cyp"?.Txt
%{HELLO:bn} -> je "cYp"?.txt
%{HELLO:dn} -> C:/Users/faFa
%{HELLO:html} -> C:/Users/faFa/je "cYp"?.txt
%{HELLO:slug} -> cusersfafaje-cyptxt
%{HELLO:esc} -> C:/Users/faFa/je \"cYp\"?.txt
Special Variables
You can use some special predefined variables.
_YEAR_: current year_MONTH_: current month of year_DAY_: current day of month_HOUR_: current hour of day (24 hour format)_MINUTE_: current minute of hour_SECOND_: current second of minute__FILE__: current file__LINE__: current line
Installation
TODO: installation
Dependencies
xhtml2pdf
Extension
You can build the Yapper extension VSIX file for Visual Studio Code using the default commands.
npm install
npx vsce package
Develop
TODO: add tags on syntax changes
Scripts
Run all scripts from project directory.
apply- installs all requirements, builds and installs package as editablebuild-readme- generatesREADME.mdfrom docsrun-tests- invokesunittestandpylint
Tests
To run tests use unittest from project directory.
python -m unittest
If you're feeling fancy try pylint (also from project directory).
pylint src/yaptex/**/*.py
Code Style
Notes based on pylint yap:
- If the docstring is not needed fill it with some yap (best is to use something thematic).
- "Too few public methods" indicates that the file or mechanism might be too clean. There is no point in making it more stupid.
- Pylint is not deterministic.
Warning
Using YapTeX may result in:
- Existential crises
This document was built using YapTeX