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