To do equations in QTML, I simply ran the text that is in between the .eqn and ..eqn tags through GNU eqn -- which is part of the groff project. Alas, there were a couple of bugs for GNU eqn in MathML mode: the approximately equal sign didn't work, nor did the lower case xi.
So I checked out the code in order to make the fixes.
Eqn is easier to type than TeX. Eqn keywords and macros don't need a backslash
for a prefix, and it is easier to type
sup
and
sub
than it is to use punctuation for superscripts and subscripts.
But raw eqn is pretty lame when it comes to supported symbols. It doesn't even have those upside down A and E thingies used for math logic out of the box.
Fortunately, thanks to Unicode, you can define symbols like this:
define oppA "\[u2200]"
I think this would work in document creation mode, but not for MathML. I added a check for Unicode macros in the MathML part of eqn, but that still made no distinction between symbols and operators.
So I decided to build in a large list of predefined symbols. First, I just took the tables of symbols available from Leslie Lamport's LaTeX, A Document Preparation System , ditched the backslashes, and mapped them to Unicode values. The result:
varepsilon | vartheta | varpi | |||
varrho | varsigma | varphi | |||
Gamma | Delta | Theta | |||
Lambda | Xi | Pi | |||
Sigma | Upsilon | Phi | |||
Psi | Omega | pm | |||
mp | div | ast | |||
star | circ | bullet | |||
cap | cup | uplus | |||
sqcap | sqcup | vee | |||
wedge | setminus | wr | |||
diamond | bigtriangleup | bigtriangledown | |||
triangleleft | triangleright | lhd | |||
rhd | unlhd | unrhd | |||
oplus | ominus | otimes | |||
oslash | odot | bigcirc | |||
dagger | ddagger | amalg | |||
leq | prec | preceq | |||
ll | subset | subseteq | |||
sqsubset | sqsubseteq | in | |||
vdash | geq | succ | |||
succeq | gg | supset | |||
supseteq | sqsupset | sqsupseteq | |||
ni | dashv | equiv | |||
sim | simeq | asymp | |||
cong | neq | doteq | |||
propto | models | perp | |||
mid | parallel | bowtie | |||
Join | smile | frown | |||
leftarrow | Leftarrow | rightarrow | |||
Rightarrow | leftrightarrow | Leftrightarrow | |||
mapsto | hookleftarrow | leftharpoonup | |||
leftharpoondown | rightleftharpoons | longleftarrow | |||
Longleftarrow | longrightarrow | Longrightarrow | |||
longleftrightarrow | Longleftrightarrow | longmapsto | |||
hookrightarrow | rightharpoonup | rightharpoondown | |||
leadsto | uparrow | Uparrow | |||
downarrow | Downarrow | updownarrow | |||
Updownarrow | nearrow | swarrow | |||
swarrow | nwarrow | aleph | |||
hbar | imath | jmath | |||
ell | wp | Re | |||
Im | mho | emptyset | |||
nabla | surd | top | |||
bot | angle | forall | |||
exists | neg | flat | |||
natural | sharp | infty | |||
Box | Diamond | triangle | |||
clubsuit | diamondsuit | heartsuit | |||
spadesuit |
I still have work to do distinguishing which of these are operators and which are just symbols.
The above list misses a few symbols which I considered to be obvious, so I threw in some:
therefore | |
because | |
ratio | |
proportional | |
nsubset | |
nsupset | |
nsubseteq | |
nsupseteq | |
langle | |
rangle | |
bra | |
ket | |
nexists | |
nin | |
nni | |
ring | |
deg | |
anglert | |
thorn | |
Thorn | |
eth | |
Eth |
Some of the above match the eqnchar macro names put out by AT&T, but not all.
When troff was created, you needed separate font files for both font styles and for non-ASCII symbols. Today, we have Unicode. The easiest way to use the code points for different math font styles was to put a prefix before Latin letters to get a different style.
Prefix | Name |
---|---|
ds | Double Stroke |
frak | Fraktur |
bfrak | Bold Fraktur |
scr | Script |
bscr | Bold Script |
ss | Sans Serif |
bss | Bold Sans Serif |
For example the eqn code
.eqn scrA hat = {bold scrA} over scrA ..eqn
yields
The resulting available symbols:
Letter\Prefix | ds | frak | bfrak | scr | bscr | ss | bss |
---|---|---|---|---|---|---|---|
A | |||||||
B | |||||||
C | |||||||
D | |||||||
E | |||||||
F | |||||||
G | |||||||
H | |||||||
I | |||||||
J | |||||||
K | |||||||
L | |||||||
M | |||||||
N | |||||||
O | |||||||
P | |||||||
Q | |||||||
R | |||||||
S | |||||||
T | |||||||
U | |||||||
V | |||||||
W | |||||||
X | |||||||
Y | |||||||
Z | |||||||
a | |||||||
b | |||||||
c | |||||||
d | |||||||
e | |||||||
f | |||||||
g | |||||||
h | |||||||
i | |||||||
j | |||||||
k | |||||||
l | |||||||
m | |||||||
n | |||||||
o | |||||||
p | |||||||
q | |||||||
r | |||||||
s | |||||||
t | |||||||
u | |||||||
v | |||||||
w | |||||||
x | |||||||
y | |||||||
z |
I have not checked to see if this works in PostScript mode.
Anyway, since I started with GNU code, I have posted my updates to GNU eqn on Github for your copying pleasure.
There is no warranty! I did a lot of Unicode mapping by hand, so I probably botched a few symbols.
Carl Milsted, Jr on Jan 1, 2024 7:34 PM
in response to
comment_118_2
Pass along to all friends who like to talk shop over the Internet!
That's part of what Conntects is for.
P.S. I have made updates so that symbols are treated as symbols, and operators are treated as operators (more space). Not perfect,
and the bug regarding
left
without a right is challenging to fix. It's deep within the groff code,
possibly within YACC generated code which I am incapable of following.
Maybe I can get the "owners" of the code to fix that bug. I'm inclined
to start from scratch using Go instead of C++ than dig that deep.
You must be logged in to comment