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