This language is soooo hard to parse… whitespace, parenthesizes for everything, and Unicode :(
DONE:
[O] Code mode: #
to enter code mode
1
, "hi"
, true
, false
, none
, auto
{ x = 1 }
[ hello ]
(1 + 2)
(1, 2, 3)
(a: "hi", b: 2)
-x
x + y
x = 1
x
x.y
x.flatten()
let f(x) = 2 * x
(x, y) => x + y
min(x, y)
let x = 1
set text(14pt)
set text(..) if ..
show par: set block(..)
show par: set block(..)
show: set block(..)
if x < 0 {0} else {x}
for x in [1, 2, 3]
while x < 10 {}
break
, continue
return x
include "bar.typ"
import "bar.typ"
import "bar.typ": a, b, c
// hi
or /* hi */
.[ ] Math mode
[ ] Markup mode
Outdated specification comes from: https://www.user.tu-berlin.de/laurmaedje/programmable-markup-language-for-typesetting.pdf
I'll be using the textmate grammar as inspiration: https://github.com/typst/typst/blob/main/tools/support/typst.tmLanguage.json
For myself, I'll paste it here:
Below is an approximate EBNF grammar for the Typst language that is based on our handwritten recursive descent parser. We follow these conventions:
– Production names are all lowercase.
– Text enclosed in single (') or double quotes (") defines a terminal.
– * for an arbitrary number of repetitions.
– + for at least one repetition.
– ? for zero or one repetitions.
– ! to negate a simple (character-class-like) production.
– . to match an arbitrary character.
– a - b to match anything that matches a but not b.
– unicode(Property) to match any character that has the given unicode property.
Note that comments and spaces are allowed almost everywhere within code constructs. For readability, this is omitted in the grammar. Moreover, the grammar omits the indentation rules for lists, as EBNF cannot handle context-sensitive constructs.
// Markup.
markup ::= markup-node*
markup-node ::=
space | nbsp | shy | endash | emdash | ellipsis | quote |
strong | emph | raw | link | math | heading | list | enum | desc
// Markup nodes.
nbsp ::= '~'
shy ::= '-?'
endash ::= '--'
emdash = '---'
ellipsis ::= '...'
quote ::= "'" | '"'
strong ::= '*' markup '*'
raw ::= '`' (raw | .*) '`'
link ::= 'http' 's'? '://' (!space)*
math ::= ('$' .* '$') | ('$[' .* ']$')
heading ::= '='+ space markup
list ::= '-' space markup
enum ::= digit* '.' space markup
desc ::= '/' space markup ':' space markup