Skip to content

Commit b8f35ff

Browse files
OmikhleiaDidier Willis
authored andcommitted
feat(math): Support TeX-like apostrophe and multiplication sign as primes and asterisk
1 parent a726e0a commit b8f35ff

1 file changed

Lines changed: 39 additions & 6 deletions

File tree

packages/math/texlike.lua

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,49 @@ local mathGrammar = function (_ENV)
107107
return pl.utils.unpack(t)
108108
end
109109

110+
-- TeX uses the regular asterisk (* = U+002A) in superscripts or subscript:
111+
-- The TeXbook exercice 18.32 (p. 179, 330) for instance.
112+
-- Fonts usually have the asterisk raised too high, so using the Unicode
113+
-- asterisk operator U+2217 looks better (= \ast in TeX).
114+
local astop = P"*" / luautf8.char(0x2217)
115+
-- TeX interprets apostrophes as primes in math mode:
116+
-- The TeXbook p. 130 expands ' to ^\prime commands and repeats the \prime
117+
-- for multiple apostrophes.
118+
-- The TeXbook p. 134: "Then there is the character ', which we know is used
119+
-- as an abbreviation for \prime superscripts."
120+
-- (So we are really sure superscript primes are really the intended meaning.)
121+
-- Here we use the Unicode characters for primes, but the intent is the same.
122+
local primes = (
123+
P"''''" / luautf8.char(0x2057) + -- quadruple prime
124+
P"'''" / luautf8.char(0x2034) + -- triple prime
125+
P"''" / luautf8.char(0x2033) + -- double prime
126+
P"'" / luautf8.char(0x2032) -- prime
127+
) / function (s)
128+
return { id="atom", s }
129+
end
130+
local primes_sup = (
131+
primes * _ * P"^" * _ * element_no_infix / function (p, e)
132+
-- Combine the prime with the superscript in the same mathlist
133+
if e.id == "mathlist" then
134+
table.insert(e, 1, p)
135+
return e
136+
end
137+
return { id="mathlist", p, e }
138+
end
139+
+ primes -- or standalone primes
140+
)
141+
110142
START "math"
111143
math = V"mathlist" * EOF"Unexpected character at end of math code"
112144
mathlist = (comment + (WS * _) + element)^0
113-
supsub = element_no_infix * _ * P"^" * _ * element_no_infix * _ *
114-
P"_" * _ * element_no_infix
115-
subsup = element_no_infix * _ * P"_" * _ * element_no_infix * _ *
116-
P"^" * _ * element_no_infix
117-
sup = element_no_infix * _ * P"^" * _ * element_no_infix
145+
supsub = element_no_infix * _ * primes_sup * _ * P"_" * _ * element_no_infix +
146+
element_no_infix * _ * P"^" * _ * element_no_infix * _ * P"_" * _ * element_no_infix
147+
subsup = element_no_infix * _ * P"_" * _ * element_no_infix * primes_sup +
148+
element_no_infix * _ * P"_" * _ * element_no_infix * _ * P"^" * _ * element_no_infix
149+
sup = element_no_infix * _ * primes_sup +
150+
element_no_infix * _ * P"^" * _ * element_no_infix
118151
sub = element_no_infix * _ * P"_" * _ * element_no_infix
119-
atom = natural + C(utf8code - S"\\{}%^_&") +
152+
atom = natural + astop + C(utf8code - S"\\{}%^_&'") +
120153
(P"\\{" + P"\\}") / function (s) return string.sub(s, -1) end
121154
text = (
122155
P"\\text" *

0 commit comments

Comments
 (0)