aboutsummaryrefslogtreecommitdiff
path: root/lib/render
diff options
context:
space:
mode:
Diffstat (limited to 'lib/render')
-rw-r--r--lib/render/escape.ml33
-rw-r--r--lib/render/escape.mli10
2 files changed, 34 insertions, 9 deletions
diff --git a/lib/render/escape.ml b/lib/render/escape.ml
index f506c44..ee9ce6c 100644
--- a/lib/render/escape.ml
+++ b/lib/render/escape.ml
@@ -1,18 +1,19 @@
-type flavour = Latex | Groff | Html | Xml | Ics | None_
+type flavour = Latex | Typst | Groff | Html | Xml | Ics | None_
-let all = [ Latex; Groff; Html; Xml; Ics; None_ ]
+let all = [ Latex; Typst; Groff; Html; Xml; Ics; None_ ]
let to_string = function
- | Latex -> "latex" | Groff -> "groff" | Html -> "html"
+ | Latex -> "latex" | Typst -> "typst" | Groff -> "groff" | Html -> "html"
| Xml -> "xml" | Ics -> "ics" | None_ -> "none"
let of_string = function
- | "latex" -> Some Latex | "groff" -> Some Groff | "html" -> Some Html
+ | "latex" -> Some Latex | "typst" -> Some Typst | "groff" -> Some Groff | "html" -> Some Html
| "xml" -> Some Xml | "ics" -> Some Ics | "none" -> Some None_
| _ -> None
let of_extension = function
| ".tex" -> Some Latex
+ | ".typ" -> Some Typst
| ".ms" | ".mom" | ".me" -> Some Groff
| ".html" | ".htm" -> Some Html
| ".xml" -> Some Xml
@@ -37,6 +38,29 @@ let latex = function
| '~' -> "\\textasciitilde{}"
| c -> String.make 1 c
+(* Typst markup metacharacters, verified live against the installed `typst`
+ 0.14.2 binary rather than assumed (probe: each character escaped,
+ compiled, pdftotext'd back, confirmed literal; each also confirmed to
+ do something ELSE when left bare -- '#' opens code mode, '*'/'_' toggle
+ strong/emph, '$' opens math, '@' opens a reference (a bare "@word" is a
+ hard COMPILE ERROR, not merely mangled output, if "word" resolves to no
+ label), '<'/'>' can close around a bare word into label syntax that
+ swallows it whole, '`' opens raw, '~' is a non-breaking space, and a run
+ of two or three '-' becomes an en/em dash). Backslash-escapable in every
+ case -- no character on this list needed a non-backslash workaround.
+ '-' is escaped UNCONDITIONALLY, not only inside a detected run: this
+ function has no lookahead (see [expand]'s own comment above), so it
+ cannot tell "is this hyphen part of a run" one character at a time: a
+ probe confirmed escaping every hyphen independently ("\-\-\-") still
+ typesets as three literal hyphens, never collapsing to an em dash, so
+ the single per-character rule is sufficient for runs of any length. *)
+let typst = function
+ | '\\' -> "\\\\"
+ | '#' -> "\\#" | '*' -> "\\*" | '_' -> "\\_" | '$' -> "\\$"
+ | '@' -> "\\@" | '<' -> "\\<" | '>' -> "\\>" | '`' -> "\\`"
+ | '~' -> "\\~" | '-' -> "\\-"
+ | c -> String.make 1 c
+
let html = function
| '&' -> "&amp;" | '<' -> "&lt;" | '>' -> "&gt;"
| '"' -> "&quot;" | '\'' -> "&#39;"
@@ -57,6 +81,7 @@ let groff s =
let apply flavour s =
match flavour with
| Latex -> expand latex s
+ | Typst -> expand typst s
| Groff -> groff s
| Html | Xml -> expand html s
| Ics -> expand ics s
diff --git a/lib/render/escape.mli b/lib/render/escape.mli
index 97cf050..ee1e20b 100644
--- a/lib/render/escape.mli
+++ b/lib/render/escape.mli
@@ -3,11 +3,11 @@
Knows nothing about calendars. Pure and total: every function is defined on
every string, and none reads the clock, the environment or the filesystem. *)
-(** The six escaping modes. Markdown, AsciiDoc and plain text all use [None_]:
- their metacharacter sets are context-dependent, and escaping them
- aggressively produces worse output than not escaping at all (spec section 5).
- This is a documented limitation of those flavours. *)
-type flavour = Latex | Groff | Html | Xml | Ics | None_
+(** The seven escaping modes. Markdown, AsciiDoc and plain text all use
+ [None_]: their metacharacter sets are context-dependent, and escaping
+ them aggressively produces worse output than not escaping at all (spec
+ section 5). This is a documented limitation of those flavours. *)
+type flavour = Latex | Typst | Groff | Html | Xml | Ics | None_
val all : flavour list
val to_string : flavour -> string