[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Groff-commit] groff/src/preproc/eqn text.cpp
From: |
Eric S. Raymond |
Subject: |
[Groff-commit] groff/src/preproc/eqn text.cpp |
Date: |
Sat, 03 Feb 2007 05:33:05 +0000 |
CVSROOT: /sources/groff
Module name: groff
Changes by: Eric S. Raymond <esr> 07/02/03 05:33:05
Modified files:
src/preproc/eqn: text.cpp
Log message:
The -TMathML option for eqn.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/eqn/text.cpp?cvsroot=groff&r1=1.2&r2=1.3
Patches:
Index: text.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/text.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- text.cpp 26 May 2005 21:02:00 -0000 1.2
+++ text.cpp 3 Feb 2007 05:33:04 -0000 1.3
@@ -18,10 +18,391 @@
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+#include <ctype.h>
#include "eqn.h"
#include "pbox.h"
#include "ptable.h"
+struct map {
+ char *from;
+ char *to;
+};
+
+struct map entity_table[] = {
+ // Classic troff special characters
+ {"%", "­"}, // ISOnum
+ {"'", "´"}, // ISOdia
+ {"!=", "≠"}, // ISOtech
+ {"**", "∗"}, // ISOtech
+ {"*a", "α"}, // ISOgrk3
+ {"*A", "A"},
+ {"*b", "β"}, // ISOgrk3
+ {"*B", "B"},
+ {"*d", "δ"}, // ISOgrk3
+ {"*D", "Δ"}, // ISOgrk3
+ {"*e", "ε"}, // ISOgrk3
+ {"*E", "E"},
+ {"*f", "φ"}, // ISOgrk3
+ {"*F", "Φ"}, // ISOgrk3
+ {"*g", "γ"}, // ISOgrk3
+ {"*G", "Γ"}, // ISOgrk3
+ {"*h", "θ"}, // ISOgrk3
+ {"*H", "Θ"}, // ISOgrk3
+ {"*i", "ι"}, // ISOgrk3
+ {"*I", "I"},
+ {"*k", "κ"}, // ISOgrk3
+ {"*K", "K;"},
+ {"*l", "&lamda;"}, // ISOgrk3
+ {"*L", "Λ"}, // ISOgrk3
+ {"*m", "μ"}, // ISOgrk3
+ {"*M", "M"},
+ {"*n", "&nu"}, // ISOgrk3
+ {"*N", "N"},
+ {"*o", "o"},
+ {"*O", "O"},
+ {"*p", "π"}, // ISOgrk3
+ {"*P", "Π"}, // ISOgrk3
+ {"*q", "ψ"}, // ISOgrk3
+ {"*Q", "&PSI;"}, // ISOgrk3
+ {"*r", "ρ"}, // ISOgrk3
+ {"*R", "R"},
+ {"*s", "σ"}, // ISOgrk3
+ {"*S", "Σ"}, // ISOgrk3
+ {"*t", "τ"}, // ISOgrk3
+ {"*T", "Τ"}, // ISOgrk3
+ {"*u", "υ"}, // ISOgrk3
+ {"*U", "Υ"}, // ISOgrk3
+ {"*w", "ω"}, // ISOgrk3
+ {"*W", "Ω"}, // ISOgrk3
+ {"*x", "χ"}, // ISOgrk3
+ {"*X", "Χ"}, // ISOgrk3
+ {"*y", "η"}, // ISOgrk3
+ {"*Y", "Η"}, // ISOgrk3
+ {"*z", "ζ"}, // ISOgrk3
+ {"*Z", "Ζ"}, // ISOgrk3
+ {"+-", "±"}, // ISOnum
+ {"->", "→"}, // ISOnum
+ {"12", "½"}, // ISOnum
+ {"14", "¼"}, // ISOnum
+ {"34", "¾"}, // ISOnum
+ {"<-", "←"}, // ISOnum
+ {"==", "≡"}, // ISOtech
+ {"Fi", "ffi"}, // ISOpub
+ {"Fl", "ffl"}, // ISOpub
+ {"aa", "´"}, // ISOdia
+ {"ap", "∼"}, // ISOtech
+ {"bl", "&phonexb;"}, // ISOpub
+ {"br", "│"}, // ISObox
+ {"bs", "☎"}, // ISOpub (for the Bell logo)
+ {"bu", "•"}, // ISOpub
+ {"bv", "|"}, // ISOnum
+ {"ca", "∩"}, // ISOtech
+ {"ci", "○"}, // ISOpub
+ {"co", "©"}, // ISOnum
+ {"ct", "¢"}, // ISOnum
+ {"cu", "∪"}, // ISOtech
+ {"da", "↓"}, // ISOnum
+ {"de", "°"}, // ISOnum
+ {"dg", "†"}, // ISOpub
+ {"dd", "‡"}, // ISOpub
+ {"di", "÷"}, // ISOnum
+ {"em", "—"}, // ISOpub
+ {"eq", "="}, // ISOnum
+ {"es", "∅"}, // ISOamso
+ {"ff", "ff"}, // ISOpub
+ {"fi", "fi"}, // ISOpub
+ {"fl", "fl"}, // ISOpub
+ {"fm", "′"}, // ISOtech
+ {"ge", "≥"}, // ISOtech
+ {"gr", "∇"}, // ISOtech
+ {"hy", "‐"}, // ISOnum
+ {"ib", "⊆"}, // ISOtech
+ {"if", "∞"}, // ISOtech
+ {"ip", "⊇"}, // ISOtech
+ {"is", "∫"}, // ISOtech
+ {"le", "≤"}, // ISOtech
+ // Some pile characters go here
+ {"mi", "−"}, // ISOtech
+ {"mo", "∈"}, // ISOtech
+ {"mu", "×"}, // ISOnum
+ {"no", "¬"}, // ISOnum
+ {"or", "|"}, // ISOnum
+ {"pl", "+"}, // ISOnum
+ {"pt", "∝"}, // ISOtech
+ {"rg", "™"}, // ISOnum
+ // More pile characters go here
+ {"rn", "¯"}, // ISOdia
+ {"ru", "_"}, // ISOnum
+ {"sb", "⊂"}, // ISOtech
+ {"sc", "§"}, // ISOnum
+ {"sl", "/"},
+ {"sp", "⊃"}, // ISOtech
+ {"sq", "▪"}, // ISOpub
+ {"sr", "√"}, // ISOtech
+ {"ts", "ς"}, // ISOgrk3
+ {"ua", "↑"}, // ISOnum
+ {"ul", "_"},
+ {"~=", "≅"}, // ISOtech
+ // Extended specials supported by groff; see groff_char(7).
+ // These are listed in the order they occur on that man page.
+ {"-D", "Ð"}, // ISOlat: Icelandic uppercase eth
+ {"Sd", "ð"}, // ISOlat1: Icelandic lowercase eth
+ {"TP", "Þ"}, // ISOlat1: Icelandic uppercase thorn
+ {"Tp", "þ"}, // ISOlat1: Icelandic lowercase thorn
+ {"ss", "ß"}, // ISOlat1
+ // Ligatures
+ // ff, fi, fl, ffi, ffl from old troff go here
+ {"AE", "Æ"}, // ISOlat1
+ {"ae", "æ"}, // ISOlat1
+ {"OE", "Œ"}, // ISOlat2
+ {"oe", "œ"}, // ISOlat2
+ {"IJ", "ij"}, // ISOlat2: Dutch IJ ligature
+ {"ij", "IJ"}, // ISOlat2: Dutch ij ligature
+ {".i", "ı"}, // ISOlat2,ISOamso
+ {".j", "&jnodot;"}, // ISOamso (undocumented but in 1.19)
+ // Accented characters
+ {"'A", "Á"}, // ISOlat1
+ {"'C", "Ć"}, // ISOlat2
+ {"'E", "É"}, // ISOlat1
+ {"'I", "Í"}, // ISOlat1
+ {"'O", "Ó"}, // ISOlat1
+ {"'U", "Ú"}, // ISOlat1
+ {"'Y", "Ý"}, // ISOlat1
+ {"'a", "á"}, // ISOlat1
+ {"'c", "ć"}, // ISOlat2
+ {"'e", "é"}, // ISOlat1
+ {"'i", "í"}, // ISOlat1
+ {"'o", "ó"}, // ISOlat1
+ {"'u", "ú"}, // ISOlat1
+ {"'y", "ý"}, // ISOlat1
+ {":A", "Ä"}, // ISOlat1
+ {":E", "Ë"}, // ISOlat1
+ {":I", "Ï"}, // ISOlat1
+ {":O", "Ö"}, // ISOlat1
+ {":U", "Ü"}, // ISOlat1
+ {":Y", "Ÿ"}, // ISOlat2
+ {":a", "ä"}, // ISOlat1
+ {":e", "ë"}, // ISOlat1
+ {":i", "ï"}, // ISOlat1
+ {":o", "ö"}, // ISOlat1
+ {":u", "ü"}, // ISOlat1
+ {":y", "ÿ"}, // ISOlat1
+ {"^A", "Â"}, // ISOlat1
+ {"^E", "Ê"}, // ISOlat1
+ {"^I", "Î"}, // ISOlat1
+ {"^O", "Ô"}, // ISOlat1
+ {"^U", "Û"}, // ISOlat1
+ {"^a", "â"}, // ISOlat1
+ {"^e", "ê"}, // ISOlat1
+ {"^i", "î"}, // ISOlat1
+ {"^o", "ô"}, // ISOlat1
+ {"^u", "û"}, // ISOlat1
+ {"`A", "À"}, // ISOlat1
+ {"`E", "È"}, // ISOlat1
+ {"`I", "Ì"}, // ISOlat1
+ {"`O", "Ò"}, // ISOlat1
+ {"`U", "Ù"}, // ISOlat1
+ {"`a", "à"}, // ISOlat1
+ {"`e", "è"}, // ISOlat1
+ {"`i", "ì"}, // ISOlat1
+ {"`o", "ò"}, // ISOlat1
+ {"`u", "ù"}, // ISOlat1
+ {"~A", "Ã"}, // ISOlat1
+ {"~N", "Ñ"}, // ISOlat1
+ {"~O", "Õ"}, // ISOlat1
+ {"~a", "ã"}, // ISOlat1
+ {"~n", "ñ"}, // ISOlat1
+ {"~o", "õ"}, // ISOlat1
+ {"vS", "Š"}, // ISOlat2
+ {"vs", "š"}, // ISOlat2
+ {"vZ", "Ž"}, // ISOlat2
+ {"vz", "ž"}, // ISOlat2
+ {",C", "Ç"}, // ISOlat1
+ {",c", "ç"}, // ISOlat1
+ {"/L", "Ł"}, // ISOlat2: Polish L with a slash
+ {"/l", "ł"}, // ISOlat2: Polish l with a slash
+ {"/O", "Ø"}, // ISOlat1
+ {"/o", "ø"}, // ISOlat1
+ {"oA", "Å"}, // ISOlat1
+ {"oa", "å"}, // ISOlat1
+ // Accents
+ {"a\"","˝"}, // ISOdia: double acute accent (Hungarian
umlaut)
+ {"a-", "¯"}, // ISOdia: macron or bar accent
+ {"a.", "˙"}, // ISOdia: dot above
+ {"a^", "ˆ"}, // ISOdia: circumflex accent
+ {"aa", "´"}, // ISOdia: acute accent
+ {"ga", "`"}, // ISOdia: grave accent
+ {"ab", "˘"}, // ISOdia: breve accent
+ {"ac", "¸"}, // ISOdia: cedilla accent
+ {"ad", "¨"}, // ISOdia: umlaut or dieresis
+ {"ah", "ˇ"}, // ISOdia: caron (aka hacek accent)
+ {"ao", "˚"}, // ISOdia: ring or circle accent
+ {"a~", "˜"}, // ISOdia: tilde accent
+ {"ho", "˛"}, // ISOdia: hook or ogonek accent
+ {"ha", "^"}, // ASCII circumflex, hat, caret
+ {"ti", "~"}, // ASCII tilde, large tilde
+ // Quotes
+ {"Bq", "‚"}, // ISOpub: low double comma quote
+ {"bq", "„"}, // ISOpub: low single comma quote
+ {"lq", "“"}, // ISOnum
+ {"rq", "”"}, // ISOpub
+ {"oq", "‘"}, // ISOnum: single open quote
+ {"cq", "’"}, // ISOnum: single closing quote (ASCII 39)
+ {"aq", "&zerosp;'"}, // apostrophe quote
+ {"dq", "\""}, // double quote (ASCII 34)
+ {"Fo", "«"}, // ISOnum
+ {"Fc", "»"}, // ISOnum
+ //{"fo", "&fo;"},
+ //{"fc", "&fc;"},
+ // Punctuation
+ {"r!", "¡"}, // ISOnum
+ {"r?", "¿"}, // ISOnum
+ // Old troff \(em goes here
+ {"en", "–"}, // ISOpub: en dash
+ // Old troff \(hy goes here
+ // Brackets
+ {"lB", "["}, // ISOnum: left (square) bracket
+ {"rB", "]"}, // ISOnum: right (square) bracket
+ {"lC", "{"}, // ISOnum: left (curly) brace
+ {"rC", "}"}, // ISOnum: right (curly) brace
+ {"la", "⟨"}, // ISOtech: left angle bracket
+ {"ra", "⟩"}, // ISOtech: right angle bracket
+ // Old troff \(bv goes here
+ // Bracket-pile characters could go here.
+ // Arrows
+ // Old troff \(<- and \(-> go here
+ {"<>", "↔"}, // ISOamsa
+ {"da", "↓"}, // ISOnum
+ {"ua", "↑"}, // ISOnum
+ {"lA", "⇐"}, // ISOtech
+ {"rA", "⇒"}, // ISOtech
+ {"hA", "⇔"}, // ISOtech: horizontal double-headed arrow
+ {"dA", "⇓"}, // ISOamsa
+ {"uA", "⇑"}, // ISOamsa
+ {"vA", "⇕"}, // ISOamsa: vertical double-headed double arrow
+ //{"an", "&an;"},
+ // Lines
+ {"-h", "ℏ"}, // ISOamso: h-bar (Planck's constant)
+ // Old troff \(or goes here
+ {"ba", "|"}, // ISOnum
+ // Old troff \(br, \{u, \(ul, \(bv go here
+ {"bb", "¦"}, // ISOnum
+ {"sl", "/"},
+ {"rs", "\"}, // ISOnum
+ // Text markers
+ // Old troff \(ci, \(bu, \(dd, \(dg go here
+ {"lz", "◊"}, // ISOpub
+ // Old troff sq goes here
+ {"ps", "¶"}, // ISOnum: paragraph or pilcrow sign
+ {"sc", "§"}, // ISOnum (in old troff)
+ // Old troff \(lh, \{h go here
+ {"at", "@"}, // ISOnum
+ {"sh", "#"}, // ISOnum
+ //{"CR", "&CR;"},
+ {"OK", "✓"}, // ISOpub
+ // Legalize
+ // Old troff \(co, \{g go here
+ {"tm", "™"}, // ISOnum
+ // Currency symbols
+ {"Do", "$"}, // ISOnum
+ {"ct", "¢"}, // ISOnum
+ {"eu", "€"},
+ {"Eu", "€"},
+ {"Ye", "¥"}, // ISOnum
+ {"Po", "£"}, // ISOnum
+ {"Cs", "¤"}, // ISOnum: currency sign
+ {"Fn", "&fnof"}, // ISOtech
+ // Units
+ // Old troff de goes here
+ {"%0", "‰"}, // ISOtech: per thousand, per mille sign
+ // Old troff \(fm goes here
+ {"sd", "″"}, // ISOtech
+ {"mc", "µ"}, // ISOnum
+ {"Of", "ª"}, // ISOnum
+ {"Om", "º"}, // ISOnum
+ // Logical symbols
+ {"AN", "∧"}, // ISOtech
+ {"OR", "∨"}, // ISOtech
+ // Old troff \(no goes here
+ {"te", "∃"}, // ISOtech: there exists, existential quantifier
+ {"fa", "∀"}, // ISOtech: for all, universal quantifier
+ {"st", "&bepsi"}, // ISOamsr: such that
+ {"3d", "∴"}, // ISOtech
+ {"tf", "∴"}, // ISOtech
+ // Mathematical symbols
+ // Old troff "12", "14", "34" goes here
+ {"S1", "¹"}, // ISOnum
+ {"S2", "²"}, // ISOnum
+ {"S3", "³"}, // ISOnum
+ // Old troff \(pl", \-, \(+- go here
+ {"t+-", "±"}, // ISOnum
+ {"-+", "∓"}, // ISOtech
+ {"pc", "·"}, // ISOnum
+ {"md", "·"}, // ISOnum
+ // Old troff \(mu goes here
+ {"tmu", "×"}, // ISOnum
+ {"c*", "⊗"}, // ISOamsb: multiply sign in a circle
+ {"c+", "⊕"}, // ISOamsb: plus sign in a circle
+ // Old troff \(di goes here
+ {"tdi", "÷"}, // ISOnum
+ {"f/", "―"}, // ISOnum: horizintal bar for fractions
+ // Old troff \(** goes here
+ {"<=", "≤"}, // ISOtech
+ {">=", "≥"}, // ISOtech
+ {"<<", "≪"}, // ISOamsr
+ {">>", "≫"}, // ISOamsr
+ {"!=", "≠"}, // ISOtech
+ // Old troff \(eq and \(== go here
+ {"=~", "≅"}, // ISOamsr
+ // Old troff \(ap goes here
+ {"~~", "≈"}, // ISOtech
+ // This appears to be an error in the groff table.
+ // It clashes with the Bell Labs use of ~= for a congruence sign
+ // {"~=", "≈"}, // ISOamsr
+ // Old troff \(pt, \(es, \(mo go here
+ {"nm", "∉"}, // ISOtech
+ {"nb", "⊄"}, // ISOamsr
+ {"nc", "⊅"}, // ISOamsn
+ {"ne", "≢"}, // ISOamsn
+ // Old troff \(sb, \(sp, \(ib, \(ip, \(ca, \(cu go here
+ {"/_", "∠"}, // ISOamso
+ {"pp", "⊥"}, // ISOtech
+ // Old troff \(is goes here
+ {"sum", "∑"}, // ISOamsb
+ {"product", "∏"}, // ISOamsb
+ {"gr", "∇"}, // ISOtech
+ // Old troff \(sr. \{n, \(if go here
+ {"Ah", "ℵ"}, // ISOtech
+ {"Im", "ℑ"}, // ISOamso: Fraktur I, imaginary
+ {"Re", "ℜ"}, // ISOamso: Fraktur R, real
+ {"wp", "℘"}, // ISOamso
+ {"pd", "∂"}, // ISOtech: partial differentiation sign
+ // Their table duplicates the Greek letters here.
+ // We list only the variant forms here, mapping them into
+ // the ISO Greek 4 variants (which may or may not be correct :-()
+ {"+f", "&b.phiv;"}, // ISOgrk4: variant phi
+ {"+h", "&b.thetas;"}, // ISOgrk4: variant theta
+ {"+p", "&b.omega;"}, // ISOgrk4: variant pi, looking like omega
+ // Card symbols
+ {"CL", "♣"}, // ISOpub: club suit
+ {"SP", "♠"}, // ISOpub: spade suit
+ {"HE", "♥"}, // ISOpub: heart suit
+ {"DI", "♦"}, // ISOpub: diamond suit
+};
+
+char *special_to_entity(const char *sp)
+{
+ struct map *mp;
+ char *entity;
+ for (mp = entity_table;
+ mp < entity_table + sizeof(entity_table)/sizeof(entity_table[0]);
+ mp++){
+ if (strcmp(mp->from, sp) == 0)
+ return mp->to;
+ }
+ return NULL;
+}
+
class char_box : public simple_box {
unsigned char c;
char next_is_italic;
@@ -48,6 +429,18 @@
void handle_char_type(int, int);
};
+enum spacing_type {
+ s_ordinary,
+ s_operator,
+ s_binary,
+ s_relation,
+ s_opening,
+ s_closing,
+ s_punctuation,
+ s_inner,
+ s_suppress,
+};
+
const char *spacing_type_table[] = {
"ordinary",
"operator",
@@ -115,24 +508,24 @@
void init_char_table()
{
- set_special_char_type("pl", 2, -1); // binary
- set_special_char_type("mi", 2, -1);
- set_special_char_type("eq", 3, -1); // relation
- set_special_char_type("<=", 3, -1);
- set_special_char_type(">=", 3, -1);
- char_table['}'].spacing_type = 5; // closing
- char_table[')'].spacing_type = 5;
- char_table[']'].spacing_type = 5;
- char_table['{'].spacing_type = 4; // opening
- char_table['('].spacing_type = 4;
- char_table['['].spacing_type = 4;
- char_table[','].spacing_type = 6; // punctuation
- char_table[';'].spacing_type = 6;
- char_table[':'].spacing_type = 6;
- char_table['.'].spacing_type = 6;
- char_table['>'].spacing_type = 3;
- char_table['<'].spacing_type = 3;
- char_table['*'].spacing_type = 2; // binary
+ set_special_char_type("pl", s_binary, -1);
+ set_special_char_type("mi", s_binary, -1);
+ set_special_char_type("eq", s_relation, -1);
+ set_special_char_type("<=", s_relation, -1);
+ set_special_char_type(">=", s_relation, -1);
+ char_table['}'].spacing_type = s_closing;
+ char_table[')'].spacing_type = s_closing;
+ char_table[']'].spacing_type = s_closing;
+ char_table['{'].spacing_type = s_opening;
+ char_table['('].spacing_type = s_opening;
+ char_table['['].spacing_type = s_opening;
+ char_table[','].spacing_type = s_punctuation;
+ char_table[';'].spacing_type = s_punctuation;
+ char_table[':'].spacing_type = s_punctuation;
+ char_table['.'].spacing_type = s_punctuation;
+ char_table['>'].spacing_type = s_relation;
+ char_table['<'].spacing_type = s_relation;
+ char_table['*'].spacing_type = s_binary;
for (int i = 0; i < 256; i++)
if (csalpha(i))
char_table[i].font_type = LETTER_TYPE;
@@ -180,6 +573,7 @@
void char_box::output()
{
+ if (output_format == troff) {
int font_type = char_table[c].font_type;
if (font_type != LETTER_TYPE)
printf("\\f[%s]", current_roman_font);
@@ -195,6 +589,28 @@
fputs("\\&", stdout); // suppress ligaturing and kerning
if (font_type != LETTER_TYPE)
fputs("\\fP", stdout);
+ } else if (output_format == mathml) {
+ if (isdigit(c))
+ printf("<mn>");
+ else if (char_table[c].spacing_type)
+ printf("<mo>");
+ else
+ printf("<mi>");
+ if (c == '<')
+ printf("<");
+ else if (c == '>')
+ printf(">");
+ else if (c == '&')
+ printf("&");
+ else
+ putchar(c);
+ if (isdigit(c))
+ printf("</mn>");
+ else if (char_table[c].spacing_type)
+ printf("</mo>");
+ else
+ printf("</mi>");
+ }
}
int char_box::left_is_italic()
@@ -237,12 +653,20 @@
void special_char_box::output()
{
+ if (output_format == troff) {
int font_type = get_special_char_font_type(s);
if (font_type != LETTER_TYPE)
printf("\\f[%s]", current_roman_font);
printf("\\,\\[%s]\\/", s);
if (font_type != LETTER_TYPE)
printf("\\fP");
+ } else if (output_format == mathml) {
+ char *entity = special_to_entity(s);
+ if (entity != NULL)
+ printf("<mo>%s</mo>", entity);
+ else
+ printf("<merror>unknown eqn/troff special char %s</merror>", s);
+ }
}
int special_char_box::is_char()
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Groff-commit] groff/src/preproc/eqn text.cpp,
Eric S. Raymond <=