/*
*
* (c) COPYRIGHT MIT and INRIA, 1996.
* Please first read the full copyright statement in file COPYRIGHT.
*
*/
/*
*
* MathMLbuilder
*
* Author: V. Quint
*/
#define THOT_EXPORT extern
#include "amaya.h"
#include "css.h"
#include "undo.h"
#include "MathML.h"
#include "parser.h"
#include "Mathedit_f.h"
#include "XMLparser_f.h"
#include "styleparser_f.h"
typedef UCHAR_T MathEntityName[30];
typedef struct _MathEntity
{ /* a Math entity representing an operator char */
MathEntityName MentityName; /* entity name */
int charCode; /* decimal code of char */
CHAR_T alphabet; /* 'L' = ISO-Latin-1, 'G' = Symbol */
}
MathEntity;
static MathEntity MathEntityTable[] =
{
/* This table MUST be in alphabetical order */
/* This table contains characters from the Symbol font plus some
specific MathML entities */
#if defined (_I18N_) || defined (__JIS__)
{L"Agr", 65, L'G'},
{L"And", 217, L'G'},
{L"ApplyFunction", 32, L'L'}, /* render as white space */
{L"Backslash", 92, L'L'},
{L"Bgr", 66, L'G'},
{L"Cap", 199, L'G'},
{L"CenterDot", 215, L'G'},
{L"CirclePlus", 197, L'G'},
{L"CircleTimes", 196, L'G'},
{L"Colon", 58, L'G'},
{L"Congruent", 64, L'G'},
{L"Cup", 200, L'G'},
{L"Delta", 68, L'G'},
{L"Diamond", 168, L'G'},
{L"DoubleDownArrow", 223, L'G'},
{L"DoubleLeftArrow", 220, L'G'},
{L"DoubleLeftRightArrow", 219, L'G'},
{L"DoubleRightArrow", 222, L'G'},
{L"DoubleUpArrow", 221, L'G'},
{L"DownArrow", 175, L'G'},
{L"DownTee", 94, L'G'},
{L"EEgr", 72, L'G'},
{L"Egr", 69, L'G'},
{L"Element", 206, L'G'},
{L"Equal", 61, L'L'},
{L"EqualTilde", 64, L'G'},
{L"Exists", 36, L'G'},
{L"ForAll", 34, L'G'},
{L"Gamma", 71, L'G'},
{L"GreaterEqual", 179, L'G'},
{L"Igr", 73, L'G'},
{L"Integral", 242, L'G'},
{L"Intersection", 199, L'G'},
{L"InvisibleTimes", 0, SPACE},
{L"Kgr", 75, L'G'},
{L"KHgr", 67, L'G'},
{L"Lambda", 76, L'G'},
{L"LeftArrow", 172, L'G'},
{L"LeftRightArrow", 171, L'G'},
{L"Mgr", 77, L'G'},
{L"Ngr", 78, L'G'},
{L"NonBreakingSpace", 160, L'L'},
{L"Not", 216, L'G'},
{L"NotElement", 207, L'G'},
{L"NotEqual", 185, L'G'},
{L"NotSubset", 203, L'G'},
{L"Ogr", 79, L'G'},
{L"Omega", 87, L'G'},
{L"Or", 218, L'G'},
{L"PI", 213, L'G'},
{L"PartialD", 182, L'G'},
{L"Phi", 70, L'G'},
{L"Pi", 80, L'G'},
{L"PlusMinus", 177, L'G'},
{L"Product", 213, L'G'},
{L"Proportional", 181, L'G'},
{L"Psi", 89, L'G'},
{L"Rgr", 82, L'G'},
{L"RightArrow", 174, L'G'},
{L"Sigma", 83, L'G'},
{L"Sol", 164, L'G'},
{L"Star", 42, L'L'},
{L"Subset", 204, L'G'},
{L"SubsetEqual", 205, L'G'},
{L"SuchThat", 39, L'G'},
{L"Sum", 229, L'G'},
{L"Superset", 201, L'G'},
{L"SupersetEqual", 202, L'G'},
{L"Tgr", 84, L'G'},
{L"Therefore", 92, L'G'},
{L"Theta", 81, L'G'},
{L"Tilde", 126, L'L'},
{L"TripleDot", 188, L'G'},
{L"Union", 200, L'G'},
{L"UpArrow", 173, L'G'},
{L"Upsi", 85, L'G'},
{L"Upsi1", 161, L'G'},
{L"Vee", 218, L'G'},
{L"Verbar", 189, L'G'},
{L"VerticalBar", 124, L'L'},
{L"Xi", 88, L'G'},
{L"Zgr", 90, L'G'},
{L"af", 32, L'L'}, /* render as white space */
{L"aleph", 192, L'G'},
{L"alpha", 97, L'G'},
{L"and", 217, L'G'},
{L"angle", 208, L'G'},
{L"ap", 187, L'G'},
{L"beta", 98, L'G'},
{L"bottom", 94, L'G'},
{L"bull", 183, L'G'},
{L"cap", 199, L'G'},
{L"chi", 99, L'G'},
{L"clubs", 167, L'G'},
{L"cong", 64, L'G'},
{L"copysf", 211, L'G'},
{L"copyssf", 227, L'G'},
{L"cr", 191, L'G'},
{L"cup", 200, L'G'},
{L"darr", 175, L'G'},
{L"dArr", 223, L'G'},
{L"dd", 100, L'L'},
{L"deg", 176, L'G'},
{L"delta", 100, L'G'},
{L"diams", 168, L'G'},
{L"divide", 184, L'G'},
{L"dtri", 209, L'G'},
{L"ee", 101, L'L'},
{L"empty", 198, L'G'},
{L"emsp", 32, L'G'},
{L"epsiv", 101, L'G'},
{L"equiv", 186, L'G'},
{L"eta", 104, L'G'},
{L"exist", 36, L'G'},
{L"florin", 166, L'G'},
{L"forall", 34, L'G'},
{L"gamma", 103, L'G'},
{L"ge", 179, L'G'},
{L"gt", 62, L'L'},
{L"hearts", 169, L'G'},
{L"horbar", 190, L'G'},
{L"ifraktur", 193, L'G'},
{L"infin", 165, L'G'},
{L"int", 242, L'G'},
{L"iota", 105, L'G'},
{L"isin", 206, L'G'},
{L"it", 242, L'G'},
{L"kappa", 107, L'G'},
{L"lambda", 108, L'G'},
{L"lang", 225, L'G'},
{L"larr", 172, L'G'},
{L"lArr", 220, L'G'},
{L"le", 163, L'G'},
{L"lowbar", 95, L'G'},
{L"loz", 224, L'G'},
{L"lrarr", 171, L'G'},
{L"lrArr", 219, L'G'},
{L"lsqb", 91, L'G'},
{L"lt", 60, L'L'},
{L"middot", 215, L'G'},
{L"mldr", 188, L'G'},
{L"mu", 109, L'G'},
{L"ne", 185, L'G'},
{L"not", 216, L'G'},
{L"notin", 207, L'G'},
{L"nu", 110, L'G'},
{L"ogr", 111, L'G'},
{L"omega", 119, L'G'},
{L"oplus", 197, L'G'},
{L"or", 218, L'G'},
{L"otimes", 196, L'G'},
{L"part", 182, L'G'},
{L"phi", 102, L'G'},
{L"phiv", 106, L'G'},
{L"pi", 112, L'G'},
{L"piv", 118, L'G'},
{L"prop", 181, L'G'},
{L"psi", 121, L'G'},
{L"radic", 214, L'G'},
{L"rarr", 174, L'G'},
{L"rArr", 222, L'G'},
{L"rdquo", 178, L'G'},
{L"regsf", 210, L'G'},
{L"regssf", 226, L'G'},
{L"rfraktur", 194, L'G'},
{L"rho", 114, L'G'},
{L"rsqb", 93, L'G'},
{L"sigma", 115, L'G'},
{L"sigmav", 86, L'G'},
{L"spades", 170, L'G'},
{L"sub", 204, L'G'},
{L"sube", 205, L'G'},
{L"subne", 203, L'G'},
{L"sum", 229, L'G'},
{L"sup", 201, L'G'},
{L"supe", 202, L'G'},
{L"tau", 116, L'G'},
{L"there4", 92, L'G'},
{L"theta", 113, L'G'},
{L"thetav", 74, L'G'},
{L"thickspace", 32, L'L'},
{L"times", 180, L'G'},
{L"trade", 212, L'G'},
{L"tradesf", 212, L'G'},
{L"tradessf", 228, L'G'},
{L"uarr", 173, L'G'},
{L"uArr", 221, L'G'},
{L"upsi", 117, L'G'},
{L"vee", 218, L'G'},
{L"weierp", 195, L'G'},
{L"xi", 120, L'G'},
{L"zeta", 122, L'G'},
{L"zzzz", -1, SPACE} /* this last entry is required */
#else
{"Agr", 65, 'G'},
{"And", 217, 'G'},
{"ApplyFunction", 32, 'L'}, /* render as white space */
{"Backslash", 92, 'L'},
{"Bgr", 66, 'G'},
{"Cap", 199, 'G'},
{"CenterDot", 215, 'G'},
{"CirclePlus", 197, 'G'},
{"CircleTimes", 196, 'G'},
{"Colon", 58, 'G'},
{"Congruent", 64, 'G'},
{"Cup", 200, 'G'},
{"Delta", 68, 'G'},
{"Diamond", 168, 'G'},
{"DoubleDownArrow", 223, 'G'},
{"DoubleLeftArrow", 220, 'G'},
{"DoubleLeftRightArrow", 219, 'G'},
{"DoubleRightArrow", 222, 'G'},
{"DoubleUpArrow", 221, 'G'},
{"DownArrow", 175, 'G'},
{"DownTee", 94, 'G'},
{"EEgr", 72, 'G'},
{"Egr", 69, 'G'},
{"Element", 206, 'G'},
{"Equal", 61, 'L'},
{"EqualTilde", 64, 'G'},
{"Exists", 36, 'G'},
{"ForAll", 34, 'G'},
{"Gamma", 71, 'G'},
{"GreaterEqual", 179, 'G'},
{"Igr", 73, 'G'},
{"Integral", 242, 'G'},
{"Intersection", 199, 'G'},
{"InvisibleTimes", 0, SPACE},
{"Kgr", 75, 'G'},
{"KHgr", 67, 'G'},
{"Lambda", 76, 'G'},
{"LeftArrow", 172, 'G'},
{"LeftRightArrow", 171, 'G'},
{"Mgr", 77, 'G'},
{"Ngr", 78, 'G'},
{"NonBreakingSpace", 160, 'L'},
{"Not", 216, 'G'},
{"NotElement", 207, 'G'},
{"NotEqual", 185, 'G'},
{"NotSubset", 203, 'G'},
{"Ogr", 79, 'G'},
{"Omega", 87, 'G'},
{"Or", 218, 'G'},
{"PI", 213, 'G'},
{"PartialD", 182, 'G'},
{"Phi", 70, 'G'},
{"Pi", 80, 'G'},
{"PlusMinus", 177, 'G'},
{"Product", 213, 'G'},
{"Proportional", 181, 'G'},
{"Psi", 89, 'G'},
{"Rgr", 82, 'G'},
{"RightArrow", 174, 'G'},
{"Sigma", 83, 'G'},
{"Sol", 164, 'G'},
{"Star", 42, 'L'},
{"Subset", 204, 'G'},
{"SubsetEqual", 205, 'G'},
{"SuchThat", 39, 'G'},
{"Sum", 229, 'G'},
{"Superset", 201, 'G'},
{"SupersetEqual", 202, 'G'},
{"Tgr", 84, 'G'},
{"Therefore", 92, 'G'},
{"Theta", 81, 'G'},
{"Tilde", 126, 'L'},
{"TripleDot", 188, 'G'},
{"Union", 200, 'G'},
{"UpArrow", 173, 'G'},
{"Upsi", 85, 'G'},
{"Upsi1", 161, 'G'},
{"Vee", 218, 'G'},
{"Verbar", 189, 'G'},
{"VerticalBar", 124, 'L'},
{"Xi", 88, 'G'},
{"Zgr", 90, 'G'},
{"af", 32, 'L'}, /* render as white space */
{"aleph", 192, 'G'},
{"alpha", 97, 'G'},
{"and", 217, 'G'},
{"angle", 208, 'G'},
{"ap", 187, 'G'},
{"beta", 98, 'G'},
{"bottom", 94, 'G'},
{"bull", 183, 'G'},
{"cap", 199, 'G'},
{"chi", 99, 'G'},
{"clubs", 167, 'G'},
{"cong", 64, 'G'},
{"copysf", 211, 'G'},
{"copyssf", 227, 'G'},
{"cr", 191, 'G'},
{"cup", 200, 'G'},
{"darr", 175, 'G'},
{"dArr", 223, 'G'},
{"dd", 100, 'L'},
{"deg", 176, 'G'},
{"delta", 100, 'G'},
{"diams", 168, 'G'},
{"divide", 184, 'G'},
{"dtri", 209, 'G'},
{"ee", 101, 'L'},
{"empty", 198, 'G'},
{"emsp", 32, 'G'},
{"epsiv", 101, 'G'},
{"equiv", 186, 'G'},
{"eta", 104, 'G'},
{"exist", 36, 'G'},
{"florin", 166, 'G'},
{"forall", 34, 'G'},
{"gamma", 103, 'G'},
{"ge", 179, 'G'},
{"gt", 62, 'L'},
{"hearts", 169, 'G'},
{"horbar", 190, 'G'},
{"ifraktur", 193, 'G'},
{"infin", 165, 'G'},
{"int", 242, 'G'},
{"iota", 105, 'G'},
{"isin", 206, 'G'},
{"it", 242, 'G'},
{"kappa", 107, 'G'},
{"lambda", 108, 'G'},
{"lang", 225, 'G'},
{"larr", 172, 'G'},
{"lArr", 220, 'G'},
{"le", 163, 'G'},
{"lowbar", 95, 'G'},
{"loz", 224, 'G'},
{"lrarr", 171, 'G'},
{"lrArr", 219, 'G'},
{"lsqb", 91, 'G'},
{"lt", 60, 'L'},
{"middot", 215, 'G'},
{"mldr", 188, 'G'},
{"mu", 109, 'G'},
{"ne", 185, 'G'},
{"not", 216, 'G'},
{"notin", 207, 'G'},
{"nu", 110, 'G'},
{"ogr", 111, 'G'},
{"omega", 119, 'G'},
{"oplus", 197, 'G'},
{"or", 218, 'G'},
{"otimes", 196, 'G'},
{"part", 182, 'G'},
{"phi", 102, 'G'},
{"phiv", 106, 'G'},
{"pi", 112, 'G'},
{"piv", 118, 'G'},
{"prop", 181, 'G'},
{"psi", 121, 'G'},
{"radic", 214, 'G'},
{"rarr", 174, 'G'},
{"rArr", 222, 'G'},
{"rdquo", 178, 'G'},
{"regsf", 210, 'G'},
{"regssf", 226, 'G'},
{"rfraktur", 194, 'G'},
{"rho", 114, 'G'},
{"rsqb", 93, 'G'},
{"sigma", 115, 'G'},
{"sigmav", 86, 'G'},
{"spades", 170, 'G'},
{"sub", 204, 'G'},
{"sube", 205, 'G'},
{"subne", 203, 'G'},
{"sum", 229, 'G'},
{"sup", 201, 'G'},
{"supe", 202, 'G'},
{"tau", 116, 'G'},
{"there4", 92, 'G'},
{"theta", 113, 'G'},
{"thetav", 74, 'G'},
{"thickspace", 32, 'L'},
{"times", 180, 'G'},
{"trade", 212, 'G'},
{"tradesf", 212, 'G'},
{"tradessf", 228, 'G'},
{"uarr", 173, 'G'},
{"uArr", 221, 'G'},
{"upsi", 117, 'G'},
{"vee", 218, 'G'},
{"weierp", 195, 'G'},
{"xi", 120, 'G'},
{"zeta", 122, 'G'},
{"zzzz", -1, SPACE} /* this last entry is required */
#endif
};
/* mapping table of MathML elements */
static ElemMapping MathMLElemMappingTable[] =
{
/* This table MUST be in alphabetical order */
# if defined (_I18N_) || defined (__JIS__)
{L"XMLcomment", SPACE, MathML_EL_XMLcomment},
{L"XMLcomment_line", SPACE, MathML_EL_XMLcomment_line},
{L"maligngroup", 'E', MathML_EL_MALIGNGROUP},
{L"malignmark", 'E', MathML_EL_MALIGNMARK},
{L"merror", SPACE, MathML_EL_MERROR},
{L"mf", SPACE, MathML_EL_MF}, /* for compatibility with an old version of
MathML: WD-math-970704 */
{L"mfenced", SPACE, MathML_EL_MFENCED},
{L"mfrac", SPACE, MathML_EL_MFRAC},
{L"mi", SPACE, MathML_EL_MI},
{L"mmultiscripts", SPACE, MathML_EL_MMULTISCRIPTS},
{L"mn", SPACE, MathML_EL_MN},
{L"mo", SPACE, MathML_EL_MO},
{L"mover", SPACE, MathML_EL_MOVER},
{L"mpadded", SPACE, MathML_EL_MPADDED},
{L"mphantom", SPACE, MathML_EL_MPHANTOM},
{L"mprescripts", SPACE, MathML_EL_PrescriptPairs},
{L"mroot", SPACE, MathML_EL_MROOT},
{L"mrow", SPACE, MathML_EL_MROW},
{L"ms", SPACE, MathML_EL_MS},
{L"mspace", 'E', MathML_EL_MSPACE},
{L"msqrt", SPACE, MathML_EL_MSQRT},
{L"mstyle", SPACE, MathML_EL_MSTYLE},
{L"msub", SPACE, MathML_EL_MSUB},
{L"msubsup", SPACE, MathML_EL_MSUBSUP},
{L"msup", SPACE, MathML_EL_MSUP},
{L"mtable", SPACE, MathML_EL_MTABLE},
{L"mtd", SPACE, MathML_EL_MTD},
{L"mtext", SPACE, MathML_EL_MTEXT},
{L"mtr", SPACE, MathML_EL_MTR},
{L"munder", SPACE, MathML_EL_MUNDER},
{L"munderover", SPACE, MathML_EL_MUNDEROVER},
{L"none", SPACE, MathML_EL_Construct},
{L"sep", 'E', MathML_EL_SEP},
{L"", SPACE, 0} /* Last entry. Mandatory */
# else /* !defined (_I18N_) && ! defined (__JIS__) */
{"XMLcomment", SPACE, MathML_EL_XMLcomment},
{"XMLcomment_line", SPACE, MathML_EL_XMLcomment_line},
{"maction", SPACE, MathML_EL_MACTION},
{"maligngroup", 'E', MathML_EL_MALIGNGROUP},
{"malignmark", 'E', MathML_EL_MALIGNMARK},
{"merror", SPACE, MathML_EL_MERROR},
{"mf", SPACE, MathML_EL_MF}, /* for compatibility with an old version of
MathML: WD-math-970704 */
{"mfenced", SPACE, MathML_EL_MFENCED},
{"mfrac", SPACE, MathML_EL_MFRAC},
{"mi", SPACE, MathML_EL_MI},
{"mmultiscripts", SPACE, MathML_EL_MMULTISCRIPTS},
{"mn", SPACE, MathML_EL_MN},
{"mo", SPACE, MathML_EL_MO},
{"mover", SPACE, MathML_EL_MOVER},
{"mpadded", SPACE, MathML_EL_MPADDED},
{"mphantom", SPACE, MathML_EL_MPHANTOM},
{"mprescripts", SPACE, MathML_EL_PrescriptPairs},
{"mroot", SPACE, MathML_EL_MROOT},
{"mrow", SPACE, MathML_EL_MROW},
{"ms", SPACE, MathML_EL_MS},
{"mspace", 'E', MathML_EL_MSPACE},
{"msqrt", SPACE, MathML_EL_MSQRT},
{"mstyle", SPACE, MathML_EL_MSTYLE},
{"msub", SPACE, MathML_EL_MSUB},
{"msubsup", SPACE, MathML_EL_MSUBSUP},
{"msup", SPACE, MathML_EL_MSUP},
{"mtable", SPACE, MathML_EL_MTABLE},
{"mtd", SPACE, MathML_EL_MTD},
{"mtext", SPACE, MathML_EL_MTEXT},
{"mtr", SPACE, MathML_EL_MTR},
{"munder", SPACE, MathML_EL_MUNDER},
{"munderover", SPACE, MathML_EL_MUNDEROVER},
{"none", SPACE, MathML_EL_Construct},
{"sep", 'E', MathML_EL_SEP},
{"", SPACE, 0} /* Last entry. Mandatory */
# endif /* defined (_I18N_) || defined (__JIS__) */
};
static AttributeMapping MathMLAttributeMappingTable[] =
{
/* The first entry MUST be unknown_attr */
/* The rest of this table MUST be in alphabetical order */
#if defined (_I18N_) || defined (__JIS__)
{L"unknown_attr", _EMPTYSTR_, 'A', MathML_ATTR_Invalid_attribute},
{L"ZZGHOST", _EMPTYSTR_, 'A', MathML_ATTR_Ghost_restruct},
{L"accent", L"", L'A', MathML_ATTR_accent},
{L"accentunder", L"", L'A', MathML_ATTR_accentunder},
{L"actiontype", L"", L'A', MathML_ATTR_actiontype},
{L"align", L"", L'A', MathML_ATTR_align},
{L"alignmentscope", L"", L'A', MathML_ATTR_alignmentscope},
{L"background", L"", L'A', MathML_ATTR_background_},
{L"class", L"", L'A', MathML_ATTR_class},
{L"close", L"", L'A', MathML_ATTR_close},
{L"columnalign", L"", L'A', MathML_ATTR_columnalign},
{L"columnlines", L"", L'A', MathML_ATTR_columnlines},
{L"columnspacing", L"", L'A', MathML_ATTR_columnspacing},
{L"columnspan", L"", L'A', MathML_ATTR_columnspan},
{L"color", L"", L'A', MathML_ATTR_color},
{L"depth", L"", L'A', MathML_ATTR_depth_},
{L"displaystyle", L"", L'A', MathML_ATTR_displaystyle},
{L"edge", L"", L'A', MathML_ATTR_edge},
{L"equalcolumns", L"", L'A', MathML_ATTR_equalcolumns},
{L"equalrows", L"", L'A', MathML_ATTR_equalrows},
{L"fence", L"", L'A', MathML_ATTR_fence},
{L"fontfamily", L"", L'A', MathML_ATTR_fontfamily},
{L"fontstyle", L"", L'A', MathML_ATTR_fontstyle},
{L"fontsize", L"", L'A', MathML_ATTR_fontsize},
{L"fontweight", L"", L'A', MathML_ATTR_fontweight},
{L"form", L"", L'A', MathML_ATTR_form},
{L"frame", L"", L'A', MathML_ATTR_frame},
{L"framespacing", L"", L'A', MathML_ATTR_framespacing},
{L"groupalign", L"", L'A', MathML_ATTR_groupalign},
{L"height", L"", L'A', MathML_ATTR_height_},
{L"id", L"", L'A', MathML_ATTR_id},
{L"largeop", L"", L'A', MathML_ATTR_largeop},
{L"linethickness", L"", L'A', MathML_ATTR_linethickness},
{L"link", L"", L'A', MathML_ATTR_link},
{L"lquote", L"", L'A', MathML_ATTR_lquote},
{L"lspace", L"", L'A', MathML_ATTR_lspace},
{L"maxsize", L"", L'A', MathML_ATTR_maxsize},
{L"minsize", L"", L'A', MathML_ATTR_minsize},
{L"movablelimits", L"", L'A', MathML_ATTR_movablelimits},
{L"open", L"", L'A', MathML_ATTR_open},
{L"other", L"", L'A', MathML_ATTR_other},
{L"rowalign", L"", L'A', MathML_ATTR_rowalign},
{L"rowlines", L"", L'A', MathML_ATTR_rowlines},
{L"rowspacing", L"", L'A', MathML_ATTR_rowspacing},
{L"rowspan", L"", L'A', MathML_ATTR_rowspan_},
{L"rquote", L"", L'A', MathML_ATTR_rquote},
{L"rspace", L"", L'A', MathML_ATTR_rspace},
{L"scriptlevel", L"", L'A', MathML_ATTR_scriptlevel},
{L"scriptminsize", L"", L'A', MathML_ATTR_scriptminsize},
{L"scriptsizemultiplier", L"", L'A', MathML_ATTR_scriptsizemultiplier},
{L"selection", L"", L'A', MathML_ATTR_selection},
{L"separator", L"", L'A', MathML_ATTR_separator},
{L"separators", L"", L'A', MathML_ATTR_separators},
{L"stretchy", L"", L'A', MathML_ATTR_stretchy},
{L"style", L"", L'A', MathML_ATTR_style_},
{L"subscriptshift", L"", L'A', MathML_ATTR_subscriptshift},
{L"superscriptshift", L"", L'A', MathML_ATTR_superscriptshift},
{L"symmetric", L"", L'A', MathML_ATTR_symmetric},
{L"width", L"", L'A', MathML_ATTR_width_},
{L"", L"", EOS, 0} /* Last entry. Mandatory */
#else /* defined (_I18N_) || defined (__JIS__) */
{"unknown_attr", _EMPTYSTR_, 'A', MathML_ATTR_Invalid_attribute},
{"ZZGHOST", _EMPTYSTR_, 'A', MathML_ATTR_Ghost_restruct},
{"accent", "", 'A', MathML_ATTR_accent},
{"accentunder", "", 'A', MathML_ATTR_accentunder},
{"actiontype", "", 'A', MathML_ATTR_actiontype},
{"align", "", 'A', MathML_ATTR_align},
{"alignmentscope", "", 'A', MathML_ATTR_alignmentscope},
{"background", "", 'A', MathML_ATTR_background_},
{"class", "", 'A', MathML_ATTR_class},
{"close", "", 'A', MathML_ATTR_close},
{"columnalign", "", 'A', MathML_ATTR_columnalign},
{"columnlines", "", 'A', MathML_ATTR_columnlines},
{"columnspacing", "", 'A', MathML_ATTR_columnspacing},
{"columnspan", "", 'A', MathML_ATTR_columnspan},
{"color", "", 'A', MathML_ATTR_color},
{"depth", "", 'A', MathML_ATTR_depth_},
{"displaystyle", "", 'A', MathML_ATTR_displaystyle},
{"edge", "", 'A', MathML_ATTR_edge},
{"equalcolumns", "", 'A', MathML_ATTR_equalcolumns},
{"equalrows", "", 'A', MathML_ATTR_equalrows},
{"fence", "", 'A', MathML_ATTR_fence},
{"fontfamily", "", 'A', MathML_ATTR_fontfamily},
{"fontstyle", "", 'A', MathML_ATTR_fontstyle},
{"fontsize", "", 'A', MathML_ATTR_fontsize},
{"fontweight", "", 'A', MathML_ATTR_fontweight},
{"form", "", 'A', MathML_ATTR_form},
{"frame", "", 'A', MathML_ATTR_frame},
{"framespacing", "", 'A', MathML_ATTR_framespacing},
{"groupalign", "", 'A', MathML_ATTR_groupalign},
{"height", "", 'A', MathML_ATTR_height_},
{"id", "", 'A', MathML_ATTR_id},
{"largeop", "", 'A', MathML_ATTR_largeop},
{"linethickness", "", 'A', MathML_ATTR_linethickness},
{"link", "", 'A', MathML_ATTR_link},
{"lquote", "", 'A', MathML_ATTR_lquote},
{"lspace", "", 'A', MathML_ATTR_lspace},
{"maxsize", "", 'A', MathML_ATTR_maxsize},
{"minsize", "", 'A', MathML_ATTR_minsize},
{"movablelimits", "", 'A', MathML_ATTR_movablelimits},
{"open", "", 'A', MathML_ATTR_open},
{"other", "", 'A', MathML_ATTR_other},
{"rowalign", "", 'A', MathML_ATTR_rowalign},
{"rowlines", "", 'A', MathML_ATTR_rowlines},
{"rowspacing", "", 'A', MathML_ATTR_rowspacing},
{"rowspan", "", 'A', MathML_ATTR_rowspan_},
{"rquote", "", 'A', MathML_ATTR_rquote},
{"rspace", "", 'A', MathML_ATTR_rspace},
{"scriptlevel", "", 'A', MathML_ATTR_scriptlevel},
{"scriptminsize", "", 'A', MathML_ATTR_scriptminsize},
{"scriptsizemultiplier", "", 'A', MathML_ATTR_scriptsizemultiplier},
{"selection", "", 'A', MathML_ATTR_selection},
{"separator", "", 'A', MathML_ATTR_separator},
{"separators", "", 'A', MathML_ATTR_separators},
{"stretchy", "", 'A', MathML_ATTR_stretchy},
{"style", "", 'A', MathML_ATTR_style_},
{"subscriptshift", "", 'A', MathML_ATTR_subscriptshift},
{"superscriptshift", "", 'A', MathML_ATTR_superscriptshift},
{"symmetric", "", 'A', MathML_ATTR_symmetric},
{"width", "", 'A', MathML_ATTR_width_},
{"", "", EOS, 0} /* Last entry. Mandatory */
#endif /* defined (_I18N_) || defined (__JIS__) */
};
/* mapping table of attribute values */
static AttrValueMapping MathMLAttrValueMappingTable[] =
{
# if defined (_I18N_) || defined(__JIS__)
{MathML_ATTR_accent, L"true", MathML_ATTR_accent_VAL_true},
{MathML_ATTR_accent, L"false", MathML_ATTR_accent_VAL_false},
{MathML_ATTR_accentunder, L"true", MathML_ATTR_accentunder_VAL_true},
{MathML_ATTR_accentunder, L"false", MathML_ATTR_accentunder_VAL_false},
{MathML_ATTR_displaystyle, L"true", MathML_ATTR_displaystyle_VAL_true},
{MathML_ATTR_displaystyle, L"false", MathML_ATTR_displaystyle_VAL_false},
{MathML_ATTR_edge, L"left", MathML_ATTR_edge_VAL_left_},
{MathML_ATTR_edge, L"right", MathML_ATTR_edge_VAL_right_},
{MathML_ATTR_fence, L"true", MathML_ATTR_fence_VAL_true},
{MathML_ATTR_fence, L"false", MathML_ATTR_fence_VAL_false},
{MathML_ATTR_fontstyle, L"italic", MathML_ATTR_fontstyle_VAL_italic},
{MathML_ATTR_fontstyle, L"normal", MathML_ATTR_fontstyle_VAL_normal},
{MathML_ATTR_link, L"document", MathML_ATTR_link_VAL_document},
{MathML_ATTR_link, L"extended", MathML_ATTR_link_VAL_extended},
{MathML_ATTR_link, L"group", MathML_ATTR_link_VAL_group},
{MathML_ATTR_link, L"locator", MathML_ATTR_link_VAL_locator},
{MathML_ATTR_link, L"simple", MathML_ATTR_link_VAL_simple},
{0, L"", 0} /* Last entry. Mandatory */
# else /* defined (_I18N_) || defined(__JIS__) */
{MathML_ATTR_accent, "true", MathML_ATTR_accent_VAL_true},
{MathML_ATTR_accent, "false", MathML_ATTR_accent_VAL_false},
{MathML_ATTR_accentunder, "true", MathML_ATTR_accentunder_VAL_true},
{MathML_ATTR_accentunder, "false", MathML_ATTR_accentunder_VAL_false},
{MathML_ATTR_displaystyle, "true", MathML_ATTR_displaystyle_VAL_true},
{MathML_ATTR_displaystyle, "false", MathML_ATTR_displaystyle_VAL_false},
{MathML_ATTR_edge, "left", MathML_ATTR_edge_VAL_left_},
{MathML_ATTR_edge, "right", MathML_ATTR_edge_VAL_right_},
{MathML_ATTR_fence, "true", MathML_ATTR_fence_VAL_true},
{MathML_ATTR_fence, "false", MathML_ATTR_fence_VAL_false},
{MathML_ATTR_fontstyle, "italic", MathML_ATTR_fontstyle_VAL_italic},
{MathML_ATTR_fontstyle, "normal", MathML_ATTR_fontstyle_VAL_normal},
{MathML_ATTR_fontweight, "bold", MathML_ATTR_fontweight_VAL_bold_},
{MathML_ATTR_fontweight, "normal", MathML_ATTR_fontweight_VAL_normal},
{MathML_ATTR_form, "prefix", MathML_ATTR_form_VAL_prefix},
{MathML_ATTR_form, "infix", MathML_ATTR_form_VAL_infix},
{MathML_ATTR_form, "postfix", MathML_ATTR_form_VAL_postfix},
{MathML_ATTR_frame, "none", MathML_ATTR_frame_VAL_none},
{MathML_ATTR_frame, "solid", MathML_ATTR_frame_VAL_solid_},
{MathML_ATTR_frame, "dashed", MathML_ATTR_frame_VAL_dashed_},
{MathML_ATTR_largeop, "true", MathML_ATTR_largeop_VAL_true},
{MathML_ATTR_largeop, "false", MathML_ATTR_largeop_VAL_false},
{MathML_ATTR_link, "document", MathML_ATTR_link_VAL_document},
{MathML_ATTR_link, "extended", MathML_ATTR_link_VAL_extended},
{MathML_ATTR_link, "group", MathML_ATTR_link_VAL_group},
{MathML_ATTR_link, "locator", MathML_ATTR_link_VAL_locator},
{MathML_ATTR_link, "simple", MathML_ATTR_link_VAL_simple},
{MathML_ATTR_movablelimits, "true", MathML_ATTR_movablelimits_VAL_true},
{MathML_ATTR_movablelimits, "false", MathML_ATTR_movablelimits_VAL_false},
{MathML_ATTR_separator, "true", MathML_ATTR_separator_VAL_true},
{MathML_ATTR_separator, "false", MathML_ATTR_separator_VAL_false},
{MathML_ATTR_stretchy, "true", MathML_ATTR_stretchy_VAL_true},
{MathML_ATTR_stretchy, "false", MathML_ATTR_stretchy_VAL_false},
{MathML_ATTR_symmetric, "true", MathML_ATTR_symmetric_VAL_true},
{MathML_ATTR_symmetric, "false", MathML_ATTR_symmetric_VAL_false},
{0, "", 0} /* Last entry. Mandatory */
# endif /* defined (_I18N_) || defined(__JIS__) */
};
#define MaxMsgLength 200
#include "HTMLtable_f.h"
/*----------------------------------------------------------------------
GetMathMLSSchema returns the MathML Thot schema for document doc.
----------------------------------------------------------------------*/
#ifdef __STDC__
SSchema GetMathMLSSchema (Document doc)
#else
SSchema GetMathMLSSchema (doc)
Document doc;
#endif
{
SSchema MathMLSSchema;
MathMLSSchema = TtaGetSSchema (TEXT("MathML"), doc);
if (MathMLSSchema == NULL)
MathMLSSchema = TtaNewNature(TtaGetDocumentSSchema(doc), TEXT("MathML"), TEXT("MathMLP"));
return (MathMLSSchema);
}
/*----------------------------------------------------------------------
MapMathMLElementType
search in the mapping tables the entry for the element type of
name XMLname and returns the corresponding Thot element type.
Returns -1 and schema = NULL if not found.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MapMathMLElementType (STRING XMLname, ElementType *elType, STRING* mappedName, STRING content, Document doc)
#else
void MapMathMLElementType (XMLname, elType, mappedName, content, doc)
STRING XMLname;
ElementType *elType;
USTRING* mappedName;
STRING content;
Document doc;
#endif
{
int i;
elType->ElTypeNum = 0;
/* search in MathMLElemMappingTable */
i = 0;
do
if (ustrcasecmp (MathMLElemMappingTable[i].XMLname, XMLname))
i++;
else
{
elType->ElTypeNum = MathMLElemMappingTable[i].ThotType;
if (elType->ElSSchema == NULL)
elType->ElSSchema = GetMathMLSSchema (doc);
*mappedName = MathMLElemMappingTable[i].XMLname;
*content = MathMLElemMappingTable[i].XMLcontents;
}
while (elType->ElTypeNum <= 0 && MathMLElemMappingTable[i].XMLname[0] != EOS);
}
/*----------------------------------------------------------------------
GetMathMLElementName
search in the mapping tables the XML name for a given Thot type
----------------------------------------------------------------------*/
#ifdef __STDC__
void GetMathMLElementName (ElementType elType, STRING *buffer)
#else
void GetMathMLElementName (elType, buffer)
ElementType elType;
STRING buffer;
#endif
{
int i;
if (elType.ElTypeNum > 0)
{
i = 0;
if (ustrcmp (TEXT("MathML"), TtaGetSSchemaName (elType.ElSSchema)) == 0)
do
{
if (MathMLElemMappingTable[i].ThotType == elType.ElTypeNum)
{
*buffer = MathMLElemMappingTable[i].XMLname;
return;
}
i++;
}
while (MathMLElemMappingTable[i].XMLname[0] != EOS);
}
*buffer = TEXT("???");
return;
}
/*----------------------------------------------------------------------
MapMathMLAttribute
Search in the Attribute Mapping Table the entry for the
attribute of name Attr and returns the corresponding Thot attribute type.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MapMathMLAttribute (STRING Attr, AttributeType *attrType, STRING elementName, Document doc)
#else
void MapMathMLAttribute (Attr, attrType, elementName, doc)
STRING Attr;
AttributeType *attrType;
STRING elementName;
Document doc;
#endif
{
int i;
attrType->AttrTypeNum = 0;
attrType->AttrSSchema = NULL;
i = 0;
do
if (ustrcasecmp (MathMLAttributeMappingTable[i].XMLattribute, Attr))
i++;
else
if (MathMLAttributeMappingTable[i].XMLelement[0] == EOS)
{
attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
attrType->AttrSSchema = GetMathMLSSchema (doc);
}
else if (!ustrcasecmp (MathMLAttributeMappingTable[i].XMLelement,
elementName))
{
attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
attrType->AttrSSchema = GetMathMLSSchema (doc);
}
else
i++;
while (attrType->AttrTypeNum <= 0 && MathMLAttributeMappingTable[i].AttrOrContent != EOS);
}
/*----------------------------------------------------------------------
MapMathMLAttributeValue
Search in the Attribute Value Mapping Table the entry for the attribute
ThotAtt and its value AttrVal. Returns the corresponding Thot value.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MapMathMLAttributeValue (STRING AttrVal, AttributeType attrType, int *value)
#else
void MapMathMLAttributeValue (AttrVal, attrType, value)
STRING AttrVal;
AttributeType attrType;
int *value;
#endif
{
int i;
*value = 0;
i = 0;
while (MathMLAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
MathMLAttrValueMappingTable[i].ThotAttr != 0)
i++;
if (MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
do
if (!ustrcasecmp (MathMLAttrValueMappingTable[i].XMLattrValue, AttrVal))
*value = MathMLAttrValueMappingTable[i].ThotAttrValue;
else
i++;
while (*value <= 0 && MathMLAttrValueMappingTable[i].ThotAttr != 0);
}
/*----------------------------------------------------------------------
MapMathMLEntity
Search that entity in the entity table and return the corresponding value.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MapMathMLEntity (STRING entityName, STRING entityValue, int valueLength, STRING alphabet)
#else
void MapMathMLEntity (entityName, entityValue, valueLength, alphabet)
STRING entityName;
STRING entityValue;
int valueLength;
STRING alphabet;
#endif
{
int i;
for (i = 0; MathEntityTable[i].charCode >= 0 &&
ustrcmp (MathEntityTable[i].MentityName, entityName);
i++);
if (!ustrcmp (MathEntityTable[i].MentityName, entityName))
/* entity found */
{
entityValue[0] = (UCHAR_T) MathEntityTable[i].charCode;
entityValue[1] = EOS;
*alphabet = MathEntityTable[i].alphabet;
}
else
{
entityValue[0] = EOS;
*alphabet = EOS;
}
}
/*----------------------------------------------------------------------
MathMLEntityCreated
A MathML entity has been created by the XML parser.
Create a text element containing the entity name.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MathMLEntityCreated (USTRING entityValue, STRING entityName, Document doc)
#else
void MathMLEntityCreated (entityValue, entityName, doc)
USTRING entityValue;
STRING entityName;
Document doc;
#endif
{
ElementType elType;
Element elText;
AttributeType attrType;
Attribute attr;
Language lang;
int len;
#define MAX_ENTITY_LENGTH 80
CHAR_T buffer[MAX_ENTITY_LENGTH];
if (ustrlen (entityValue) <= 1)
if (entityValue[0] == EOS || entityValue[0] == SPACE ||
((int)entityValue[0]) == 129 || /* thin space */
((int)entityValue[0]) == 130 || /* en space */
((int)entityValue[0]) == 160) /* sticky space */
/* null character or space */
/* create a text element containing the entity name with an
attribute entity */
{
XMLTextToDocument ();
len = ustrlen (entityName);
if (len > MAX_ENTITY_LENGTH -3)
len = MAX_ENTITY_LENGTH -3;
buffer[0] = '&';
ustrncpy (&buffer[1], entityName, len);
buffer[len+1] = ';';
buffer[len+2] = EOS;
elType.ElTypeNum = MathML_EL_TEXT_UNIT;
elType.ElSSchema = GetMathMLSSchema (doc);
elText = TtaNewElement (doc, elType);
XMLInsertElement (elText);
lang = TtaGetLanguageIdFromAlphabet('L');
TtaSetTextContent (elText, buffer, lang, doc);
attrType.AttrSSchema = GetMathMLSSchema (doc);
attrType.AttrTypeNum = MathML_ATTR_IntEntity;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (elText, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntEntity_VAL_yes_, elText, doc);
}
}
/*----------------------------------------------------------------------
CheckTextElement Put the content of input buffer into the document.
----------------------------------------------------------------------*/
#ifdef __STDC__
static void CheckTextElement (Element *el, Document doc)
#else
static void CheckTextElement (el, doc)
Element *el;
Document doc;
#endif
{
ElementType parentType, elType;
Element parent, new;
int len;
Language lang;
CHAR_T alphabet;
CHAR_T text[4];
len = TtaGetTextLength (*el);
if (len == 1)
{
len = 2;
TtaGiveTextContent (*el, text, &len, &lang);
alphabet = TtaGetAlphabet (lang);
parent = TtaGetParent (*el);
if (text[0] != EOS)
{
parentType = TtaGetElementType (parent);
elType = parentType;
if (parentType.ElTypeNum == MathML_EL_MF &&
(text[0] == '(' ||
text[0] == ')' ||
text[0] == '[' ||
text[0] == ']' ||
text[0] == '{' ||
text[0] == '}'))
/* Transform the text element into a Thot SYMBOL */
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
else if (parentType.ElTypeNum == MathML_EL_MF &&
text[0] == '|')
/* Transform the text element into a Thot GRAPHIC */
{
elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
text[0] = 'v';
}
else
/* a TEXT element is OK */
elType.ElTypeNum = MathML_EL_TEXT_UNIT;
if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
{
new = TtaNewElement (doc, elType);
TtaInsertSibling (new, *el, FALSE, doc);
TtaDeleteTree (*el, doc);
*el = new;
TtaSetGraphicsShape (new, text[0], doc);
}
}
}
}
/*----------------------------------------------------------------------
ElementNeedsPlaceholder
returns TRUE if element el needs a sibling placeholder.
----------------------------------------------------------------------*/
#ifdef __STDC__
ThotBool ElementNeedsPlaceholder (Element el)
#else
ThotBool ElementNeedsPlaceholder (el)
Element el;
#endif
{
ElementType elType;
Element child, parent;
ThotBool ret;
ret = FALSE;
elType = TtaGetElementType (el);
if (elType.ElTypeNum == MathML_EL_MROW ||
elType.ElTypeNum == MathML_EL_MF ||
elType.ElTypeNum == MathML_EL_MFENCED ||
elType.ElTypeNum == MathML_EL_MACTION ||
elType.ElTypeNum == MathML_EL_MROOT ||
elType.ElTypeNum == MathML_EL_MSQRT ||
elType.ElTypeNum == MathML_EL_MFRAC ||
elType.ElTypeNum == MathML_EL_MSUBSUP ||
elType.ElTypeNum == MathML_EL_MSUB ||
elType.ElTypeNum == MathML_EL_MSUP ||
elType.ElTypeNum == MathML_EL_MUNDER ||
elType.ElTypeNum == MathML_EL_MOVER ||
elType.ElTypeNum == MathML_EL_MUNDEROVER ||
elType.ElTypeNum == MathML_EL_MMULTISCRIPTS)
ret = TRUE;
else
if (elType.ElTypeNum == MathML_EL_MO)
/* an operator that contains a single Symbol needs a placeholder,
except when it is in a Base or UnderOverBase */
{
child = TtaGetFirstChild (el);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
{
ret = TRUE;
parent = TtaGetParent (el);
if (parent != NULL)
{
elType = TtaGetElementType (parent);
if (elType.ElTypeNum == MathML_EL_Base ||
elType.ElTypeNum == MathML_EL_UnderOverBase)
ret = FALSE;
}
}
}
}
return ret;
}
/*----------------------------------------------------------------------
CreatePlaceholders
----------------------------------------------------------------------*/
#ifdef __STDC__
static void CreatePlaceholders (Element el, Document doc)
#else
static void CreatePlaceholders (el, doc)
Element el;
Document doc;
#endif
{
Element sibling, prev, constr, child;
Attribute attr;
ElementType elType;
AttributeType attrType;
ThotBool create;
elType.ElSSchema = GetMathMLSSchema (doc);
prev = NULL;
create = TRUE;
sibling = el;
while (sibling != NULL)
{
if (!ElementNeedsPlaceholder (sibling))
create = FALSE;
else
{
if (sibling == el)
/* first element */
{
elType = TtaGetElementType (sibling);
if (elType.ElTypeNum == MathML_EL_MF)
/* the first element is a MF. Don't create a placeholder
before */
create = FALSE;
else if (elType.ElTypeNum == MathML_EL_MROW)
/* the first element is a MROW */
{
child = TtaGetFirstChild (sibling);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum != MathML_EL_MF)
/* the first child of the MROW element is not a MF */
/* Don't create a placeholder before */
create = FALSE;
}
}
}
if (create)
{
elType.ElTypeNum = MathML_EL_Construct;
constr = TtaNewElement (doc, elType);
TtaInsertSibling (constr, sibling, TRUE, doc);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (constr, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, constr, doc);
}
create = TRUE;
}
prev = sibling;
TtaNextSibling (&sibling);
}
if (prev != NULL && create)
{
elType = TtaGetElementType (prev);
/* don't insert a placeholder after the last element if it's a MF
or a SEP */
if (elType.ElTypeNum == MathML_EL_MF ||
elType.ElTypeNum == MathML_EL_SEP)
create = FALSE;
else if (elType.ElTypeNum == MathML_EL_MROW)
/* the last element is a MROW */
{
child = TtaGetLastChild (prev);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum != MathML_EL_MF)
/* the last child of the MROW element is not a MF */
/* Don't create a placeholder before */
create = FALSE;
}
}
if (create)
{
elType.ElTypeNum = MathML_EL_Construct;
constr = TtaNewElement (doc, elType);
TtaInsertSibling (constr, prev, FALSE, doc);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (constr, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, constr, doc);
}
}
}
/*----------------------------------------------------------------------
NextNotSep
Return the next sibling of element el that is not a SEP element
Return el itself if it's not a SEP
----------------------------------------------------------------------*/
#ifdef __STDC__
static void NextNotSep (Element* el, Element* prev)
#else
static void NextNotSep (el, prev)
Element *el;
#endif
{
ElementType elType;
if (*el == NULL)
return;
elType = TtaGetElementType (*el);
while (*el != NULL && elType.ElTypeNum == MathML_EL_SEP)
{
*prev = *el;
TtaNextSibling (el);
if (*el != NULL)
elType = TtaGetElementType (*el);
}
}
/*----------------------------------------------------------------------
CheckMathSubExpressions
Children of element el should be of type type1, type2, and type3.
Create an element of that type.
----------------------------------------------------------------------*/
#ifdef __STDC__
static void CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
#else
static void CheckMathSubExpressions (el, type1, type2, type3, doc)
Element el;
int type1;
int type2;
int type3;
Document doc;
#endif
{
Element child, new, prev;
ElementType elType, childType;
elType.ElSSchema = GetMathMLSSchema (doc);
child = TtaGetFirstChild (el);
prev = NULL;
NextNotSep (&child, &prev);
if (child != NULL && type1 != 0)
{
elType.ElTypeNum = type1;
childType = TtaGetElementType (child);
if (TtaSameTypes (childType, elType) == 0)
{
TtaRemoveTree (child, doc);
new = TtaNewElement (doc, elType);
if (prev == NULL)
TtaInsertFirstChild (&new, el, doc);
else
TtaInsertSibling (new, prev, FALSE, doc);
TtaInsertFirstChild (&child, new, doc);
CreatePlaceholders (child, doc);
child = new;
}
if (type2 != 0)
{
prev = child;
TtaNextSibling (&child);
NextNotSep (&child, &prev);
if (child != NULL)
{
elType.ElTypeNum = type2;
childType = TtaGetElementType (child);
if (TtaSameTypes (childType, elType) == 0)
{
TtaRemoveTree (child, doc);
new = TtaNewElement (doc, elType);
TtaInsertSibling (new, prev, FALSE, doc);
TtaInsertFirstChild (&child, new, doc);
CreatePlaceholders (child, doc);
child = new;
}
if (type3 != 0)
{
prev = child;
TtaNextSibling (&child);
NextNotSep (&child, &prev);
if (child != NULL)
{
elType.ElTypeNum = type3;
childType = TtaGetElementType (child);
if (TtaSameTypes (childType, elType) == 0)
{
TtaRemoveTree (child, doc);
new = TtaNewElement (doc, elType);
TtaInsertSibling (new, prev, FALSE, doc);
TtaInsertFirstChild (&child, new, doc);
CreatePlaceholders (child, doc);
}
}
}
}
}
}
}
/*----------------------------------------------------------------------
SetSingleIntHorizStretchAttr
Put a IntHorizStretch attribute on element el if it contains only
a MO element that is a stretchable symbol.
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetSingleIntHorizStretchAttr (Element el, Document doc, Element* selEl)
#else /* __STDC__*/
void SetSingleIntHorizStretchAttr (el, doc, selEl)
Element el;
Document doc;
Element* selEl;
#endif /* __STDC__*/
{
Element child, sibling, textEl, symbolEl;
ElementType elType;
Attribute attr;
AttributeType attrType;
int len;
Language lang;
CHAR_T alphabet;
UCHAR_T text[2], c;
if (el == NULL)
return;
child = TtaGetFirstChild (el);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum == MathML_EL_MO)
/* the first child is a MO */
{
sibling = child;
TtaNextSibling (&sibling);
if (sibling == NULL)
/* there is no other child */
{
textEl = TtaGetFirstChild (child);
elType = TtaGetElementType (textEl);
if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
{
len = TtaGetTextLength (textEl);
if (len == 1)
{
len = 2;
TtaGiveTextContent (textEl, text, &len, &lang);
alphabet = TtaGetAlphabet (lang);
if (len == 1)
if (alphabet == 'G')
/* a single Symbol character */
if ((int)text[0] == 172 || (int)text[0] == 174)
/* horizontal arrow */
{
c = EOS;
/* attach a IntHorizStretch attribute */
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntHorizStretch;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, el, doc);
/* replace the TEXT element by a Thot SYMBOL element */
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
symbolEl = TtaNewElement (doc, elType);
TtaInsertSibling (symbolEl, textEl, FALSE, doc);
if (selEl != NULL)
if (*selEl == textEl)
*selEl = symbolEl;
TtaDeleteTree (textEl, doc);
if ((int)text[0] == 172)
c = '<';
if ((int)text[0] == 174)
c = '>';
if (c != EOS)
TtaSetGraphicsShape (symbolEl, c, doc);
}
}
}
}
}
}
}
/*----------------------------------------------------------------------
SetIntHorizStretchAttr
Put a IntHorizStretch attribute on all children of element el which
contain only a MO element that is a stretchable symbol.
-----------------------------------------------------------------------*/
#ifdef __STDC__
static void SetIntHorizStretchAttr (Element el, Document doc)
#else /* __STDC__*/
static void SetIntHorizStretchAttr (el, doc)
Element el;
Document doc;
#endif /* __STDC__*/
{
Element child;
if (el == NULL)
return;
child = TtaGetFirstChild (el);
while (child != NULL)
{
SetSingleIntHorizStretchAttr (child, doc, NULL);
TtaNextSibling (&child);
}
}
/*----------------------------------------------------------------------
SetIntVertStretchAttr
Put a IntVertStretch attribute on element el if its base element
(Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
a MUNDER of a MOVER) contains only a MO element that is a vertically
stretchable symbol.
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetIntVertStretchAttr (Element el, Document doc, int base, Element* selEl)
#else /* __STDC__*/
void SetIntVertStretchAttr (el, doc, base, selEl)
Element el;
Document doc;
int base;
Element* selEl;
#endif /* __STDC__*/
{
Element child, sibling, textEl, symbolEl, parent, operator;
ElementType elType;
Attribute attr;
AttributeType attrType;
int len;
Language lang;
CHAR_T alphabet;
UCHAR_T text[2], c;
if (el == NULL)
return;
operator = NULL;
if (base == 0)
/* it's a MO */
{
parent = TtaGetParent (el);
if (parent != NULL)
{
elType = TtaGetElementType (parent);
if (elType.ElTypeNum != MathML_EL_Base &&
elType.ElTypeNum != MathML_EL_UnderOverBase &&
elType.ElTypeNum != MathML_EL_MSUBSUP &&
elType.ElTypeNum != MathML_EL_MSUB &&
elType.ElTypeNum != MathML_EL_MSUP &&
elType.ElTypeNum != MathML_EL_MUNDEROVER &&
elType.ElTypeNum != MathML_EL_MUNDER &&
elType.ElTypeNum != MathML_EL_MUNDEROVER)
operator = el;
}
}
else
/* it's not a MO */
{
/* search the Base or UnderOverBase child */
child = TtaGetFirstChild (el);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum == base)
/* the first child is a Base or UnderOverBase */
{
child = TtaGetFirstChild (child);
if (child != NULL)
{
elType = TtaGetElementType (child);
if (elType.ElTypeNum == MathML_EL_MO)
/* its first child is a MO */
{
sibling = child;
TtaNextSibling (&sibling);
if (sibling == NULL)
/* there is no other child */
operator = child;
}
}
}
}
}
if (operator != NULL)
{
textEl = TtaGetFirstChild (operator);
if (textEl != NULL)
{
elType = TtaGetElementType (textEl);
if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
{
len = TtaGetTextLength (textEl);
if (len == 1)
{
len = 2;
TtaGiveTextContent (textEl, text, &len, &lang);
alphabet = TtaGetAlphabet (lang);
if (len == 1)
if (alphabet == 'G')
/* a single Symbol character */
if ((int)text[0] == 242)
/* Integral */
{
/* attach a IntVertStretch attribute */
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntVertStretch_VAL_yes_, el, doc);
/* replace the TEXT element by a Thot SYMBOL element*/
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
symbolEl = TtaNewElement (doc, elType);
TtaInsertSibling (symbolEl, textEl, FALSE, doc);
if (selEl != NULL)
if (*selEl == textEl)
*selEl = symbolEl;
TtaDeleteTree (textEl, doc);
c = 'i';
TtaSetGraphicsShape (symbolEl, c, doc);
}
}
}
}
}
}
/*----------------------------------------------------------------------
SetIntPlaceholderAttr
Put a IntPlaceholder attribute on all Construct elements in the
subtree of root el.
-----------------------------------------------------------------------*/
#ifdef __STDC__
static void SetIntPlaceholderAttr (Element el, Document doc)
#else /* __STDC__*/
static void SetIntPlaceholderAttr (el, doc)
Element el;
Document doc;
#endif /* __STDC__*/
{
Element child;
ElementType elType;
Attribute attr;
AttributeType attrType;
if (el == NULL)
return;
elType = TtaGetElementType (el);
if (elType.ElTypeNum == MathML_EL_Construct &&
elType.ElSSchema == GetMathMLSSchema (doc))
{
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, el, doc);
}
else
{
child = TtaGetFirstChild (el);
while (child != NULL)
{
SetIntPlaceholderAttr (child, doc);
TtaNextSibling (&child);
}
}
}
/*----------------------------------------------------------------------
BuildMultiscript
The content of a MMULTISCRIPT element has been created following
the original MathML structure. Create all Thot elements defined
in the MathML S schema.
-----------------------------------------------------------------------*/
#ifdef __STDC__
static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
#else /* __STDC__*/
static void BuildMultiscript (elMMULTISCRIPT, doc)
Element elMMULTISCRIPT;
Document doc;
#endif /* __STDC__*/
{
Element elem, base, next, group, pair, script, prevPair, prevScript;
ElementType elType, elTypeGroup, elTypePair, elTypeScript;
SSchema MathMLSSchema;
base = NULL;
group = NULL;
prevPair = NULL;
prevScript = NULL;
MathMLSSchema = GetMathMLSSchema (doc);
elTypeGroup.ElSSchema = MathMLSSchema;
elTypePair.ElSSchema = MathMLSSchema;
elTypeScript.ElSSchema = MathMLSSchema;
/* process all children of the MMULTISCRIPT element */
elem = TtaGetFirstChild (elMMULTISCRIPT);
while (elem != NULL)
{
/* remember the element to be processed after the current one */
next = elem;
TtaNextSibling (&next);
/* remove the current element from the tree */
TtaRemoveTree (elem, doc);
if (base == NULL)
/* the current element is the first child of the MMULTISCRIPT
element */
{
/* Create a MultiscriptBase element as the first child of
MMULTISCRIPT and move the current element as the first child
of the MultiscriptBase element */
elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
base = TtaNewElement (doc, elTypeGroup);
TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
TtaInsertFirstChild (&elem, base, doc);
}
else
/* the current element is a subscript or a superscript */
{
if (group == NULL)
/* there is no PostscriptPairs element. Create one */
{
elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
group = TtaNewElement (doc, elTypeGroup);
TtaInsertSibling (group, base, FALSE, doc);
elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
/* create a first and a last PostscriptPair as placeholders */
pair = TtaNewTree (doc, elTypePair, _EMPTYSTR_);
TtaInsertFirstChild (&pair, group, doc);
SetIntPlaceholderAttr (pair, doc);
prevPair = pair;
pair = TtaNewTree (doc, elTypePair, _EMPTYSTR_);
TtaInsertSibling (pair, prevPair, FALSE, doc);
SetIntPlaceholderAttr (pair, doc);
prevScript = NULL;
}
if (prevScript == NULL)
/* the current element is the first subscript or superscript
in a pair */
{
/* create a PostscriptPair or PrescriptPair element */
pair = TtaNewElement (doc, elTypePair);
if (prevPair == NULL)
TtaInsertFirstChild (&pair, group, doc);
else
TtaInsertSibling (pair, prevPair, FALSE, doc);
prevPair = pair;
/* create a MSubscript element */
elTypeScript.ElTypeNum = MathML_EL_MSubscript;
script = TtaNewElement (doc, elTypeScript);
TtaInsertFirstChild (&script, pair, doc);
prevScript = script;
}
else
/* the current element is a superscript in a pair */
{
/* create a MSuperscript element */
elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
script = TtaNewElement (doc, elTypeScript);
/* insert it as a sibling of the previous MSubscript element */
TtaInsertSibling (script, prevScript, FALSE, doc);
prevScript = NULL;
}
/* insert the current element as a child of the new MSuperscript or
MSubscript element */
TtaInsertFirstChild (&elem, script, doc);
SetIntPlaceholderAttr (elem, doc);
}
CreatePlaceholders (elem, doc);
/* get next child of the MMULTISCRIPT element */
elem = next;
if (elem != NULL)
{
elType = TtaGetElementType (elem);
if (elType.ElSSchema == MathMLSSchema &&
elType.ElTypeNum == MathML_EL_PrescriptPairs)
/* the next element is a PrescriptPairs */
{
/* if there there is no PostscriptPairs element, create one as a
placeholder */
if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
{
elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
group = TtaNewTree (doc, elTypeGroup, _EMPTYSTR_);
TtaInsertSibling (group, elem, TRUE, doc);
SetIntPlaceholderAttr (group, doc);
}
/* the following elements will be interpreted as sub- superscripts
in PrescriptPair elements, wich will be children of this
PrescriptPairs element */
elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
group = elem;
/* create a first and a last PostscriptPair as placeholders */
pair = TtaNewTree (doc, elTypePair, _EMPTYSTR_);
TtaInsertFirstChild (&pair, group, doc);
SetIntPlaceholderAttr (pair, doc);
prevPair = pair;
pair = TtaNewTree (doc, elTypePair, _EMPTYSTR_);
TtaInsertSibling (pair, prevPair, FALSE, doc);
SetIntPlaceholderAttr (pair, doc);
prevScript = NULL;
TtaNextSibling (&elem);
}
}
}
/* all children of element MMULTISCRIPTS have been processed */
/* if the last group processed is not a PrescriptPairs element,
create one as a placeholder */
if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
{
elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
elem = TtaNewTree (doc, elTypeGroup, _EMPTYSTR_);
if (group == NULL)
group = base;
TtaInsertSibling (elem, group, TRUE, doc);
SetIntPlaceholderAttr (elem, doc);
}
}
/*----------------------------------------------------------------------
CheckMTable
The content of a MTABLE element has been created following
the original MathML structure. Create all Thot elements defined
in the MathML S schema.
-----------------------------------------------------------------------*/
#ifdef __STDC__
void CheckMTable (Element elMTABLE, Document doc)
#else /* __STDC__*/
void CheckMTable (elMTABLE, doc)
Element elMTABLE;
Document doc;
#endif /* __STDC__*/
{
ElementType elType;
Element MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
nextCell, newMTD, firstColHead, child, prevChild, nextChild,
wrapper;
SSchema MathMLSSchema;
MathMLSSchema = GetMathMLSSchema (doc);
row = TtaGetFirstChild (elMTABLE);
/* create a MTable_head as the first child of element MTABLE */
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MTable_head;
MTableHead = TtaNewElement (doc, elType);
TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
elType.ElTypeNum = MathML_EL_MColumn_head;
firstColHead = TtaNewTree (doc, elType, _EMPTYSTR_);
TtaInsertFirstChild (&firstColHead, MTableHead, doc);
/* create a MTable_body */
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MTable_body;
MTableBody = TtaNewElement (doc, elType);
TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
/* move all children of element MTABLE into the new MTable_body element
and wrap each non-MTR element with a MTR */
prevRow = NULL;
while (row)
{
nextRow = row;
TtaNextSibling (&nextRow);
elType = TtaGetElementType (row);
TtaRemoveTree (row, doc);
if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
(elType.ElTypeNum == MathML_EL_XMLcomment ||
elType.ElTypeNum == MathML_EL_MTR))
{
if (prevRow == NULL)
TtaInsertFirstChild (&row, MTableBody, doc);
else
TtaInsertSibling (row, prevRow, FALSE, doc);
prevRow = row;
if (elType.ElTypeNum == MathML_EL_MTR)
cell = TtaGetFirstChild (row);
else
cell = NULL;
}
else
/* this child is not a MTR nor a comment, create a MTR element */
{
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MTR;
el = TtaNewElement (doc, elType);
if (prevRow == NULL)
TtaInsertFirstChild (&el, MTableBody, doc);
else
TtaInsertSibling (el, prevRow, FALSE, doc);
TtaInsertFirstChild (&row, el, doc);
cell = row;
prevRow = el;
}
while (cell)
/* check all children of the current MTR element */
{
nextCell = cell;
TtaNextSibling (&nextCell);
elType = TtaGetElementType (cell);
if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
(elType.ElTypeNum != MathML_EL_XMLcomment &&
elType.ElTypeNum != MathML_EL_MTD))
/* this is not a MTD nor a comment, create a wrapping MTD */
{
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MTD;
newMTD = TtaNewElement (doc, elType);
TtaInsertSibling (newMTD, cell, TRUE, doc);
TtaRemoveTree (cell, doc);
TtaInsertFirstChild (&cell, newMTD, doc);
cell = newMTD;
}
if (elType.ElTypeNum == MathML_EL_MTD)
/* This is a MTD element. Wrap its contents with a CellWrapper */
{
child = TtaGetFirstChild (cell);
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_CellWrapper;
wrapper = TtaNewElement (doc, elType);
TtaInsertFirstChild (&wrapper, cell, doc);
prevChild = NULL;
while (child)
{
nextChild = child;
TtaNextSibling (&nextChild);
TtaRemoveTree (child, doc);
if (prevChild == NULL)
TtaInsertFirstChild (&child, wrapper, doc);
else
TtaInsertSibling (child, prevChild, FALSE, doc);
prevChild = child;
child = nextChild;
}
}
cell = nextCell;
}
row = nextRow;
}
CheckAllRows (elMTABLE, doc);
}
/*----------------------------------------------------------------------
SetFontstyleAttr
The content of a MI element has been created or modified.
Create or change attribute IntFontstyle for that element accordingly.
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetFontstyleAttr (Element el, Document doc)
#else /* __STDC__*/
void SetFontstyleAttr (el, doc)
Element el;
Document doc;
#endif /* __STDC__*/
{
ElementType elType;
AttributeType attrType;
Attribute attr, IntAttr;
int len;
if (el != NULL)
{
/* search the fontstyle attribute */
elType = TtaGetElementType (el);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_fontstyle;
attr = TtaGetAttribute (el, attrType);
attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
IntAttr = TtaGetAttribute (el, attrType);
if (attr != NULL)
/* there is a fontstyle attribute. Remove the corresponding
internal attribute that is not needed */
{
if (IntAttr != NULL)
TtaRemoveAttribute (el, IntAttr, doc);
}
else
/* there is no fontstyle attribute. Create an internal attribute
IntFontstyle with a value that depends on the content of the MI */
{
/* get content length */
len = TtaGetElementVolume (el);
if (len > 1)
/* put an attribute IntFontstyle = IntNormal */
{
if (IntAttr == NULL)
{
IntAttr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, IntAttr, doc);
}
TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
el, doc);
}
else
/* MI contains a single character. Remove attribute IntFontstyle
if it exists */
{
if (IntAttr != NULL)
TtaRemoveAttribute (el, IntAttr, doc);
}
}
}
}
/*----------------------------------------------------------------------
SetIntAddSpaceAttr
The content of a MO element has been created or modified.
Create or change attribute IntAddSpace for that element accordingly.
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetIntAddSpaceAttr (Element el, Document doc)
#else /* __STDC__*/
void SetIntAddSpaceAttr (el, doc)
Element el;
Document doc;
#endif /* __STDC__*/
{
Element textEl, previous;
ElementType elType;
AttributeType attrType;
Attribute attr;
int len, val;
#define BUFLEN 10
UCHAR_T text[BUFLEN];
Language lang;
CHAR_T alphabet;
textEl = TtaGetFirstChild (el);
if (textEl != NULL)
{
/* search the IntAddSpace attribute */
elType = TtaGetElementType (el);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntAddSpace;
attr = TtaGetAttribute (el, attrType);
if (attr == NULL)
{
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, attr, doc);
}
val = MathML_ATTR_IntAddSpace_VAL_nospace;
len = TtaGetTextLength (textEl);
if (len > 0 && len < BUFLEN)
{
len = BUFLEN;
TtaGiveTextContent (textEl, text, &len, &lang);
alphabet = TtaGetAlphabet (lang);
if (len == 1)
if (alphabet == 'L')
/* ISO-Latin 1 character */
{
if (text[0] == '-')
/* unary or binary operator? */
{
previous = el;
TtaPreviousSibling (&previous);
if (previous == NULL)
/* no previous sibling => unary operator */
val = MathML_ATTR_IntAddSpace_VAL_nospace;
else
{
elType = TtaGetElementType (previous);
if (elType.ElTypeNum == MathML_EL_MO)
/* after an operator => unary operator */
val = MathML_ATTR_IntAddSpace_VAL_nospace;
else
/* binary operator */
val = MathML_ATTR_IntAddSpace_VAL_both;
}
}
else if (text[0] == '+' ||
text[0] == '&' ||
text[0] == '*' ||
text[0] == '<' ||
text[0] == '=' ||
text[0] == '>' ||
text[0] == '^')
/* binary operator */
val = MathML_ATTR_IntAddSpace_VAL_both;
else if (text[0] == ',' ||
text[0] == ';')
val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
}
else if (alphabet == 'G')
/* Symbol character set */
if ((int)text[0] == 163 || /* less or equal */
(int)text[0] == 177 || /* plus or minus */
(int)text[0] == 179 || /* greater or equal */
(int)text[0] == 180 || /* times */
(int)text[0] == 184 || /* divide */
(int)text[0] == 185 || /* not equal */
(int)text[0] == 186 || /* identical */
(int)text[0] == 187 || /* equivalent */
(int)text[0] == 196 || /* circle times */
(int)text[0] == 197 || /* circle plus */
((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
(int)text[0] == 217 || /* and */
(int)text[0] == 218 ) /* or */
val = MathML_ATTR_IntAddSpace_VAL_both;
}
TtaSetAttributeValue (attr, val, el, doc);
}
}
/*----------------------------------------------------------------------
ChangeTypeOfElement
Change the type of element elem into newTypeNum
-----------------------------------------------------------------------*/
#ifdef __STDC__
void ChangeTypeOfElement (Element elem, Document doc, int newTypeNum)
#else /* __STDC__*/
void ChangeTypeOfElement (elem, doc, newTypeNum)
Element elem;
Document doc;
int newTypeNum;
#endif /* __STDC__*/
{
Element prev, next, parent;
parent = NULL;
prev = elem;
TtaPreviousSibling (&prev);
if (prev == NULL)
{
next = elem;
TtaNextSibling (&next);
if (next == NULL)
parent = TtaGetParent (elem);
}
TtaRemoveTree (elem, doc);
ChangeElementType (elem, newTypeNum);
if (prev != NULL)
TtaInsertSibling (elem, prev, FALSE, doc);
else if (next != NULL)
TtaInsertSibling (elem, next, TRUE, doc);
else
TtaInsertFirstChild (&elem, parent, doc);
}
/*----------------------------------------------------------------------
CheckFence
If el is a MO element that contains a single fence character,
transform the MO into a MF and the character into a Thot symbol.
----------------------------------------------------------------------*/
#ifdef __STDC__
void CheckFence (Element el, Document doc)
#else
void CheckFence (el, doc)
Element el;
Document doc;
#endif
{
ElementType elType;
Element content;
AttributeType attrType;
Attribute attr;
int len;
Language lang;
CHAR_T alphabet;
UCHAR_T text[2], c;
elType = TtaGetElementType (el);
if (elType.ElTypeNum == MathML_EL_MO)
{
content = TtaGetFirstChild (el);
if (content != NULL)
{
elType = TtaGetElementType (content);
if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
{
len = TtaGetTextLength (content);
if (len == 1)
{
len = 2;
TtaGiveTextContent (content, text, &len, &lang);
alphabet = TtaGetAlphabet (lang);
if (len == 1)
if (alphabet == 'L')
/* a single character */
if (text[0] == '(' || text[0] == ')' ||
text[0] == '[' || text[0] == ']' ||
text[0] == '{' || text[0] == '}' ||
text[0] == '|' )
{
/* remove the content of the MO element */
TtaDeleteTree (content, doc);
/* change the MO element into a MF element */
ChangeTypeOfElement (el, doc, MathML_EL_MF);
/* attach a IntVertStretch attribute to the MF element */
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (el, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntVertStretch_VAL_yes_, el, doc);
/* create a new content for the MF element */
if (text[0] == '|')
{
elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
c = 'v';
}
else
{
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
c = text[0];
}
content = TtaNewElement (doc, elType);
TtaInsertFirstChild (&content, el, doc);
TtaSetGraphicsShape (content, c, doc);
}
}
}
}
}
}
/*----------------------------------------------------------------------
CreateFencedSeparators
Create FencedSeparator elements within the fencedExpression
according to attribute separators of the MFENCED element.
----------------------------------------------------------------------*/
#ifdef __STDC__
void CreateFencedSeparators (Element fencedExpression, Document doc, ThotBool record)
#else
void CreateFencedSeparators (fencedExpression, doc, record)
Element fencedExpression;
Document doc;
ThotBool record;
#endif
{
ElementType elType;
Element child, separator, leaf, next, prev, mfenced;
AttributeType attrType;
Attribute attr;
int length, sep, i;
Language lang;
CHAR_T text[32], sepValue[4];
/* get the separators attribute */
mfenced = TtaGetParent (fencedExpression);
elType = TtaGetElementType (fencedExpression);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_separators;
text[0] = ','; /* default value is sparators="," */
text[1] = EOS;
length = 1;
attr = TtaGetAttribute (mfenced, attrType);
if (attr != NULL)
{
length = 31;
TtaGiveTextAttributeValue (attr, text, &length);
}
/* create FencedSeparator elements in the FencedExpression */
prev = NULL;
sep = 0;
/* skip leading spaces in attribute separators */
while (text[sep] <= SPACE && text[sep] != EOS)
sep++;
/* if attribute separators is empty or contains only spaces, do not
insert any separator element */
if (text[sep] != EOS)
{
child = TtaGetFirstChild (fencedExpression);
while (child != NULL)
{
next = child;
TtaNextSibling (&next);
elType = TtaGetElementType (child);
if (elType.ElTypeNum != MathML_EL_Construct)
{
if (prev != NULL)
{
elType.ElTypeNum = MathML_EL_FencedSeparator;
separator = TtaNewElement (doc, elType);
TtaInsertSibling (separator, prev, FALSE, doc);
elType.ElTypeNum = MathML_EL_TEXT_UNIT;
leaf = TtaNewElement (doc, elType);
TtaInsertFirstChild (&leaf, separator, doc);
sepValue[0] = text[sep];
sepValue[1] = SPACE;
sepValue[2] = EOS;
lang = TtaGetLanguageIdFromAlphabet('L');
TtaSetTextContent (leaf, sepValue, lang, doc);
/* is there a following non-space character in separators? */
i = sep + 1;
while (text[i] <= SPACE && text[i] != EOS)
i++;
if (text[i] > SPACE && text[i] != EOS)
sep = i;
if (record)
TtaRegisterElementCreate (separator, doc);
}
prev = child;
}
child = next;
}
}
}
/*----------------------------------------------------------------------
TransformMFENCED
Transform the content of a MFENCED element: create elements
OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
----------------------------------------------------------------------*/
#ifdef __STDC__
void TransformMFENCED (Element el, Document doc)
#else
void TransformMFENCED (el, doc)
Element el;
Document doc;
#endif
{
ElementType elType;
Element child, fencedExpression, leaf, fence, next, prev,
firstChild;
AttributeType attrType;
Attribute attr;
int length;
CHAR_T text[32], c;
child = TtaGetFirstChild (el);
if (child != NULL)
elType = TtaGetElementType (child);
if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
/* The first child of this MFENCED element is an OpeningFence.
This MFENCED expression has already been transformed, possibly
by the Transform command */
{
TtaNextSibling (&child);
fencedExpression = child;
if (fencedExpression != NULL)
elType = TtaGetElementType (fencedExpression);
if (elType.ElTypeNum == MathML_EL_FencedExpression)
/* the second child is a FencedExpression. OK.
Remove all existing FencedSeparator elements */
{
child = TtaGetFirstChild (fencedExpression);
prev = NULL;
while (child != NULL)
{
elType = TtaGetElementType (child);
next = child;
TtaNextSibling (&next);
if (elType.ElTypeNum == MathML_EL_FencedSeparator)
/* Remove this separator */
TtaDeleteTree (child, doc);
child = next;
}
/* create FencedSeparator elements in the FencedExpression */
CreateFencedSeparators (fencedExpression, doc, FALSE);
}
}
else
/* this MFENCED element must be transformed */
{
/* create a FencedExpression element as a child of the MFENCED elem. */
elType = TtaGetElementType (el);
elType.ElTypeNum = MathML_EL_FencedExpression;
fencedExpression = TtaNewElement (doc, elType);
TtaInsertFirstChild (&fencedExpression, el, doc);
if (child == NULL)
/* empty MFENCED element */
{
elType.ElTypeNum = MathML_EL_Construct;
child = TtaNewElement (doc, elType);
TtaInsertFirstChild (&child, fencedExpression, doc);
SetIntPlaceholderAttr (child, doc);
}
else
{
/* move the content of the MFENCED element within the new
FencedExpression element */
prev = NULL;
firstChild = NULL;
while (child != NULL)
{
next = child;
TtaNextSibling (&next);
TtaRemoveTree (child, doc);
if (prev == NULL)
{
TtaInsertFirstChild (&child, fencedExpression, doc);
firstChild = child;
}
else
TtaInsertSibling (child, prev, FALSE, doc);
prev = child;
child = next;
}
/* create FencedSeparator elements in the FencedExpression */
CreateFencedSeparators (fencedExpression, doc, FALSE);
/* Create placeholders within the FencedExpression element */
CreatePlaceholders (firstChild, doc);
}
/* create the OpeningFence element according to the open attribute */
c = '(';
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_open;
attr = TtaGetAttribute (el, attrType);
if (attr != NULL)
{
length = 7;
TtaGiveTextAttributeValue (attr, text, &length);
c = text[0];
}
elType.ElTypeNum = MathML_EL_OpeningFence;
fence = TtaNewElement (doc, elType);
TtaInsertSibling (fence, fencedExpression, TRUE, doc);
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
leaf = TtaNewElement (doc, elType);
TtaInsertFirstChild (&leaf, fence, doc);
TtaSetGraphicsShape (leaf, c, doc);
/* create the ClosingFence element according to close attribute */
c = ')';
attrType.AttrTypeNum = MathML_ATTR_close;
attr = TtaGetAttribute (el, attrType);
if (attr != NULL)
{
length = 7;
TtaGiveTextAttributeValue (attr, text, &length);
c = text[0];
}
elType.ElTypeNum = MathML_EL_ClosingFence;
fence = TtaNewElement (doc, elType);
TtaInsertSibling (fence, fencedExpression, FALSE, doc);
elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
leaf = TtaNewElement (doc, elType);
TtaInsertFirstChild (&leaf, fence, doc);
TtaSetGraphicsShape (leaf, c, doc);
}
}
/*----------------------------------------------------------------------
MathMLElementComplete
Check the Thot structure of the MathML element el.
----------------------------------------------------------------------*/
#ifdef __STDC__
void MathMLElementComplete (Element el, Document doc)
#else
void MathMLElementComplete (el, doc)
Element el;
Document doc;
#endif
{
ElementType elType, parentType;
Element child, parent, new, prev, next;
AttributeType attrType;
Attribute attr;
SSchema MathMLSSchema;
elType = TtaGetElementType (el);
MathMLSSchema = GetMathMLSSchema (doc);
if (elType.ElSSchema != MathMLSSchema)
/* this is not a MathML element. It's the HTML element <math>, or
any other element containing a MathML expression */
{
if (TtaGetFirstChild (el) == NULL && !TtaIsLeaf (elType))
/* this element is empty. Create a MathML element as it's child */
{
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MathML;
new = TtaNewElement (doc, elType);
TtaInsertFirstChild (&new, el, doc);
/* Create a placeholder within the MathML element */
elType.ElTypeNum = MathML_EL_Construct;
child = TtaNewElement (doc, elType);
TtaInsertFirstChild (&child, new, doc);
attrType.AttrSSchema = elType.ElSSchema;
attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
attr = TtaNewAttribute (attrType);
TtaAttachAttribute (child, attr, doc);
TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, child, doc);
}
}
else
{
switch (elType.ElTypeNum)
{
case MathML_EL_TEXT_UNIT:
CheckTextElement (&el, doc);
break;
case MathML_EL_MI:
SetFontstyleAttr (el, doc);
break;
case MathML_EL_MO:
SetIntAddSpaceAttr (el, doc);
SetIntVertStretchAttr (el, doc, 0, NULL);
break;
case MathML_EL_MROOT:
/* end of a Root. Create a RootBase and an Index */
CheckMathSubExpressions (el, MathML_EL_RootBase, MathML_EL_Index,
0, doc);
break;
case MathML_EL_MSQRT:
/* end od a Square Root. Create a RootBase */
CheckMathSubExpressions (el, MathML_EL_RootBase, 0, 0, doc);
break;
case MathML_EL_MFRAC:
/* end of a fraction. Create a Numerator and a Denominator */
CheckMathSubExpressions (el, MathML_EL_Numerator,
MathML_EL_Denominator, 0, doc);
break;
case MathML_EL_MFENCED:
TransformMFENCED (el, doc);
break;
case MathML_EL_MSUBSUP:
/* end of a MSUBSUP. Create Base, Subscript, and Superscript */
CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
MathML_EL_Superscript, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
break;
case MathML_EL_MSUB:
/* end of a MSUB. Create Base and Subscript */
CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
0, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
break;
case MathML_EL_MSUP:
/* end of a MSUP. Create Base and Superscript */
CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Superscript,
0, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
break;
case MathML_EL_MUNDEROVER:
/* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
Overscript */
CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
MathML_EL_Underscript, MathML_EL_Overscript, doc);
SetIntHorizStretchAttr (el, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
break;
case MathML_EL_MUNDER:
/* end of a MUNDER. Create UnderOverBase, and Underscript */
CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
MathML_EL_Underscript, 0, doc);
SetIntHorizStretchAttr (el, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
break;
case MathML_EL_MOVER:
/* end of a MOVER. Create UnderOverBase, and Overscript */
CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
MathML_EL_Overscript, 0, doc);
SetIntHorizStretchAttr (el, doc);
SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
break;
case MathML_EL_MMULTISCRIPTS:
/* end of a MMULTISCRIPTS. Create all elements defined in the
MathML S schema */
BuildMultiscript (el, doc);
break;
case MathML_EL_MTABLE:
/* end of a MTABLE. Create all elements defined in the MathML S
schema */
CheckMTable (el, doc);
break;
case MathML_EL_MROW:
/* end of MROW */
/*if the first and the last child are MO containing a fence character
transform the MO into a MF and the character into a Thot SYMBOL */
child = TtaGetFirstChild (el);
if (child != NULL)
{
CheckFence (child, doc);
child = TtaGetLastChild (el);
if (child != NULL)
CheckFence (child, doc);
/* Create placeholders within the MROW */
CreatePlaceholders (TtaGetFirstChild (el), doc);
}
break;
default:
break;
}
parent = TtaGetParent (el);
parentType = TtaGetElementType (parent);
if (parentType.ElSSchema != elType.ElSSchema)
/* root of a MathML tree, Create a MathML element if there is no */
if (elType.ElTypeNum != MathML_EL_MathML)
{
elType.ElSSchema = MathMLSSchema;
elType.ElTypeNum = MathML_EL_MathML;
new = TtaNewElement (doc, elType);
TtaInsertSibling (new, el, TRUE, doc);
next = el;
TtaNextSibling (&next);
TtaRemoveTree (el, doc);
TtaInsertFirstChild (&el, new, doc);
prev = el;
while (next != NULL)
{
child = next;
TtaNextSibling (&next);
TtaRemoveTree (child, doc);
TtaInsertSibling (child, prev, FALSE, doc);
prev = child;
}
/* Create placeholders within the MathML element */
CreatePlaceholders (el, doc);
}
}
}
/*----------------------------------------------------------------------
SetFontfamily
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetFontfamily (Document doc, Element el, STRING value)
#else /* __STDC__*/
void SetFontfamily (doc, el, value)
Document doc;
Element el;
STRING value;
#endif /* __STDC__*/
{
#define buflen 50
CHAR_T css_command[buflen+20];
usprintf (css_command, TEXT("font-family: %s"), value);
ParseHTMLSpecificStyle (el, css_command, doc, FALSE);
}
/*----------------------------------------------------------------------
SetFontsize
-----------------------------------------------------------------------*/
#ifdef __STDC__
void SetFontsize (Document doc, Element el, STRING value)
#else /* __STDC__*/
void SetFontsize (doc, el, value)
Document doc;
Element el;
STRING value;
#endif /* __STDC__*/
{
#define buflen 50
CHAR_T css_command[buflen+20];
usprintf (css_command, TEXT("font-size: %s"), value);
ParseHTMLSpecificStyle (el, css_command, doc, FALSE);
}
/*----------------------------------------------------------------------
MathMLAttributeComplete
----------------------------------------------------------------------*/
#ifdef __STDC__
void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
#else
void MathMLAttributeComplete (attr, el, doc)
Attribute attr;
Element el;
Document doc;
#endif
{
AttributeType attrType;
int attrKind;
#define buflen 50
STRING value = (STRING) TtaGetMemory (sizeof (CHAR_T) * buflen);
int length;
TtaGiveAttributeType (attr, &attrType, &attrKind);
if (attrType.AttrTypeNum == MathML_ATTR_color ||
attrType.AttrTypeNum == MathML_ATTR_background_ ||
attrType.AttrTypeNum == MathML_ATTR_fontsize ||
attrType.AttrTypeNum == MathML_ATTR_fontfamily)
{
value[0] = EOS;
length = TtaGetTextAttributeLength (attr);
if (length >= buflen)
length = buflen - 1;
if (length > 0)
{
TtaGiveTextAttributeValue (attr, value, &length);
switch (attrType.AttrTypeNum)
{
case MathML_ATTR_color:
HTMLSetForegroundColor (doc, el, value);
break;
case MathML_ATTR_background_:
HTMLSetBackgroundColor (doc, el, value);
break;
case MathML_ATTR_fontsize:
SetFontsize (doc, el, value);
break;
case MathML_ATTR_fontfamily:
SetFontfamily (doc, el, value);
break;
}
}
}
}
/*----------------------------------------------------------------------
MathMLGetDTDName
----------------------------------------------------------------------*/
#ifdef __STDC__
void MathMLGetDTDName (STRING DTDname, STRING elementName)
#else
void MathMLGetDTDName (DTDname, elementName)
STRING DTDname;
STRING elementName;
#endif
{
/* no other DTD allowed within MathML elements */
ustrcpy (DTDname, _EMPTYSTR_);
}
/* end of module */
Webmaster