Diffs between last version checked in and current workfile(s):
Index: box.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/box.cpp,v
retrieving revision 1.3
diff -u -r1.3 box.cpp
--- box.cpp 26 May 2005 21:02:00 -0000 1.3
+++ box.cpp 31 Jan 2007 18:18:26 -0000
@@ -226,9 +226,12 @@
void start_string()
{
- printf(".nr " COMPATIBLE_REG " \\n(.C\n");
- printf(".cp 0\n");
- printf(".ds " LINE_STRING "\n");
+ if (output_format == troff) {
+ printf(".nr " COMPATIBLE_REG " \\n(.C\n");
+ printf(".cp 0\n");
+ printf(".ds " LINE_STRING "\n");
+ } else if (output_format == mathml)
+ printf("\n");
}
void do_text(const char *s)
@@ -275,69 +281,73 @@
void box::top_level()
{
- // debug_print();
- // putc('\n', stderr);
box *b = this;
- printf(".nr " SAVED_FONT_REG " \\n[.f]\n");
- printf(".ft\n");
- printf(".nr " SAVED_PREV_FONT_REG " \\n[.f]\n");
- printf(".ft %s\n", get_gfont());
- printf(".nr " SAVED_SIZE_REG " \\n[.ps]\n");
- if (gsize > 0) {
- char buf[INT_DIGITS + 1];
- sprintf(buf, "%d", gsize);
- b = new size_box(strsave(buf), b);
+ if (output_format == troff) {
+ // debug_print();
+ // putc('\n', stderr);
+ printf(".nr " SAVED_FONT_REG " \\n[.f]\n");
+ printf(".ft\n");
+ printf(".nr " SAVED_PREV_FONT_REG " \\n[.f]\n");
+ printf(".ft %s\n", get_gfont());
+ printf(".nr " SAVED_SIZE_REG " \\n[.ps]\n");
+ if (gsize > 0) {
+ char buf[INT_DIGITS + 1];
+ sprintf(buf, "%d", gsize);
+ b = new size_box(strsave(buf), b);
+ }
+ current_roman_font = get_grfont();
+ // This catches tabs used within \Z (which aren't allowed).
+ b->check_tabs(0);
+ int r = b->compute_metrics(DISPLAY_STYLE);
+ printf(".ft \\n[" SAVED_PREV_FONT_REG "]\n");
+ printf(".ft \\n[" SAVED_FONT_REG "]\n");
+ printf(".nr " MARK_OR_LINEUP_FLAG_REG " %d\n", r);
+ if (r == FOUND_MARK) {
+ printf(".nr " SAVED_MARK_REG " \\n[" MARK_REG "]\n");
+ printf(".nr " MARK_WIDTH_REG " 0\\n[" WIDTH_FORMAT "]\n", b->uid);
+ }
+ else if (r == FOUND_LINEUP)
+ printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
+ SAVED_MARK_REG "]u-\\n[" MARK_REG "]u'\n");
+ else
+ assert(r == FOUND_NOTHING);
+ // The problem here is that the argument to \f is read in copy mode,
+ // so we cannot use \E there; so we hide it in a string instead.
+ // Another problem is that if we use \R directly, then the space will
+ // prevent it working in a macro argument.
+ printf(".ds " SAVE_FONT_STRING " "
+ "\\R'" SAVED_INLINE_FONT_REG " \\\\n[.f]'"
+ "\\fP"
+ "\\R'" SAVED_INLINE_PREV_FONT_REG " \\\\n[.f]'"
+ "\\R'" SAVED_INLINE_SIZE_REG " \\\\n[.ps]'"
+ "\\s0"
+ "\\R'" SAVED_INLINE_PREV_SIZE_REG " \\\\n[.ps]'"
+ "\n"
+ ".ds " RESTORE_FONT_STRING " "
+ "\\f[\\\\n[" SAVED_INLINE_PREV_FONT_REG "]]"
+ "\\f[\\\\n[" SAVED_INLINE_FONT_REG "]]"
+ "\\s'\\\\n[" SAVED_INLINE_PREV_SIZE_REG "]u'"
+ "\\s'\\\\n[" SAVED_INLINE_SIZE_REG "]u'"
+ "\n");
+ printf(".as1 " LINE_STRING " \\&\\E*[" SAVE_FONT_STRING "]");
+ printf("\\f[%s]", get_gfont());
+ printf("\\s'\\En[" SAVED_SIZE_REG "]u'");
+ current_roman_font = get_grfont();
+ b->output();
+ printf("\\E*[" RESTORE_FONT_STRING "]\n");
+ if (r == FOUND_LINEUP)
+ printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
+ MARK_WIDTH_REG "]u-\\n[" SAVED_MARK_REG "]u-(\\n["
+ WIDTH_FORMAT "]u-\\n[" MARK_REG "]u)'\n",
+ b->uid);
+ b->extra_space();
+ if (!inline_flag)
+ printf(".ne \\n[" HEIGHT_FORMAT "]u-%dM>?0+(\\n["
+ DEPTH_FORMAT "]u-%dM>?0)\n",
+ b->uid, body_height, b->uid, body_depth);
+ } else if (output_format == mathml) {
+ b->output();
}
- current_roman_font = get_grfont();
- // This catches tabs used within \Z (which aren't allowed).
- b->check_tabs(0);
- int r = b->compute_metrics(DISPLAY_STYLE);
- printf(".ft \\n[" SAVED_PREV_FONT_REG "]\n");
- printf(".ft \\n[" SAVED_FONT_REG "]\n");
- printf(".nr " MARK_OR_LINEUP_FLAG_REG " %d\n", r);
- if (r == FOUND_MARK) {
- printf(".nr " SAVED_MARK_REG " \\n[" MARK_REG "]\n");
- printf(".nr " MARK_WIDTH_REG " 0\\n[" WIDTH_FORMAT "]\n", b->uid);
- }
- else if (r == FOUND_LINEUP)
- printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
- SAVED_MARK_REG "]u-\\n[" MARK_REG "]u'\n");
- else
- assert(r == FOUND_NOTHING);
- // The problem here is that the argument to \f is read in copy mode,
- // so we cannot use \E there; so we hide it in a string instead.
- // Another problem is that if we use \R directly, then the space will
- // prevent it working in a macro argument.
- printf(".ds " SAVE_FONT_STRING " "
- "\\R'" SAVED_INLINE_FONT_REG " \\\\n[.f]'"
- "\\fP"
- "\\R'" SAVED_INLINE_PREV_FONT_REG " \\\\n[.f]'"
- "\\R'" SAVED_INLINE_SIZE_REG " \\\\n[.ps]'"
- "\\s0"
- "\\R'" SAVED_INLINE_PREV_SIZE_REG " \\\\n[.ps]'"
- "\n"
- ".ds " RESTORE_FONT_STRING " "
- "\\f[\\\\n[" SAVED_INLINE_PREV_FONT_REG "]]"
- "\\f[\\\\n[" SAVED_INLINE_FONT_REG "]]"
- "\\s'\\\\n[" SAVED_INLINE_PREV_SIZE_REG "]u'"
- "\\s'\\\\n[" SAVED_INLINE_SIZE_REG "]u'"
- "\n");
- printf(".as1 " LINE_STRING " \\&\\E*[" SAVE_FONT_STRING "]");
- printf("\\f[%s]", get_gfont());
- printf("\\s'\\En[" SAVED_SIZE_REG "]u'");
- current_roman_font = get_grfont();
- b->output();
- printf("\\E*[" RESTORE_FONT_STRING "]\n");
- if (r == FOUND_LINEUP)
- printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
- MARK_WIDTH_REG "]u-\\n[" SAVED_MARK_REG "]u-(\\n["
- WIDTH_FORMAT "]u-\\n[" MARK_REG "]u)'\n",
- b->uid);
- b->extra_space();
- if (!inline_flag)
- printf(".ne \\n[" HEIGHT_FORMAT "]u-%dM>?0+(\\n["
- DEPTH_FORMAT "]u-%dM>?0)\n",
- b->uid, body_height, b->uid, body_depth);
delete b;
next_uid = 0;
}
@@ -538,8 +548,15 @@
void quoted_text_box::output()
{
- if (text)
- fputs(text, stdout);
+ if (text) {
+ if (output_format == troff)
+ fputs(text, stdout);
+ else if (output_format == mathml) {
+ fputs("", stdout);
+ fputs(text, stdout);
+ fputs("", stdout);
+ }
+ }
}
tab_box::tab_box() : disabled(0)
@@ -569,7 +586,11 @@
void space_box::output()
{
- printf("\\h'%dM'", thick_space);
+ if (output_format == troff)
+ printf("\\h'%dM'", thick_space);
+ else if (output_format == mathml)
+ //    doesn't display right under Firefox 1.5.
+ printf(" ");
}
half_space_box::half_space_box()
@@ -579,7 +600,10 @@
void half_space_box::output()
{
- printf("\\h'%dM'", thin_space);
+ if (output_format == troff)
+ printf("\\h'%dM'", thin_space);
+ else if (output_format == mathml)
+ printf(" ");
}
void box_list::list_debug_print(const char *sep)
--- box.h.~1.6.~ 2005-06-16 05:47:49.000000000 -0400
+++ box.h 2007-01-30 17:48:29.000000000 -0500
@@ -216,6 +216,14 @@
void debug_print();
};
+class big_box : public pointer_box {
+public:
+ big_box(box *);
+ int compute_metrics(int);
+ void output();
+ void debug_print();
+};
+
class fat_box : public pointer_box {
public:
fat_box(box *);
Index: delim.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/delim.cpp,v
retrieving revision 1.2
diff -u -r1.2 delim.cpp
--- delim.cpp 26 May 2005 21:02:00 -0000 1.2
+++ delim.cpp 31 Jan 2007 18:18:27 -0000
@@ -378,11 +378,17 @@
void delim_box::output()
{
- if (left)
- printf("\\*[" LEFT_DELIM_STRING_FORMAT "]", uid);
- p->output();
- if (right)
- printf("\\*[" RIGHT_DELIM_STRING_FORMAT "]", uid);
+ if (output_format == troff) {
+ if (left)
+ printf("\\*[" LEFT_DELIM_STRING_FORMAT "]", uid);
+ p->output();
+ if (right)
+ printf("\\*[" RIGHT_DELIM_STRING_FORMAT "]", uid);
+ } else if (output_format == mathml) {
+ printf("%s", left);
+ p->output();
+ printf("%s", right);
+ }
}
void delim_box::check_tabs(int level)
Index: eqn.h
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/eqn.h,v
retrieving revision 1.3
diff -u -r1.3 eqn.h
--- eqn.h 26 May 2005 21:02:00 -0000 1.3
+++ eqn.h 31 Jan 2007 18:18:27 -0000
@@ -29,6 +29,8 @@
#include "box.h"
+typedef enum {troff, mathml} eqnmode_t;
+
extern char start_delim;
extern char end_delim;
extern int non_empty_flag;
@@ -37,6 +39,7 @@
extern int one_size_reduction_flag;
extern int compatible_flag;
extern int nroff;
+extern eqnmode_t output_format;
void init_lex(const char *str, const char *filename, int lineno);
void lex_error(const char *message,
Index: eqn.man
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/eqn.man,v
retrieving revision 1.10
diff -u -r1.10 eqn.man
--- eqn.man 20 Feb 2005 10:38:37 -0000 1.10
+++ eqn.man 31 Jan 2007 18:18:27 -0000
@@ -176,13 +176,16 @@
.BI \-T name
The output is for device
.IR name .
-The only effect of this is to define a macro
+Normally, the only effect of this is to define a macro
.I name
with a value of\~\c
-.BR 1 .
-Typically
+.BR 1 ;
.B eqnrc
will use this to provide definitions appropriate for the output device.
+However, if the specified device is "MathML", the output will be
+MathML markup rather than troff commands, and
+.B eqnrc
+will not be loaded at all.
The default output device is
.BR @DEVICE@ .
.
@@ -232,10 +235,16 @@
.B eqn
and Unix eqn are described here.
.
+GNU
+.B eqn
+emits Presentation MathML output when invoked with the
+,B -T MathML
+option.
+.
.LP
-Most of the new features of GNU
+Most of the new features of the GNU
.B eqn
-are based on \*(tx.
+input language are based on \*(tx.
There are some references to the differences between \*(tx and GNU
.B eqn
below;
@@ -349,6 +358,11 @@
.
.SS New primitives
.TP
+.IB big\ e1
+Enlarges the expression it modifies; intended to have semantics like
+CSS 'large'. In troff output, the point size is increased by 5; in
+MathML output, the expression is wrapped in an
+pair.
.IB e1\ smallover\ e2
This is similar to
.BR over ;
@@ -390,6 +404,8 @@
{ type "operator" vcenter size +5 \e(*S }
.RE
.
+(Note that vcenter is silently ignored when generating MathML.)
+.
.TP
.IB e1\ accent\ e2
This sets
@@ -726,6 +742,8 @@
primitive emboldens an equation
by overprinting two copies of the equation
horizontally offset by this amount.
+(This parameter is not used in MathML mode; instead, fat text is
+wrapped in an tag pair.)
.
.TP
.B over_hang
@@ -1142,11 +1160,51 @@
.B @MACRODIR@/eqnrc
Initialization file.
.
+.SH MATHL MODE LIMITATIONS
+MathML is designed on the assumption that it cannot know the exact
+physical characteristics of the media and devices on which it will
+be rendered. It does not support fine control of motions and sizes
+to the same degree troff does. Thus:
+.IP *
+.B eqn
+parameters have no effect on the generated MathML.
+.LP
+.IP *
+The
+.BR special,
+.BR up ,
+.BR down ,
+.BR fwd ,
+and
+.BR back ,
+operations cannot be implemented, and will yield a
+MathML message instead.
+.IP *
+The
+.B vcenter
+keyword is silently ignored, as centering on the math axis is the
+MathML default.
+.IP *
+Characters that eqn over troff sets extra large - notably the integral
+sign - may appear too small and need to have their wrappers
+adjusted by hand.
+.LP
+See the
+.B BUGS
+section for translation limits specific to
+.BR eqn .
.
.SH BUGS
Inline equations will be set at the point size that is current at the
beginning of the input line.
.
+In MathML mode, the
+.BR mark,
+and
+.B lineup
+features don't work. These could, in theory, be implemented with
+ elements.
+.
.
.SH "SEE ALSO"
.BR groff (@MAN1EXT@),
Index: lex.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/lex.cpp,v
retrieving revision 1.3
diff -u -r1.3 lex.cpp
--- lex.cpp 16 Jun 2005 09:47:49 -0000 1.3
+++ lex.cpp 31 Jan 2007 18:18:28 -0000
@@ -120,10 +120,12 @@
{ "special", SPECIAL },
};
-static struct {
+struct builtin_def {
const char *name;
const char *def;
-} def_table[] = {
+};
+
+static struct builtin_def common_defs[] = {
{ "ALPHA", "\\(*A" },
{ "BETA", "\\(*B" },
{ "CHI", "\\(*X" },
@@ -215,11 +217,6 @@
{ "and", "{roman \"and\"}" },
{ "if", "{roman \"if\"}" },
{ "for", "{roman \"for\"}" },
- { "sum", "{type \"operator\" vcenter size +5 \\(*S}" },
- { "prod", "{type \"operator\" vcenter size +5 \\(*P}" },
- { "int", "{type \"operator\" vcenter size +8 \\(is}" },
- { "union", "{type \"operator\" vcenter size +5 \\(cu}" },
- { "inter", "{type \"operator\" vcenter size +5 \\(ca}" },
{ "times", "type \"binary\" \\(mu" },
{ "ldots", "type \"inner\" { . . . }" },
{ "inf", "\\(if" },
@@ -228,34 +225,58 @@
{ "half", "{1 smallover 2}" },
{ "hat_def", "roman \"^\"" },
{ "hat", "accent { hat_def }" },
- { "dot_def", "back 15 \"\\v'-52M'.\\v'52M'\"" },
- { "dot", "accent { dot_def }" },
- { "dotdot_def", "back 25 \"\\v'-52M'..\\v'52M'\"" },
- { "dotdot", "accent { dotdot_def }" },
{ "tilde_def", "\"~\"" },
{ "tilde", "accent { tilde_def }" },
- { "utilde_def", "\"\\v'75M'~\\v'-75M'\"" },
- { "utilde", "uaccent { utilde_def }" },
- { "vec_def", "up 52 size -5 \\(->" },
- { "vec", "accent { vec_def }" },
- { "dyad_def", "up 52 size -5 {\\(<- back 60 \\(->}" },
- { "dyad", "accent { dyad_def }" },
{ "==", "type \"relation\" \\(==" },
{ "!=", "type \"relation\" \\(!=" },
{ "+-", "type \"binary\" \\(+-" },
{ "->", "type \"relation\" \\(->" },
{ "<-", "type \"relation\" \\(<-" },
- { "<<", "{ < back 20 < }" },
- { ">>", "{ > back 20 > }" },
- { "...", "type \"inner\" vcenter { . . . }" },
+ { "<<", "type \"relation\" \\(<<" },
+ { ">>", "type \"relation\" \\(>>" },
{ "prime", "'" },
{ "approx", "type \"relation\" \"\\(~=\"" },
{ "grad", "\\(gr" },
{ "del", "\\(gr" },
- { "cdot", "type \"binary\" vcenter ." },
+ { "cdot", "type \"binary\" \\(md" },
{ "dollar", "$" },
};
+/* composite definitions that require troff size and motion operators */
+static struct builtin_def troff_defs[] = {
+ { "sum", "{type \"operator\" vcenter size +5 \\(*S}" },
+ { "prod", "{type \"operator\" vcenter size +5 \\(*P}" },
+ { "int", "{type \"operator\" vcenter size +8 \\(is}" },
+ { "union", "{type \"operator\" vcenter size +5 \\(cu}" },
+ { "inter", "{type \"operator\" vcenter size +5 \\(ca}" },
+ { "dot_def", "up 52 back 15 \".\"" },
+ { "dot", "accent { dot_def }" },
+ { "dotdot_def", "up 52 back 25 \"..\"" },
+ { "dotdot", "accent { dotdot_def }" },
+ { "utilde_def", "down 75 \"~\"" },
+ { "utilde", "uaccent { utilde_def }" },
+ { "vec_def", "up 52 size -5 \\(->" },
+ { "vec", "accent { vec_def }" },
+ { "dyad_def", "up 52 size -5 { \\(<> }" },
+ { "dyad", "accent { dyad_def }" },
+ { "...", "type \"inner\" vcenter { . . . }" },
+};
+
+/* equivalent definitions for MathML mode */
+static struct builtin_def mathml_defs[] = {
+ { "sum", "{type \"operator\" size big \\(*S}" },
+ { "prod", "{type \"operator\" size big \\(*P}" },
+ { "int", "{type \"operator\" size big \\(is}" },
+ { "union", "{type \"operator\" size big \\(cu}" },
+ { "inter", "{type \"operator\" size big \\(ca}" },
+ { "dot", "accent { \".\" }" },
+ { "dotdot", "accent { \"..\" }" },
+ { "utilde", "uaccent { \"~\" }" },
+ { "vec", "accent { \\(-> }" },
+ { "dyad", "accent { \\(<> }" },
+ { "...", "type \"inner\" { . . . }" },
+};
+
void init_table(const char *device)
{
unsigned int i;
@@ -265,12 +286,29 @@
def->tok = token_table[i].token;
macro_table.define(token_table[i].name, def);
}
- for (i = 0; i < sizeof(def_table)/sizeof(def_table[0]); i++) {
+ for (i = 0; i < sizeof(common_defs)/sizeof(common_defs[0]); i++) {
definition *def = new definition[1];
def->is_macro = 1;
- def->contents = strsave(def_table[i].def);
+ def->contents = strsave(common_defs[i].def);
def->is_simple = 1;
- macro_table.define(def_table[i].name, def);
+ macro_table.define(common_defs[i].name, def);
+ }
+ if (output_format == troff) {
+ for (i = 0; i < sizeof(troff_defs)/sizeof(troff_defs[0]); i++) {
+ definition *def = new definition[1];
+ def->is_macro = 1;
+ def->contents = strsave(troff_defs[i].def);
+ def->is_simple = 1;
+ macro_table.define(troff_defs[i].name, def);
+ }
+ } else if (output_format == mathml) {
+ for (i = 0; i < sizeof(mathml_defs)/sizeof(mathml_defs[0]); i++) {
+ definition *def = new definition[1];
+ def->is_macro = 1;
+ def->contents = strsave(mathml_defs[i].def);
+ def->is_simple = 1;
+ macro_table.define(mathml_defs[i].name, def);
+ }
}
definition *def = new definition[1];
def->is_macro = 1;
Index: limit.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/limit.cpp,v
retrieving revision 1.2
diff -u -r1.2 limit.cpp
--- limit.cpp 26 May 2005 21:02:00 -0000 1.2
+++ limit.cpp 31 Jan 2007 18:18:28 -0000
@@ -139,33 +139,53 @@
void limit_box::output()
{
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
- if (to != 0) {
+ if (output_format == troff) {
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ if (to != 0) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
+ "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'",
+ uid, to->uid, p->uid);
+ to->output();
+ printf(DELIMITER_CHAR);
+ }
+ if (from != 0) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
+ "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, p->uid, from->uid);
+ from->output();
+ printf(DELIMITER_CHAR);
+ }
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
printf("\\Z" DELIMITER_CHAR);
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
- "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'",
- uid, to->uid, p->uid);
- to->output();
+ "-(\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, p->uid);
+ p->output();
printf(DELIMITER_CHAR);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ } else if (output_format == mathml) {
+ if (from != 0 && to != 0) {
+ printf("");
+ p->output();
+ from->output();
+ to->output();
+ printf("");
+ } else if (from != 0) {
+ printf("");
+ p->output();
+ from->output();
+ printf("");
+ } else if (to != 0) {
+ printf("");
+ p->output();
+ to->output();
+ printf("");
+ }
}
- if (from != 0) {
- printf("\\Z" DELIMITER_CHAR);
- printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
- "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, p->uid, from->uid);
- from->output();
- printf(DELIMITER_CHAR);
- }
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
- "-(\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, p->uid);
- p->output();
- printf(DELIMITER_CHAR);
- printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
}
void limit_box::debug_print()
Index: list.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/list.cpp,v
retrieving revision 1.2
diff -u -r1.2 list.cpp
--- list.cpp 26 May 2005 21:02:00 -0000 1.2
+++ list.cpp 31 Jan 2007 18:18:28 -0000
@@ -208,8 +208,10 @@
void list_box::output()
{
+ if (output_format == mathml)
+ printf("");
for (int i = 0; i < list.len; i++) {
- if (i > 0) {
+ if (output_format == troff && i > 0) {
int n = compute_spacing(is_script,
list.p[i-1]->spacing_type,
list.p[i]->spacing_type);
@@ -218,6 +220,8 @@
}
list.p[i]->output();
}
+ if (output_format == mathml)
+ printf("");
}
void list_box::handle_char_type(int st, int ft)
Index: main.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/main.cpp,v
retrieving revision 1.3
diff -u -r1.3 main.cpp
--- main.cpp 29 Dec 2005 21:26:49 -0000 1.3
+++ main.cpp 31 Jan 2007 18:18:28 -0000
@@ -45,7 +45,7 @@
int compatible_flag = 0;
int no_newline_in_delim_flag = 0;
int html = 0;
-
+eqnmode_t output_format;
int read_line(FILE *fp, string *p)
{
@@ -67,7 +67,8 @@
{
string linebuf;
string str;
- printf(".lf 1 %s\n", filename);
+ if (output_format == troff)
+ printf(".lf 1 %s\n", filename);
current_filename = filename;
current_lineno = 0;
while (read_line(fp, &linebuf)) {
@@ -110,11 +111,12 @@
inline_flag = 0;
yyparse();
restore_compatibility();
- if (non_empty_flag) {
+ if (output_format == troff && non_empty_flag) {
printf(".lf %d\n", current_lineno - 1);
output_string();
}
- printf(".lf %d\n", current_lineno);
+ if (output_format == troff)
+ printf(".lf %d\n", current_lineno);
put_string(linebuf, stdout);
}
else if (start_delim != '\0' && linebuf.search(start_delim) >= 0
@@ -171,14 +173,14 @@
ptr = &linebuf[0];
}
str += '\0';
- if (html) {
+ if (output_format == troff && html) {
printf(".as1 %s ", LINE_STRING);
html_begin_suppress();
printf("\n");
}
init_lex(str.contents(), current_filename, start_lineno);
yyparse();
- if (html) {
+ if (output_format == troff && html) {
printf(".as1 %s ", LINE_STRING);
html_end_suppress();
printf("\n");
@@ -193,9 +195,11 @@
}
}
restore_compatibility();
- printf(".lf %d\n", current_lineno);
+ if (output_format == troff)
+ printf(".lf %d\n", current_lineno);
output_string();
- printf(".lf %d\n", current_lineno + 1);
+ if (output_format == troff)
+ printf(".lf %d\n", current_lineno + 1);
return 1;
}
@@ -302,6 +306,9 @@
if (strcmp(device, "ps:html") == 0) {
device = "ps";
html = 1;
+ } else if (strcmp(device, "MathML") == 0) {
+ output_format = mathml;
+ load_startup_file = 0;
}
break;
case 's':
@@ -349,19 +356,21 @@
}
init_table(device);
init_char_table();
- printf(".if !'\\*(.T'%s' "
- ".if !'\\*(.T'html' " // the html device uses `-Tps' to render
- // equations as images
- ".tm warning: %s should have been given a `-T\\*(.T' option\n",
- device, program_name);
- printf(".if '\\*(.T'html' "
- ".if !'%s'ps' "
- ".tm warning: %s should have been given a `-Tps' option\n",
- device, program_name);
- printf(".if '\\*(.T'html' "
- ".if !'%s'ps' "
- ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n",
- device);
+ if (output_format == troff) {
+ printf(".if !'\\*(.T'%s' "
+ ".if !'\\*(.T'html' " // the html device uses `-Tps' to render
+ // equations as images
+ ".tm warning: %s should have been given a `-T\\*(.T' option\n",
+ device, program_name);
+ printf(".if '\\*(.T'html' "
+ ".if !'%s'ps' "
+ ".tm warning: %s should have been given a `-Tps' option\n",
+ device, program_name);
+ printf(".if '\\*(.T'html' "
+ ".if !'%s'ps' "
+ ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n",
+ device);
+ }
if (load_startup_file) {
char *path;
FILE *fp = config_macro_path.open_file(STARTUP_FILE, &path);
Index: other.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/other.cpp,v
retrieving revision 1.2
diff -u -r1.2 other.cpp
--- other.cpp 26 May 2005 21:02:00 -0000 1.2
+++ other.cpp 31 Jan 2007 18:18:29 -0000
@@ -65,17 +65,24 @@
void accent_box::output()
{
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
- SKEW_FORMAT "]u'",
- p->uid, ab->uid, p->uid);
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- ab->output();
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", ab->uid);
- printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
- printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
- SKEW_FORMAT "]u)'",
- p->uid, ab->uid, p->uid);
- p->output();
+ if (output_format == troff) {
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
+ SKEW_FORMAT "]u'",
+ p->uid, ab->uid, p->uid);
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ ab->output();
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", ab->uid);
+ printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
+ SKEW_FORMAT "]u)'",
+ p->uid, ab->uid, p->uid);
+ p->output();
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ ab->output();
+ printf("")
+ }
}
#endif
@@ -110,19 +117,26 @@
void accent_box::output()
{
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u+\\n[" SKEW_FORMAT "]u"
- "-(\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, p->uid, ab->uid);
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- ab->output();
- printf(DELIMITER_CHAR);
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, p->uid);
- p->output();
- printf(DELIMITER_CHAR);
- printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ if (output_format == troff) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u+\\n[" SKEW_FORMAT "]u"
+ "-(\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, p->uid, ab->uid);
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ ab->output();
+ printf(DELIMITER_CHAR);
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, p->uid);
+ p->output();
+ printf(DELIMITER_CHAR);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ ab->output();
+ printf("");
+ }
}
void accent_box::check_tabs(int level)
@@ -153,10 +167,14 @@
void overline_char_box::output()
{
- printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height);
- printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
- accent_width);
- printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height);
+ if (output_format == troff) {
+ printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height);
+ printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
+ accent_width);
+ printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height);
+ } else if (output_format == mathml) {
+ printf("¯");
+ }
}
void overline_char_box::debug_print()
@@ -197,16 +215,22 @@
void overline_box::output()
{
- // 9
- printf("\\Z" DELIMITER_CHAR);
- printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
- p->uid, 7*default_rule_thickness);
- if (draw_flag)
- printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
- else
- printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
- printf(DELIMITER_CHAR);
- p->output();
+ if (output_format == troff) {
+ // 9
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
+ p->uid, 7*default_rule_thickness);
+ if (draw_flag)
+ printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
+ else
+ printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
+ printf(DELIMITER_CHAR);
+ p->output();
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ printf("¯");
+ }
}
void overline_box::debug_print()
@@ -267,18 +291,25 @@
void uaccent_box::output()
{
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, ab->uid);
- printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid);
- ab->output();
- printf(DELIMITER_CHAR);
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, p->uid);
- p->output();
- printf(DELIMITER_CHAR);
- printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ if (output_format == troff) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, ab->uid);
+ printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid);
+ ab->output();
+ printf(DELIMITER_CHAR);
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, p->uid);
+ p->output();
+ printf(DELIMITER_CHAR);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ ab->output();
+ printf("");
+ }
}
void uaccent_box::check_tabs(int level)
@@ -314,10 +345,14 @@
void underline_char_box::output()
{
- printf("\\v'%dM/2u'", 7*default_rule_thickness);
- printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
- accent_width);
- printf("\\v'-%dM/2u'", 7*default_rule_thickness);
+ if (output_format == troff) {
+ printf("\\v'%dM/2u'", 7*default_rule_thickness);
+ printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
+ accent_width);
+ printf("\\v'-%dM/2u'", 7*default_rule_thickness);
+ } else if (output_format == mathml) {
+ printf("_");
+ }
}
void underline_char_box::debug_print()
@@ -360,16 +395,22 @@
void underline_box::output()
{
- // 10
- printf("\\Z" DELIMITER_CHAR);
- printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
- p->uid, 7*default_rule_thickness);
- if (draw_flag)
- printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
- else
- printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
- printf(DELIMITER_CHAR);
- p->output();
+ if (output_format == troff) {
+ // 10
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
+ p->uid, 7*default_rule_thickness);
+ if (draw_flag)
+ printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
+ else
+ printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
+ printf(DELIMITER_CHAR);
+ p->output();
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ printf("¯");
+ }
}
// we want an underline box to have 0 subscript kern
@@ -405,9 +446,15 @@
void size_box::output()
{
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
- p->output();
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ if (output_format == troff) {
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ p->output();
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ } else if (output_format == mathml) {
+ printf("", size);
+ p->output();
+ printf("");
+ }
}
size_box::~size_box()
@@ -449,12 +496,32 @@
void font_box::output()
{
- printf("\\f[%s]", f);
- const char *old_roman_font = current_roman_font;
- current_roman_font = f;
- p->output();
- current_roman_font = old_roman_font;
- printf("\\f[\\n[" FONT_FORMAT "]]", uid);
+ if (output_format == troff) {
+ printf("\\f[%s]", f);
+ const char *old_roman_font = current_roman_font;
+ current_roman_font = f;
+ p->output();
+ current_roman_font = old_roman_font;
+ printf("\\f[\\n[" FONT_FORMAT "]]", uid);
+ } else if (output_format == mathml) {
+ char *mlfont = f;
+ // bold and italic are already in MathML; translate eqn roman here
+ switch (f[0]) {
+ case 'I': case 'i':
+ mlfont = "italic";
+ break;
+ case 'B': case 'b':
+ mlfont = "bold";
+ break;
+ case 'R': case 'r':
+ default:
+ mlfont = "normal";
+ break;
+ }
+ printf("", mlfont);
+ p->output();
+ printf("");
+ }
}
void font_box::debug_print()
@@ -480,10 +547,16 @@
void fat_box::output()
{
- p->output();
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
- printf("\\h'%dM'", fat_offset);
- p->output();
+ if (output_format == troff) {
+ p->output();
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
+ printf("\\h'%dM'", fat_offset);
+ p->output();
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ printf("");
+ }
}
@@ -519,9 +592,14 @@
void vmotion_box::output()
{
- printf("\\v'%dM'", -n);
- p->output();
- printf("\\v'%dM'", n);
+ if (output_format == troff) {
+ printf("\\v'%dM'", -n);
+ p->output();
+ printf("\\v'%dM'", n);
+ } else if (output_format == mathml) {
+ printf("eqn vertical motion cannot be expressed in MathML");
+ p->output();
+ }
}
void vmotion_box::debug_print()
@@ -552,8 +630,13 @@
void hmotion_box::output()
{
- printf("\\h'%dM'", n);
- p->output();
+ if (output_format == troff) {
+ printf("\\h'%dM'", n);
+ p->output();
+ } else if (output_format == mathml) {
+ printf("eqn horizontal motion cannot be expessed in MathML");
+ p->output();
+ }
}
void hmotion_box::debug_print()
@@ -587,9 +670,11 @@
void vcenter_box::output()
{
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ if (output_format == troff)
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
p->output();
- printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ if (output_format == troff)
+ printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
}
void vcenter_box::debug_print()
Index: over.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/over.cpp,v
retrieving revision 1.2
diff -u -r1.2 over.cpp
--- over.cpp 26 May 2005 21:02:00 -0000 1.2
+++ over.cpp 31 Jan 2007 18:18:29 -0000
@@ -118,64 +118,71 @@
void over_box::output()
{
- if (reduce_size)
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
-#ifdef USE_Z
- printf("\\Z" DELIMITER_CHAR);
-#endif
- // move up to the numerator baseline
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- // move across so that it's centered
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
- uid, num->uid);
-
- // print the numerator
- num->output();
-
-#ifdef USE_Z
- printf(DELIMITER_CHAR);
-#else
- // back again
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
- printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, num->uid);
- // down again
- printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
-#endif
-#ifdef USE_Z
- printf("\\Z" DELIMITER_CHAR);
-#endif
- // move down to the denominator baseline
- printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
-
- // move across so that it's centered
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
- uid, den->uid);
-
- // print the the denominator
- den->output();
-
-#ifdef USE_Z
- printf(DELIMITER_CHAR);
-#else
- // back again
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
- printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
- uid, den->uid);
- // up again
- printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
-#endif
- if (reduce_size)
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
- // draw the line
- printf("\\h'%dM'", null_delimiter_space);
- printf("\\v'-%dM'", axis_height);
- fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
- printf("\\n[" WIDTH_FORMAT "]u-%dM",
- uid, 2*null_delimiter_space);
- fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
- printf("\\v'%dM'", axis_height);
- printf("\\h'%dM'", null_delimiter_space);
+ if (output_format == troff) {
+ if (reduce_size)
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ #ifdef USE_Z
+ printf("\\Z" DELIMITER_CHAR);
+ #endif
+ // move up to the numerator baseline
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ // move across so that it's centered
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
+ uid, num->uid);
+
+ // print the numerator
+ num->output();
+
+ #ifdef USE_Z
+ printf(DELIMITER_CHAR);
+ #else
+ // back again
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
+ printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, num->uid);
+ // down again
+ printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ #endif
+ #ifdef USE_Z
+ printf("\\Z" DELIMITER_CHAR);
+ #endif
+ // move down to the denominator baseline
+ printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
+
+ // move across so that it's centered
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
+ uid, den->uid);
+
+ // print the the denominator
+ den->output();
+
+ #ifdef USE_Z
+ printf(DELIMITER_CHAR);
+ #else
+ // back again
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
+ printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
+ uid, den->uid);
+ // up again
+ printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
+ #endif
+ if (reduce_size)
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ // draw the line
+ printf("\\h'%dM'", null_delimiter_space);
+ printf("\\v'-%dM'", axis_height);
+ fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
+ printf("\\n[" WIDTH_FORMAT "]u-%dM",
+ uid, 2*null_delimiter_space);
+ fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
+ printf("\\v'%dM'", axis_height);
+ printf("\\h'%dM'", null_delimiter_space);
+ } else if (output_format == mathml) {
+ printf("", reduce_size ? "false" : "true");
+ num->output();
+ den->output();
+ printf("");
+ }
}
void over_box::debug_print()
Index: pile.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/pile.cpp,v
retrieving revision 1.3
diff -u -r1.3 pile.cpp
--- pile.cpp 26 May 2005 21:02:00 -0000 1.3
+++ pile.cpp 31 Jan 2007 18:18:29 -0000
@@ -56,45 +56,62 @@
void pile_box::output()
{
- int i;
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- for (i = 0; i < col.len; i++) {
- switch (col.align) {
- case LEFT_ALIGN:
- break;
- case CENTER_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
- uid, col.p[i]->uid);
- break;
- case RIGHT_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
- uid, col.p[i]->uid);
- break;
- default:
- assert(0);
+ if (output_format == troff) {
+ int i;
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ for (i = 0; i < col.len; i++) {
+ switch (col.align) {
+ case LEFT_ALIGN:
+ break;
+ case CENTER_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
+ uid, col.p[i]->uid);
+ break;
+ case RIGHT_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
+ uid, col.p[i]->uid);
+ break;
+ default:
+ assert(0);
+ }
+ col.p[i]->output();
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid);
+ switch (col.align) {
+ case LEFT_ALIGN:
+ break;
+ case CENTER_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
+ col.p[i]->uid, uid);
+ break;
+ case RIGHT_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
+ col.p[i]->uid, uid);
+ break;
+ default:
+ assert(0);
+ }
+ if (i != col.len - 1)
+ printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
}
- col.p[i]->output();
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid);
+ printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ } else if (output_format == mathml) {
+ char *av;
switch (col.align) {
- case LEFT_ALIGN:
- break;
- case CENTER_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
- col.p[i]->uid, uid);
- break;
- case RIGHT_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
- col.p[i]->uid, uid);
- break;
- default:
- assert(0);
+ case LEFT_ALIGN: av = "left"; break;
+ case RIGHT_ALIGN: av = "right"; break;
+ case CENTER_ALIGN: av = "center"; break;
+ default: assert(0);
}
- if (i != col.len - 1)
- printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
+ printf("", av);
+ for (int i = 0; i < col.len; i++) {
+ printf("");
+ col.p[i]->output();
+ printf("");
+ }
+ printf("");
}
- printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
- printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid);
- printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
}
pile_box::pile_box(box *pp) : col(pp)
@@ -163,51 +180,73 @@
void matrix_box::output()
{
- printf("\\h'%dM'", matrix_side_sep);
- for (int i = 0; i < len; i++) {
- int j;
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- for (j = 0; j < p[i]->len; j++) {
- switch (p[i]->align) {
- case LEFT_ALIGN:
- break;
- case CENTER_ALIGN:
- printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
- uid, i, p[i]->p[j]->uid);
- break;
- case RIGHT_ALIGN:
- printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
- uid, i, p[i]->p[j]->uid);
- break;
- default:
- assert(0);
+ if (output_format == troff) {
+ printf("\\h'%dM'", matrix_side_sep);
+ for (int i = 0; i < len; i++) {
+ int j;
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ for (j = 0; j < p[i]->len; j++) {
+ switch (p[i]->align) {
+ case LEFT_ALIGN:
+ break;
+ case CENTER_ALIGN:
+ printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
+ uid, i, p[i]->p[j]->uid);
+ break;
+ case RIGHT_ALIGN:
+ printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
+ uid, i, p[i]->p[j]->uid);
+ break;
+ default:
+ assert(0);
+ }
+ p[i]->p[j]->output();
+ printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid);
+ switch (p[i]->align) {
+ case LEFT_ALIGN:
+ break;
+ case CENTER_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'",
+ p[i]->p[j]->uid, uid, i);
+ break;
+ case RIGHT_ALIGN:
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'",
+ p[i]->p[j]->uid, uid, i);
+ break;
+ default:
+ assert(0);
+ }
+ if (j != p[i]->len - 1)
+ printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
}
- p[i]->p[j]->output();
- printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid);
- switch (p[i]->align) {
- case LEFT_ALIGN:
- break;
- case CENTER_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'",
- p[i]->p[j]->uid, uid, i);
- break;
- case RIGHT_ALIGN:
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'",
- p[i]->p[j]->uid, uid, i);
- break;
- default:
- assert(0);
+ printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
+ printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
+ if (i != len - 1)
+ printf("\\h'%dM'", column_sep);
+ }
+ printf("\\h'%dM'", matrix_side_sep);
+ } else if (output_format == mathml) {
+ int n = p[0]->len; // Each column must have the same number of rows in it
+ printf("");
+ for (int i = 0; i < n; i++) {
+ printf("");
+ for (int j = 0; j < len; j++) {
+ char *av;
+ switch (p[j]->align) {
+ case LEFT_ALIGN: av = "left"; break;
+ case RIGHT_ALIGN: av = "right"; break;
+ case CENTER_ALIGN: av = "center"; break;
+ default: assert(0);
+ }
+ printf("", av);
+ p[j]->p[i]->output();
+ printf("");
}
- if (j != p[i]->len - 1)
- printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
+ printf("");
}
- printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
- printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
- printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
- if (i != len - 1)
- printf("\\h'%dM'", column_sep);
+ printf("");
}
- printf("\\h'%dM'", matrix_side_sep);
}
matrix_box::matrix_box(column *pp)
Index: script.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/script.cpp,v
retrieving revision 1.3
diff -u -r1.3 script.cpp
--- script.cpp 26 May 2005 21:02:00 -0000 1.3
+++ script.cpp 31 Jan 2007 18:18:29 -0000
@@ -168,26 +168,47 @@
void script_box::output()
{
- p->output();
- if (sup != 0) {
- printf("\\Z" DELIMITER_CHAR);
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
- sup->output();
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
- printf(DELIMITER_CHAR);
- }
- if (sub != 0) {
- printf("\\Z" DELIMITER_CHAR);
- printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
- printf("\\h'-\\n[" SUB_KERN_FORMAT "]u'", p->uid);
- sub->output();
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
- printf(DELIMITER_CHAR);
+ if (output_format == troff) {
+ p->output();
+ if (sup != 0) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ sup->output();
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ printf(DELIMITER_CHAR);
+ }
+ if (sub != 0) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ printf("\\h'-\\n[" SUB_KERN_FORMAT "]u'", p->uid);
+ sub->output();
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ printf(DELIMITER_CHAR);
+ }
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
+ uid, p->uid);
+ } else if (output_format == mathml) {
+ if (sup != 0 and sub != 0) {
+ printf("");
+ p->output();
+ sub->output();
+ sup->output();
+ printf("");
+ } else if (sup != 0) {
+ printf("");
+ p->output();
+ sup->output();
+ printf("");
+ } else if (sub != 0) {
+ printf("");
+ p->output();
+ sub->output();
+ printf("");
+ }
+
}
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
- uid, p->uid);
}
void script_box::hint(unsigned flags)
--- special.cpp.~1.2.~ 2005-05-26 17:02:00.000000000 -0400
+++ special.cpp 2007-01-31 13:14:09.000000000 -0500
@@ -104,7 +104,10 @@
void special_box::output()
{
- printf("\\*[" STRING_FORMAT "]", uid);
+ if (output_format == troff)
+ printf("\\*[" STRING_FORMAT "]", uid);
+ else if (output_format == mathml)
+ printf("eqn specials cannot be expressed in MathML");
}
void special_box::debug_print()
Index: sqrt.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/sqrt.cpp,v
retrieving revision 1.2
diff -u -r1.2 sqrt.cpp
--- sqrt.cpp 26 May 2005 21:02:00 -0000 1.2
+++ sqrt.cpp 31 Jan 2007 18:18:29 -0000
@@ -150,21 +150,27 @@
void sqrt_box::output()
{
- printf("\\Z" DELIMITER_CHAR);
- printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
- printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
- printf("\\*[" SQRT_STRING_FORMAT "]", uid);
- printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
- printf(DELIMITER_CHAR);
+ if (output_format == troff) {
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
+ printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
+ printf("\\*[" SQRT_STRING_FORMAT "]", uid);
+ printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
+ printf(DELIMITER_CHAR);
- printf("\\Z" DELIMITER_CHAR);
- printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
- "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
- uid, p->uid, uid);
- p->output();
- printf(DELIMITER_CHAR);
+ printf("\\Z" DELIMITER_CHAR);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
+ "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
+ uid, p->uid, uid);
+ p->output();
+ printf(DELIMITER_CHAR);
- printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
+ } else if (output_format == mathml) {
+ printf("");
+ p->output();
+ printf("");
+ }
}
void sqrt_box::debug_print()
Index: text.cpp
===================================================================
RCS file: /sources/groff/groff/src/preproc/eqn/text.cpp,v
retrieving revision 1.2
diff -u -r1.2 text.cpp
--- text.cpp 26 May 2005 21:02:00 -0000 1.2
+++ text.cpp 31 Jan 2007 18:18:30 -0000
@@ -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
#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,21 +573,44 @@
void char_box::output()
{
- int font_type = char_table[c].font_type;
- if (font_type != LETTER_TYPE)
- printf("\\f[%s]", current_roman_font);
- if (!prev_is_italic)
- fputs("\\,", stdout);
- if (c == '\\')
- fputs("\\e", stdout);
- else
- putchar(c);
- if (!next_is_italic)
- fputs("\\/", stdout);
- else
- fputs("\\&", stdout); // suppress ligaturing and kerning
- if (font_type != LETTER_TYPE)
- fputs("\\fP", stdout);
+ if (output_format == troff) {
+ int font_type = char_table[c].font_type;
+ if (font_type != LETTER_TYPE)
+ printf("\\f[%s]", current_roman_font);
+ if (!prev_is_italic)
+ fputs("\\,", stdout);
+ if (c == '\\')
+ fputs("\\e", stdout);
+ else
+ putchar(c);
+ if (!next_is_italic)
+ fputs("\\/", stdout);
+ else
+ fputs("\\&", stdout); // suppress ligaturing and kerning
+ if (font_type != LETTER_TYPE)
+ fputs("\\fP", stdout);
+ } else if (output_format == mathml) {
+ if (isdigit(c))
+ printf("");
+ else if (char_table[c].spacing_type)
+ printf("");
+ else
+ printf("");
+ if (c == '<')
+ printf("<");
+ else if (c == '>')
+ printf(">");
+ else if (c == '&')
+ printf("&");
+ else
+ putchar(c);
+ if (isdigit(c))
+ printf("");
+ else if (char_table[c].spacing_type)
+ printf("");
+ else
+ printf("");
+ }
}
int char_box::left_is_italic()
@@ -237,12 +653,20 @@
void special_char_box::output()
{
- 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");
+ 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("%s", entity);
+ else
+ printf("unknown eqn/troff special char %s", s);
+ }
}
int special_char_box::is_char()
End of diffs.