Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.138
1.1 cvs 1: /*
2: *
1.110 cvs 3: * (c) COPYRIGHT MIT and INRIA, 1996-2001
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
8: /*
9: *
10: * MathMLbuilder
11: *
12: * Author: V. Quint
13: */
14:
15: #define THOT_EXPORT extern
1.4 cvs 16: #include "amaya.h"
1.25 cvs 17: #include "css.h"
1.59 cvs 18: #include "html2thot_f.h"
1.133 cvs 19: #include "HTMLactions_f.h"
1.25 cvs 20: #include "MathML.h"
21: #include "parser.h"
1.59 cvs 22: #include "styleparser_f.h"
23: #include "style.h"
24: #include "undo.h"
1.133 cvs 25: #include "Xml2thot_f.h"
1.109 cvs 26:
1.106 cvs 27: /* Define a pointer to let parser functions access the Math entity table */
28: extern XmlEntity *pMathEntityTable;
1.1 cvs 29:
30: /* mapping table of attribute values */
31: static AttrValueMapping MathMLAttrValueMappingTable[] =
32: {
1.115 cvs 33: {MathML_ATTR_accent, "true", MathML_ATTR_accent_VAL_true},
34: {MathML_ATTR_accent, "false", MathML_ATTR_accent_VAL_false},
1.46 cvs 35:
1.115 cvs 36: {MathML_ATTR_accentunder, "true", MathML_ATTR_accentunder_VAL_true},
37: {MathML_ATTR_accentunder, "false", MathML_ATTR_accentunder_VAL_false},
1.46 cvs 38:
1.115 cvs 39: {MathML_ATTR_align, "top", MathML_ATTR_align_VAL_top_},
40: {MathML_ATTR_align, "bottom", MathML_ATTR_align_VAL_bottom_},
41: {MathML_ATTR_align, "center", MathML_ATTR_align_VAL_center},
42: {MathML_ATTR_align, "baseline", MathML_ATTR_align_VAL_baseline},
43: {MathML_ATTR_align, "axis", MathML_ATTR_align_VAL_axis},
44:
45: {MathML_ATTR_bevelled, "true", MathML_ATTR_bevelled_VAL_true},
46: {MathML_ATTR_bevelled, "false", MathML_ATTR_bevelled_VAL_false},
47:
48: {MathML_ATTR_columnalign_mtd, "center", MathML_ATTR_columnalign_mtd_VAL_center_},
49: {MathML_ATTR_columnalign_mtd, "left", MathML_ATTR_columnalign_mtd_VAL_left_},
50: {MathML_ATTR_columnalign_mtd, "right", MathML_ATTR_columnalign_mtd_VAL_right_},
51:
52: {MathML_ATTR_denomalign, "center", MathML_ATTR_denomalign_VAL_center_},
53: {MathML_ATTR_denomalign, "left", MathML_ATTR_denomalign_VAL_left_},
54: {MathML_ATTR_denomalign, "right", MathML_ATTR_denomalign_VAL_right_},
55:
56: {MathML_ATTR_display, "block", MathML_ATTR_display_VAL_block},
57: {MathML_ATTR_display, "display", MathML_ATTR_display_VAL_block},
58: {MathML_ATTR_display, "inline", MathML_ATTR_display_VAL_inline_},
59:
60: {MathML_ATTR_displaystyle, "true", MathML_ATTR_displaystyle_VAL_true},
61: {MathML_ATTR_displaystyle, "false", MathML_ATTR_displaystyle_VAL_false},
62:
63: {MathML_ATTR_edge, "left", MathML_ATTR_edge_VAL_left_},
64: {MathML_ATTR_edge, "right", MathML_ATTR_edge_VAL_right_},
65:
66: {MathML_ATTR_equalcolumns, "true", MathML_ATTR_equalcolumns_VAL_true},
67: {MathML_ATTR_equalcolumns, "false", MathML_ATTR_equalcolumns_VAL_false},
68:
69: {MathML_ATTR_equalrows, "true", MathML_ATTR_equalrows_VAL_true},
70: {MathML_ATTR_equalrows, "false", MathML_ATTR_equalrows_VAL_false},
71:
72: {MathML_ATTR_fence, "true", MathML_ATTR_fence_VAL_true},
73: {MathML_ATTR_fence, "false", MathML_ATTR_fence_VAL_false},
74:
75: {MathML_ATTR_fontstyle, "italic", MathML_ATTR_fontstyle_VAL_italic},
76: {MathML_ATTR_fontstyle, "normal", MathML_ATTR_fontstyle_VAL_normal_},
77:
78: {MathML_ATTR_fontweight, "normal", MathML_ATTR_fontweight_VAL_normal_},
79: {MathML_ATTR_fontweight, "bold", MathML_ATTR_fontweight_VAL_bold_},
80:
81: {MathML_ATTR_form, "prefix", MathML_ATTR_form_VAL_prefix},
82: {MathML_ATTR_form, "infix", MathML_ATTR_form_VAL_infix},
83: {MathML_ATTR_form, "postfix", MathML_ATTR_form_VAL_postfix},
84:
85: {MathML_ATTR_frame, "none", MathML_ATTR_frame_VAL_none_},
86: {MathML_ATTR_frame, "solid", MathML_ATTR_frame_VAL_solid_},
87: {MathML_ATTR_frame, "dashed", MathML_ATTR_frame_VAL_dashed_},
88:
89: {MathML_ATTR_groupalign_malgr, "left", MathML_ATTR_groupalign_malgr_VAL_left_},
90: {MathML_ATTR_groupalign_malgr, "center", MathML_ATTR_groupalign_malgr_VAL_center_},
91: {MathML_ATTR_groupalign_malgr, "right", MathML_ATTR_groupalign_malgr_VAL_right_},
92: {MathML_ATTR_groupalign_malgr, "decimalpoint", MathML_ATTR_groupalign_malgr_VAL_decimalpoint},
93:
94: {MathML_ATTR_largeop, "true", MathML_ATTR_largeop_VAL_true},
95: {MathML_ATTR_largeop, "false", MathML_ATTR_largeop_VAL_false},
96:
97: {MathML_ATTR_linebreak_, "auto", MathML_ATTR_linebreak__VAL_auto_},
98: {MathML_ATTR_linebreak_, "newline", MathML_ATTR_linebreak__VAL_newline},
99: {MathML_ATTR_linebreak_, "indentingnewline", MathML_ATTR_linebreak__VAL_indentingnewline},
100: {MathML_ATTR_linebreak_, "nobreak", MathML_ATTR_linebreak__VAL_nobreak_},
101: {MathML_ATTR_linebreak_, "goodbreak", MathML_ATTR_linebreak__VAL_goodbreak},
102: {MathML_ATTR_linebreak_, "badbreak", MathML_ATTR_linebreak__VAL_badbreak},
103:
104: {MathML_ATTR_mathvariant, "normal", MathML_ATTR_mathvariant_VAL_normal_},
105: {MathML_ATTR_mathvariant, "bold", MathML_ATTR_mathvariant_VAL_bold_},
106: {MathML_ATTR_mathvariant, "italic", MathML_ATTR_mathvariant_VAL_italic},
107: {MathML_ATTR_mathvariant, "bold-italic", MathML_ATTR_mathvariant_VAL_bold_italic},
108: {MathML_ATTR_mathvariant, "double-struck", MathML_ATTR_mathvariant_VAL_double_struck},
109: {MathML_ATTR_mathvariant, "bold-fraktur", MathML_ATTR_mathvariant_VAL_bold_fraktur},
110: {MathML_ATTR_mathvariant, "script", MathML_ATTR_mathvariant_VAL_script},
111: {MathML_ATTR_mathvariant, "bold-script", MathML_ATTR_mathvariant_VAL_bold_script},
112: {MathML_ATTR_mathvariant, "fraktur", MathML_ATTR_mathvariant_VAL_fraktur},
113: {MathML_ATTR_mathvariant, "sans-serif", MathML_ATTR_mathvariant_VAL_sans_serif},
114: {MathML_ATTR_mathvariant, "bold-sans-serif", MathML_ATTR_mathvariant_VAL_bold_sans_serif},
115: {MathML_ATTR_mathvariant, "sans-serif-italic", MathML_ATTR_mathvariant_VAL_sans_serif_italic},
116: {MathML_ATTR_mathvariant, "sans-serif-bold-italic", MathML_ATTR_mathvariant_VAL_sans_serif_bold_italic},
117: {MathML_ATTR_mathvariant, "monospace", MathML_ATTR_mathvariant_VAL_monospace},
118:
119: {MathML_ATTR_movablelimits, "true", MathML_ATTR_movablelimits_VAL_true},
120: {MathML_ATTR_movablelimits, "false", MathML_ATTR_movablelimits_VAL_false},
121:
122: {MathML_ATTR_notation, "longdiv", MathML_ATTR_notation_VAL_longdiv},
123: {MathML_ATTR_notation, "actuarial", MathML_ATTR_notation_VAL_actuarial},
124: {MathML_ATTR_notation, "radical", MathML_ATTR_notation_VAL_radical},
125:
126: {MathML_ATTR_numalign, "center", MathML_ATTR_numalign_VAL_center_},
127: {MathML_ATTR_numalign, "left", MathML_ATTR_numalign_VAL_left_},
128: {MathML_ATTR_numalign, "right", MathML_ATTR_numalign_VAL_right_},
129:
130: {MathML_ATTR_overflow, "scroll", MathML_ATTR_overflow_VAL_scroll},
131: {MathML_ATTR_overflow, "elide", MathML_ATTR_overflow_VAL_elide},
132: {MathML_ATTR_overflow, "truncate", MathML_ATTR_overflow_VAL_truncate},
133: {MathML_ATTR_overflow, "scale", MathML_ATTR_overflow_VAL_scale_},
134:
135: {MathML_ATTR_rowalign_mtr, "top", MathML_ATTR_rowalign_mtr_VAL_top_},
136: {MathML_ATTR_rowalign_mtr, "bottom", MathML_ATTR_rowalign_mtr_VAL_bottom_},
137: {MathML_ATTR_rowalign_mtr, "center", MathML_ATTR_rowalign_mtr_VAL_center},
138: {MathML_ATTR_rowalign_mtr, "baseline", MathML_ATTR_rowalign_mtr_VAL_baseline},
139: {MathML_ATTR_rowalign_mtr, "axis", MathML_ATTR_rowalign_mtr_VAL_axis},
140:
141: {MathML_ATTR_separator, "true", MathML_ATTR_separator_VAL_true},
142: {MathML_ATTR_separator, "false", MathML_ATTR_separator_VAL_false},
143:
144: {MathML_ATTR_side, "left", MathML_ATTR_side_VAL_left_},
145: {MathML_ATTR_side, "leftoverlap", MathML_ATTR_side_VAL_leftoverlap},
146: {MathML_ATTR_side, "right", MathML_ATTR_side_VAL_right_},
147: {MathML_ATTR_side, "rightoverlap", MathML_ATTR_side_VAL_rightoverlap},
148:
149: {MathML_ATTR_stretchy, "true", MathML_ATTR_stretchy_VAL_true},
150: {MathML_ATTR_stretchy, "false", MathML_ATTR_stretchy_VAL_false},
1.46 cvs 151:
1.115 cvs 152: {MathML_ATTR_symmetric, "true", MathML_ATTR_symmetric_VAL_true},
153: {MathML_ATTR_symmetric, "false", MathML_ATTR_symmetric_VAL_false},
1.21 cvs 154:
1.115 cvs 155: {MathML_ATTR_xml_space, "default", MathML_ATTR_xml_space_VAL_xml_space_default},
156: {MathML_ATTR_xml_space, "preserve", MathML_ATTR_xml_space_VAL_xml_space_preserve},
1.73 cvs 157:
1.115 cvs 158: {0, "", 0} /* Last entry. Mandatory */
1.1 cvs 159: };
160:
161: #define MaxMsgLength 200
162:
1.12 cvs 163: #include "HTMLtable_f.h"
1.29 cvs 164: #include "Mathedit_f.h"
165: #include "XMLparser_f.h"
166: #include "styleparser_f.h"
167: #include "fetchXMLname_f.h"
1.1 cvs 168:
169: /*----------------------------------------------------------------------
170: MapMathMLAttribute
171: Search in the Attribute Mapping Table the entry for the
172: attribute of name Attr and returns the corresponding Thot attribute type.
173: ----------------------------------------------------------------------*/
1.120 cvs 174: void MapMathMLAttribute (char *attrName, AttributeType *attrType,
175: char *elementName, ThotBool *level, Document doc)
1.1 cvs 176: {
1.68 cvs 177: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.91 cvs 178: MapXMLAttribute (MATH_TYPE, attrName, elementName, level, doc, &(attrType->AttrTypeNum));
1.1 cvs 179: }
180:
181: /*----------------------------------------------------------------------
182: MapMathMLAttributeValue
183: Search in the Attribute Value Mapping Table the entry for the attribute
184: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
185: ----------------------------------------------------------------------*/
1.120 cvs 186: void MapMathMLAttributeValue (char *AttrVal, AttributeType attrType,
187: int *value)
1.1 cvs 188: {
1.123 cvs 189: int i;
1.1 cvs 190:
1.123 cvs 191: *value = 0;
192: i = 0;
193: while (MathMLAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
194: MathMLAttrValueMappingTable[i].ThotAttr != 0)
195: i++;
196: if (MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
197: do
198: if (!strcmp (MathMLAttrValueMappingTable[i].XMLattrValue, AttrVal))
199: *value = MathMLAttrValueMappingTable[i].ThotAttrValue;
200: else
201: i++;
202: while (*value == 0 &&
203: MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum);
1.1 cvs 204: }
205:
206: /*----------------------------------------------------------------------
207: MapMathMLEntity
208: Search that entity in the entity table and return the corresponding value.
209: ----------------------------------------------------------------------*/
1.120 cvs 210: void MapMathMLEntity (char *entityName, char *entityValue,
211: char *alphabet)
1.1 cvs 212: {
213: int i;
1.67 cvs 214: ThotBool found;
1.1 cvs 215:
1.67 cvs 216: found = FALSE;
1.106 cvs 217: for (i = 0; pMathEntityTable[i].charCode >= 0 && !found; i++)
1.116 cvs 218: found = !strcmp (pMathEntityTable[i].charName, entityName);
1.67 cvs 219:
220: if (found)
221: /* entity found */
222: {
223: i--;
1.116 cvs 224: entityValue[0] = (unsigned char) pMathEntityTable[i].charCode;
1.1 cvs 225: entityValue[1] = EOS;
1.110 cvs 226: *alphabet = 'G';
1.109 cvs 227: /* *alphabet = pMathEntityTable[i].charAlphabet;*/
1.67 cvs 228: }
229: else
230: {
1.1 cvs 231: entityValue[0] = EOS;
232: *alphabet = EOS;
1.67 cvs 233: }
1.1 cvs 234: }
235:
236: /*----------------------------------------------------------------------
1.130 carcone 237: MathMLEntityCreated
238: ----------------------------------------------------------------------*/
239: void MathMLEntityCreated (unsigned char *entityValue, Language lang,
240: char *entityName, Document doc)
241: {
242: }
243:
244: /*----------------------------------------------------------------------
1.1 cvs 245: ElementNeedsPlaceholder
246: returns TRUE if element el needs a sibling placeholder.
247: ----------------------------------------------------------------------*/
1.18 cvs 248: ThotBool ElementNeedsPlaceholder (Element el)
1.1 cvs 249: {
250: ElementType elType;
1.138 ! cvs 251: Element child, parent, sibling;
1.18 cvs 252: ThotBool ret;
1.1 cvs 253:
254: ret = FALSE;
255: elType = TtaGetElementType (el);
1.43 cvs 256: if (elType.ElTypeNum == MathML_EL_MS ||
257: elType.ElTypeNum == MathML_EL_MSPACE ||
1.39 cvs 258: elType.ElTypeNum == MathML_EL_MFRAC ||
1.54 cvs 259: elType.ElTypeNum == MathML_EL_BevelledMFRAC ||
1.39 cvs 260: elType.ElTypeNum == MathML_EL_MSQRT ||
261: elType.ElTypeNum == MathML_EL_MROOT ||
262: elType.ElTypeNum == MathML_EL_MSTYLE ||
263: elType.ElTypeNum == MathML_EL_MERROR ||
264: elType.ElTypeNum == MathML_EL_MPADDED ||
265: elType.ElTypeNum == MathML_EL_MPHANTOM ||
266: elType.ElTypeNum == MathML_EL_MFENCED ||
1.1 cvs 267: elType.ElTypeNum == MathML_EL_MF ||
268: elType.ElTypeNum == MathML_EL_MSUB ||
269: elType.ElTypeNum == MathML_EL_MSUP ||
1.39 cvs 270: elType.ElTypeNum == MathML_EL_MSUBSUP ||
1.1 cvs 271: elType.ElTypeNum == MathML_EL_MUNDER ||
272: elType.ElTypeNum == MathML_EL_MOVER ||
273: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
1.28 cvs 274: elType.ElTypeNum == MathML_EL_MMULTISCRIPTS ||
1.39 cvs 275: elType.ElTypeNum == MathML_EL_MTABLE ||
276: elType.ElTypeNum == MathML_EL_MACTION)
1.1 cvs 277: ret = TRUE;
1.138 ! cvs 278: else if (elType.ElTypeNum == MathML_EL_MROW)
! 279: /* a mrow needs a place holder only if it's not the sole child of
! 280: an element such as Numerator, Denominator, RootBase, Index, etc. */
! 281: {
! 282: ret = TRUE;
! 283: sibling = el; TtaNextSibling (&sibling);
! 284: if (!sibling)
! 285: {
! 286: sibling = el; TtaNextSibling (&sibling);
! 287: if (!sibling)
! 288: {
! 289: parent = TtaGetParent (el);
! 290: if (parent)
! 291: {
! 292: elType = TtaGetElementType (parent);
! 293: if (elType.ElTypeNum == MathML_EL_Numerator ||
! 294: elType.ElTypeNum == MathML_EL_Denominator ||
! 295: elType.ElTypeNum == MathML_EL_RootBase ||
! 296: elType.ElTypeNum == MathML_EL_Index ||
! 297: elType.ElTypeNum == MathML_EL_FencedExpression ||
! 298: elType.ElTypeNum == MathML_EL_Base ||
! 299: elType.ElTypeNum == MathML_EL_Subscript ||
! 300: elType.ElTypeNum == MathML_EL_Superscript ||
! 301: elType.ElTypeNum == MathML_EL_UnderOverBase ||
! 302: elType.ElTypeNum == MathML_EL_Underscript ||
! 303: elType.ElTypeNum == MathML_EL_Overscript ||
! 304: elType.ElTypeNum == MathML_EL_MultiscriptBase ||
! 305: elType.ElTypeNum == MathML_EL_MSubscript ||
! 306: elType.ElTypeNum == MathML_EL_MSuperscript)
! 307: ret = FALSE;
! 308: }
! 309: }
! 310: }
! 311: }
! 312: else if (elType.ElTypeNum == MathML_EL_MO)
! 313: /* an operator that contains a single Symbol needs a placeholder,
! 314: except when it is in a Base or UnderOverBase */
! 315: {
! 316: child = TtaGetFirstChild (el);
! 317: if (child != NULL)
1.1 cvs 318: {
1.138 ! cvs 319: elType = TtaGetElementType (child);
! 320: if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
! 321: {
1.1 cvs 322: ret = TRUE;
323: parent = TtaGetParent (el);
324: if (parent != NULL)
325: {
1.138 ! cvs 326: elType = TtaGetElementType (parent);
! 327: if (elType.ElTypeNum == MathML_EL_Base ||
! 328: elType.ElTypeNum == MathML_EL_UnderOverBase)
! 329: ret = FALSE;
1.1 cvs 330: }
1.138 ! cvs 331: }
1.1 cvs 332: }
1.138 ! cvs 333: }
1.1 cvs 334: return ret;
335: }
1.132 cvs 336:
1.1 cvs 337: /*----------------------------------------------------------------------
338: CreatePlaceholders
339: ----------------------------------------------------------------------*/
340: static void CreatePlaceholders (Element el, Document doc)
341: {
1.132 cvs 342: Element sibling, prev, constr, child;
343: Attribute attr;
344: ElementType elType;
345: AttributeType attrType;
346: ThotBool create, stretchableSubsup;
1.1 cvs 347:
1.55 cvs 348: if (!el)
349: return;
1.2 cvs 350: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 351: prev = NULL;
352: create = TRUE;
353: sibling = el;
354: while (sibling != NULL)
355: {
356: if (!ElementNeedsPlaceholder (sibling))
357: create = FALSE;
358: else
359: {
360: if (sibling == el)
361: /* first element */
362: {
363: elType = TtaGetElementType (sibling);
364: if (elType.ElTypeNum == MathML_EL_MF)
365: /* the first element is a MF. Don't create a placeholder
366: before */
367: create = FALSE;
368: else if (elType.ElTypeNum == MathML_EL_MROW)
369: /* the first element is a MROW */
370: {
371: child = TtaGetFirstChild (sibling);
372: if (child != NULL)
373: {
374: elType = TtaGetElementType (child);
375: if (elType.ElTypeNum != MathML_EL_MF)
376: /* the first child of the MROW element is not a MF */
377: /* Don't create a placeholder before */
378: create = FALSE;
379: }
380: }
381: }
382: if (create)
383: {
384: elType.ElTypeNum = MathML_EL_Construct;
385: constr = TtaNewElement (doc, elType);
386: TtaInsertSibling (constr, sibling, TRUE, doc);
387: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 388: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 389: attr = TtaNewAttribute (attrType);
390: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 391: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
392: constr, doc);
1.1 cvs 393: }
394: create = TRUE;
395: }
396: prev = sibling;
397: TtaNextSibling (&sibling);
398: }
399: if (prev != NULL && create)
400: {
1.132 cvs 401: stretchableSubsup = FALSE;
1.1 cvs 402: elType = TtaGetElementType (prev);
1.95 cvs 403: /* don't insert a placeholder after the last element if it's a MF */
404: if (elType.ElTypeNum == MathML_EL_MF)
1.1 cvs 405: create = FALSE;
406: else if (elType.ElTypeNum == MathML_EL_MROW)
407: /* the last element is a MROW */
408: {
409: child = TtaGetLastChild (prev);
410: if (child != NULL)
411: {
412: elType = TtaGetElementType (child);
413: if (elType.ElTypeNum != MathML_EL_MF)
414: /* the last child of the MROW element is not a MF */
415: /* Don't create a placeholder before */
416: create = FALSE;
417: }
418: }
1.132 cvs 419: else if (elType.ElTypeNum == MathML_EL_MSUBSUP ||
420: elType.ElTypeNum == MathML_EL_MSUB ||
421: elType.ElTypeNum == MathML_EL_MSUP ||
422: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
423: elType.ElTypeNum == MathML_EL_MUNDER ||
424: elType.ElTypeNum == MathML_EL_MUNDEROVER)
425: {
426: attrType.AttrSSchema = elType.ElSSchema;
427: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
428: if (TtaGetAttribute (prev, attrType))
429: stretchableSubsup = TRUE;
430: }
431:
1.1 cvs 432: if (create)
433: {
1.132 cvs 434: if (stretchableSubsup)
435: elType.ElTypeNum = MathML_EL_Construct1;
436: else
437: elType.ElTypeNum = MathML_EL_Construct;
1.1 cvs 438: constr = TtaNewElement (doc, elType);
439: TtaInsertSibling (constr, prev, FALSE, doc);
440: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 441: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 442: attr = TtaNewAttribute (attrType);
443: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 444: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
445: constr, doc);
1.132 cvs 446: }
1.1 cvs 447: }
448: }
449:
450: /*----------------------------------------------------------------------
1.95 cvs 451: NextNotComment
452: Return the next sibling of element el that is not an XMLcomment element.
453: Return el itself if it's not a comment.
1.1 cvs 454: ----------------------------------------------------------------------*/
1.95 cvs 455: static void NextNotComment (Element* el, Element* prev)
1.1 cvs 456: {
457: ElementType elType;
458:
459: if (*el == NULL)
460: return;
461: elType = TtaGetElementType (*el);
1.95 cvs 462: while (*el != NULL && elType.ElTypeNum == MathML_EL_XMLcomment)
1.1 cvs 463: {
464: *prev = *el;
465: TtaNextSibling (el);
466: if (*el != NULL)
467: elType = TtaGetElementType (*el);
468: }
469: }
470:
471: /*----------------------------------------------------------------------
472: CheckMathSubExpressions
473: Children of element el should be of type type1, type2, and type3.
1.56 cvs 474: If they are not, wrap them in elements of these types.
1.124 cvs 475: If element el has too many or not enough children, return FALSE.
1.1 cvs 476: ----------------------------------------------------------------------*/
1.56 cvs 477: static ThotBool CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
1.1 cvs 478: {
479: Element child, new, prev;
480: ElementType elType, childType;
1.124 cvs 481: char msgBuffer[200];
1.56 cvs 482: ThotBool result;
1.1 cvs 483:
1.56 cvs 484: result = TRUE;
1.2 cvs 485: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 486: child = TtaGetFirstChild (el);
487: prev = NULL;
1.95 cvs 488: NextNotComment (&child, &prev);
1.56 cvs 489: if (type1 == 0)
1.1 cvs 490: {
1.56 cvs 491: if (child)
492: /* no child expected and there is one, error */
1.124 cvs 493: {
494: sprintf (msgBuffer, "No subexpression allowed in %s",
495: TtaGetElementTypeName (TtaGetElementType (el)));
496: XmlParseError (errorParsing, msgBuffer, 0);
497: result = FALSE;
498: }
1.56 cvs 499: }
500: else
501: if (!child)
502: /* a first child is expected and it's missing */
1.124 cvs 503: {
504: sprintf (msgBuffer, "Missing subexpression in %s",
505: TtaGetElementTypeName (TtaGetElementType (el)));
506: XmlParseError (errorParsing, msgBuffer, 0);
507: result = FALSE;
508: }
1.56 cvs 509: else
510: {
1.1 cvs 511: elType.ElTypeNum = type1;
512: childType = TtaGetElementType (child);
513: if (TtaSameTypes (childType, elType) == 0)
514: {
515: TtaRemoveTree (child, doc);
516: new = TtaNewElement (doc, elType);
517: if (prev == NULL)
518: TtaInsertFirstChild (&new, el, doc);
519: else
520: TtaInsertSibling (new, prev, FALSE, doc);
521: TtaInsertFirstChild (&child, new, doc);
522: CreatePlaceholders (child, doc);
523: child = new;
524: }
1.56 cvs 525: prev = child;
526: TtaNextSibling (&child);
1.95 cvs 527: NextNotComment (&child, &prev);
1.56 cvs 528: if (type2 == 0)
529: {
530: if (child)
531: /* this second child is not expected, error */
1.124 cvs 532: {
533: sprintf (msgBuffer, "Only 1 subexpression allowed in %s",
534: TtaGetElementTypeName (TtaGetElementType (el)));
535: XmlParseError (errorParsing, msgBuffer, 0);
536: result = FALSE;
537: }
1.56 cvs 538: }
539: else
1.1 cvs 540: {
1.56 cvs 541: if (!child)
542: /* a second child is expected and it's missing */
1.124 cvs 543: {
544: sprintf (msgBuffer, "2 subexpressions required in %s",
545: TtaGetElementTypeName (TtaGetElementType (el)));
546: XmlParseError (errorParsing, msgBuffer, 0);
547: result = FALSE;
548: }
1.56 cvs 549: else
1.1 cvs 550: {
551: elType.ElTypeNum = type2;
552: childType = TtaGetElementType (child);
553: if (TtaSameTypes (childType, elType) == 0)
554: {
555: TtaRemoveTree (child, doc);
556: new = TtaNewElement (doc, elType);
557: TtaInsertSibling (new, prev, FALSE, doc);
558: TtaInsertFirstChild (&child, new, doc);
559: CreatePlaceholders (child, doc);
560: child = new;
561: }
1.56 cvs 562: prev = child;
563: TtaNextSibling (&child);
1.95 cvs 564: NextNotComment (&child, &prev);
1.56 cvs 565: if (type3 == 0)
1.1 cvs 566: {
1.56 cvs 567: if (child)
568: /* this third child is not expected, error */
1.124 cvs 569: {
570: sprintf (msgBuffer, "Only 2 subexpressions allowed in %s",
571: TtaGetElementTypeName (TtaGetElementType (el)));
572: XmlParseError (errorParsing, msgBuffer, 0);
573: result = FALSE;
574: }
1.56 cvs 575: }
576: else
577: {
578: if (!child)
579: /* a third child is expected and it's missing */
1.124 cvs 580: {
581: sprintf (msgBuffer, "3 subexpressions required in %s",
582: TtaGetElementTypeName (TtaGetElementType (el)));
583: XmlParseError (errorParsing, msgBuffer, 0);
584: result = FALSE;
585: }
1.56 cvs 586: else
1.1 cvs 587: {
588: elType.ElTypeNum = type3;
589: childType = TtaGetElementType (child);
590: if (TtaSameTypes (childType, elType) == 0)
591: {
592: TtaRemoveTree (child, doc);
593: new = TtaNewElement (doc, elType);
594: TtaInsertSibling (new, prev, FALSE, doc);
595: TtaInsertFirstChild (&child, new, doc);
596: CreatePlaceholders (child, doc);
1.56 cvs 597: child = new;
1.1 cvs 598: }
599: }
1.56 cvs 600: prev = child;
601: TtaNextSibling (&child);
1.95 cvs 602: NextNotComment (&child, &prev);
1.56 cvs 603: if (child)
604: /* this fourth child is unexpected */
1.124 cvs 605: {
606: sprintf (msgBuffer,"Only 3 subexpressions allowed in %s",
607: TtaGetElementTypeName (TtaGetElementType (el)));
608: XmlParseError (errorParsing, msgBuffer, 0);
609: result = FALSE;
610: }
1.1 cvs 611: }
612: }
613: }
1.56 cvs 614: }
615: return result;
1.1 cvs 616: }
617:
618:
619: /*----------------------------------------------------------------------
1.22 cvs 620: SetSingleIntHorizStretchAttr
1.1 cvs 621:
1.22 cvs 622: Put a IntHorizStretch attribute on element el if it contains only
1.1 cvs 623: a MO element that is a stretchable symbol.
624: -----------------------------------------------------------------------*/
1.22 cvs 625: void SetSingleIntHorizStretchAttr (Element el, Document doc, Element* selEl)
1.1 cvs 626: {
627: Element child, sibling, textEl, symbolEl;
628: ElementType elType;
629: Attribute attr;
630: AttributeType attrType;
1.55 cvs 631: Language lang;
1.128 vatton 632: CHAR_T text[2];
633: char alphabet;
1.49 cvs 634: unsigned char c;
1.128 vatton 635: int len;
1.1 cvs 636:
637: if (el == NULL)
638: return;
639: child = TtaGetFirstChild (el);
1.55 cvs 640: if (child)
1.1 cvs 641: {
642: elType = TtaGetElementType (child);
1.98 cvs 643: while (elType.ElTypeNum == MathML_EL_MROW && child)
644: /* the first child is a mrow. Look whether it contains a single
645: child of type mo */
646: {
647: child = TtaGetFirstChild (child);
648: if (child)
649: {
650: sibling = child;
651: TtaNextSibling (&sibling);
652: if (sibling == NULL)
653: /* the mrow element has a single child. Get its type */
654: elType = TtaGetElementType (child);
655: else
656: child = NULL;
657: }
658: }
659: if (elType.ElTypeNum == MathML_EL_MO && child)
1.1 cvs 660: /* the first child is a MO */
661: {
662: sibling = child;
663: TtaNextSibling (&sibling);
664: if (sibling == NULL)
665: /* there is no other child */
666: {
667: textEl = TtaGetFirstChild (child);
668: elType = TtaGetElementType (textEl);
669: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1.55 cvs 670: /* the MO child contains a TEXT element */
1.1 cvs 671: {
1.128 vatton 672: len = TtaGetVolume (textEl);
1.1 cvs 673: if (len == 1)
1.123 cvs 674: /* the TEXT element contains a single character */
675: {
676: c = EOS;
677: /* get that character */
678: len = 2;
1.128 vatton 679: TtaGiveBufferContent (textEl, text, len, &lang);
1.123 cvs 680: alphabet = TtaGetAlphabet (lang);
681: if (alphabet == 'L')
682: {
683: if (text[0] == '-' || text[0] == '_' ||
1.128 vatton 684: text[0] == 175)
1.123 cvs 685: /* a horizontal line in the middle of the box */
686: c = 'h';
687: }
688: else if (alphabet == 'G')
689: /* a single Symbol character */
690: {
1.128 vatton 691: if (text[0] == 172)
1.123 cvs 692: c = 'L'; /* arrow left */
1.128 vatton 693: else if (text[0] == 174)
1.123 cvs 694: c = 'R'; /* arrow right */
1.128 vatton 695: else if (text[0] == 45) /* - (minus) */
1.123 cvs 696: /* a horizontal line in the middle of the box */
697: c = 'h';
1.128 vatton 698: else if (text[0] == 132)
1.123 cvs 699: c = 'o'; /* Over brace */
1.128 vatton 700: else if (text[0] == 133)
1.123 cvs 701: c = 'u'; /* Under brace */
702: }
703: if (c != EOS)
704: {
705: /* attach a IntHorizStretch attribute to the mo */
706: attrType.AttrSSchema = elType.ElSSchema;
707: attrType.AttrTypeNum = MathML_ATTR_IntHorizStretch;
708: attr = TtaNewAttribute (attrType);
709: TtaAttachAttribute (el, attr, doc);
710: TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, el, doc);
711: /* replace the TEXT element by a Thot SYMBOL element */
712: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
713: symbolEl = TtaNewElement (doc, elType);
714: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
715: if (selEl != NULL)
716: if (*selEl == textEl)
717: *selEl = symbolEl;
718: TtaDeleteTree (textEl, doc);
719: if (c != EOS)
720: TtaSetGraphicsShape (symbolEl, c, doc);
721: }
722: }
1.1 cvs 723: }
724: }
725: }
726: }
727: }
1.123 cvs 728:
1.1 cvs 729: /*----------------------------------------------------------------------
1.22 cvs 730: SetIntHorizStretchAttr
1.1 cvs 731:
1.22 cvs 732: Put a IntHorizStretch attribute on all children of element el which
1.1 cvs 733: contain only a MO element that is a stretchable symbol.
734: -----------------------------------------------------------------------*/
1.22 cvs 735: static void SetIntHorizStretchAttr (Element el, Document doc)
1.1 cvs 736: {
737: Element child;
738:
739: if (el == NULL)
740: return;
741: child = TtaGetFirstChild (el);
742: while (child != NULL)
743: {
1.22 cvs 744: SetSingleIntHorizStretchAttr (child, doc, NULL);
1.1 cvs 745: TtaNextSibling (&child);
746: }
747: }
748:
749: /*----------------------------------------------------------------------
1.22 cvs 750: SetIntVertStretchAttr
1.1 cvs 751:
1.22 cvs 752: Put a IntVertStretch attribute on element el if its base element
1.1 cvs 753: (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
754: a MUNDER of a MOVER) contains only a MO element that is a vertically
1.132 cvs 755: stretchable symbol (integral).
1.1 cvs 756: -----------------------------------------------------------------------*/
1.22 cvs 757: void SetIntVertStretchAttr (Element el, Document doc, int base, Element* selEl)
1.1 cvs 758: {
1.132 cvs 759: Element child, sibling, textEl, symbolEl, parent, operator, next;
1.1 cvs 760: ElementType elType;
761: Attribute attr;
762: AttributeType attrType;
1.131 cvs 763: SSchema MathMLSSchema;
1.128 vatton 764: Language lang;
1.116 cvs 765: char alphabet;
1.131 cvs 766: #define buflen 50
767: CHAR_T text[buflen];
1.49 cvs 768: unsigned char c;
1.131 cvs 769: int len, i;
770: ThotBool inbase, integral;
1.1 cvs 771:
772: if (el == NULL)
1.131 cvs 773: return;
1.1 cvs 774: operator = NULL;
1.131 cvs 775: inbase = FALSE;
776: MathMLSSchema = TtaGetElementType(el).ElSSchema;
777:
1.1 cvs 778: if (base == 0)
1.131 cvs 779: /* it's a MO */
780: {
781: parent = TtaGetParent (el);
782: if (parent != NULL)
1.1 cvs 783: {
1.131 cvs 784: /* don't process the mo if it is within a base. It will be processed
785: when the enclosing construct is processed (see below) */
786: elType = TtaGetElementType (parent);
787: if (elType.ElSSchema != MathMLSSchema ||
788: (elType.ElTypeNum != MathML_EL_Base &&
789: elType.ElTypeNum != MathML_EL_UnderOverBase &&
790: elType.ElTypeNum != MathML_EL_MSUBSUP &&
791: elType.ElTypeNum != MathML_EL_MSUB &&
792: elType.ElTypeNum != MathML_EL_MSUP &&
793: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
794: elType.ElTypeNum != MathML_EL_MUNDER &&
795: elType.ElTypeNum != MathML_EL_MUNDEROVER))
796: operator = el;
1.1 cvs 797: }
1.131 cvs 798: }
1.1 cvs 799: else
1.131 cvs 800: /* it's not a MO */
801: {
802: /* search the Base or UnderOverBase child */
803: child = TtaGetFirstChild (el);
804: if (child != NULL)
1.1 cvs 805: {
1.131 cvs 806: elType = TtaGetElementType (child);
807: if (elType.ElTypeNum == base && elType.ElSSchema == MathMLSSchema)
808: /* the first child is a Base or UnderOverBase */
809: {
810: child = TtaGetFirstChild (child);
811: if (child != NULL)
812: {
813: elType = TtaGetElementType (child);
814: if (elType.ElTypeNum == MathML_EL_MO &&
815: elType.ElSSchema == MathMLSSchema)
816: /* its first child is a MO */
817: {
818: sibling = child;
819: TtaNextSibling (&sibling);
820: if (sibling == NULL)
821: /* there is no other child */
822: {
823: operator = child;
824: if (base == MathML_EL_Base ||
825: base == MathML_EL_UnderOverBase)
826: {
827: parent = el;
828: inbase = TRUE;
829: }
830: }
831: }
832: }
833: }
1.1 cvs 834: }
1.131 cvs 835: }
836: if (operator)
837: {
838: textEl = TtaGetFirstChild (operator);
839: if (textEl != NULL)
1.84 cvs 840: {
1.131 cvs 841: elType = TtaGetElementType (textEl);
842: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
843: {
844: len = TtaGetVolume (textEl);
845: if (len >= 1)
846: {
847: if (len >= buflen)
848: len = buflen-1;
849: len++;
850: TtaGiveBufferContent (textEl, text, len, &lang);
851: len --;
852: alphabet = TtaGetAlphabet (lang);
853: if (alphabet == 'G')
854: /* Adobe Symbol character set */
1.55 cvs 855: {
1.131 cvs 856: integral = TRUE;
857: /* check all characters in this TEXT element */
858: for (i = 0; i < len; i++)
859: if (text[i] != 242)
860: /**** accept also other symbols like double or triple
861: integral, contour integral, etc. ****/
862: integral = FALSE;
863: if (integral)
864: /* the operator contains only integral symbols */
865: {
866: /* attach a IntVertStretch attribute */
867: attrType.AttrSSchema = MathMLSSchema;
868: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
869: attr = TtaNewAttribute (attrType);
870: TtaAttachAttribute (el, attr, doc);
871: TtaSetAttributeValue (attr,
872: MathML_ATTR_IntVertStretch_VAL_yes_,
873: el, doc);
874: TtaRegisterAttributeCreate (attr, el, doc);
875:
876: /* replace the Integral characters by a Thot SYMBOL
877: element. If there are several such characters in
878: the mo (multiple integral), replace them too. */
879: do
880: {
881: /* replace the TEXT element by a Thot SYMBOL */
882: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
883: elType.ElSSchema = MathMLSSchema;
884: for (i = 0; i < len; i++)
885: if (text[i] == 242)
886: {
887: symbolEl = TtaNewElement (doc, elType);
888: TtaInsertSibling (symbolEl, textEl, TRUE,doc);
889: if (selEl != NULL)
890: if (*selEl == textEl)
891: *selEl = symbolEl;
892: c = 'i';
893: TtaSetGraphicsShape (symbolEl, c, doc);
894: TtaRegisterElementCreate (symbolEl, doc);
895: }
896: TtaRegisterElementDelete (textEl, doc);
897: TtaDeleteTree (textEl, doc);
898: /* is there an other text element after the
899: integral symbol? */
900: textEl = symbolEl; TtaNextSibling (&textEl);
901: if (textEl)
902: {
903: elType = TtaGetElementType (textEl);
904: if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
905: textEl = NULL;
906: else
907: /* there is another text element.
908: Is it a single integral symbol? */
909: {
910: len = TtaGetVolume (textEl);
911: if (len < 1)
912: /* not a single character */
913: textEl = NULL;
914: else
915: {
916: if (len >= buflen)
917: len = buflen-1;
918: len++;
919: TtaGiveBufferContent (textEl, text,
920: len, &lang);
921: alphabet = TtaGetAlphabet (lang);
922: if (alphabet != 'G')
923: /* not the right alphabet for an
924: integral*/
925: textEl = NULL;
926: else
927: if (text[0] != 242)
928: /* not an integral symbol */
929: textEl = NULL;
930: }
931: }
932: }
933: }
934: while (textEl);
935:
936: if (inbase)
937: /* it's within a Base or UnderOverBase element */
938: {
939: sibling = parent;
940: TtaNextSibling (&sibling);
1.132 cvs 941: if (sibling)
942: /* the msubsup of munderover element has a next
943: sibling */
1.131 cvs 944: {
945: elType = TtaGetElementType (sibling);
946: if (elType.ElTypeNum == MathML_EL_Construct &&
947: elType.ElSSchema == MathMLSSchema)
1.132 cvs 948: /* the next sibling is a Construct */
1.131 cvs 949: {
1.132 cvs 950: next = sibling;
951: TtaNextSibling (&next);
952: if (!next)
953: /* there is no other sibling after the
954: Construct. Change it into Construct1*/
955: {
956: TtaRegisterElementDelete (sibling, doc);
957: TtaRemoveTree (sibling, doc);
958: ChangeElementType (sibling,
959: MathML_EL_Construct1);
960: TtaInsertSibling (sibling, parent,
961: FALSE, doc);
962: TtaRegisterElementCreate (sibling, doc);
963: /* force the msubsup element to be
964: reformatted and to take into account
965: its new next sibling */
966: TtaRemoveTree (parent, doc);
967: TtaInsertSibling (parent, sibling, TRUE,
968: doc);
969: }
1.131 cvs 970: }
971: }
972: }
973: }
1.55 cvs 974: }
1.131 cvs 975: }
976: }
1.84 cvs 977: }
1.131 cvs 978: }
1.1 cvs 979: }
980:
981: /*----------------------------------------------------------------------
1.22 cvs 982: SetIntPlaceholderAttr
1.1 cvs 983:
1.22 cvs 984: Put a IntPlaceholder attribute on all Construct elements in the
1.1 cvs 985: subtree of root el.
986: -----------------------------------------------------------------------*/
1.22 cvs 987: static void SetIntPlaceholderAttr (Element el, Document doc)
1.1 cvs 988: {
989: Element child;
990: ElementType elType;
991: Attribute attr;
992: AttributeType attrType;
993:
994: if (el == NULL)
995: return;
996: elType = TtaGetElementType (el);
997: if (elType.ElTypeNum == MathML_EL_Construct &&
1.2 cvs 998: elType.ElSSchema == GetMathMLSSchema (doc))
1.1 cvs 999: {
1000: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 1001: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 1002: attr = TtaNewAttribute (attrType);
1003: TtaAttachAttribute (el, attr, doc);
1.22 cvs 1004: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, el, doc);
1.1 cvs 1005: }
1006: else
1007: {
1008: child = TtaGetFirstChild (el);
1009: while (child != NULL)
1010: {
1.22 cvs 1011: SetIntPlaceholderAttr (child, doc);
1.1 cvs 1012: TtaNextSibling (&child);
1013: }
1014: }
1015: }
1016:
1017: /*----------------------------------------------------------------------
1018: BuildMultiscript
1019:
1020: The content of a MMULTISCRIPT element has been created following
1021: the original MathML structure. Create all Thot elements defined
1022: in the MathML S schema.
1023: -----------------------------------------------------------------------*/
1024: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
1025: {
1026: Element elem, base, next, group, pair, script, prevPair, prevScript;
1027: ElementType elType, elTypeGroup, elTypePair, elTypeScript;
1.2 cvs 1028: SSchema MathMLSSchema;
1.1 cvs 1029: base = NULL;
1030: group = NULL;
1031: prevPair = NULL;
1032: prevScript = NULL;
1033:
1.2 cvs 1034: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 1035: elTypeGroup.ElSSchema = MathMLSSchema;
1036: elTypePair.ElSSchema = MathMLSSchema;
1037: elTypeScript.ElSSchema = MathMLSSchema;
1038:
1039: /* process all children of the MMULTISCRIPT element */
1040: elem = TtaGetFirstChild (elMMULTISCRIPT);
1041: while (elem != NULL)
1042: {
1043: /* remember the element to be processed after the current one */
1044: next = elem;
1045: TtaNextSibling (&next);
1046:
1047: /* remove the current element from the tree */
1048: TtaRemoveTree (elem, doc);
1049:
1050: if (base == NULL)
1051: /* the current element is the first child of the MMULTISCRIPT
1052: element */
1053: {
1054: /* Create a MultiscriptBase element as the first child of
1055: MMULTISCRIPT and move the current element as the first child
1056: of the MultiscriptBase element */
1057: elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
1058: base = TtaNewElement (doc, elTypeGroup);
1059: TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
1060: TtaInsertFirstChild (&elem, base, doc);
1061: }
1062: else
1063: /* the current element is a subscript or a superscript */
1064: {
1065: if (group == NULL)
1066: /* there is no PostscriptPairs element. Create one */
1067: {
1068: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1069: group = TtaNewElement (doc, elTypeGroup);
1070: TtaInsertSibling (group, base, FALSE, doc);
1071: elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
1072: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1073: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1074: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1075: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1076: prevPair = pair;
1.47 cvs 1077: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1078: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1079: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1080: prevScript = NULL;
1081: }
1082: if (prevScript == NULL)
1083: /* the current element is the first subscript or superscript
1084: in a pair */
1085: {
1086: /* create a PostscriptPair or PrescriptPair element */
1087: pair = TtaNewElement (doc, elTypePair);
1088: if (prevPair == NULL)
1089: TtaInsertFirstChild (&pair, group, doc);
1090: else
1091: TtaInsertSibling (pair, prevPair, FALSE, doc);
1092: prevPair = pair;
1093: /* create a MSubscript element */
1094: elTypeScript.ElTypeNum = MathML_EL_MSubscript;
1095: script = TtaNewElement (doc, elTypeScript);
1096: TtaInsertFirstChild (&script, pair, doc);
1097: prevScript = script;
1098: }
1099: else
1100: /* the current element is a superscript in a pair */
1101: {
1102: /* create a MSuperscript element */
1103: elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
1104: script = TtaNewElement (doc, elTypeScript);
1105: /* insert it as a sibling of the previous MSubscript element */
1106: TtaInsertSibling (script, prevScript, FALSE, doc);
1107: prevScript = NULL;
1108: }
1109: /* insert the current element as a child of the new MSuperscript or
1110: MSubscript element */
1111: TtaInsertFirstChild (&elem, script, doc);
1.22 cvs 1112: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1113: }
1114:
1115: CreatePlaceholders (elem, doc);
1116:
1117: /* get next child of the MMULTISCRIPT element */
1118: elem = next;
1119: if (elem != NULL)
1120: {
1121: elType = TtaGetElementType (elem);
1122: if (elType.ElSSchema == MathMLSSchema &&
1123: elType.ElTypeNum == MathML_EL_PrescriptPairs)
1124: /* the next element is a PrescriptPairs */
1125: {
1126: /* if there there is no PostscriptPairs element, create one as a
1127: placeholder */
1128: if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
1129: {
1130: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1.47 cvs 1131: group = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1132: TtaInsertSibling (group, elem, TRUE, doc);
1.22 cvs 1133: SetIntPlaceholderAttr (group, doc);
1.1 cvs 1134: }
1135: /* the following elements will be interpreted as sub- superscripts
1136: in PrescriptPair elements, wich will be children of this
1137: PrescriptPairs element */
1138: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1139: elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
1140: group = elem;
1141: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1142: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1143: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1144: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1145: prevPair = pair;
1.47 cvs 1146: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1147: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1148: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1149: prevScript = NULL;
1150: TtaNextSibling (&elem);
1151: }
1152: }
1153: }
1154: /* all children of element MMULTISCRIPTS have been processed */
1155: /* if the last group processed is not a PrescriptPairs element,
1156: create one as a placeholder */
1157: if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
1158: {
1159: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1.47 cvs 1160: elem = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1161: if (group == NULL)
1162: group = base;
1163: TtaInsertSibling (elem, group, TRUE, doc);
1.22 cvs 1164: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1165: }
1166: }
1167:
1.39 cvs 1168: /*----------------------------------------------------------------------
1169: CreateWrapper
1170:
1171: Create an element of type wrapperType as a child of element el and
1172: move all chidren of element el within the new element.
1173: -----------------------------------------------------------------------*/
1174: static void CreateWrapper (Element el, int wrapperType, Document doc)
1175: {
1176: Element wrapper, child, prevChild, nextChild;
1177: ElementType elType;
1178:
1179: child = TtaGetFirstChild (el);
1180: elType.ElSSchema = GetMathMLSSchema (doc);
1181: elType.ElTypeNum = wrapperType;
1182: wrapper = TtaNewElement (doc, elType);
1183: TtaInsertFirstChild (&wrapper, el, doc);
1184: prevChild = NULL;
1185: while (child)
1186: {
1187: nextChild = child;
1188: TtaNextSibling (&nextChild);
1189: TtaRemoveTree (child, doc);
1190: if (prevChild == NULL)
1191: TtaInsertFirstChild (&child, wrapper, doc);
1192: else
1193: TtaInsertSibling (child, prevChild, FALSE, doc);
1194: prevChild = child;
1195: child = nextChild;
1196: }
1197: }
1.5 cvs 1198:
1199: /*----------------------------------------------------------------------
1200: CheckMTable
1201:
1202: The content of a MTABLE element has been created following
1203: the original MathML structure. Create all Thot elements defined
1204: in the MathML S schema.
1.64 cvs 1205: If placeholder, associate an attribute IntPlaceholder with all
1.103 cvs 1206: cells generated in the MathML table.
1.5 cvs 1207: -----------------------------------------------------------------------*/
1.64 cvs 1208: void CheckMTable (Element elMTABLE, Document doc, ThotBool placeholder)
1.5 cvs 1209: {
1210: ElementType elType;
1211: Element MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
1.103 cvs 1212: nextCell, newMTD, firstColHead, label;
1.5 cvs 1213: SSchema MathMLSSchema;
1214:
1215: MathMLSSchema = GetMathMLSSchema (doc);
1216: row = TtaGetFirstChild (elMTABLE);
1217:
1218: /* create a MTable_head as the first child of element MTABLE */
1219: elType.ElSSchema = MathMLSSchema;
1220: elType.ElTypeNum = MathML_EL_MTable_head;
1221: MTableHead = TtaNewElement (doc, elType);
1222: TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
1223: elType.ElTypeNum = MathML_EL_MColumn_head;
1.47 cvs 1224: firstColHead = TtaNewTree (doc, elType, "");
1.5 cvs 1225: TtaInsertFirstChild (&firstColHead, MTableHead, doc);
1226:
1227: /* create a MTable_body */
1228: elType.ElTypeNum = MathML_EL_MTable_body;
1229: MTableBody = TtaNewElement (doc, elType);
1230: TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
1231:
1232: /* move all children of element MTABLE into the new MTable_body element
1.103 cvs 1233: and wrap each non-MTR element in a MTR, except comments */
1.5 cvs 1234: prevRow = NULL;
1235: while (row)
1236: {
1237: nextRow = row;
1238: TtaNextSibling (&nextRow);
1239: elType = TtaGetElementType (row);
1240: TtaRemoveTree (row, doc);
1241: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1242: (elType.ElTypeNum == MathML_EL_XMLcomment ||
1.101 cvs 1243: elType.ElTypeNum == MathML_EL_MTR ||
1244: elType.ElTypeNum == MathML_EL_MLABELEDTR))
1.5 cvs 1245: {
1246: if (prevRow == NULL)
1247: TtaInsertFirstChild (&row, MTableBody, doc);
1248: else
1249: TtaInsertSibling (row, prevRow, FALSE, doc);
1250: prevRow = row;
1.101 cvs 1251: if (elType.ElTypeNum == MathML_EL_MTR ||
1252: elType.ElTypeNum == MathML_EL_MLABELEDTR)
1.103 cvs 1253: {
1.5 cvs 1254: cell = TtaGetFirstChild (row);
1.103 cvs 1255: if (elType.ElTypeNum == MathML_EL_MLABELEDTR)
1256: /* skip the first significant child of the mlabeledtr element */
1257: {
1258: /* skip comments first */
1259: do
1260: {
1261: elType = TtaGetElementType (cell);
1262: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1263: elType.ElTypeNum == MathML_EL_XMLcomment)
1264: TtaNextSibling (&cell);
1265: }
1266: while (cell && elType.ElTypeNum == MathML_EL_XMLcomment);
1267: /* skip the first element after the comments: it's a label */
1268: if (cell)
1269: {
1.105 cvs 1270: /* if it's a MTD change its type into LabelCell */
1271: if (elType.ElTypeNum == MathML_EL_MTD &&
1272: elType.ElSSchema == MathMLSSchema)
1273: ChangeElementType (cell, MathML_EL_LabelCell);
1.103 cvs 1274: /* wrap this element in a RowLabel element */
1.105 cvs 1275: /* This will allow the P schema to specify the horizontal
1276: position of the label */
1.103 cvs 1277: elType.ElSSchema = MathMLSSchema;
1278: elType.ElTypeNum = MathML_EL_RowLabel;
1279: label = TtaNewElement (doc, elType);
1280: TtaInsertSibling (label, cell, TRUE, doc);
1281: TtaRemoveTree (cell, doc);
1282: TtaInsertFirstChild (&cell, label, doc);
1283: cell = label;
1284: TtaNextSibling (&cell);
1285: }
1286: }
1287: }
1.5 cvs 1288: else
1289: cell = NULL;
1290: }
1291: else
1.103 cvs 1292: /* this child is not a MTR, MLABELEDTR, or a comment.
1293: In MathML 2.0, this in an error, but we try to recover by
1294: creating a MTR element */
1.5 cvs 1295: {
1296: elType.ElSSchema = MathMLSSchema;
1297: elType.ElTypeNum = MathML_EL_MTR;
1298: el = TtaNewElement (doc, elType);
1299: if (prevRow == NULL)
1300: TtaInsertFirstChild (&el, MTableBody, doc);
1301: else
1302: TtaInsertSibling (el, prevRow, FALSE, doc);
1303: TtaInsertFirstChild (&row, el, doc);
1304: cell = row;
1305: prevRow = el;
1306: }
1307: while (cell)
1308: /* check all children of the current MTR element */
1309: {
1310: nextCell = cell;
1311: TtaNextSibling (&nextCell);
1312: elType = TtaGetElementType (cell);
1313: if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
1314: (elType.ElTypeNum != MathML_EL_XMLcomment &&
1315: elType.ElTypeNum != MathML_EL_MTD))
1316: /* this is not a MTD nor a comment, create a wrapping MTD */
1317: {
1318: elType.ElSSchema = MathMLSSchema;
1319: elType.ElTypeNum = MathML_EL_MTD;
1320: newMTD = TtaNewElement (doc, elType);
1321: TtaInsertSibling (newMTD, cell, TRUE, doc);
1322: TtaRemoveTree (cell, doc);
1323: TtaInsertFirstChild (&cell, newMTD, doc);
1324: cell = newMTD;
1325: }
1326: if (elType.ElTypeNum == MathML_EL_MTD)
1327: /* This is a MTD element. Wrap its contents with a CellWrapper */
1.39 cvs 1328: CreateWrapper (cell, MathML_EL_CellWrapper, doc);
1.5 cvs 1329: cell = nextCell;
1330: }
1331: row = nextRow;
1332: }
1.107 cvs 1333: CheckAllRows (elMTABLE, doc, placeholder, FALSE);
1.5 cvs 1334: }
1.12 cvs 1335:
1.46 cvs 1336: /*----------------------------------------------------------------------
1.1 cvs 1337: SetFontstyleAttr
1338: The content of a MI element has been created or modified.
1339: Create or change attribute IntFontstyle for that element accordingly.
1340: -----------------------------------------------------------------------*/
1341: void SetFontstyleAttr (Element el, Document doc)
1342: {
1343: ElementType elType;
1344: AttributeType attrType;
1345: Attribute attr, IntAttr;
1.54 cvs 1346: Element textEl;
1.1 cvs 1347: int len;
1.120 cvs 1348: char *value;
1.54 cvs 1349: ThotBool italic;
1.1 cvs 1350:
1351: if (el != NULL)
1352: {
1353: /* search the fontstyle attribute */
1354: elType = TtaGetElementType (el);
1355: attrType.AttrSSchema = elType.ElSSchema;
1356: attrType.AttrTypeNum = MathML_ATTR_fontstyle;
1357: attr = TtaGetAttribute (el, attrType);
1358: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1359: IntAttr = TtaGetAttribute (el, attrType);
1360: if (attr != NULL)
1361: /* there is a fontstyle attribute. Remove the corresponding
1362: internal attribute that is not needed */
1363: {
1364: if (IntAttr != NULL)
1.54 cvs 1365: TtaRemoveAttribute (el, IntAttr, doc);
1.1 cvs 1366: }
1367: else
1368: /* there is no fontstyle attribute. Create an internal attribute
1369: IntFontstyle with a value that depends on the content of the MI */
1370: {
1371: /* get content length */
1372: len = TtaGetElementVolume (el);
1373: if (len > 1)
1374: /* put an attribute IntFontstyle = IntNormal */
1375: {
1376: if (IntAttr == NULL)
1377: {
1378: IntAttr = TtaNewAttribute (attrType);
1379: TtaAttachAttribute (el, IntAttr, doc);
1380: }
1381: TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
1382: el, doc);
1383: }
1384: else
1385: /* MI contains a single character. Remove attribute IntFontstyle
1.54 cvs 1386: if it exists, except if it's ImaginaryI, ExponentialE or
1.124 cvs 1387: DifferentialD */
1.1 cvs 1388: {
1.54 cvs 1389: italic = TRUE;
1390: textEl = TtaGetFirstChild (el);
1391: if (textEl != NULL)
1392: {
1393: /* is there an attribute EntityName on that character? */
1394: attrType.AttrTypeNum = MathML_ATTR_EntityName;
1395: attr = TtaGetAttribute (textEl, attrType);
1396: if (attr)
1397: {
1398: len = TtaGetTextAttributeLength (attr);
1399: if (len > 0)
1400: {
1.116 cvs 1401: value = TtaGetMemory (len+1);
1.54 cvs 1402: TtaGiveTextAttributeValue (attr, value, &len);
1.124 cvs 1403: if (strcmp (&value[1], "ImaginaryI;") == 0 ||
1404: strcmp (&value[1], "ExponentialE;") == 0 ||
1405: strcmp (&value[1], "DifferentialD;") == 0)
1.54 cvs 1406: italic = FALSE;
1407: TtaFreeMemory (value);
1408: }
1409: }
1410: if (italic)
1411: {
1412: if (IntAttr != NULL)
1413: TtaRemoveAttribute (el, IntAttr, doc);
1414: }
1415: else
1416: {
1417: /* put an attribute IntFontstyle = IntNormal */
1418: if (IntAttr == NULL)
1419: {
1420: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1421: IntAttr = TtaNewAttribute (attrType);
1422: TtaAttachAttribute (el, IntAttr, doc);
1423: }
1424: TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
1425: el, doc);
1426: }
1427: }
1.1 cvs 1428: }
1429: }
1430: }
1431: }
1432:
1433: /*----------------------------------------------------------------------
1.22 cvs 1434: SetIntAddSpaceAttr
1.1 cvs 1435: The content of a MO element has been created or modified.
1.22 cvs 1436: Create or change attribute IntAddSpace for that element accordingly.
1.1 cvs 1437: -----------------------------------------------------------------------*/
1.22 cvs 1438: void SetIntAddSpaceAttr (Element el, Document doc)
1.1 cvs 1439: {
1440: Element textEl, previous;
1441: ElementType elType;
1442: AttributeType attrType;
1.60 cvs 1443: Attribute attr, formAttr;
1444: int len, val, form;
1.1 cvs 1445: #define BUFLEN 10
1.116 cvs 1446: unsigned char text[BUFLEN];
1.1 cvs 1447: Language lang;
1.116 cvs 1448: char alphabet;
1.1 cvs 1449:
1.60 cvs 1450: /* get the content of the mo element */
1.1 cvs 1451: textEl = TtaGetFirstChild (el);
1452: if (textEl != NULL)
1.60 cvs 1453: /* the mo element is not empty */
1.1 cvs 1454: {
1.60 cvs 1455: /* does the mo element have an IntAddSpace attribute? */
1.1 cvs 1456: elType = TtaGetElementType (el);
1457: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 1458: attrType.AttrTypeNum = MathML_ATTR_IntAddSpace;
1.1 cvs 1459: attr = TtaGetAttribute (el, attrType);
1460: if (attr == NULL)
1.60 cvs 1461: /* no IntAddSpace Attr, create one */
1.1 cvs 1462: {
1463: attr = TtaNewAttribute (attrType);
1464: TtaAttachAttribute (el, attr, doc);
1465: }
1.135 cvs 1466: /* space on both sides by default */
1467: val = MathML_ATTR_IntAddSpace_VAL_both;
1.60 cvs 1468: /* does the mo element have a form attribute? */
1469: attrType.AttrTypeNum = MathML_ATTR_form;
1470: formAttr = TtaGetAttribute (el, attrType);
1471: if (formAttr)
1472: /* there is a form attribute */
1473: {
1474: form = TtaGetAttributeValue (formAttr);
1475: switch (form)
1476: {
1477: case MathML_ATTR_form_VAL_prefix:
1478: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1479: break;
1480: case MathML_ATTR_form_VAL_infix:
1481: val = MathML_ATTR_IntAddSpace_VAL_both;
1482: break;
1483: case MathML_ATTR_form_VAL_postfix:
1484: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
1485: break;
1.136 cvs 1486: default:
1487: val = MathML_ATTR_IntAddSpace_VAL_both;
1488: break;
1.60 cvs 1489: }
1490: }
1491: else
1492: /* no form attribute. Analyze the content */
1493: {
1494: len = TtaGetTextLength (textEl);
1495: if (len > 0 && len < BUFLEN)
1496: {
1497: len = BUFLEN;
1498: TtaGiveTextContent (textEl, text, &len, &lang);
1499: alphabet = TtaGetAlphabet (lang);
1500: if (len == 1)
1.99 cvs 1501: {
1.60 cvs 1502: /* the mo element contains a single character */
1503: if (alphabet == 'L')
1504: /* ISO-Latin 1 character */
1505: {
1506: if (text[0] == '-')
1507: /* prefix or infix operator? */
1508: {
1509: previous = el;
1510: TtaPreviousSibling (&previous);
1511: if (previous == NULL)
1512: /* no previous sibling => prefix operator */
1513: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1514: else
1515: {
1516: elType = TtaGetElementType (previous);
1517: if (elType.ElTypeNum == MathML_EL_MO)
1518: /* after an operator => prefix operator */
1519: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1520: else
1521: /* infix operator */
1522: val = MathML_ATTR_IntAddSpace_VAL_both;
1523: }
1524: }
1.111 cvs 1525: else if (text[0] == '&' ||
1.60 cvs 1526: text[0] == '*' ||
1.111 cvs 1527: text[0] == '+' ||
1.100 cvs 1528: text[0] == '/' ||
1.60 cvs 1529: text[0] == '<' ||
1530: text[0] == '=' ||
1531: text[0] == '>' ||
1.111 cvs 1532: text[0] == '^' ||
1533: (int)text[0] == 177 || /* plus or minus */
1534: (int)text[0] == 215 || /* times */
1535: (int)text[0] == 247) /* divide */
1.60 cvs 1536: /* infix operator */
1537: val = MathML_ATTR_IntAddSpace_VAL_both;
1538: else if (text[0] == ',' ||
1.135 cvs 1539: text[0] == '!' ||
1540: text[0] == '&' ||
1541: text[0] == ':' ||
1.60 cvs 1542: text[0] == ';')
1543: /* separator */
1544: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
1.135 cvs 1545: else if (text[0] == '(' ||
1546: text[0] == ')' ||
1547: text[0] == '[' ||
1548: text[0] == ']' ||
1549: text[0] == '{' ||
1550: text[0] == '}' ||
1551: text[0] == '.' ||
1552: text[0] == '@' ||
1553: (int)text[0] == 129 || /* thin space */
1554: (int)text[0] == 130 || /* en space */
1555: (int)text[0] == 160) /* em space */
1556: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.60 cvs 1557: }
1558: else if (alphabet == 'G')
1.137 vatton 1559: {
1560: /* Symbol character set */
1561: if ((int)text[0] == 163 || /* less or equal */
1562: (int)text[0] == 177 || /* plus or minus */
1563: (int)text[0] == 179 || /* greater or equal */
1564: (int)text[0] == 180 || /* times */
1565: (int)text[0] == 184 || /* divide */
1566: (int)text[0] == 185 || /* not equal */
1567: (int)text[0] == 186 || /* identical */
1568: (int)text[0] == 187 || /* equivalent */
1569: (int)text[0] == 196 || /* circle times */
1570: (int)text[0] == 197 || /* circle plus */
1571: ((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
1572: (int)text[0] == 217 || /* and */
1573: (int)text[0] == 218 ) /* or */
1574: /* infix operator */
1575: val = MathML_ATTR_IntAddSpace_VAL_both;
1576: else
1577: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1578: }
1.99 cvs 1579: }
1.60 cvs 1580: }
1581: }
1.1 cvs 1582: TtaSetAttributeValue (attr, val, el, doc);
1583: }
1584: }
1585:
1586: /*----------------------------------------------------------------------
1.58 cvs 1587: ChildOfMRowOrInferred
1588: Return TRUE if element el is a child of a MROW element or an
1589: inferred MROW element
1590: ----------------------------------------------------------------------*/
1591: ThotBool ChildOfMRowOrInferred (Element el)
1592: {
1593: ElementType elType;
1594: Element parent;
1595: ThotBool result;
1596:
1597: result = FALSE;
1598: parent = TtaGetParent (el);
1599: if (parent)
1600: {
1601: elType = TtaGetElementType (parent);
1602: result = (elType.ElTypeNum == MathML_EL_MROW ||
1603: elType.ElTypeNum == MathML_EL_SqrtBase ||
1604: elType.ElTypeNum == MathML_EL_MSTYLE ||
1605: elType.ElTypeNum == MathML_EL_MERROR ||
1.92 cvs 1606: elType.ElTypeNum == MathML_EL_MENCLOSE ||
1.58 cvs 1607: elType.ElTypeNum == MathML_EL_MPADDED ||
1608: elType.ElTypeNum == MathML_EL_MPHANTOM ||
1609: elType.ElTypeNum == MathML_EL_CellWrapper ||
1.92 cvs 1610: elType.ElTypeNum == MathML_EL_MathML ||
1.58 cvs 1611: elType.ElTypeNum == MathML_EL_FencedExpression);
1612: }
1613: return result;
1614: }
1615:
1616: /*----------------------------------------------------------------------
1.1 cvs 1617: CheckFence
1.84 cvs 1618: If el is a MO element,
1619: - if it's a large operator (∑ for instance), put a presentation
1620: rule to enlarge the character.
1621: - if it's a child of a MROW (or equivalent) element and if it contains
1622: a single fence character, transform the MO into a MF and the fence
1623: character into a Thot stretchable symbol.
1.1 cvs 1624: ----------------------------------------------------------------------*/
1.84 cvs 1625: void CheckFence (Element el, Document doc)
1.1 cvs 1626: {
1.128 vatton 1627: ElementType elType;
1628: Element content;
1629: AttributeType attrType;
1630: Attribute attr, attrStretchy;
1631: Language lang;
1.84 cvs 1632: PresentationValue pval;
1633: PresentationContext ctxt;
1.128 vatton 1634: CHAR_T text[2];
1635: char alphabet;
1636: unsigned char c;
1637: int len, val;
1.1 cvs 1638:
1639: elType = TtaGetElementType (el);
1640: if (elType.ElTypeNum == MathML_EL_MO)
1.58 cvs 1641: /* the element is a MO */
1642: {
1.84 cvs 1643: content = TtaGetFirstChild (el);
1644: if (content != NULL)
1645: {
1646: elType = TtaGetElementType (content);
1647: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1648: {
1.128 vatton 1649: len = TtaGetVolume (content);
1.84 cvs 1650: if (len == 1)
1651: /* the MO element contains a single character */
1652: {
1653: len = 2;
1.128 vatton 1654: TtaGiveBufferContent (content, text, len, &lang);
1.84 cvs 1655: alphabet = TtaGetAlphabet (lang);
1656: if ((alphabet == 'G') &&
1.128 vatton 1657: (text[0] == 229 || text[0] == 213)) /* Sigma, Pi */
1.84 cvs 1658: /* it's a large operator */
1659: {
1660: ctxt = TtaGetSpecificStyleContext (doc);
1661: ctxt->destroy = FALSE;
1662: /* the specific presentation to be created is not a CSS rule */
1663: ctxt->cssLevel = 0;
1664: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1665: pval.typed_data.real = FALSE;
1666: pval.typed_data.value = 180;
1667: TtaSetStylePresentation (PRSize, content, NULL, ctxt, pval);
1668: }
1669: else if (ChildOfMRowOrInferred (el))
1670: /* the MO element is a child of a MROW element */
1.1 cvs 1671: {
1.102 cvs 1672: if (((alphabet == 'L') &&
1.115 cvs 1673: (text[0] == '(' || text[0] == ')' ||
1674: text[0] == '[' || text[0] == ']' ||
1675: text[0] == '{' || text[0] == '}' ||
1676: text[0] == '|')) ||
1.102 cvs 1677: ((alphabet == 'G') &&
1.128 vatton 1678: (text[0] == 225 || text[0] == 241)))
1.84 cvs 1679: /* it's a stretchable parenthesis or equivalent */
1680: {
1681: /* remove the content of the MO element */
1682: TtaDeleteTree (content, doc);
1683: /* change the MO element into a MF element */
1684: ChangeTypeOfElement (el, doc, MathML_EL_MF);
1.55 cvs 1685:
1.84 cvs 1686: /* is there an attribute stretchy on this mo element? */
1687: attrType.AttrSSchema = elType.ElSSchema;
1688: attrType.AttrTypeNum = MathML_ATTR_stretchy;
1689: attrStretchy = TtaGetAttribute (el, attrType);
1690: if (attrStretchy)
1691: val = TtaGetAttributeValue (attrStretchy);
1692: else
1693: val = MathML_ATTR_stretchy_VAL_true;
1694: if (val == MathML_ATTR_stretchy_VAL_true)
1695: {
1696: /* attach a IntVertStretch attribute to the MF element*/
1697: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
1698: attr = TtaNewAttribute (attrType);
1699: TtaAttachAttribute (el, attr, doc);
1700: TtaSetAttributeValue (attr,
1701: MathML_ATTR_IntVertStretch_VAL_yes_,
1702: el, doc);
1703: }
1704: /* create a new content for the MF element */
1.87 cvs 1705: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1.128 vatton 1706: if (alphabet == 'G' && text[0] == 241)
1.102 cvs 1707: c = '>'; /* RightAngleBracket */
1.128 vatton 1708: else if (alphabet == 'G' && text[0] == 225)
1.102 cvs 1709: c = '<'; /* LeftAngleBracket */
1710: else
1711: c = (char) text[0];
1.84 cvs 1712: content = TtaNewElement (doc, elType);
1713: TtaInsertFirstChild (&content, el, doc);
1714: TtaSetGraphicsShape (content, c, doc);
1715: }
1.1 cvs 1716: }
1.84 cvs 1717: }
1718: }
1.58 cvs 1719: }
1720: }
1.1 cvs 1721: }
1722:
1723: /*----------------------------------------------------------------------
1724: CreateFencedSeparators
1725: Create FencedSeparator elements within the fencedExpression
1726: according to attribute separators of the MFENCED element.
1727: ----------------------------------------------------------------------*/
1.110 cvs 1728: void CreateFencedSeparators (Element fencedExpression, Document doc, ThotBool record)
1.1 cvs 1729: {
1730: ElementType elType;
1731: Element child, separator, leaf, next, prev, mfenced;
1732: AttributeType attrType;
1733: Attribute attr;
1734: int length, sep, i;
1735: Language lang;
1.116 cvs 1736: char text[32], sepValue[4];
1.1 cvs 1737:
1738: /* get the separators attribute */
1739: mfenced = TtaGetParent (fencedExpression);
1740: elType = TtaGetElementType (fencedExpression);
1741: attrType.AttrSSchema = elType.ElSSchema;
1742: attrType.AttrTypeNum = MathML_ATTR_separators;
1743: text[0] = ','; /* default value is sparators="," */
1744: text[1] = EOS;
1745: length = 1;
1746: attr = TtaGetAttribute (mfenced, attrType);
1747: if (attr != NULL)
1748: {
1749: length = 31;
1750: TtaGiveTextAttributeValue (attr, text, &length);
1751: }
1752:
1753: /* create FencedSeparator elements in the FencedExpression */
1754: prev = NULL;
1755: sep = 0;
1756: /* skip leading spaces in attribute separators */
1757: while (text[sep] <= SPACE && text[sep] != EOS)
1758: sep++;
1759: /* if attribute separators is empty or contains only spaces, do not
1760: insert any separator element */
1761: if (text[sep] != EOS)
1762: {
1763: child = TtaGetFirstChild (fencedExpression);
1764: while (child != NULL)
1765: {
1766: next = child;
1767: TtaNextSibling (&next);
1768: elType = TtaGetElementType (child);
1769: if (elType.ElTypeNum != MathML_EL_Construct)
1770: {
1771: if (prev != NULL)
1772: {
1773: elType.ElTypeNum = MathML_EL_FencedSeparator;
1774: separator = TtaNewElement (doc, elType);
1775: TtaInsertSibling (separator, prev, FALSE, doc);
1776: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1777: leaf = TtaNewElement (doc, elType);
1778: TtaInsertFirstChild (&leaf, separator, doc);
1779: sepValue[0] = text[sep];
1780: sepValue[1] = SPACE;
1781: sepValue[2] = EOS;
1782: lang = TtaGetLanguageIdFromAlphabet('L');
1783: TtaSetTextContent (leaf, sepValue, lang, doc);
1784: /* is there a following non-space character in separators? */
1785: i = sep + 1;
1786: while (text[i] <= SPACE && text[i] != EOS)
1787: i++;
1788: if (text[i] > SPACE && text[i] != EOS)
1789: sep = i;
1.17 cvs 1790: if (record)
1791: TtaRegisterElementCreate (separator, doc);
1.1 cvs 1792: }
1793: prev = child;
1794: }
1795: child = next;
1796: }
1797: }
1798: }
1799:
1.124 cvs 1800: /*----------------------------------------------------------------------
1801: CreateOpeningOrClosingFence
1802: Create the OpeningFence or ClosingFence element (depending on parameter
1803: open) for the MFENCED element el which contain the fencedExpression
1804: element.
1805: ----------------------------------------------------------------------*/
1806: static void CreateOpeningOrClosingFence (Element fencedExpression,
1807: Element el, Document doc,
1808: ThotBool open)
1809: {
1810: ElementType elType;
1811: Element leaf, fence;
1812: AttributeType attrType;
1813: Attribute attr;
1814: int length;
1815: char text[32];
1816: char c;
1817:
1818: elType = TtaGetElementType (el);
1819: attrType.AttrSSchema = elType.ElSSchema;
1820: if (open)
1821: {
1822: c = '('; /* default value of attribute 'open' */
1823: attrType.AttrTypeNum = MathML_ATTR_open;
1824: elType.ElTypeNum = MathML_EL_OpeningFence;
1825: }
1826: else
1827: {
1828: c = ')'; /* default value of attribute 'close' */
1829: attrType.AttrTypeNum = MathML_ATTR_close;
1830: elType.ElTypeNum = MathML_EL_ClosingFence;
1831: }
1832: attr = TtaGetAttribute (el, attrType);
1833: if (attr != NULL)
1834: {
1835: length = 31;
1836: TtaGiveTextAttributeValue (attr, text, &length);
1837: if (length != 1)
1838: /* content of attribute open or close should be a single character */
1839: c = '?';
1840: else
1841: {
1.128 vatton 1842: c = text[0];
1.124 cvs 1843: /* filter characters that would represent strange symbols, such
1844: as root, integrals, arrows, etc. */
1845: if (c == 'r' || c == 'i' || c == 'c' || c == 'd' || c == 'S' ||
1846: c == 'P' || c == 'I' || c == 'U' || c == 'o' || c == 'u' ||
1847: c == 'h' || c == 'v' || c == 'R' || c == '^' || c == 'L' ||
1848: c == 'V' || c == 'D')
1849: c = '?';
1850: }
1851: }
1852: fence = TtaNewElement (doc, elType);
1853: TtaInsertSibling (fence, fencedExpression, open, doc);
1854: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1855: leaf = TtaNewElement (doc, elType);
1856: TtaInsertFirstChild (&leaf, fence, doc);
1857: TtaSetGraphicsShape (leaf, c, doc);
1858: }
1.1 cvs 1859:
1860: /*----------------------------------------------------------------------
1861: TransformMFENCED
1862: Transform the content of a MFENCED element: create elements
1863: OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
1864: ----------------------------------------------------------------------*/
1.46 cvs 1865: static void TransformMFENCED (Element el, Document doc)
1.1 cvs 1866: {
1867: ElementType elType;
1.124 cvs 1868: Element child, fencedExpression, next, prev, firstChild;
1.1 cvs 1869:
1870: child = TtaGetFirstChild (el);
1871: if (child != NULL)
1872: elType = TtaGetElementType (child);
1873: if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
1874: /* The first child of this MFENCED element is an OpeningFence.
1875: This MFENCED expression has already been transformed, possibly
1876: by the Transform command */
1877: {
1878: TtaNextSibling (&child);
1879: fencedExpression = child;
1880: if (fencedExpression != NULL)
1881: elType = TtaGetElementType (fencedExpression);
1882: if (elType.ElTypeNum == MathML_EL_FencedExpression)
1883: /* the second child is a FencedExpression. OK.
1884: Remove all existing FencedSeparator elements */
1885: {
1886: child = TtaGetFirstChild (fencedExpression);
1887: prev = NULL;
1888: while (child != NULL)
1889: {
1890: elType = TtaGetElementType (child);
1891: next = child;
1892: TtaNextSibling (&next);
1893: if (elType.ElTypeNum == MathML_EL_FencedSeparator)
1894: /* Remove this separator */
1895: TtaDeleteTree (child, doc);
1896: child = next;
1897: }
1898: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 1899: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 1900: }
1901: }
1902: else
1903: /* this MFENCED element must be transformed */
1904: {
1905: /* create a FencedExpression element as a child of the MFENCED elem. */
1906: elType = TtaGetElementType (el);
1907: elType.ElTypeNum = MathML_EL_FencedExpression;
1908: fencedExpression = TtaNewElement (doc, elType);
1909: TtaInsertFirstChild (&fencedExpression, el, doc);
1910: if (child == NULL)
1911: /* empty MFENCED element */
1912: {
1913: elType.ElTypeNum = MathML_EL_Construct;
1914: child = TtaNewElement (doc, elType);
1915: TtaInsertFirstChild (&child, fencedExpression, doc);
1.22 cvs 1916: SetIntPlaceholderAttr (child, doc);
1.1 cvs 1917: }
1918: else
1919: {
1920: /* move the content of the MFENCED element within the new
1921: FencedExpression element */
1922: prev = NULL;
1923: firstChild = NULL;
1924: while (child != NULL)
1925: {
1926: next = child;
1927: TtaNextSibling (&next);
1928: TtaRemoveTree (child, doc);
1929: if (prev == NULL)
1930: {
1931: TtaInsertFirstChild (&child, fencedExpression, doc);
1932: firstChild = child;
1933: }
1934: else
1935: TtaInsertSibling (child, prev, FALSE, doc);
1936: prev = child;
1937: child = next;
1938: }
1939:
1940: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 1941: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 1942:
1943: /* Create placeholders within the FencedExpression element */
1944: CreatePlaceholders (firstChild, doc);
1945: }
1946:
1947: /* create the OpeningFence element according to the open attribute */
1.124 cvs 1948: CreateOpeningOrClosingFence (fencedExpression, el, doc, TRUE);
1.1 cvs 1949:
1950: /* create the ClosingFence element according to close attribute */
1.124 cvs 1951: CreateOpeningOrClosingFence (fencedExpression, el, doc, FALSE);
1.1 cvs 1952: }
1953: }
1954:
1955: /*----------------------------------------------------------------------
1.59 cvs 1956: MathMLScriptShift
1957: The MathML attribute attr (superscriptshift or subscriptshift) is associated
1958: with element el (a msub, msup or msubsup).
1959: If value is not NULL, generate the corresponding Thot VertPos rule for the
1960: Subscript or Superscript child of el.
1961: If value is NULL, remove the Thot VertPos rule.
1962: -----------------------------------------------------------------------*/
1.120 cvs 1963: void MathMLScriptShift (Document doc, Element el, char *value, int attr)
1.59 cvs 1964: {
1965: ElementType elType;
1966: Element script, child;
1967: int scrType;
1968: PresentationValue pval;
1969: PresentationContext ctxt;
1970:
1971: /* get the Superscript or Subscript child of el */
1972: if (attr == MathML_ATTR_superscriptshift)
1973: scrType = MathML_EL_Superscript;
1974: else if (attr == MathML_ATTR_subscriptshift)
1975: scrType = MathML_EL_Subscript;
1976: else
1977: return;
1978: script = NULL;
1979: child = TtaGetFirstChild (el);
1980: while (!script && child)
1981: {
1982: elType = TtaGetElementType (child);
1983: if (elType.ElTypeNum == scrType)
1984: script = child;
1985: else
1986: TtaNextSibling (&child);
1987: }
1988: if (script)
1989: /* Superscript or Subscript element found */
1990: {
1991: ctxt = TtaGetSpecificStyleContext (doc);
1992: if (!value)
1993: /* remove the presentation rule */
1994: {
1995: ctxt->destroy = TRUE;
1.75 cvs 1996: pval.typed_data.value = 0;
1.59 cvs 1997: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
1998: }
1999: else
2000: {
2001: ctxt->destroy = FALSE;
2002: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 2003: value = TtaSkipBlanks (value);
1.59 cvs 2004: value = ParseCSSUnit (value, &pval);
2005: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
2006: {
1.78 cvs 2007: /* the specific presentation to be created is not a CSS rule */
2008: ctxt->cssLevel = 0;
1.59 cvs 2009: if (attr == MathML_ATTR_superscriptshift)
2010: pval.typed_data.value = - pval.typed_data.value;
2011: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
2012: }
2013: }
2014: TtaFreeMemory (ctxt);
2015: }
2016: }
2017:
2018: /*----------------------------------------------------------------------
2019: SetScriptShift
2020: If element el (which is a msup, msub or msubsup) has an attribute
2021: att (which is subscriptshift or superscriptshift), generate the
2022: corresponding Thot presentation rule.
2023: ----------------------------------------------------------------------*/
1.120 cvs 2024: static void SetScriptShift (Element el, Document doc, int att)
1.59 cvs 2025: {
2026: AttributeType attrType;
2027: ElementType elType;
2028: Attribute attr;
1.120 cvs 2029: char *value;
1.59 cvs 2030: int length;
2031:
2032: elType = TtaGetElementType (el);
2033: attrType.AttrSSchema = elType.ElSSchema;
2034: attrType.AttrTypeNum = att;
2035: attr = TtaGetAttribute (el, attrType);
2036: if (attr)
2037: {
2038: length = TtaGetTextAttributeLength (attr);
2039: if (length > 0)
2040: {
1.116 cvs 2041: value = TtaGetMemory (length+1);
1.59 cvs 2042: value[0] = EOS;
2043: TtaGiveTextAttributeValue (attr, value, &length);
2044: MathMLScriptShift (doc, el, value, att);
2045: TtaFreeMemory (value);
2046: }
2047: }
2048: }
2049:
2050: /*----------------------------------------------------------------------
1.1 cvs 2051: MathMLElementComplete
2052: Check the Thot structure of the MathML element el.
2053: ----------------------------------------------------------------------*/
1.56 cvs 2054: void MathMLElementComplete (Element el, Document doc, int *error)
1.1 cvs 2055: {
1.74 cvs 2056: ElementType elType, parentType;
1.1 cvs 2057: Element child, parent, new, prev, next;
1.101 cvs 2058: AttributeType attrType;
2059: Attribute attr;
1.56 cvs 2060: SSchema MathMLSSchema;
2061: ThotBool ok;
1.1 cvs 2062:
1.56 cvs 2063: ok = TRUE;
2064: *error = 0;
1.1 cvs 2065: elType = TtaGetElementType (el);
1.2 cvs 2066: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 2067:
1.76 cvs 2068: if (elType.ElSSchema == MathMLSSchema)
1.1 cvs 2069: {
2070: switch (elType.ElTypeNum)
2071: {
1.76 cvs 2072: case MathML_EL_MathML:
2073: /* Create placeholders within the MathML element */
2074: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.132 cvs 2075: break;
1.1 cvs 2076: case MathML_EL_MI:
2077: SetFontstyleAttr (el, doc);
2078: break;
2079: case MathML_EL_MO:
1.22 cvs 2080: SetIntAddSpaceAttr (el, doc);
2081: SetIntVertStretchAttr (el, doc, 0, NULL);
1.58 cvs 2082: /* if the MO element is a child of a MROW (or equivalent) and if it
2083: contains a fence character, transform this MO into MF and
2084: transform the fence character into a Thot SYMBOL */
2085: CheckFence (el, doc);
1.1 cvs 2086: break;
1.60 cvs 2087: case MathML_EL_MSPACE:
2088: break;
1.39 cvs 2089: case MathML_EL_MROW:
1.55 cvs 2090: /* Create placeholders within the MROW */
2091: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.39 cvs 2092: break;
2093: case MathML_EL_MFRAC:
1.54 cvs 2094: case MathML_EL_BevelledMFRAC:
1.39 cvs 2095: /* end of a fraction. Create a Numerator and a Denominator */
1.56 cvs 2096: ok = CheckMathSubExpressions (el, MathML_EL_Numerator,
2097: MathML_EL_Denominator, 0, doc);
1.39 cvs 2098: break;
2099: case MathML_EL_MSQRT:
1.50 cvs 2100: /* end of a Square Root */
2101: /* Create placeholders within the element */
2102: CreatePlaceholders (TtaGetFirstChild (el), doc);
2103: /* Create a SqrtBase that contains all children of the MSQRT */
1.39 cvs 2104: CreateWrapper (el, MathML_EL_SqrtBase, doc);
2105: break;
1.1 cvs 2106: case MathML_EL_MROOT:
2107: /* end of a Root. Create a RootBase and an Index */
1.56 cvs 2108: ok = CheckMathSubExpressions (el, MathML_EL_RootBase,
2109: MathML_EL_Index, 0, doc);
1.1 cvs 2110: break;
1.50 cvs 2111: case MathML_EL_MENCLOSE:
2112: /* Create placeholders within the element */
2113: CreatePlaceholders (TtaGetFirstChild (el), doc);
2114: break;
1.39 cvs 2115: case MathML_EL_MSTYLE:
2116: case MathML_EL_MERROR:
2117: case MathML_EL_MPADDED:
2118: case MathML_EL_MPHANTOM:
2119: /* Create placeholders within the element */
2120: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 2121: break;
2122: case MathML_EL_MFENCED:
2123: TransformMFENCED (el, doc);
2124: break;
2125: case MathML_EL_MSUB:
2126: /* end of a MSUB. Create Base and Subscript */
1.56 cvs 2127: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2128: MathML_EL_Subscript, 0, doc);
1.59 cvs 2129: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
1.22 cvs 2130: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2131: break;
2132: case MathML_EL_MSUP:
2133: /* end of a MSUP. Create Base and Superscript */
1.56 cvs 2134: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2135: MathML_EL_Superscript, 0, doc);
1.59 cvs 2136: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.22 cvs 2137: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2138: break;
1.39 cvs 2139: case MathML_EL_MSUBSUP:
2140: /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
1.56 cvs 2141: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2142: MathML_EL_Subscript,
2143: MathML_EL_Superscript, doc);
1.59 cvs 2144: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
2145: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.39 cvs 2146: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2147: break;
2148: case MathML_EL_MUNDER:
2149: /* end of a MUNDER. Create UnderOverBase, and Underscript */
1.56 cvs 2150: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2151: MathML_EL_Underscript, 0, doc);
1.22 cvs 2152: SetIntHorizStretchAttr (el, doc);
2153: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 2154: break;
2155: case MathML_EL_MOVER:
2156: /* end of a MOVER. Create UnderOverBase, and Overscript */
1.56 cvs 2157: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2158: MathML_EL_Overscript, 0, doc);
1.22 cvs 2159: SetIntHorizStretchAttr (el, doc);
2160: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 2161: break;
1.39 cvs 2162: case MathML_EL_MUNDEROVER:
2163: /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
2164: Overscript */
1.56 cvs 2165: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2166: MathML_EL_Underscript,
2167: MathML_EL_Overscript, doc);
1.39 cvs 2168: SetIntHorizStretchAttr (el, doc);
2169: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
2170: break;
1.1 cvs 2171: case MathML_EL_MMULTISCRIPTS:
2172: /* end of a MMULTISCRIPTS. Create all elements defined in the
2173: MathML S schema */
2174: BuildMultiscript (el, doc);
1.5 cvs 2175: break;
2176: case MathML_EL_MTABLE:
2177: /* end of a MTABLE. Create all elements defined in the MathML S
2178: schema */
1.64 cvs 2179: CheckMTable (el, doc, TRUE);
1.101 cvs 2180: /* if the table has a rowalign attribute, process it */
2181: attrType.AttrSSchema = MathMLSSchema;
2182: attrType.AttrTypeNum = MathML_ATTR_rowalign;
2183: attr = TtaGetAttribute (el, attrType);
2184: if (attr)
2185: HandleRowalignAttribute (attr, el, doc, FALSE);
2186: /* if the table has a columnalign attribute, process it */
2187: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2188: attr = TtaGetAttribute (el, attrType);
2189: if (attr)
1.108 cvs 2190: HandleColalignAttribute (attr, el, doc, FALSE, FALSE);
1.101 cvs 2191: break;
2192: case MathML_EL_MTR:
2193: /* if the row has a columnalign attribute, process it */
2194: attrType.AttrSSchema = MathMLSSchema;
2195: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2196: attr = TtaGetAttribute (el, attrType);
2197: if (attr)
1.108 cvs 2198: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.101 cvs 2199: break;
2200: case MathML_EL_MLABELEDTR:
2201: /* if the row has a columnalign attribute, process it */
2202: attrType.AttrSSchema = MathMLSSchema;
2203: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2204: attr = TtaGetAttribute (el, attrType);
2205: if (attr)
1.108 cvs 2206: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.1 cvs 2207: break;
1.39 cvs 2208: case MathML_EL_MTD:
2209: /* Create placeholders within the table cell */
2210: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.46 cvs 2211: break;
1.39 cvs 2212: case MathML_EL_MACTION:
2213: /* Create placeholders within the MACTION element */
2214: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 2215: break;
2216: default:
2217: break;
2218: }
2219: parent = TtaGetParent (el);
1.118 cvs 2220: if (parent)
2221: {
2222: parentType = TtaGetElementType (parent);
2223: if (parentType.ElSSchema != elType.ElSSchema)
2224: /* root of a MathML tree, Create a MathML element if there is no */
2225: if (elType.ElTypeNum != MathML_EL_MathML)
2226: {
2227: elType.ElSSchema = MathMLSSchema;
2228: elType.ElTypeNum = MathML_EL_MathML;
2229: new = TtaNewElement (doc, elType);
2230: TtaInsertSibling (new, el, TRUE, doc);
2231: next = el;
2232: TtaNextSibling (&next);
2233: TtaRemoveTree (el, doc);
2234: TtaInsertFirstChild (&el, new, doc);
2235: prev = el;
2236: while (next != NULL)
2237: {
2238: child = next;
2239: TtaNextSibling (&next);
2240: TtaRemoveTree (child, doc);
2241: TtaInsertSibling (child, prev, FALSE, doc);
2242: prev = child;
2243: }
2244: /* Create placeholders within the MathML element */
2245: CreatePlaceholders (el, doc);
2246: }
2247: }
1.1 cvs 2248: }
1.56 cvs 2249: if (!ok)
2250: /* send an error message */
2251: *error = 1;
1.1 cvs 2252: }
2253:
2254: /*----------------------------------------------------------------------
1.126 cvs 2255: UnknownMathMLNameSpace
2256: Create an element that belongs to a non-supported namespace
2257: ----------------------------------------------------------------------*/
2258: void UnknownMathMLNameSpace (ParserData *context, char* content)
2259: {
2260: ElementType elType;
2261: Element elInv, elText;
2262:
2263: /* Create a new Invalid_element */
2264: elType.ElSSchema = GetXMLSSchema (MATH_TYPE, context->doc);
2265: elType.ElTypeNum = MathML_EL_Unknown_namespace;
2266: elInv = TtaNewElement (context->doc, elType);
2267: if (elInv != NULL)
2268: {
2269: XmlSetElemLineNumber (elInv);
2270: InsertXmlElement (&elInv);
2271: context->lastElementClosed = TRUE;
2272: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
2273: elText = TtaNewElement (context->doc, elType);
2274: XmlSetElemLineNumber (elText);
2275: TtaInsertFirstChild (&elText, elInv, context->doc);
2276: TtaSetTextContent (elText, content, context->language, context->doc);
2277: TtaSetAccessRight (elText, ReadOnly, context->doc);
2278: }
2279: }
2280:
2281: /*----------------------------------------------------------------------
1.24 cvs 2282: SetFontfamily
2283: -----------------------------------------------------------------------*/
1.120 cvs 2284: void SetFontfamily (Document doc, Element el, char *value)
1.24 cvs 2285: {
2286: #define buflen 50
1.116 cvs 2287: char css_command[buflen+20];
1.24 cvs 2288:
1.116 cvs 2289: sprintf (css_command, "font-family: %s", value);
1.72 cvs 2290: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 2291: }
2292:
2293: /*----------------------------------------------------------------------
1.83 cvs 2294: MathMLlinethickness
2295: The MathML attribute linthickness is associated with element el. Generate
2296: the corresponding style property for this element.
2297: -----------------------------------------------------------------------*/
1.120 cvs 2298: void MathMLlinethickness (Document doc, Element el, char *value)
1.83 cvs 2299: {
2300: #define buflen 50
1.116 cvs 2301: char css_command[buflen+20];
1.83 cvs 2302:
1.116 cvs 2303: if (strcmp (value, "thin") == 0)
2304: strcpy (value, "1pt");
2305: else if (strcmp (value, "medium") == 0)
2306: strcpy (value, "1pt");
2307: else if (strcmp (value, "thick") == 0)
2308: strcpy (value, "2pt");
2309: sprintf (css_command, "stroke-width: %s", value);
1.83 cvs 2310: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
2311: }
2312:
2313: /*----------------------------------------------------------------------
1.58 cvs 2314: MathMLAttrToStyleProperty
2315: The MathML attribute attr is associated with element el. Generate
2316: the corresponding style property for this element.
1.24 cvs 2317: -----------------------------------------------------------------------*/
1.138 ! cvs 2318: void MathMLAttrToStyleProperty (Document doc, Element el, char *value,
! 2319: int attr)
1.24 cvs 2320: {
1.116 cvs 2321: char css_command[buflen+20];
1.58 cvs 2322:
2323: switch (attr)
2324: {
2325: case MathML_ATTR_fontsize:
1.116 cvs 2326: sprintf (css_command, "font-size: %s", value);
1.58 cvs 2327: break;
1.93 cvs 2328: case MathML_ATTR_mathsize:
1.116 cvs 2329: if (strcmp (value, "small") == 0)
2330: strcpy (value, "80%");
2331: else if (strcmp (value, "normal") == 0)
2332: strcpy (value, "100%");
2333: else if (strcmp (value, "big") == 0)
2334: strcpy (value, "125%");
2335: sprintf (css_command, "font-size: %s", value);
1.93 cvs 2336: break;
1.58 cvs 2337: case MathML_ATTR_lspace:
1.116 cvs 2338: sprintf (css_command, "padding-left: %s", value);
1.58 cvs 2339: break;
2340: case MathML_ATTR_rspace:
1.116 cvs 2341: sprintf (css_command, "padding-right: %s", value);
1.58 cvs 2342: break;
2343: }
1.72 cvs 2344: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 2345: }
2346:
2347: /*----------------------------------------------------------------------
1.60 cvs 2348: MathMLSetScriptLevel
2349: A scriptlevel attribute with value value is associated with element el.
2350: Generate the corresponding style property for this element.
2351: -----------------------------------------------------------------------*/
1.120 cvs 2352: void MathMLSetScriptLevel (Document doc, Element el, char *value)
1.60 cvs 2353: {
2354: PresentationValue pval;
2355: PresentationContext ctxt;
2356: ThotBool relative;
2357: int percentage;
2358:
2359: ctxt = TtaGetSpecificStyleContext (doc);
2360: if (!value)
2361: /* remove the presentation rule */
2362: {
2363: ctxt->destroy = TRUE;
1.75 cvs 2364: pval.typed_data.value = 0;
1.60 cvs 2365: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
2366: }
2367: else
2368: {
2369: ctxt->destroy = FALSE;
2370: /* parse the attribute value (an optional sign and an integer) */
1.119 cvs 2371: value = TtaSkipBlanks (value);
1.60 cvs 2372: relative = (value[0] == '-' || value[0] == '+');
2373: value = ParseCSSUnit (value, &pval);
2374: if (pval.typed_data.unit != STYLE_UNIT_REL &&
2375: pval.typed_data.real)
2376: /* this is an error: it should be an integer without any unit name */
2377: /* error */;
2378: else
2379: {
2380: if (relative)
2381: {
1.63 cvs 2382: percentage = 100;
1.60 cvs 2383: if (pval.typed_data.value == 0)
2384: /* scriptlevel="+0" */
2385: percentage = 100;
2386: else if (pval.typed_data.value == 1)
2387: /* scriptlevel="+1" */
2388: percentage = 71;
2389: else if (pval.typed_data.value == 2)
2390: /* scriptlevel="+2" */
2391: percentage = 50;
2392: else if (pval.typed_data.value >= 3)
2393: /* scriptlevel="+3" or more */
2394: percentage = 35;
2395: else if (pval.typed_data.value == -1)
2396: /* scriptlevel="-1" */
2397: percentage = 141;
2398: else if (pval.typed_data.value == -2)
2399: /* scriptlevel="-2" */
2400: percentage = 200;
2401: else if (pval.typed_data.value <= -3)
2402: /* scriptlevel="-3" or less */
2403: percentage = 282;
2404: pval.typed_data.value = percentage;
2405: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1.78 cvs 2406: /* the specific presentation to be created is not a CSS rule */
2407: ctxt->cssLevel = 0;
1.60 cvs 2408: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
2409: }
2410: else
2411: /* absolute value */
2412: {
2413: /**** ****/;
2414: }
2415: }
2416: }
2417: TtaFreeMemory (ctxt);
2418: }
2419:
2420: /*----------------------------------------------------------------------
2421: MathMLSpacingAttr
2422: The MathML attribute attr (height, width or depth) is associated
2423: with element el (a mspace or mpadding).
2424: If value is not NULL, generate the corresponding Thot presentation rule for
2425: the element.
2426: If value is NULL, remove the corresponding Thot presentation rule.
2427: -----------------------------------------------------------------------*/
1.120 cvs 2428: void MathMLSpacingAttr (Document doc, Element el, char *value, int attr)
1.60 cvs 2429: {
2430: ElementType elType;
2431: PresentationValue pval;
2432: PresentationContext ctxt;
2433: int ruleType;
2434:
2435: /* provisionally, handles only mspace elements */
2436: elType = TtaGetElementType (el);
1.96 cvs 2437: if (elType.ElTypeNum != MathML_EL_MSPACE &&
1.97 cvs 2438: elType.ElTypeNum != MathML_EL_MPADDED &&
2439: elType.ElTypeNum != MathML_EL_MTABLE)
1.60 cvs 2440: return;
2441: switch (attr)
2442: {
2443: case MathML_ATTR_width_:
2444: ruleType = PRWidth;
2445: break;
2446: case MathML_ATTR_height_:
2447: ruleType = PRPaddingTop;
2448: break;
2449: case MathML_ATTR_depth_:
2450: ruleType = PRPaddingBottom;
2451: break;
2452: default:
2453: return;
2454: }
2455: ctxt = TtaGetSpecificStyleContext (doc);
1.116 cvs 2456: if (!value || (strcmp (value, "auto") == 0))
1.60 cvs 2457: /* remove the presentation rule */
2458: {
2459: ctxt->destroy = TRUE;
1.75 cvs 2460: pval.typed_data.value = 0;
1.60 cvs 2461: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
2462: }
2463: else
2464: {
2465: ctxt->destroy = FALSE;
2466: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 2467: value = TtaSkipBlanks (value);
1.60 cvs 2468: value = ParseCSSUnit (value, &pval);
2469: /***** we should accept namedspace for width *****/
2470: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
1.78 cvs 2471: {
2472: /* the specific presentation to be created is not a CSS rule */
2473: ctxt->cssLevel = 0;
2474: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
2475: }
1.60 cvs 2476: }
2477: TtaFreeMemory (ctxt);
2478: }
2479:
2480: /*----------------------------------------------------------------------
1.1 cvs 2481: MathMLAttributeComplete
1.58 cvs 2482: The XML parser has completed parsing attribute attr (as well as its value)
2483: that is associated with element el in document doc.
1.1 cvs 2484: ----------------------------------------------------------------------*/
1.120 cvs 2485: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
1.1 cvs 2486: {
1.134 cvs 2487: AttributeType attrType, depAttrType;
1.23 cvs 2488: int attrKind;
1.50 cvs 2489: ElementType elType;
1.23 cvs 2490: #define buflen 50
1.120 cvs 2491: char *value;
1.50 cvs 2492: int val, length;
1.101 cvs 2493: Attribute intAttr;
1.23 cvs 2494:
1.58 cvs 2495: /* first get the type of that attribute */
1.23 cvs 2496: TtaGiveAttributeType (attr, &attrType, &attrKind);
1.54 cvs 2497: if (attrType.AttrTypeNum == MathML_ATTR_bevelled)
1.58 cvs 2498: /* it's a bevelled attribute */
1.50 cvs 2499: {
2500: val = TtaGetAttributeValue (attr);
1.54 cvs 2501: if (val == MathML_ATTR_bevelled_VAL_true)
2502: /* bevelled = true. Transform MFRAC into BevelledMFRAC */
1.50 cvs 2503: {
2504: elType = TtaGetElementType (el);
2505: if (elType.ElTypeNum == MathML_EL_MFRAC)
1.54 cvs 2506: ChangeTypeOfElement (el, doc, MathML_EL_BevelledMFRAC);
1.50 cvs 2507: }
2508: }
1.101 cvs 2509:
2510: else if (attrType.AttrTypeNum == MathML_ATTR_rowalign_mtr)
2511: {
2512: /* create an equivalent IntRowAlign attribute on the same element */
2513: attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
2514: intAttr = TtaGetAttribute (el, attrType);
2515: if (!intAttr)
2516: /* no IntRowAlign attribute, create one */
2517: {
2518: intAttr = TtaNewAttribute (attrType);
2519: TtaAttachAttribute (el, intAttr, doc);
2520: }
2521: val = TtaGetAttributeValue (attr);
2522: TtaSetAttributeValue (intAttr, val, el, doc);
2523: }
2524:
2525: else if (attrType.AttrTypeNum == MathML_ATTR_rowalign)
2526: {
2527: /* parse the attribute value and create a IntRowAlign attribute
2528: for each mrow contained in the element */
2529: HandleRowalignAttribute (attr, el, doc, FALSE);
2530: }
2531:
2532: else if (attrType.AttrTypeNum == MathML_ATTR_columnalign_mtd)
2533: {
2534: /* create an equivalent IntColAlign attribute on the same element */
2535: attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
2536: intAttr = TtaGetAttribute (el, attrType);
2537: if (!intAttr)
2538: /* no IntColAlign attribute, create one */
2539: {
2540: intAttr = TtaNewAttribute (attrType);
2541: TtaAttachAttribute (el, intAttr, doc);
2542: }
2543: val = TtaGetAttributeValue (attr);
2544: TtaSetAttributeValue (intAttr, val, el, doc);
2545: }
2546:
1.104 cvs 2547: /* don't handle attribute columnalign now: the table or the row is not
2548: complete yet. Handle it when the element is complete.
1.101 cvs 2549: else if (attrType.AttrTypeNum == MathML_ATTR_columnalign)
1.104 cvs 2550: */
1.138 ! cvs 2551:
! 2552: else if (attrType.AttrTypeNum == MathML_ATTR_Language)
! 2553: {
! 2554: if (el == TtaGetRootElement (doc))
! 2555: /* it's the lang attribute on the root element */
! 2556: /* set the RealLang attribute */
! 2557: {
! 2558: depAttrType.AttrSSchema = attrType.AttrSSchema ;
! 2559: depAttrType.AttrTypeNum = MathML_ATTR_RealLang;
! 2560: if (!TtaGetAttribute (el, depAttrType))
! 2561: /* it's not present. Add it */
! 2562: {
! 2563: intAttr = TtaNewAttribute (depAttrType);
! 2564: TtaAttachAttribute (el, intAttr, doc);
! 2565: TtaSetAttributeValue (intAttr, MathML_ATTR_RealLang_VAL_Yes_,
! 2566: el, doc);
! 2567: }
! 2568: }
! 2569: }
1.101 cvs 2570:
1.50 cvs 2571: else if (attrType.AttrTypeNum == MathML_ATTR_color ||
1.93 cvs 2572: attrType.AttrTypeNum == MathML_ATTR_mathcolor ||
2573: attrType.AttrTypeNum == MathML_ATTR_background_ ||
2574: attrType.AttrTypeNum == MathML_ATTR_mathbackground ||
2575: attrType.AttrTypeNum == MathML_ATTR_fontsize ||
2576: attrType.AttrTypeNum == MathML_ATTR_mathsize ||
2577: attrType.AttrTypeNum == MathML_ATTR_fontfamily ||
2578: attrType.AttrTypeNum == MathML_ATTR_linethickness ||
2579: attrType.AttrTypeNum == MathML_ATTR_lspace ||
2580: attrType.AttrTypeNum == MathML_ATTR_rspace ||
2581: attrType.AttrTypeNum == MathML_ATTR_scriptlevel ||
2582: attrType.AttrTypeNum == MathML_ATTR_width_ ||
2583: attrType.AttrTypeNum == MathML_ATTR_height_ ||
2584: attrType.AttrTypeNum == MathML_ATTR_depth_ )
2585: {
1.23 cvs 2586: length = TtaGetTextAttributeLength (attr);
2587: if (length >= buflen)
2588: length = buflen - 1;
2589: if (length > 0)
2590: {
1.116 cvs 2591: value = TtaGetMemory (buflen);
1.33 cvs 2592: value[0] = EOS;
2593: TtaGiveTextAttributeValue (attr, value, &length);
2594: switch (attrType.AttrTypeNum)
2595: {
2596: case MathML_ATTR_color:
1.134 cvs 2597: /* deprecated attribute */
2598: /* if the same element has a mathcolor attribute, ignore
2599: the color attribute */
2600: depAttrType.AttrSSchema = attrType.AttrSSchema ;
2601: depAttrType.AttrTypeNum = MathML_ATTR_mathcolor;
2602: if (!TtaGetAttribute (el, depAttrType))
2603: HTMLSetForegroundColor (doc, el, value);
2604: break;
1.93 cvs 2605: case MathML_ATTR_mathcolor:
1.24 cvs 2606: HTMLSetForegroundColor (doc, el, value);
2607: break;
1.33 cvs 2608: case MathML_ATTR_background_:
1.134 cvs 2609: /* deprecated attribute */
2610: /* if the same element has a mathbackground attribute, ignore
2611: the background attribute */
2612: depAttrType.AttrSSchema = attrType.AttrSSchema;
2613: depAttrType.AttrTypeNum = MathML_ATTR_mathbackground;
2614: if (!TtaGetAttribute (el, depAttrType))
2615: HTMLSetBackgroundColor (doc, el, value);
2616: break;
1.93 cvs 2617: case MathML_ATTR_mathbackground:
1.24 cvs 2618: HTMLSetBackgroundColor (doc, el, value);
2619: break;
1.33 cvs 2620: case MathML_ATTR_fontfamily:
1.24 cvs 2621: SetFontfamily (doc, el, value);
1.83 cvs 2622: break;
2623: case MathML_ATTR_linethickness:
2624: MathMLlinethickness (doc, el, value);
1.58 cvs 2625: break;
2626: case MathML_ATTR_fontsize:
1.134 cvs 2627: /* deprecated attribute */
2628: /* if the same element has a mathsize attribute, ignore
2629: the fontsize attribute */
2630: depAttrType.AttrSSchema = attrType.AttrSSchema;
2631: depAttrType.AttrTypeNum = MathML_ATTR_mathsize;
2632: if (!TtaGetAttribute (el, depAttrType))
2633: MathMLAttrToStyleProperty (doc, el, value,
2634: attrType.AttrTypeNum);
2635: break;
1.93 cvs 2636: case MathML_ATTR_mathsize:
1.58 cvs 2637: case MathML_ATTR_lspace:
2638: case MathML_ATTR_rspace:
1.60 cvs 2639: MathMLAttrToStyleProperty (doc, el, value,attrType.AttrTypeNum);
2640: break;
2641: case MathML_ATTR_scriptlevel:
2642: MathMLSetScriptLevel (doc, el, value);
2643: break;
2644: case MathML_ATTR_width_:
2645: case MathML_ATTR_height_:
2646: case MathML_ATTR_depth_:
2647: MathMLSpacingAttr (doc, el, value, attrType.AttrTypeNum);
1.59 cvs 2648: break;
2649: default:
1.24 cvs 2650: break;
1.33 cvs 2651: }
2652: TtaFreeMemory (value);
1.23 cvs 2653: }
2654: }
1.1 cvs 2655: }
2656:
2657: /*----------------------------------------------------------------------
2658: MathMLGetDTDName
2659: ----------------------------------------------------------------------*/
1.120 cvs 2660: void MathMLGetDTDName (char *DTDname, char *elementName)
1.1 cvs 2661: {
2662: /* no other DTD allowed within MathML elements */
1.116 cvs 2663: strcpy (DTDname, "");
1.1 cvs 2664: }
2665:
2666: /* end of module */
Webmaster