Verzeichnis macros/luatex/latex/scholatex
scholatex
Print-ready teaching worksheets, without writing LaTeX. — A small, consistent tag language for the documents a teacher actually makes.
Why scholatex?
Write a single .tex file with a tiny, readable syntax and get a clean, print-ready worksheet — framed exercises, a results table, simple formulas, an image — without \begin{tabular}{|c|c|}, without counting ampersands, without remembering which package draws a coloured box.
% !TeX program = lualatex \documentclass[margins=20, size=12]{scholatex} \begin{document} <Navy b 18pt c>My first scholatex document This is a normal paragraph. <b>{Bold}, <i>{italic}, <Red>{red}. <box line:Navy fill:AliceBlue radius:3 title:{A framed note}>{ Boxes, tables, images and maths all use the same tag syntax. } \end{document}
Compile with lualatex myfile.tex — the scholatex class reads the body between \begin{document} and \end{document}, transpiles it to LaTeX, and typesets it. The output has full LaTeX quality; the syntax is meant to be read and edited in minutes by someone who does not know LaTeX. scholatex is a closed language: the backslash is an ordinary character, so raw LaTeX commands in the body are typeset literally rather than executed. Everything a worksheet needs is expressed through tags, which keeps documents consistent and safe to share.
Quick start
tlmgr install scholatex # add sudo on macOS/Linux; see Installation below
\documentclass[margins=20, size=12, lang=en]{scholatex} \begin{document} <Navy b section>First topic A paragraph with <b>{bold} and <Red>{colour}. \end{document}
Key features
- 🏷️ One tag syntax —
<attributes>{content}covers text, tables, images, maths, boxes, lists and full-page layouts - 🎨 151 colours — the full CSS / svgnames palette in CamelCase, 22 of them with a lowercase shortcut
- 📐 A maths mini-language — fractions, roots, sums, products, integrals, derivatives, trigonometry, matrices and systems, all in
$...$ - 📦 Framed boxes & grids — coloured
<box>panels and CSS-Grid-style named-area page layouts - 📊 Tables without pain — two-letter cell placement, spans, headers, borders, no ampersand counting
- ♻️ Aliases & macros — factor a style once, name it everywhere; one edit restyles the whole document
- 🔁 Control flow — loops, conditionals and
#{...}interpolation in the document body - 🔒 Sandbox option —
untrusted=trueruns document Lua in a restricted environment
The one rule
Everything is a tag: <attributes> followed either by {content} (inline) or by a line that ends in { (a block). Attribute words follow a single case convention:
| Form | Meaning | Examples |
|---|---|---|
lowercase |
a short keyword (style, alignment, skip) | b, i, c, 2tab |
CamelCase |
an extended CSS colour (151 of them) | SteelBlue, Crimson |
UPPERCASE |
a font name | DEJAVU SANS |
The order of words inside a tag never matters — emission is always normalised (page break, then vertical skips, then alignment, then tabs, then styles).
Installation
scholatex is on CTAN and ships with TeX Live, so on a current, fully updated TeX Live or MacTeX it is already there — compile with lualatex and nothing more is needed. If your installation predates the package, install it once with the TeX Live manager; the same two commands work on macOS, Linux and Windows:
tlmgr update --self tlmgr install scholatex
On macOS (MacTeX) and most Linux setups tlmgr needs administrator rights, so prefix both with sudo. On Windows, open the TeX Live Command-Line (or a terminal as Administrator) and run them without sudo. MiKTeX users install through the MiKTeX Console (Packages → search scholatex → Install), or with mpm --install=scholatex.
tlmgr update --self comes first because the manager refuses to install packages when its own version is older than the repository's. After installing, check the class is found:
kpsewhich scholatex.cls
It should print a path under your TeX tree. From then on \documentclass{scholatex} works from any folder.
If tlmgr install scholatex reports the package is not present in the repository, your mirror has not yet synced a recent release; either wait a day or switch to the main CTAN mirror and retry:
sudo tlmgr option repository https://mirror.ctan.org/systems/texlive/tlnet sudo tlmgr update --self sudo tlmgr install scholatex
Manual install (any OS, no waiting)
To use the package immediately without tlmgr, drop the files into your personal TeX tree, mirroring the CTAN layout, then refresh the filename database. The home tree is ~/Library/texmf on macOS, ~/texmf on Linux, and %USERPROFILE%\texmf on Windows:
mkdir -p ~/texmf/tex/luatex/latex/scholatex cp scholatex.cls scholatex.lua scholatex-*.lua ~/texmf/tex/luatex/latex/scholatex/ mktexlsr ~/texmf
A LuaLaTeX engine is required (lualatex); the package does not compile with pdflatex or xelatex.
## Class options
Set in \documentclass[...]{scholatex}:
| Option | Default | Meaning |
|---|---|---|
margins |
20 |
N (all sides) or {top,right,bottom,left} in mm |
font |
Latin Modern Roman |
main text font |
mathfont |
Latin Modern Math |
math font |
size |
11 |
base font size in pt |
imgdir |
img |
folder(s) searched for bare image names; comma-separated list, e.g. {IMG, IMAGES/PNG} |
tabwidth |
8 |
width of one tab, in mm (a large Seyès square) |
lineheight |
8 |
height of one explicit line skip (<line>, <Nlines>), in mm |
linespread |
1.0 |
overall line spacing (1.5 = one-and-a-half); tall maths never touches even at 1.0 |
scriptscale |
100 |
scale (%) of up/down scripts |
padding |
2 |
inner padding (mm) between a box/grid frame and its content; override locally with sep:N |
lang |
fr |
decimal separator: fr (comma) or en (point); affects typed and interpolated decimals alike |
precision |
-1 |
decimals a computed #{...} value is rounded to for display (-1 = no rounding); round(x, d) overrides locally |
untrusted |
false |
run document Lua in a restricted sandbox — see Security |
Headings carry no extra vertical space or built-in colour: to style one, fold a heading keyword into an alias, e.g. let h = <line Navy b section> then <h>My title.
Text attributes
Inline styles — b bold, i italic, u underline, emph, sf sans-serif, sc small caps. They combine in one tag: <b i red>{bold italic red}.
Colours — a colour is always one of the 151 CSS colours, written in CamelCase: Navy, Red, Tomato, SteelBlue, ForestGreen, …. One rule, no lowercase shortcuts — the everyday colours are simply capitalised (Red, Blue, Green, Gray). See the colour reference.
Fonts and sizes — a font name in CAPITALS (<DEJAVU SANS>{…}); sizes as Npt or Npx (<14pt>{…}).
Alignment — l left, c centre, r right, j justified.
Tabs and skips (the number is always a prefix) — Ntab indents the first line by N tabs; vertical skips obey singular/plural agreement: line or 1line skips one, 2lines, 3lines, … skip several. Bare tab = 1tab.
Scripts — upN raises text by N mm, downN lowers it: x<up4>{2}, H<down2>{2}O.
Page break — nextpage.
Section headings — section, subsection, subsubsection give the three levels, numbered automatically:
<section>First topic <subsection>A detail <subsubsection>A finer point
renders as 1 First topic, 1.1 A detail, 1.1.1 A finer point. A table of contents is printed with <tableofcontents>; give it a title in braces: <tableofcontents>{Table of contents}.
Numbering style — by default the numbers are hierarchical (1, then 1.1, then 1.1.1). A counter keyword on a heading changes the style of that level, on its own — no inherited prefix: num (1, 2, 3), roman (i, ii, iii), ROMAN (I, II, III), alpha (a, b, c), ALPHA (A, B, C). For example let study = <Navy b section ROMAN> and let step = <Navy b subsection num> give sections I, II and, under each, steps 1, 2, 3 (not I.1). Each level is independent; without a keyword, the default hierarchical numbering stands.
Aliases and macros — the factoring tool
Define a style once, at the top of the document, then name it everywhere instead of repeating its attributes. One edit at the definition restyles the whole document.
let title = <Navy b 18pt c> % style alias
let h1 = <Navy b section> % a heading style, reusable
let p = <tab> % a standard indented paragraph
<title>My heading
<h1>First topic
<p>{ A paragraph, indented and justified, named not described. }
let n = 7 % value, usable in #{...}
Seven squared is #{n*n}.
let greet{name} = Hello #name! % text macro with parameters
Change let h1 = <Navy b section> to <ForestGreen b section> once and every first-level heading follows — the single point of control that keeps a long worksheet consistent.
Tables
Columns are declared in brackets, one two-letter placement code per column. The first letter is vertical (t/m/b), the second horizontal (l/c/r): mc is middle-centre, br bottom-right. This is the only placement syntax scholatex uses — in tables as in boxes and grids.
<table [mc, ml, mc, mc] borders header fill:AliceBlue line:Navy headerfill:Navy headertext:White>{
<colspan:4 mc>{Term report}
Day | Subject | Mark | Coef.
<rowspan:2 mc>{Monday} | Maths | 15 | 4
. | French | 12 | 3
}
One row per line, | between cells. <colspan:N> and <rowspan:N> span cells; . marks a cell covered by a span above. N: before a placement code fixes a column width in mm.
Images
<img 30>{photo.png} % 30 mm wide
<img 40x25>{photo.png} % 40 mm × 25 mm
<img>{photo.png} % full available width, never enlarged
A bare name is searched in each folder of imgdir in turn, then at the project root. An explicit path always works (<img 20>{IMG/PNG/chat.png}).
## Maths
Wrap maths in $…$. A small mini-language keeps it light:
| You write | You get |
|---|---|
* |
× |
+- |
± |
<= >= != |
≤ ≥ ≠ |
a/b |
fraction (chained a/b/c reads as (a/b)/c) |
x^2 x_i |
power / index (bind tighter than /, so x^2/y is \frac{x^2}{y}) |
sqrt(2) |
√2 |
sum(i=1, n) i |
∑ with bounds, display style |
prod(k=1, n) k |
∏ with bounds, display style |
int(x) f(x) |
∫ f(x) dx (primitive; the differential is added) |
int(x=a, b) f(x) |
∫ from a to b, f(x) dx |
contourint(C) f(z) |
∮ contour integral |
pvint(x=a, b) f(x) |
p.v. ∫ Cauchy principal value |
meanint(x=a, b) f(x) |
⨍ average (normalised) integral |
dy/dx, df/dx |
derivative, upright differential d (ISO) |
sin(x) cos(x) ln(x) … |
upright function names |
abs(x) |
x |
norm(v) |
‖v‖ |
vec(AB) |
→AB (over-arrow vector) |
floor(x) ceil(x) |
⌊x⌋ ⌈x⌉ (integer part) |
bar(z), conj(z) |
z̄ (conjugate, mean, closure) |
not(A cup B) |
(A∪B)‾ (logical negation, same overline) |
lim(x->0) f(x) |
limit, -> becomes the arrow, target under the word |
partial, nabla |
∂, ∇ (use (partial f)/(partial x) for ∂f/∂x) |
pi, alpha, … |
Greek letters |
inf |
∞ |
The helpers nest, so the secondary-school staples come for free: norm(vec(AB)) is the norm of a vector, vec(AB) + vec(BC) = vec(AC) is Chasles' relation.
Sets, logic and relations
From collège to the upper years a worksheet needs the standard notation. It is carried as plain words and ASCII shortcuts, so a statement reads as one types it.
Number sets — a doubled capital gives the blackboard-bold set (the ASCIIMath convention). Doubling avoids any clash with a one-letter variable:
| You write | You get |
|---|---|
NN ZZ DD QQ RR CC |
ℕ ℤ 𝔻 ℚ ℝ ℂ |
PP KK HH FF EE UU |
ℙ 𝕂 ℍ 𝔽 𝔼 𝕌 (advanced) |
Quantifiers and logic — forall ∀, exists ∃; connectives and ∧, or ∨, lnot ¬, neg ¬. Implication and equivalence come both as words and as arrows: => or implies ⇒, <=> or iff ⇔ (inside a formula; in running prose double the chevrons as <<=>>). The longer arrow forms win over the comparison they contain, so abs(x) <= 1 <=> -1 <= x <= 1 parses correctly.
Negation — one rule: ! before a relation or quantifier negates it, picking the proper struck-through glyph. So !in is ∉, !exists is ∄, !subset is ⊄, !subseteq is ⊈, !equiv is ≢. (!= stays "not equal", ≠.)
Set relations — in ∈, subset ⊂, supset ⊃, subseteq ⊆, supseteq ⊇, cup ∪, cap ∩, setminus ∖, emptyset ∅ (negate any with !).
Arrows — -> or to →, mapsto ↦.
$forall epsilon > 0, exists eta > 0$ $x in RR setminus QQ$ $x !in QQ$ $(P and Q) => P$
Brackets and accents
The integer part and a few one-argument wrappers follow the same name(...) shape as abs and vec: floor(x) ⌊x⌋, ceil(x) ⌈x⌉, set(x : x > 0) a brace set, abr(u, v) ⟨u, v⟩ an inner product.
An overline is named by intent — the same rule under two words: bar(...) for the generic bar (complex conjugate, mean, closure of a set) and not(...) for logical negation, so bar(z) is z̄ and not(A cup B) is (A∪B)‾. The usual accents complete the set: hat(f), tilde(x).
Limits with an arrow
lim(x->0) f(x) already sets a limit with its target under the word. For the running phrase "uₙ tends to ℓ" written over an arrow, use arrow(...): u_n arrow(n to +inf) l sets a long right arrow with the condition underneath. to and -> are interchangeable inside it.
$lim(n -> +inf) u_n = l$ $u_n arrow(n to +inf) l$
Operators with an index: sum, prod, lim
sum, prod and lim carry their index in (...) and set their whole expression in display style, so a fraction in the body keeps full size and a limit's target sits under the word, as on a blackboard. The body runs to the end of the formula or to the first =:
$sum(i=1, n) i = n(n+1)/2$ $prod(k=1, n) k$ $lim(x->0) sin(x)/x = 1$ $lim(x->+inf) 1/x$
Functions and trigonometry
Function names are set upright automatically — no backslashes. The set covers sin cos tan cot sec csc, the inverses arcsin arccos arctan, the hyperbolics sinh cosh tanh coth, and ln log exp det dim gcd deg ker arg max min sup. A name glued to (...) takes its argument as one atom, so fractions and powers behave:
$sin(x)^2 + cos(x)^2 = 1$ $cos(a+b) = cos(a)cos(b) - sin(a)sin(b)$ $tan(x) = sin(x)/cos(x)$
Integrals
The integral family writes its variable and bounds in the head (...) and captures the integrand as its body; the differential \,dx is appended automatically. No bounds gives a primitive, a comma-separated pair a definite integral:
$int(x) f(x)$ ∫ f(x) dx $int(x=a, b) f(x)$ ∫ from a to b of f(x) dx
Multiple integrals — separate several domains with ;. The count of domains chooses ∫, ∬ or ∭; the differentials come out in reverse order (Fubini):
$int(x=a, b ; y=c, d) f(x,y)$ ∬ … dy dx $int(x=a, b ; y=c, d ; z=e, g) f$ ∭ … dz dy dx
A single named domain is a region integral: int(D) f gives ∬D f dω. Named integrals: contourint(C) f(z) is a contour integral ∮, pvint(x=a, b) f(x) a Cauchy principal value, meanint(x=a, b) f(x) the average integral ⨍.
Derivatives
A Leibniz derivative is written as the fraction it is, and the differential d is set upright (ISO 80000-2), matching the d of the integrals — only when both sides of the fraction carry it, so a variable named d is never disturbed (d/2 stays the fraction d over 2):
$dy/dx$ dy/dx, upright d $(d^2 y)/(dx^2)$ second derivative $dy/dx + y = 0$ a differential equation
Partial derivatives use partial (∂); parenthesise each side so the fraction groups correctly:
$(partial f)/(partial x)$ $(partial u)/(partial t) = (partial^2 u)/(partial x^2)$
nabla (∇) is available for gradients and divergences.
Maths blocks
Matrices and systems are blocks: one line is one row, and inside a matrix ; separates the entries. Every cell still goes through the mini-language.
<matrix>{
1 ; 2 ; 3
4 ; 5 ; 6
}
<matrix> draws parentheses, <det> the bars of a determinant, <bmatrix> square brackets. A single | inside a row draws the bar of an augmented matrix (allowed on matrix and bmatrix, never on det). A <system> stacks equations under a brace, aligned on the first relational operator:
<system>{
2x + 3y = 7
x - y = 1
}
Inject a computed value with #{expr} (or #name), including inside maths: $#k^2$. Decimal numbers follow the lang option.
The expression computes with a full function library. Inside #{...} you have the transcendental functions, in radians by default:
- circular
sin cos tan cot sec cscand their inversesarcsin arccos arctan; the degree variantssind cosd tandandarcsind arccosd arctandtake or return degrees, so#{sind(30)}is0.5and#{arcsind(0.5)}is30; - hyperbolic
sinh cosh tanh coth sech cschand inversesarcsinh arccosh arctanh; - exponential and logarithms
exp,ln(natural),log(base 10),log2,logb(v, b)(base b); - algebraic and rounding
sqrt cbrt abs sign min max floor ceilandround(x, d)(to d decimals, ties away from zero), with the constantspiande.
So #{sin(pi/6)}, #{exp(1)}, #{logb(81, 3)} all evaluate. The same library backs <plot>, so a curve of cosh(x) or arctan(x) draws from the identical definition.
Rounding for display: precision. The class option precision:N rounds every computed #{...} value to N decimals, dropping trailing zeros (3.50 prints 3.5, 4.0 prints 4). The default -1 prints the number as computed. precision sets the document-wide default; round(x, d) overrides it locally in any single expression. So precision:2 turns #{1/3} into 0.33 while #{round(1/3, 5)} still gives 0.33333.
Advanced vocabulary
For the upper years, the mini-language carries the named notation of probability, linear algebra and vector analysis. Each entry keeps the name(...) shape, and the rendering is the canonical LaTeX a textbook uses.
Counting and probability — the binomial coefficient and arrangement are recognised by their two arguments, so a one-argument C(t) stays an ordinary function. Probability and expectation are the doubled blackboard letters, with the conditional bar written mid:
| You write | You get |
|---|---|
C(n, k) |
binomial coefficient ⁽ⁿₖ⁾ |
A(n, k) |
arrangement Aₙᵏ |
factorial(n) or n! |
n! |
PP(A), PP(A mid B) |
ℙ(A), ℙ(A ∣ B) |
EE(X) |
𝔼(X) |
var(X) std(X) cov(X, Y) |
Var(X), σ(X), Cov(X, Y) |
normal(mu, sigma) |
𝒩(μ, σ²) |
poisson(lambda) |
𝒫(λ) |
binomial(n, p) |
ℬ(n, p) |
repart(X, x) densite(X, x) |
F_X(x), f_X(x) |
Linear algebra — named operators on top of the matrix blocks:
| You write | You get |
|---|---|
ker(f) im(f) rank(A) |
Ker(f), Im(f), rg(A) |
span(u, v) tr(A) com(A) |
Span(u, v), tr(A), com(A) |
transpose(A) inv(A) |
Aᵀ, A⁻¹ |
eigen(A) adj(A) |
Sp(A) (spectrum), adj(A) |
Vector analysis and transforms — the differential operators, the Landau notations (spelt out so the letters o/O stay free), and the integral transforms:
| You write | You get |
|---|---|
grad(f) div(F) curl(F) |
grad f, div F, rot F |
lap(f) |
Δf (prefixes its operand, no parentheses) |
dirderiv(f, u) |
∇_u f |
bigO(...) litO(...) |
O(·), o(·) |
laplace(f) fourier(f) |
ℒ{f}, ℱ{f} |
ilaplace(f) ifourier(f) |
ℒ⁻¹{f}, ℱ⁻¹{f} |
surfint(S) volint(V) flux(F, S) |
∯_S, ∭_V, a flux |
Arithmetic, number theory and sets — and a few calculation templates:
| You write | You get |
|---|---|
lcm(a, b) gcd(a, b) sign(x) |
lcm, gcd, sgn |
card(A) powerset(A) |
card(A), 𝒫(A) |
range(1, n) |
⟦1, n⟧ (integer interval) |
set(x mid x > 0) |
{x ∣ x > 0} (the keyword mid spaces the bar) |
euler(n) mobius(n) |
φ(n), μ(n) |
a equiv b mod n |
a ≡ b (mod n) |
taylor(f, x, a, n) |
the Taylor form (template) |
jacobian(f, n) hessian(f, n) |
the generic partial-derivative matrices |
$EE(X) = sum(k=1, n) k PP(X = k)$ $var(X) = EE(X^2) - EE(X)^2$ $dim(ker(f)) + rank(f) = dim(E)$ $lap(f) = div(grad(f))$ $flux(F, S) = volint(V) div(F)$
Function studies
Three tags turn a function into a variation table and a curve. They share one source of truth: a function object built once with <fn>, then read by <vartab> (the table) and <plot> (the graph).
The function object: <fn>
The equation form reads as the board does and registers itself under its left-hand name — the variable is declared in situ, and a study is then three lines that read like the exercise:
<fn f(x) = (x+2)(x-3)>
<signtab f>
<plot f x:{-4, 5}>
Table attributes stay attributes after the expression:
<fn g(t) = t^2 - 2t
x:{-inf | 1 | +inf}
deriv:{- | +}
var:{+inf \ -1 / +inf}>
A tabular-only object (a table without a formula) takes the head without = — <fn v(x) x:{...} deriv:{...} var:{...}>. Objects rebind sequentially: a later <fn f(x) = ...> shadows the name for what follows, never for what precedes — each <signtab f> or <plot f> sees the definition above it. The 2.4 name:/expr: attributes still parse but are deprecated; the equation form is the canonical one:
let k = <fn name:{k(x)}
expr:{(x^2+1)/(x-1)}
x:{-inf | 1-sqrt(2) | 1 | 1+sqrt(2) | +inf}
second:{- | - || + | +}
deriv:{+ | - || - | +}
var:{-inf / 2-2sqrt(2) \ -inf || +inf \ 2+2sqrt(2) / +inf}>
let NAME = <fn …> stores the object under NAME (the assignment may span several lines, up to the closing >). Fields:
name:{k(x)}— the function and its variable; sets the row labelsx,k'(x),k(x)(andk''(x)when a second-derivative line shows).name:{k}alone usesx; omitname:forf(x).expr:{…}— the formula, in the maths mini-language. Read only by<plot>;<vartab>ignores it.x:{… | … | …}— the remarkable abscissas, separated by|.deriv:{…}— the sign of the first derivative, one sign per interval.second:{…}— the sign of the second derivative (convexity), one per interval. Optional.var:{…}— the variation line (see below).
The table: <vartab>
<vartab k> reads the object k. Or write the data inline: <vartab x:{…} deriv:{…} var:{…}>.
Four shapes are allowed, depending on which sign lines you give. Only x: and var: are required; deriv: and second: are each optional:
| shape | fields | rows |
|---|---|---|
| full study | second: + deriv: |
x, f″(x), f′(x), f(x) |
| classic variation | deriv: |
x, f′(x), f(x) |
| convexity only | second: |
x, f″(x), f(x) |
| value table | neither | x, f(x) |
f″ always sits above f′. The value table (no sign line) just joins the listed values by arrows.
Sign lines (deriv:, second:) take one sign per interval: +, -, or empty. || (a double bar) marks a forbidden value (a pole): the bar crosses every row. Zeros at sign changes are placed automatically — you don't write them.
The variation line (var:) alternates value and connector. A connector is / (rising) or \ (falling), surrounded by spaces — glued, as in 2/3, it is a fraction, not an arrow. || carries the two limits around a pole. Values may be numbers, +inf/-inf, or any maths expression (2-2sqrt(2), 27/4).
Rules the table enforces: a value between two arrows of the same direction is rejected — a variation table lists only bounds and extrema, never a point on a monotone branch (that point belongs on the plot). When f″ and f′ show together, x: must list the union of their zeros, since all rows share the same columns.
The sign table: <signtab>
The companion of <vartab> for factored expressions. Automatic: the rows are computed from a product/quotient of affine factors — exact rational zeros, a forbidden value at each denominator zero, even multiplicities known not to change sign:
<fn f(x) = (x+2)(x-3)> <signtab f> <fn g(x) = (x+1)/(x-2)> <signtab g> <fn h(x) = -2(x+1)^2 (x - 1/2)> <signtab h>
Manual (the general form, for rows the affine engine cannot derive) — one row per factor, usually a conclusion row last:
<signtab x:{-inf | -2 | 3 | +inf}>{
x+2 : - | 0 | + | +
x-3 : - | - | 0 | +
f(x) : + | 0 | - | 0 | +
}
A cell is a sign per interval; a 0 marks a zero at the boundary it follows, || a forbidden value. The invariant is checked at compile time: a row that changes sign without a 0 or a || at the boundary is an error, not a wrong table in print — an expression cannot change sign without vanishing or ceasing to exist there.
The graph: <plot>
<plot k samples:200 x:{-4, 6} y:{-10, 12}>
<plot k> reads expr: and name: from the object. Options:
x:{a, b}— horizontal display window (comma between the two bounds). Defaults to the finite abscissas of the table.y:{c, d}— vertical window. Required when the function runs to infinity (a pole), so the view is framed.samples:N— number of points computed (default 100).
expr: is translated to the plotter's syntax: the variable becomes the plotting variable, trigonometric calls get the degree conversion, and implicit products (2x, 2(x-1)) become explicit. Poles are handled so no spurious vertical line joins the branches. Supported in expr:: + - * / ^, parentheses, sin cos tan exp ln log sqrt abs, and pi.
<vartab> is declarative, <plot> is computed. If var: does not match expr:, the table and the curve contradict each other silently — keeping them consistent is yours to ensure.
Areas. area:{a,b} shades the region between the curve and the x-axis on a, b, with dashed verticals at the bounds; between:g shades between two curves instead (clipped to area: when given):
<plot f x:{-1, 4} area:{1, 3}>
<plot f x:{-1, 4} between:g area:{0, 3}>
Sequences: the cobweb. cobweb:{u0} (or cobweb:{u0, n}, default n = 8) draws the bisector y = x and the staircase of u(n+1) = f(u(n)); the iterates are computed at compile time and the first three labelled on the axis:
let h = <fn name:{h(x)} expr:{sqrt(2x+3)}>
<plot h x:{0, 4} y:{0, 4} cobweb:{0.2, 10}>
Probability laws. The two laws of the lycée need no <fn> object; area: highlights P(a ≤ X ≤ b) on both — shaded under the Gaussian, stronger bars on the binomial. The normal window defaults to μ ± 4σ; the binomial masses are computed exactly:
<plot normal:{0, 1} area:{-1, 1.5}>
<plot binomial:{12, 0.4} area:{3, 6}>
Maths note: in prose use the mini-language spellings!=,+-,>=,<=(not\neq,\pm, …). Write$f(x)$to typeset a formula; an unbracketedf(x)/xparses asftimes(x)/x, so phrase it as "the ratio of$f(x)$to$x$".
The lycée toolbox
Five more figures complete the secondary curriculum (2.5).
The weighted probability tree — <tree>, the most-drawn object of première and terminale. Each line reads LABEL PROBABILITY, an optional brace opening the children; a leading ! is the complementary event (overline). Probabilities may be numbers or symbols (p, 1-p). A node with exactly one branch receives its complement automatically — the only case that is mathematically determined; siblings that sum to something other than 1 are a compile error. products:on writes P(A ∩ B) = 0.18 at each leaf — the exact product when numeric, the symbolic chain otherwise. The layout is computed: leaves evenly spaced, nodes at the mean height of their children.
<tree products:on>{
A 0.3 {
B 0.6
}
!A 0.7 {
B 0.1
}
}
Descriptive statistics — one tag, <stats>, five kind:s, every number computed at compile time:
<stats kind:bars data:{1: 4 | 2: 7 | 3: 2}>
<stats kind:bars data:{Walk: 5 | Bus: 3 | Bike: 2}>
<stats kind:histogram bounds:{0, 5, 10, 20} counts:{3, 7, 2}>
<stats kind:pie data:{Walk: 5 | Bus: 3 | Bike: 2}>
<stats kind:boxplot data:{12, 15, 9, 21, 14, 15, 18}>
<stats kind:scatter data:{(1, 2.1) (2, 2.6) (3, 3.4)} fit:on>
The dictionary key: value | … is the form of the mappings — bars (numeric keys give a numeric axis, words give categories) and pie; pairs (x, y) remain the form of the clouds, where an abscissa may repeat.
Data variables. A Lua table declared with let is passed by name — the natural home of data reused across figures:
let notes = {
Mathematiques = 15.5,
Francais = 12.0,
Anglais = 18.0
}
<stats kind:bars data:notes>
<stats kind:pie data:notes>
A Lua table has no writing order, so map keys come out sorted (numbers numerically, words alphabetically); when the order matters, write a list of pairs, which keeps it: let trimestres = {{"T1", 11.5}, {"T2", 13.0}}. Lists of numbers feed boxplot, lists of {x, y} pairs feed scatter, and two list variables feed histogram through bounds: and counts:.
Three honesty guarantees, because a statistics figure teaches by its construction: the histogram draws density (count over class width), so unequal classes stay truthful; the boxplot uses the French secondary-school quartiles (Q1 the smallest value with at least a quarter of the data at or below it, Q3 likewise at three quarters); fit:on draws the least-squares line — computed, not eyeballed.
The number line — <numberline>, the figure of inequalities and absolute values. Solved: the block form takes one inequality (the tag's braces cannot carry < and >) and computes the set exactly — an affine expression against a constant, a product/quotient of affine factors against 0, or abs(affine) against a constant. Strictness decides open/closed; a denominator zero is always excluded; an isolated solution is a point:
<numberline x:{-5, 5}>{
abs(x - 1/2) >= 5/2
}
Declared, when the set is given rather than solved — brackets follow the international convention ([ ] included, ( ) excluded); a bound may be inf, the segment then runs to the arrow; points: pins isolated values:
<numberline x:{-5, 5} set:{[-2, 3) union (4, inf)} points:{-4}>
The trigonometric circle — one <draw> line: the circle, its axes, and the sixteen remarkable angles labelled by their principal measure in (−π, π]. values:on adds the dashed cos/sin projections (exact values at the remarkable angles, two decimals elsewhere). Dynamic: step:{pi/12} draws the multiples of the step, range:{0, pi/2} restricts to an arc — the first-quadrant close-up. Labels too crowded to read are a compile error suggesting a larger step:
<draw>trigcircle radius:4 values:on
<draw>trigcircle radius:4 step:{pi/6}
<draw>trigcircle radius:4 range:{0, pi/2} step:{pi/12} values:on
Space geometry — solid lines inside <draw> render the full repertoire in the French perspective cavalière (receding axis at 45°, ratio 0.5; override with angle:/ratio:). Hidden edges are computed, not declared: a face of a convex solid is visible exactly when the projection preserves its outward orientation, and an edge is dashed exactly when both of its faces are hidden. Several solids in one block sit side by side. Vertex names are optional on cube, cuboid (eight letters, base then top) and pyramid (apex first). Plane sections are deferred to a later release.
<draw>{
solid cube ABCDEFGH edge:4
solid pyramid SABCD base:4 height:5
}
<draw>{
solid cuboid sides:{5, 3, 2}
solid cylinder radius:1.5 height:4
solid cone radius:2 height:4.5
solid sphere radius:2.5
}
Boxes
<box line:Crimson fill:MistyRose radius:4 title:{A note}>{
Content here.
}
Options: line: frame colour, fill: background, text: text colour, radius:N rounded corners (mm), width:N or width:N%, boxrule:N, sep:N (inner padding, mm; boxsep:N is a synonym), break:yes, title:{…}, titlefill:, titletext:. A line containing only --- splits a box into two regions.
<row gap:N>{ … } lays its child boxes side by side, equal widths and equalised heights. A box also takes a two-letter placement code (tl…br, default tl); the vertical part needs a height: to act.
Grid (named-area layout)
For full-page layouts — a worksheet header with a logo, a title bar, info fields, and a body — <grid> borrows CSS Grid's named-area idea. A template:[ … ] of quoted rows draws the layout; each word names a cell. A name repeated horizontally spans columns, vertically spans rows; a dot . is empty.
<grid template:[
"title title logo"
"intro info logo"
"body body body"
] gap:4>{
<area title>{ <Red b 16pt>Maths assessment }
<area logo >{ <img>{blason.png} }
<area intro>{ Instructions: no calculator. }
<area info >{ Name: \\ First name: }
<area body >{ <s1>Exercise 1
Solve the equation... }
}
An area can be framed like a box (line:, fill:, radius:, title:). The grid takes width: and height:; an area or the grid takes a two-letter placement code for content position within cells.
Lists
A list is <list:STYLE> — the style follows the name, one item per line, no item tag:
<list:decimal>{
Read the instructions
Underline the key words
Write your answer
}
Styles — bullets: none disc circle square; numbered: decimal alpha ALPHA roman ROMAN (the case of the keyword sets the case of the letters); checkboxes: check. A list written under an item becomes its sub-list, nested as deep as you like. Text attributes on the tag wrap the whole list: <list:ROMAN TIMES NEW ROMAN 12pt i>{ … }.
Block aliases
Define a reusable component once; #param placeholders are filled at the call site, and the call-site body becomes the block content — so it may contain sub-blocks of its own.
let card{title, frame} = <box title:{#title} line:#frame radius:2>
<card First, Crimson>{ Called with two arguments. }
<card Second, Navy>{ Same component, different look. }
Control flow
for n in 1..3 {
<c Navy b>Sheet #n
}
for f in [chat.png, chien.png] {
<img 16>{#f}
}
if score >= 10 {
<Green>Passed.
} else {
<Red>Try again.
}
Loops and conditions work in the document body, inside boxes, and inside table bodies. The loop variable interpolates everywhere via #.
Escapes
To print a character that scholatex treats specially, double it: << >> {{ }} ## give a literal < > { } #. The backslash is an ordinary character — a path like C:\Users\Leo or a regex \d+\s*\w prints verbatim, nothing to escape. The characters _ & % ~ are escaped automatically. A line break inside a paragraph is the tag <nextline>. A line whose first non-space character is % is a comment. A bare # not followed by a name or {…} is a literal #.
Braces carry structure, so a literal brace must be balanced: write the pair {{…}} to print {…}. A lone, unmatched {{ or }} is reported as an unbalanced brace naming its line, rather than silently corrupting the surrounding block — so set-builder notation like {{ x : x > 0 }} is written as a pair. Angle brackets and hashes need no such balancing; only braces do.
## Colour reference
Every colour is written in CamelCase — there is one rule and no lowercase shortcuts. The everyday colours are simply capitalised: Red Blue Green Navy Orange Purple Teal Brown Gray/Grey Pink Yellow Black White Violet Cyan Magenta Lime Olive Aqua Silver Maroon.
For the full palette, write any of the 151 CSS / svgnames colours in CamelCase (<SteelBlue>{…}, fill:MistyRose, line:DarkOrange). They are grouped below by family for browsing; all are valid anywhere a colour is expected (line: fill: text: and inline tags).
Reds & pinks (14) — Brown, Crimson, DarkRed, FireBrick, IndianRed, LightCoral, LightPink, Maroon, MistyRose, Pink, Red, RosyBrown, Salmon, Tomato
Oranges & browns (23) — AntiqueWhite, Bisque, BlanchedAlmond, BurlyWood, Chocolate, Coral, DarkGoldenrod, DarkOrange, DarkSalmon, Goldenrod, LightSalmon, Moccasin, NavajoWhite, Orange, OrangeRed, PapayaWhip, PeachPuff, Peru, SaddleBrown, SandyBrown, Sienna, Tan, Wheat
Yellows & golds (11) — Cornsilk, DarkKhaki, Gold, Khaki, LemonChiffon, LightGoldenrod, LightGoldenrodYellow, LightYellow, Olive, PaleGoldenrod, Yellow
Greens (20) — Aquamarine, Chartreuse, DarkGreen, DarkOliveGreen, DarkSeaGreen, ForestGreen, Green, GreenYellow, LawnGreen, LightGreen, Lime, LimeGreen, MediumAquamarine, MediumSeaGreen, MediumSpringGreen, OliveDrab, PaleGreen, SeaGreen, SpringGreen, YellowGreen
Cyans & teals (17) — Aqua, CadetBlue, Cyan, DarkCyan, DarkSlateGray, DarkSlateGrey, DarkTurquoise, DeepSkyBlue, LightBlue, LightCyan, LightSeaGreen, MediumTurquoise, PaleTurquoise, PowderBlue, SkyBlue, Teal, Turquoise
Blues (21) — Blue, CornflowerBlue, DarkBlue, DarkSlateBlue, DodgerBlue, LightSkyBlue, LightSlateBlue, LightSlateGray, LightSlateGrey, LightSteelBlue, MediumBlue, MediumPurple, MediumSlateBlue, MidnightBlue, Navy, NavyBlue, RoyalBlue, SlateBlue, SlateGray, SlateGrey, SteelBlue
Purples & violets (17) — BlueViolet, DarkMagenta, DarkOrchid, DarkViolet, DeepPink, Fuchsia, HotPink, Indigo, Magenta, MediumOrchid, MediumVioletRed, Orchid, PaleVioletRed, Plum, Purple, Violet, VioletRed
Grays (10) — DarkGray, DarkGrey, DimGray, DimGrey, Gray, Grey, LightGray, LightGrey, Silver, Thistle
Whites & off-whites (17) — AliceBlue, Azure, Beige, FloralWhite, Gainsboro, GhostWhite, Honeydew, Ivory, Lavender, LavenderBlush, Linen, MintCream, OldLace, Seashell, Snow, White, WhiteSmoke
Black (1) — Black
These are exactly the colours xcolor provides under its svgnames option (the 147 CSS Color Module names plus the four X11 extras LightGoldenrod, LightSlateBlue, NavyBlue and VioletRed). Names are case-sensitive: write Seashell, not SeaShell.
## Security
scholatex evaluates let name = expr, #{expr} and the conditions of for/if/while as Lua at compile time, so by default a document can run arbitrary code — exactly like \directlua.
Setting untrusted=true in \documentclass[...]{scholatex} runs that Lua in a restricted environment: only pure, side-effect-free names are visible; os, io, package, require, load, debug and other escape vectors are absent. A blocked access stops the compile with a clear message; a runaway loop is aborted by an instruction-count ceiling; string.rep/string.format are capped.
\documentclass[untrusted=true]{scholatex}
untrusted hardens the scholatex expression layer only. It does not sandbox LuaLaTeX as a whole — a hostile .tex can still call \directlua, \write18, \input. Use it when the scholatex body comes from a semi-trusted source while the surrounding .tex is your own; for a whole untrusted .tex, run lualatex without --shell-escape, ideally in a container.
Examples
The examples/ folder contains eight self-contained, fully commented documents that together exercise every feature:
| File | Covers |
|---|---|
text-style.tex |
the case rule, styles, colours, fonts, sizes, alignment, tabs, skips, scripts; factoring styles into aliases; a table of contents from the heading keywords |
containers.tex |
tables, boxes and the named-area grid, each built up from its simplest form to a full worksheet header |
basics.tex |
the inline mini-language, number sets, quantifiers and connectives, negation with !, set relations, the integer part, the overline, and arithmetic helpers |
analysis.tex |
operators with an index, limits, trigonometry, derivatives, the vector operators, the integral family, transforms — then sign tables, the number line, areas and cobwebs, and four full function studies (<fn>, <vartab>, <plot>), from polynomial to hyperbolic |
algebra.tex |
the matrix / determinant / augmented-matrix / system blocks, and the linear-algebra vocabulary |
geometry.tex |
angles, vectors, coordinate systems, the <draw> figures and axes — then the trigonometric circle and the six solids in cabinet projection |
statistics-probability.tex |
counting, probability and expectation, variance, distributions and density — then weighted trees, the two laws, and the five figures of descriptive statistics |
Compile any of them with lualatex <file>.tex from the examples/ folder.
Project layout
scholatex.cls LaTeX class: options, packages, reads & injects the body scholatex.lua transpiler core: tags, text, control flow, aliases scholatex-style.lua attribute resolution (colours, styles, sizes, alignment…) scholatex-math.lua the $…$ math mini-language (operators, integrals, functions, trig) scholatex-util.lua parsing primitives (groups, brace balance, comma split) scholatex-table.lua the <table> block scholatex-img.lua the <img> tag scholatex-box.lua the <box> and <row> blocks scholatex-grid.lua the <grid> named-area layout block scholatex-section.lua the <section>/<subsection>/<subsubsection> blocks scholatex-list.lua the <list:STYLE> block scholatex-matrix.lua the <matrix>/<det>/<bmatrix> and <system> blocks scholatex-vartab.lua the <fn> object and the <vartab> table scholatex-signtab.lua the <signtab> sign table scholatex-plot.lua the <plot> curve: areas, cobwebs, probability laws scholatex-tree.lua the <tree> weighted probability tree scholatex-stats.lua the <stats> descriptive-statistics figures scholatex-numberline.lua the <numberline> graduated line, declared or solved scholatex-affine.lua exact sign analysis of affine factors (rational zeros) scholatex-figure.lua the <draw> block: figures, points, segments, trigcircle scholatex-solid.lua space geometry in cabinet projection (solid …) scholatex-toc.lua the <tableofcontents> tag examples/ eight commented showcase documents
New tags register themselves via scholatex.register_tag / scholatex.register_block; a name clash raises an error rather than silently overwriting, so modules stay independent.
Diagnostics
Errors point at the source line, e.g. scholatex: line 12: unknown tag attribute: 'xyz'. Defining an alias whose name is a built-in (let section = …) prints a warning: the built-in always wins, so the alias would be silently dead — pick a different name.
What's new
2.5
The lycée release: the last nine figures and tables of the French secondary curriculum, so a worksheet from seconde to terminale never leaves the tag language.
- Sign tables
<signtab>— automatic (<signtab f>computes rows, exact zeros and forbidden values from the factored expression) or manual (one row per factor,0at a boundary zero,||at a forbidden value; a sign change without either is a compile error). - Weighted probability trees
<tree>— declarative branches,!Bfor the complement, symbolic probabilities accepted, single branches auto-completed with their complement,products:onfor the leaf products (exact when numeric). - Areas in
<plot>—area:{a,b}under a curve,between:gbetween two curves. - Cobwebs —
cobweb:{u0, n}draws the staircase of u(n+1) = f(u(n)) with the bisector, iterates computed. - Probability laws —
<plot normal:{mu,sigma}>and<plot binomial:{n,p}>without an<fn>object;area:highlights P(a ≤ X ≤ b) on both. - The
<fn>equation form —<fn f(x) = (x+2)(x-3)>registers itself under its left-hand name; the declaration reads like the exercise. - Data variables —
let notes = {Mathematiques = 15.5, ...}then<stats kind:bars data:notes>; multi-linelettables accepted. - Statistics
<stats>— bars (a dictionary of frequencies, numeric or categorical), histogram (density, honest with unequal classes), pie, boxplot (French quartiles), scatter with a computed least-squaresfit:on. - Trigonometric circle —
<draw>trigcircle, remarkable angles in principal measure by default,step:{pi/12}andrange:{0, pi/2}for a chosen graduation or a first-quadrant close-up,values:onfor the cos/sin projections. - Number line
<numberline>— declared interval sets (included/excluded endpoints,union, infinite bounds, isolated points) or a solved inequality (block form), the set computed exactly. - Space geometry —
solid cube/cuboid/pyramid/cylinder/cone/spherein perspective cavalière, hidden edges computed from face orientation, solids laid side by side.
2.4
- Analytic geometry in
<draw>: theaxes:mode —<draw axes:{xmin,xmax,ymin,ymax}>draws a graduated cartesian frame and reads every line as a coordinate directive rather than a construction. One unit stays one centimetre and the drawing is clipped to the window. A block withoutaxes:keeps the 2.3 construction behaviour unchanged.point NAME (x,y)places and labels a point, available to later lines by name.vector u (x,y)draws a free vector from the origin;vector ABthe bound vector between two placed points. A named vector is remembered:vector s = u+v(oru-v) draws the sum or difference, labelled with the expression along the arrow;from:moves any vector's tail (a placed point, a literal pair, or~ufor the tip of a drawn vector) andstyle:restyles the copy (style:dashed-gray,style:Blue) — the parallelogram and triangle rules read on a single frame.lineby equation (y = 2x-1,x = -3, the general2x+3y = 6) orline through A B.circle center:A radius:r(centre a placed point or a literal pair) or by equationcircle x^2+y^2 = 4; a named circle carries atangent to:C at:Pat a point on it.regionshades the half-plane of a linear inequality (<,>), the boundary dashed.
- Parametric and polar curves in
<plot>: thekind:field —kind:parametricreadsexpr:{x(t), y(t)}overt:{a, b};kind:polarreadsexpr:{r(theta)}overtheta:{a, b}, drawn as(r cos theta, r sin theta). Bounds acceptpi. Conics follow from the parametrisation (ellipse{a cos(t), b sin(t)}, parabola{t, t^2}, hyperbola{a cosh(t), b sinh(t)}) — no separate conic directive. A<plot>withoutkind:is the function graph, unchanged.
2.3
- Figure drawing: the
<draw>block — a plane figure is described, not hand-placed. Name the shape and give its measurements; the coordinates are computed trigonometrically and emitted as hard numbers. One drawing unit is one centimetre, soside:5draws a 5 cm side.- Triangles by any classical definition —
equilateral,isosceles,right(right angle at the first point, orright:X), three sidessides:(a,b,c), two sides and the included anglesides:(a,b) angle:t, two angles and a sideangles:(A,B) side:c, or three sides named one by one (AB:3 BC:4 CA:5). - Quadrilaterals —
square,rectangle,rhombus,parallelogram,trapezoid, andkite(two pairs of adjacent equal sides, the rhombus being the case where both pairs are equal). - Regular polygons by name from the pentagon up (
pentagon,hexagon,octagon), orpolygonwith as many points as given. - Circles by centre and
radius:rordiameter:d(the radius optionally a placed segment,radius:AB);circle ABCis the circumscribed circle of three placed points, withinscribedfor the incircle.
- Triangles by any classical definition —
- Coding and measurement —
marks:oncodes equal sides and right angles;measures:cm/measures:mmlabels each side with its length. Both are opt-in. When a figure has two pairs of equal sides of different lengths (kite, rectangle, parallelogram), the pairs are told apart by their tick count — a single tick on one pair, a double tick on the other — so a kite never reads as a rhombus. - Composite figures — several figures in one block share their points; a figure repeating a point is grafted onto it, and a figure sharing an edge deduces that edge's length and is flipped to the far side so the pieces abut. A shared edge is labelled once and ticked once, not twice.
- Multi-character point names — besides the glued single letters (
triangle ABC), a parenthesised comma-separated list names multi-character points:triangle (O, A0, B0). - Loops, interpolation and rotation inside
<draw>— the samefor VARIABLE in FROM..TO { … }loops as the rest of the language;#kand#{expr}interpolate point names and measurements;rotate:θturns a figure about its first point,scale:Fmultiplies every coordinate of the picture by F leaving the text size alone (default 1, any<draw>form), andlabels:offhides the vertex names — enough to fan, rosette or step figures round a centre. - Low-level primitives
pointandline—point(P)places a dot at coordinates declared withlet P = {x, y};line(A, B)draws a segment between two points (names or literal{x, y}pairs), takingmeasures:like a figure side. As each coordinate is an ordinary expression, a loop can compute endpoints — the building block for free-form drawings. - Examples — a new
geometryshowcase covers the inline geometry vocabulary and the full<draw>block.
2.2
- Probability and statistics — the blackboard operators
PP(...)ℙ andEE(...)𝔼 (withPP(A mid B)for a conditional), spread (var,std,cov), distributions (normal,poisson,binomial), and the distribution/density functions (repart,densite). - Counting — the binomial coefficient
C(n, k)and arrangementA(n, k), recognised by their two arguments so a one-argumentC(t)stays a function; the factorialfactorial(n)orn!. - Linear-algebra vocabulary —
ker,im,rank,span,tr,com,eigen(the spectrum),adj, withtranspose(A)→ Aᵀ andinv(A)→ A⁻¹. - Vector analysis —
grad,div,curl, the Laplacianlap(f)Δf, the directional derivativedirderiv(f, u), the Landau notationsbigO/litO, the transformslaplace/fourierand their inverses, and the surface/volume integralssurfint/volint/flux. - Number theory and helpers —
eulerφ,mobiusμ, congruencea equiv b mod n, pluslcm,sign,card,powerset, the integer intervalrange(1, n)⟦1, n⟧, the keywordmidfor a spaced bar, and the templatestaylor,jacobian,hessian. - Fixes — a parenthesised group over a fraction now grows to full height (
(a/b)^2); higher-order differentialsd^2y/dx^2set the upright d throughout; plot tick numbers stay readable where a curve crosses an axis, and the axis arrow clears the last graduation. - Examples by domain — the maths showcase now mirrors the manual's four categories:
basics,algebra,analysis(which holds the function studies) andprobability.
2.1
- Mathematical vocabulary — number sets in blackboard bold (
NNZZDDQQRRCC, plusPPKKHHFFEEUU), quantifiers and connectives (forallexistsandorlnotneg), implication and equivalence as words or arrows (=>/implies,<=>/iff), set relations (insubsetcupcapsetminusemptyset…), the integer part (floorceilround), and accents (bar/conjfor the conjugate-mean-closure overline,notfor logical negation,hattilde). - Negation with a single
!—!in front of a relation or quantifier negates it with the proper struck-through glyph:!in∉,!exists∄,!subset⊄,!subseteq⊈,!equiv≢.!=stays "not equal". - Limit arrow —
arrow(n to +inf)sets a long right arrow with its condition underneath, for the "uₙ → l" phrasing in running maths. - Colours are CamelCase only (breaking change) — the lowercase keywords (
red,navy, …) are removed; write the CamelCase form (Red,Navy). One rule for all 151 colours. A lowercase colour now raises an error that names the CamelCase replacement. - Function studies — three new tags for analysis:
<fn>builds a function object (name, formula, abscissas, derivative signs, variation),<vartab>renders its variation table,<plot>draws its curve (via pgfplots, with pole handling). The table comes in four shapes — full (f″, f′, f), classic (f′, f), convexity (f″, f), or a plain value table (f) — since the two derivative lines are independent and optional. - Section numbering styles —
num,roman,ROMAN,alpha,ALPHAset the counter style of a heading level on its own, with no inherited prefix; the default stays hierarchical. - Examples reorganised — the showcase set is now
text-style,containers,math-language,math-analysis,math-algebraandfunctions(the old single03-mathis split by topic).
2.0
- New escape rules (breaking change) — to print a special character, double it:
<<>>{{}}##give a literal<>{}#. A backslash is now an ordinary character (soC:\Usersjust works); it is no longer an escape. The old\<\>\{\}\#forms no longer apply. - Line break is a tag (breaking change) — use
<nextline>(in text and table cells) instead of the old\\. In running text a blank line already starts a new paragraph, so<nextline>is only for a break without a paragraph change.
1.2
- Script/fraction precedence fix —
^and_now bind tighter than/, sox^2/yrenders as the fraction ofx^2overy(and1/i^2as1overi^2), matching ordinary mathematical reading - Automatic spacing for tall lines — consecutive lines containing fractions or integrals no longer touch; TeX inserts just enough air where needed, leaving ordinary text unchanged
1.1
- Maths expansion — full integral family (
int, multiple integrals with Fubini ordering,contourint,pvint,meanint), upright functions and trigonometry, Leibniz and partial derivatives with ISO 80000-2 upright differentials - Operators in display style —
sum,prod,limkeep fractions full-size and place limits under the word - Full colour parity — all 151 xcolor svgnames colours recognised, grouped by family in the reference
- Cross-platform install — documented
tlmgrand manual paths for macOS, Linux and Windows
Acknowledgments
scholatex is built on excellent LaTeX packages:
- tcolorbox — framed boxes and posters
- tabularray — reliable 2-D table layout
- unicode-math — OpenType maths
- fontspec — system fonts in LuaLaTeX
- xcolor — the svgnames colour palette
License
Copyright © 2026 Gérard Dubard.
scholatex is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 (or later) as published by the Free Software Foundation. See the LICENSE file for the full text.
This program 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.
Herunterladen des vollständigen Inhalts dieses Pakets in einem Zip-Archiv (587.8k).
scholatex – A tag-based language for print-ready teaching worksheets, built on LuaLaTeX
scholatex is a LuaLaTeX document class for teachers who need print-ready worksheets without writing LaTeX. The author writes a single .tex file in a compact, readable tag language; the class translates it to LaTeX at compile time and produces output of full LaTeX quality.
| Paket | scholatex |
| Hilfe | |
| Fehlermeldungen | |
| Repository | |
| Version | 2.5 |
| Lizenzen | GNU General Public License, version 3 or newer |
| Copyright | 2026 Gérard Dubard |
| Betreuer | Gérard Dubard |
| Enthalten in | TeX Live als scholatex MiKTeX als scholatex |
| Themen | Markup Lehre Struc mkup Klassen |