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