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