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