Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.168
1.1 cvs 1: /*
2: *
1.144 vatton 3: * (c) COPYRIGHT MIT and INRIA, 1996-2002
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.159 quint 7:
1.1 cvs 8: /*
9: * MathMLbuilder
10: *
11: * Author: V. Quint
12: */
13:
14: #define THOT_EXPORT extern
1.4 cvs 15: #include "amaya.h"
1.25 cvs 16: #include "css.h"
1.59 cvs 17: #include "html2thot_f.h"
1.133 cvs 18: #include "HTMLactions_f.h"
1.25 cvs 19: #include "MathML.h"
20: #include "parser.h"
1.59 cvs 21: #include "styleparser_f.h"
22: #include "style.h"
23: #include "undo.h"
1.133 cvs 24: #include "Xml2thot_f.h"
1.109 cvs 25:
1.106 cvs 26: /* Define a pointer to let parser functions access the Math entity table */
27: extern XmlEntity *pMathEntityTable;
1.1 cvs 28:
29: #define MaxMsgLength 200
30:
1.12 cvs 31: #include "HTMLtable_f.h"
1.29 cvs 32: #include "Mathedit_f.h"
33: #include "styleparser_f.h"
34: #include "fetchXMLname_f.h"
1.1 cvs 35:
36: /*----------------------------------------------------------------------
37: MapMathMLAttribute
38: Search in the Attribute Mapping Table the entry for the
39: attribute of name Attr and returns the corresponding Thot attribute type.
40: ----------------------------------------------------------------------*/
1.120 cvs 41: void MapMathMLAttribute (char *attrName, AttributeType *attrType,
42: char *elementName, ThotBool *level, Document doc)
1.1 cvs 43: {
1.68 cvs 44: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.91 cvs 45: MapXMLAttribute (MATH_TYPE, attrName, elementName, level, doc, &(attrType->AttrTypeNum));
1.1 cvs 46: }
47:
48: /*----------------------------------------------------------------------
49: MapMathMLAttributeValue
50: Search in the Attribute Value Mapping Table the entry for the attribute
51: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
52: ----------------------------------------------------------------------*/
1.150 vatton 53: void MapMathMLAttributeValue (char *attVal, AttributeType attrType, int *value)
1.1 cvs 54: {
1.150 vatton 55: MapXMLAttributeValue (MATH_TYPE, attVal, attrType, value);
1.1 cvs 56: }
57:
58: /*----------------------------------------------------------------------
1.130 carcone 59: MathMLEntityCreated
60: ----------------------------------------------------------------------*/
61: void MathMLEntityCreated (unsigned char *entityValue, Language lang,
62: char *entityName, Document doc)
63: {
64: }
65:
66: /*----------------------------------------------------------------------
1.1 cvs 67: ElementNeedsPlaceholder
68: returns TRUE if element el needs a sibling placeholder.
69: ----------------------------------------------------------------------*/
1.18 cvs 70: ThotBool ElementNeedsPlaceholder (Element el)
1.1 cvs 71: {
72: ElementType elType;
1.138 cvs 73: Element child, parent, sibling;
1.18 cvs 74: ThotBool ret;
1.139 quint 75:
1.1 cvs 76: ret = FALSE;
77: elType = TtaGetElementType (el);
1.43 cvs 78: if (elType.ElTypeNum == MathML_EL_MS ||
1.39 cvs 79: elType.ElTypeNum == MathML_EL_MFRAC ||
1.54 cvs 80: elType.ElTypeNum == MathML_EL_BevelledMFRAC ||
1.39 cvs 81: elType.ElTypeNum == MathML_EL_MSQRT ||
82: elType.ElTypeNum == MathML_EL_MROOT ||
83: elType.ElTypeNum == MathML_EL_MSTYLE ||
84: elType.ElTypeNum == MathML_EL_MERROR ||
85: elType.ElTypeNum == MathML_EL_MPADDED ||
86: elType.ElTypeNum == MathML_EL_MPHANTOM ||
87: elType.ElTypeNum == MathML_EL_MFENCED ||
1.1 cvs 88: elType.ElTypeNum == MathML_EL_MF ||
89: elType.ElTypeNum == MathML_EL_MSUB ||
90: elType.ElTypeNum == MathML_EL_MSUP ||
1.39 cvs 91: elType.ElTypeNum == MathML_EL_MSUBSUP ||
1.1 cvs 92: elType.ElTypeNum == MathML_EL_MUNDER ||
93: elType.ElTypeNum == MathML_EL_MOVER ||
94: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
1.28 cvs 95: elType.ElTypeNum == MathML_EL_MMULTISCRIPTS ||
1.39 cvs 96: elType.ElTypeNum == MathML_EL_MTABLE ||
97: elType.ElTypeNum == MathML_EL_MACTION)
1.1 cvs 98: ret = TRUE;
1.138 cvs 99: else if (elType.ElTypeNum == MathML_EL_MROW)
100: /* a mrow needs a place holder only if it's not the sole child of
101: an element such as Numerator, Denominator, RootBase, Index, etc. */
102: {
103: ret = TRUE;
104: sibling = el; TtaNextSibling (&sibling);
105: if (!sibling)
106: {
1.139 quint 107: sibling = el; TtaPreviousSibling (&sibling);
1.138 cvs 108: if (!sibling)
109: {
110: parent = TtaGetParent (el);
111: if (parent)
112: {
113: elType = TtaGetElementType (parent);
114: if (elType.ElTypeNum == MathML_EL_Numerator ||
115: elType.ElTypeNum == MathML_EL_Denominator ||
116: elType.ElTypeNum == MathML_EL_RootBase ||
117: elType.ElTypeNum == MathML_EL_Index ||
118: elType.ElTypeNum == MathML_EL_FencedExpression ||
119: elType.ElTypeNum == MathML_EL_Base ||
120: elType.ElTypeNum == MathML_EL_Subscript ||
121: elType.ElTypeNum == MathML_EL_Superscript ||
122: elType.ElTypeNum == MathML_EL_UnderOverBase ||
123: elType.ElTypeNum == MathML_EL_Underscript ||
124: elType.ElTypeNum == MathML_EL_Overscript ||
125: elType.ElTypeNum == MathML_EL_MultiscriptBase ||
126: elType.ElTypeNum == MathML_EL_MSubscript ||
127: elType.ElTypeNum == MathML_EL_MSuperscript)
128: ret = FALSE;
129: }
130: }
131: }
132: }
1.158 quint 133: else if (elType.ElTypeNum == MathML_EL_MO ||
134: elType.ElTypeNum == MathML_EL_OpeningFence ||
135: elType.ElTypeNum == MathML_EL_ClosingFence ||
136: elType.ElTypeNum == MathML_EL_FencedSeparator)
1.138 cvs 137: /* an operator that contains a single Symbol needs a placeholder,
138: except when it is in a Base or UnderOverBase */
139: {
140: child = TtaGetFirstChild (el);
141: if (child != NULL)
1.1 cvs 142: {
1.138 cvs 143: elType = TtaGetElementType (child);
144: if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
145: {
1.1 cvs 146: ret = TRUE;
147: parent = TtaGetParent (el);
148: if (parent != NULL)
149: {
1.138 cvs 150: elType = TtaGetElementType (parent);
151: if (elType.ElTypeNum == MathML_EL_Base ||
152: elType.ElTypeNum == MathML_EL_UnderOverBase)
1.139 quint 153: ret = FALSE;
154: }
155: }
156: }
157: }
158: else if (elType.ElTypeNum == MathML_EL_MSPACE)
159: {
160: /* in principle mspace needs a placeholder sibling */
161: ret = TRUE;
162: /* but if it's the only child of a mstyle element, the placeholders
163: would change the height and width of the mstyle. Consider for
164: instance:
165: <mstyle background="#000099">
166: <mspace depth="2mm" width=".2in"/>
167: </mstyle> */
168: sibling = el; TtaNextSibling (&sibling);
169: if (!sibling)
170: {
171: sibling = el; TtaPreviousSibling (&sibling);
172: if (!sibling)
173: {
174: parent = TtaGetParent (el);
175: if (parent)
176: {
177: elType = TtaGetElementType (parent);
178: if (elType.ElTypeNum == MathML_EL_MSTYLE)
1.138 cvs 179: ret = FALSE;
1.1 cvs 180: }
1.138 cvs 181: }
1.1 cvs 182: }
1.138 cvs 183: }
1.1 cvs 184: return ret;
185: }
1.132 cvs 186:
1.1 cvs 187: /*----------------------------------------------------------------------
188: CreatePlaceholders
189: ----------------------------------------------------------------------*/
190: static void CreatePlaceholders (Element el, Document doc)
191: {
1.132 cvs 192: Element sibling, prev, constr, child;
193: Attribute attr;
194: ElementType elType;
195: AttributeType attrType;
196: ThotBool create, stretchableSubsup;
1.1 cvs 197:
1.55 cvs 198: if (!el)
199: return;
1.2 cvs 200: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 201: prev = NULL;
202: create = TRUE;
203: sibling = el;
204: while (sibling != NULL)
205: {
206: if (!ElementNeedsPlaceholder (sibling))
207: create = FALSE;
208: else
209: {
210: if (sibling == el)
211: /* first element */
212: {
213: elType = TtaGetElementType (sibling);
214: if (elType.ElTypeNum == MathML_EL_MF)
215: /* the first element is a MF. Don't create a placeholder
216: before */
217: create = FALSE;
218: else if (elType.ElTypeNum == MathML_EL_MROW)
219: /* the first element is a MROW */
220: {
221: child = TtaGetFirstChild (sibling);
222: if (child != NULL)
223: {
224: elType = TtaGetElementType (child);
225: if (elType.ElTypeNum != MathML_EL_MF)
226: /* the first child of the MROW element is not a MF */
227: /* Don't create a placeholder before */
228: create = FALSE;
229: }
230: }
231: }
232: if (create)
233: {
234: elType.ElTypeNum = MathML_EL_Construct;
235: constr = TtaNewElement (doc, elType);
236: TtaInsertSibling (constr, sibling, TRUE, doc);
237: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 238: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 239: attr = TtaNewAttribute (attrType);
240: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 241: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
242: constr, doc);
1.1 cvs 243: }
244: create = TRUE;
245: }
246: prev = sibling;
247: TtaNextSibling (&sibling);
248: }
249: if (prev != NULL && create)
250: {
1.132 cvs 251: stretchableSubsup = FALSE;
1.1 cvs 252: elType = TtaGetElementType (prev);
1.95 cvs 253: /* don't insert a placeholder after the last element if it's a MF */
254: if (elType.ElTypeNum == MathML_EL_MF)
1.1 cvs 255: create = FALSE;
256: else if (elType.ElTypeNum == MathML_EL_MROW)
257: /* the last element is a MROW */
258: {
259: child = TtaGetLastChild (prev);
260: if (child != NULL)
261: {
262: elType = TtaGetElementType (child);
263: if (elType.ElTypeNum != MathML_EL_MF)
264: /* the last child of the MROW element is not a MF */
265: /* Don't create a placeholder before */
266: create = FALSE;
267: }
268: }
1.132 cvs 269: else if (elType.ElTypeNum == MathML_EL_MSUBSUP ||
270: elType.ElTypeNum == MathML_EL_MSUB ||
271: elType.ElTypeNum == MathML_EL_MSUP ||
272: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
273: elType.ElTypeNum == MathML_EL_MUNDER ||
274: elType.ElTypeNum == MathML_EL_MUNDEROVER)
275: {
276: attrType.AttrSSchema = elType.ElSSchema;
277: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
278: if (TtaGetAttribute (prev, attrType))
279: stretchableSubsup = TRUE;
280: }
281:
1.1 cvs 282: if (create)
283: {
1.132 cvs 284: if (stretchableSubsup)
285: elType.ElTypeNum = MathML_EL_Construct1;
286: else
287: elType.ElTypeNum = MathML_EL_Construct;
1.1 cvs 288: constr = TtaNewElement (doc, elType);
289: TtaInsertSibling (constr, prev, FALSE, doc);
290: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 291: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 292: attr = TtaNewAttribute (attrType);
293: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 294: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
295: constr, doc);
1.132 cvs 296: }
1.1 cvs 297: }
298: }
299:
300: /*----------------------------------------------------------------------
1.95 cvs 301: NextNotComment
302: Return the next sibling of element el that is not an XMLcomment element.
303: Return el itself if it's not a comment.
1.1 cvs 304: ----------------------------------------------------------------------*/
1.95 cvs 305: static void NextNotComment (Element* el, Element* prev)
1.1 cvs 306: {
307: ElementType elType;
308:
309: if (*el == NULL)
310: return;
311: elType = TtaGetElementType (*el);
1.95 cvs 312: while (*el != NULL && elType.ElTypeNum == MathML_EL_XMLcomment)
1.1 cvs 313: {
314: *prev = *el;
315: TtaNextSibling (el);
316: if (*el != NULL)
317: elType = TtaGetElementType (*el);
318: }
319: }
320:
321: /*----------------------------------------------------------------------
322: CheckMathSubExpressions
323: Children of element el should be of type type1, type2, and type3.
1.56 cvs 324: If they are not, wrap them in elements of these types.
1.124 cvs 325: If element el has too many or not enough children, return FALSE.
1.1 cvs 326: ----------------------------------------------------------------------*/
1.56 cvs 327: static ThotBool CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
1.1 cvs 328: {
329: Element child, new, prev;
330: ElementType elType, childType;
1.124 cvs 331: char msgBuffer[200];
1.56 cvs 332: ThotBool result;
1.1 cvs 333:
1.56 cvs 334: result = TRUE;
1.2 cvs 335: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 336: child = TtaGetFirstChild (el);
337: prev = NULL;
1.95 cvs 338: NextNotComment (&child, &prev);
1.56 cvs 339: if (type1 == 0)
1.1 cvs 340: {
1.56 cvs 341: if (child)
342: /* no child expected and there is one, error */
1.124 cvs 343: {
344: sprintf (msgBuffer, "No subexpression allowed in %s",
345: TtaGetElementTypeName (TtaGetElementType (el)));
346: XmlParseError (errorParsing, msgBuffer, 0);
347: result = FALSE;
348: }
1.56 cvs 349: }
350: else
351: if (!child)
352: /* a first child is expected and it's missing */
1.124 cvs 353: {
354: sprintf (msgBuffer, "Missing subexpression in %s",
355: TtaGetElementTypeName (TtaGetElementType (el)));
356: XmlParseError (errorParsing, msgBuffer, 0);
357: result = FALSE;
358: }
1.56 cvs 359: else
360: {
1.1 cvs 361: elType.ElTypeNum = type1;
362: childType = TtaGetElementType (child);
363: if (TtaSameTypes (childType, elType) == 0)
364: {
365: TtaRemoveTree (child, doc);
366: new = TtaNewElement (doc, elType);
367: if (prev == NULL)
368: TtaInsertFirstChild (&new, el, doc);
369: else
370: TtaInsertSibling (new, prev, FALSE, doc);
371: TtaInsertFirstChild (&child, new, doc);
372: CreatePlaceholders (child, doc);
373: child = new;
374: }
1.56 cvs 375: prev = child;
376: TtaNextSibling (&child);
1.95 cvs 377: NextNotComment (&child, &prev);
1.56 cvs 378: if (type2 == 0)
379: {
380: if (child)
381: /* this second child is not expected, error */
1.124 cvs 382: {
383: sprintf (msgBuffer, "Only 1 subexpression allowed in %s",
384: TtaGetElementTypeName (TtaGetElementType (el)));
385: XmlParseError (errorParsing, msgBuffer, 0);
386: result = FALSE;
387: }
1.56 cvs 388: }
389: else
1.1 cvs 390: {
1.56 cvs 391: if (!child)
392: /* a second child is expected and it's missing */
1.124 cvs 393: {
394: sprintf (msgBuffer, "2 subexpressions required in %s",
395: TtaGetElementTypeName (TtaGetElementType (el)));
396: XmlParseError (errorParsing, msgBuffer, 0);
397: result = FALSE;
398: }
1.56 cvs 399: else
1.1 cvs 400: {
401: elType.ElTypeNum = type2;
402: childType = TtaGetElementType (child);
403: if (TtaSameTypes (childType, elType) == 0)
404: {
405: TtaRemoveTree (child, doc);
406: new = TtaNewElement (doc, elType);
407: TtaInsertSibling (new, prev, FALSE, doc);
408: TtaInsertFirstChild (&child, new, doc);
409: CreatePlaceholders (child, doc);
410: child = new;
411: }
1.56 cvs 412: prev = child;
413: TtaNextSibling (&child);
1.95 cvs 414: NextNotComment (&child, &prev);
1.56 cvs 415: if (type3 == 0)
1.1 cvs 416: {
1.56 cvs 417: if (child)
418: /* this third child is not expected, error */
1.124 cvs 419: {
420: sprintf (msgBuffer, "Only 2 subexpressions allowed in %s",
421: TtaGetElementTypeName (TtaGetElementType (el)));
422: XmlParseError (errorParsing, msgBuffer, 0);
423: result = FALSE;
424: }
1.56 cvs 425: }
426: else
427: {
428: if (!child)
429: /* a third child is expected and it's missing */
1.124 cvs 430: {
431: sprintf (msgBuffer, "3 subexpressions required in %s",
432: TtaGetElementTypeName (TtaGetElementType (el)));
433: XmlParseError (errorParsing, msgBuffer, 0);
434: result = FALSE;
435: }
1.56 cvs 436: else
1.1 cvs 437: {
438: elType.ElTypeNum = type3;
439: childType = TtaGetElementType (child);
440: if (TtaSameTypes (childType, elType) == 0)
441: {
442: TtaRemoveTree (child, doc);
443: new = TtaNewElement (doc, elType);
444: TtaInsertSibling (new, prev, FALSE, doc);
445: TtaInsertFirstChild (&child, new, doc);
446: CreatePlaceholders (child, doc);
1.56 cvs 447: child = new;
1.1 cvs 448: }
449: }
1.56 cvs 450: prev = child;
451: TtaNextSibling (&child);
1.95 cvs 452: NextNotComment (&child, &prev);
1.56 cvs 453: if (child)
454: /* this fourth child is unexpected */
1.124 cvs 455: {
456: sprintf (msgBuffer,"Only 3 subexpressions allowed in %s",
457: TtaGetElementTypeName (TtaGetElementType (el)));
458: XmlParseError (errorParsing, msgBuffer, 0);
459: result = FALSE;
460: }
1.1 cvs 461: }
462: }
463: }
1.56 cvs 464: }
465: return result;
1.1 cvs 466: }
467:
468: /*----------------------------------------------------------------------
1.22 cvs 469: SetSingleIntHorizStretchAttr
1.1 cvs 470:
1.22 cvs 471: Put a IntHorizStretch attribute on element el if it contains only
1.1 cvs 472: a MO element that is a stretchable symbol.
473: -----------------------------------------------------------------------*/
1.22 cvs 474: void SetSingleIntHorizStretchAttr (Element el, Document doc, Element* selEl)
1.1 cvs 475: {
476: Element child, sibling, textEl, symbolEl;
1.152 quint 477: ElementType elType, childType, siblingType;
1.1 cvs 478: Attribute attr;
479: AttributeType attrType;
1.55 cvs 480: Language lang;
1.128 vatton 481: CHAR_T text[2];
1.143 vatton 482: char script;
1.49 cvs 483: unsigned char c;
1.128 vatton 484: int len;
1.152 quint 485: ThotBool doit;
1.1 cvs 486:
487: if (el == NULL)
488: return;
489: child = TtaGetFirstChild (el);
1.154 vatton 490: textEl = NULL;
1.55 cvs 491: if (child)
1.1 cvs 492: {
493: elType = TtaGetElementType (child);
1.162 quint 494: /* skip empty Constructs (placeholders) and comments */
495: while (child &&
496: (elType.ElTypeNum == MathML_EL_Construct ||
497: elType.ElTypeNum == MathML_EL_XMLcomment) &&
498: !strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
1.152 quint 499: {
500: TtaNextSibling (&child);
501: if (child)
502: elType = TtaGetElementType (child);
503: }
1.162 quint 504: while (child && elType.ElTypeNum == MathML_EL_MROW &&
505: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
506: /* the first significant child is a mrow. Check whether it has a
507: single child */
1.98 cvs 508: {
509: child = TtaGetFirstChild (child);
510: if (child)
511: {
1.152 quint 512: elType = TtaGetElementType (child);
1.162 quint 513: /* skip empty Constructs (placeholders) and comments */
514: while (child &&
515: (elType.ElTypeNum == MathML_EL_Construct ||
516: elType.ElTypeNum == MathML_EL_XMLcomment) &&
517: !strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
1.152 quint 518: {
1.162 quint 519: TtaNextSibling (&child);
520: if (child)
521: elType = TtaGetElementType (child);
1.152 quint 522: }
1.98 cvs 523: sibling = child;
524: TtaNextSibling (&sibling);
1.152 quint 525: if (sibling)
526: /* there are other children */
527: {
528: siblingType = TtaGetElementType (sibling);
1.162 quint 529: while (sibling &&
530: (siblingType.ElTypeNum == MathML_EL_Construct ||
531: siblingType.ElTypeNum == MathML_EL_XMLcomment) &&
532: !strcmp (TtaGetSSchemaName (siblingType.ElSSchema), "MathML"))
533: /* its an empty construct (placeholder) or a comment, skip it*/
534: {
535: TtaNextSibling (&sibling);
536: if (sibling)
537: siblingType = TtaGetElementType (sibling);
538: }
1.152 quint 539: if (sibling)
1.162 quint 540: /* there are significant siblings */
1.152 quint 541: child = NULL;
542: }
1.98 cvs 543: }
544: }
1.152 quint 545: if (child && (elType.ElTypeNum == MathML_EL_MO ||
546: elType.ElTypeNum == MathML_EL_MOVER ||
547: elType.ElTypeNum == MathML_EL_MUNDER))
548: /* the first child is a MO, a MUNDER or a MOVER */
1.1 cvs 549: {
550: sibling = child;
551: TtaNextSibling (&sibling);
1.152 quint 552: if (sibling)
1.162 quint 553: siblingType = TtaGetElementType (sibling);
554: /* skip empty Constructs (placeholders) and comments */
555: while (sibling &&
556: (siblingType.ElTypeNum == MathML_EL_Construct ||
557: siblingType.ElTypeNum == MathML_EL_XMLcomment) &&
558: !strcmp (TtaGetSSchemaName (siblingType.ElSSchema), "MathML"))
1.152 quint 559: {
1.162 quint 560: TtaNextSibling (&sibling);
561: if (sibling)
562: siblingType = TtaGetElementType (sibling);
1.152 quint 563: }
1.1 cvs 564: if (sibling == NULL)
1.162 quint 565: /* there is no other significant child */
1.1 cvs 566: {
1.152 quint 567: c = EOS;
568: doit = FALSE;
569: attrType.AttrSSchema = elType.ElSSchema;
570: attrType.AttrTypeNum = MathML_ATTR_IntHorizStretch;
571:
572: if (elType.ElTypeNum == MathML_EL_MOVER ||
573: elType.ElTypeNum == MathML_EL_MUNDER)
574: /* check if the UnderOverBase has a IntHorizStretch attribute */
575: {
576: childType.ElTypeNum = MathML_EL_UnderOverBase;
577: textEl = TtaSearchTypedElement (childType, SearchInTree, child);
578: if (textEl)
579: {
580: if (TtaGetAttribute (textEl, attrType))
581: doit = TRUE;
582: }
583: }
584: else if (elType.ElTypeNum == MathML_EL_MO)
585: {
586: textEl = TtaGetFirstChild (child);
587: childType = TtaGetElementType (textEl);
588: if (childType.ElTypeNum == MathML_EL_TEXT_UNIT)
589: /* the MO child contains a TEXT element */
590: {
591: len = TtaGetElementVolume (textEl);
592: if (len == 1)
1.123 cvs 593: /* the TEXT element contains a single character */
594: {
1.152 quint 595: /* get that character */
596: len = 2;
597: TtaGiveBufferContent (textEl, text, len, &lang);
598: script = TtaGetScript (lang);
599: if (
1.146 quint 600: #ifndef _I18N_
1.152 quint 601: (script == 'L') &&
1.146 quint 602: #endif
1.152 quint 603: (text[0] == '-' || text[0] == '_' ||
604: text[0] == 175))
1.146 quint 605: /* a horizontal line in the middle of the box */
606: c = 'h';
1.152 quint 607: else
608: #ifdef _I18N_
609: if (text[0] == 0x2190)
610: c = 'L'; /* arrow left */
611: else if (text[0] == 0x2192)
612: c = 'R'; /* arrow right */
1.153 quint 613: else if (text[0] == 45) /* - (minus) */
614: /* a horizontal line in the middle of the box */
615: c = 'h';
616: else if (text[0] == 0x2212) /* - (minus) */
1.152 quint 617: /* a horizontal line in the middle of the box */
618: c = 'h';
619: else if (text[0] == 0x0332) /* UnderBar */
620: /* a horizontal line */
621: c = 'h';
622: else if (text[0] == 65079)
623: c = 'o'; /* Over brace */
624: else if (text[0] == 65080)
625: c = 'u'; /* Under brace */
1.146 quint 626: #else
627: if (script == 'G')
628: /* a single Symbol character */
629: {
630: if (text[0] == 172)
631: c = 'L'; /* arrow left */
632: else if (text[0] == 174)
633: c = 'R'; /* arrow right */
634: else if (text[0] == 45) /* - (minus) */
635: /* a horizontal line in the middle of the box */
636: c = 'h';
637: else if (text[0] == 132)
638: c = 'o'; /* Over brace */
639: else if (text[0] == 133)
640: c = 'u'; /* Under brace */
641: }
642: #endif
1.152 quint 643: if (c != EOS)
644: doit = TRUE;
1.123 cvs 645: }
1.152 quint 646: }
647: }
648: if (doit)
649: {
650: /* attach a IntHorizStretch attribute to the element
651: (UnderOverBase, Underscript, or Overscript) */
652: attr = TtaNewAttribute (attrType);
653: TtaAttachAttribute (el, attr, doc);
654: TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, el, doc);
655: attr = TtaNewAttribute (attrType);
656: TtaAttachAttribute (child, attr, doc);
657: TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, child, doc);
658: }
659: if (c != EOS)
660: {
661: /* replace the TEXT element by a Thot SYMBOL element */
662: childType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
663: symbolEl = TtaNewElement (doc, childType);
664: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
665: if (selEl != NULL)
666: if (*selEl == textEl)
667: *selEl = symbolEl;
668: TtaDeleteTree (textEl, doc);
669: if (c != EOS)
670: TtaSetGraphicsShape (symbolEl, c, doc);
671: }
1.1 cvs 672: }
673: }
674: }
675: }
1.162 quint 676:
1.1 cvs 677: /*----------------------------------------------------------------------
1.22 cvs 678: SetIntHorizStretchAttr
1.1 cvs 679:
1.152 quint 680: Put a IntHorizStretch attribute on all children of element el that
1.1 cvs 681: contain only a MO element that is a stretchable symbol.
682: -----------------------------------------------------------------------*/
1.22 cvs 683: static void SetIntHorizStretchAttr (Element el, Document doc)
1.1 cvs 684: {
685: Element child;
686:
687: if (el == NULL)
688: return;
689: child = TtaGetFirstChild (el);
690: while (child != NULL)
691: {
1.22 cvs 692: SetSingleIntHorizStretchAttr (child, doc, NULL);
1.1 cvs 693: TtaNextSibling (&child);
694: }
695: }
696:
697: /*----------------------------------------------------------------------
1.22 cvs 698: SetIntVertStretchAttr
1.1 cvs 699:
1.22 cvs 700: Put a IntVertStretch attribute on element el if its base element
1.1 cvs 701: (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
702: a MUNDER of a MOVER) contains only a MO element that is a vertically
1.162 quint 703: stretchable symbol (integral, vertical arrow, etc).
1.1 cvs 704: -----------------------------------------------------------------------*/
1.22 cvs 705: void SetIntVertStretchAttr (Element el, Document doc, int base, Element* selEl)
1.1 cvs 706: {
1.132 cvs 707: Element child, sibling, textEl, symbolEl, parent, operator, next;
1.1 cvs 708: ElementType elType;
709: Attribute attr;
710: AttributeType attrType;
1.131 cvs 711: SSchema MathMLSSchema;
1.128 vatton 712: Language lang;
1.143 vatton 713: char script;
1.131 cvs 714: #define buflen 50
715: CHAR_T text[buflen];
1.49 cvs 716: unsigned char c;
1.131 cvs 717: int len, i;
1.162 quint 718: ThotBool inbase, stretchable;
1.1 cvs 719:
720: if (el == NULL)
1.131 cvs 721: return;
1.1 cvs 722: operator = NULL;
1.131 cvs 723: inbase = FALSE;
724: MathMLSSchema = TtaGetElementType(el).ElSSchema;
1.154 vatton 725: symbolEl = parent = NULL;
1.1 cvs 726: if (base == 0)
1.131 cvs 727: /* it's a MO */
728: {
729: parent = TtaGetParent (el);
730: if (parent != NULL)
1.1 cvs 731: {
1.131 cvs 732: /* don't process the mo if it is within a base. It will be processed
733: when the enclosing construct is processed (see below) */
734: elType = TtaGetElementType (parent);
735: if (elType.ElSSchema != MathMLSSchema ||
736: (elType.ElTypeNum != MathML_EL_Base &&
737: elType.ElTypeNum != MathML_EL_UnderOverBase &&
738: elType.ElTypeNum != MathML_EL_MSUBSUP &&
739: elType.ElTypeNum != MathML_EL_MSUB &&
740: elType.ElTypeNum != MathML_EL_MSUP &&
741: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
742: elType.ElTypeNum != MathML_EL_MUNDER &&
1.162 quint 743: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
744: elType.ElTypeNum != MathML_EL_MTD))
1.131 cvs 745: operator = el;
1.1 cvs 746: }
1.131 cvs 747: }
1.1 cvs 748: else
1.131 cvs 749: /* it's not a MO */
750: {
751: /* search the Base or UnderOverBase child */
752: child = TtaGetFirstChild (el);
753: if (child != NULL)
1.1 cvs 754: {
1.131 cvs 755: elType = TtaGetElementType (child);
1.162 quint 756: /* skip empty Constructs (placeholders) and comments */
757: while (child &&
758: (elType.ElTypeNum == MathML_EL_Construct ||
759: elType.ElTypeNum == MathML_EL_XMLcomment) &&
760: elType.ElSSchema == MathMLSSchema)
761: {
762: TtaNextSibling (&child);
763: if (child)
764: elType = TtaGetElementType (child);
765: }
766:
1.131 cvs 767: if (elType.ElTypeNum == base && elType.ElSSchema == MathMLSSchema)
768: /* the first child is a Base or UnderOverBase */
769: {
770: child = TtaGetFirstChild (child);
771: if (child != NULL)
772: {
773: elType = TtaGetElementType (child);
1.162 quint 774: /* skip empty Constructs (placeholders) and comments */
775: while (child &&
776: (elType.ElTypeNum == MathML_EL_Construct ||
777: elType.ElTypeNum == MathML_EL_XMLcomment) &&
778: elType.ElSSchema == MathMLSSchema)
779: {
780: TtaNextSibling (&child);
781: if (child)
782: elType = TtaGetElementType (child);
783: }
784:
1.131 cvs 785: if (elType.ElTypeNum == MathML_EL_MO &&
786: elType.ElSSchema == MathMLSSchema)
1.162 quint 787: /* its first significant child is a MO */
1.131 cvs 788: {
789: sibling = child;
790: TtaNextSibling (&sibling);
1.162 quint 791: /* skip empty Constructs (placeholders) and comments */
792: while (sibling &&
793: (elType.ElTypeNum == MathML_EL_Construct ||
794: elType.ElTypeNum == MathML_EL_XMLcomment) &&
795: elType.ElSSchema == MathMLSSchema)
796: {
797: TtaNextSibling (&sibling);
798: if (sibling)
799: elType = TtaGetElementType (sibling);
800: }
801:
1.131 cvs 802: if (sibling == NULL)
1.162 quint 803: /* there is no other significant child */
1.131 cvs 804: {
805: operator = child;
806: if (base == MathML_EL_Base ||
807: base == MathML_EL_UnderOverBase)
808: {
809: parent = el;
810: inbase = TRUE;
811: }
812: }
813: }
814: }
815: }
1.1 cvs 816: }
1.131 cvs 817: }
818: if (operator)
819: {
820: textEl = TtaGetFirstChild (operator);
821: if (textEl != NULL)
1.84 cvs 822: {
1.131 cvs 823: elType = TtaGetElementType (textEl);
824: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
825: {
1.146 quint 826: len = TtaGetElementVolume (textEl);
1.131 cvs 827: if (len >= 1)
828: {
829: if (len >= buflen)
830: len = buflen-1;
1.146 quint 831: TtaGiveBufferContent (textEl, text, len+1, &lang);
1.143 vatton 832: script = TtaGetScript (lang);
1.146 quint 833: #ifdef _I18N_
1.162 quint 834: stretchable = TRUE;
1.146 quint 835: for (i = 0; i < len; i++)
1.162 quint 836: if ((text[i] < 0x222B || text[i] > 0x2233) &&
837: text[i] != 0x2191 && text[i] != 0x2193 &&
838: text[i] != 0x2195 &&
839: text[i] != 0x21D1 && text[i] != 0x21D3 &&
840: text[i] != 0x21D5)
1.146 quint 841: /* accept only symbols like simple integral, double or
1.162 quint 842: triple integral, contour integral, etc. or vertical
843: arrows (add more arrows *****) */
844: stretchable = FALSE;
1.146 quint 845: #else
1.162 quint 846: stretchable = FALSE;
1.143 vatton 847: if (script == 'G')
1.131 cvs 848: /* Adobe Symbol character set */
1.55 cvs 849: {
1.162 quint 850: stretchable = TRUE;
1.131 cvs 851: /* check all characters in this TEXT element */
852: for (i = 0; i < len; i++)
1.162 quint 853: if (text[i] != 242 && /* integral */
854: text[i] != 173 && text[i] != 175 && /* arrows */
855: text[i] != 221 && text[i] != 223) /* double arrows */
1.131 cvs 856: /**** accept also other symbols like double or triple
857: integral, contour integral, etc. ****/
1.162 quint 858: stretchable = FALSE;
1.146 quint 859: }
860: #endif
1.162 quint 861: if (stretchable)
862: /* the operator contains only stretchable symbols */
1.146 quint 863: {
864: /* attach a IntVertStretch attribute */
865: attrType.AttrSSchema = MathMLSSchema;
866: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
867: attr = TtaNewAttribute (attrType);
868: TtaAttachAttribute (el, attr, doc);
869: TtaSetAttributeValue (attr,
1.131 cvs 870: MathML_ATTR_IntVertStretch_VAL_yes_,
871: el, doc);
1.146 quint 872: TtaRegisterAttributeCreate (attr, el, doc);
873:
1.162 quint 874: /* replace the stretchable characters by a Thot SYMBOL
1.146 quint 875: element. If there are several such characters in
1.162 quint 876: the mo (multiple integral for instance), replace
877: them too. */
1.146 quint 878: do
879: {
880: /* replace the TEXT element by a Thot SYMBOL */
1.162 quint 881: elType.ElSSchema = MathMLSSchema;
1.146 quint 882: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
883: for (i = 0; i < len; i++)
1.162 quint 884: {
885: if (selEl != NULL)
886: if (*selEl == textEl)
887: *selEl = symbolEl;
1.146 quint 888: #ifdef _I18N_
1.162 quint 889: if (text[i] == 0x222B)
890: c = 'i';
891: else if (text[i] == 0x222C)
892: c = 'd';
893: else if (text[i] == 0x222D)
894: c = 't';
895: else if (text[i] == 0x222E)
896: c = 'c';
897: else if (text[i] == 0x2191)
898: c = '^';
899: else if (text[i] == 0x2193)
900: c = 'V';
1.146 quint 901: #else
1.162 quint 902: if (text[i] == 242)
903: c = 'i';
904: else if (text[i] == 173)
905: c = '<';
906: else if (text[i] == 175)
907: c = '>';
1.146 quint 908: #endif
1.162 quint 909: symbolEl = TtaNewElement (doc, elType);
910: TtaInsertSibling (symbolEl, textEl, TRUE,doc);
911: TtaSetGraphicsShape (symbolEl, c, doc);
912: TtaRegisterElementCreate (symbolEl, doc);
913: }
1.146 quint 914: TtaRegisterElementDelete (textEl, doc);
915: TtaDeleteTree (textEl, doc);
916: /* is there an other text element after the
1.162 quint 917: stretchable symbol? */
1.146 quint 918: textEl = symbolEl; TtaNextSibling (&textEl);
919: if (textEl)
920: {
921: elType = TtaGetElementType (textEl);
922: if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
923: textEl = NULL;
924: else
925: /* there is another text element.
1.162 quint 926: Is it a single stretchable symbol? */
1.146 quint 927: {
928: len = TtaGetElementVolume (textEl);
929: if (len < 1)
930: /* not a single character */
931: textEl = NULL;
932: else
933: {
934: if (len >= buflen)
935: len = buflen-1;
936: TtaGiveBufferContent (textEl, text,
937: len+1, &lang);
938: script = TtaGetScript (lang);
939: #ifdef _I18N_
1.164 quint 940: if (text[0] != 0x222B &&
941: text[0] != 0x222C &&
942: text[0] != 0x222D &&
943: text[0] != 0x222E &&
944: text[0] != 0x2191 &&
945: text[0] != 0x2193)
1.146 quint 946: #else
1.162 quint 947: if (script != 'G' ||
1.164 quint 948: (text[0] != 242 && text[0] != 173 &&
949: text[0] != 175))
1.146 quint 950: #endif
1.162 quint 951: /* not a stretchable symbol */
1.146 quint 952: textEl = NULL;
953: }
954: }
955: }
956: }
957: while (textEl);
958:
959: if (inbase)
960: /* it's within a Base or UnderOverBase element */
961: {
962: sibling = parent;
963: TtaNextSibling (&sibling);
964: if (sibling)
965: /* the msubsup of munderover element has a next
966: sibling */
967: {
968: elType = TtaGetElementType (sibling);
969: if (elType.ElTypeNum == MathML_EL_Construct &&
970: elType.ElSSchema == MathMLSSchema)
971: /* the next sibling is a Construct */
972: {
973: next = sibling;
974: TtaNextSibling (&next);
975: if (!next)
976: /* there is no other sibling after the
977: Construct. Change it into Construct1*/
978: {
979: TtaRegisterElementDelete (sibling, doc);
980: TtaRemoveTree (sibling, doc);
981: ChangeElementType (sibling,
1.132 cvs 982: MathML_EL_Construct1);
1.146 quint 983: TtaInsertSibling (sibling, parent,
984: FALSE, doc);
985: TtaRegisterElementCreate (sibling, doc);
986: /* force the msubsup element to be
987: reformatted and to take into account
988: its new next sibling */
989: TtaRemoveTree (parent, doc);
990: TtaInsertSibling (parent, sibling, TRUE,
991: doc);
992: }
993: }
994: }
995: }
1.55 cvs 996: }
1.131 cvs 997: }
998: }
1.84 cvs 999: }
1.131 cvs 1000: }
1.1 cvs 1001: }
1002:
1003: /*----------------------------------------------------------------------
1.22 cvs 1004: SetIntPlaceholderAttr
1.1 cvs 1005:
1.22 cvs 1006: Put a IntPlaceholder attribute on all Construct elements in the
1.1 cvs 1007: subtree of root el.
1008: -----------------------------------------------------------------------*/
1.22 cvs 1009: static void SetIntPlaceholderAttr (Element el, Document doc)
1.1 cvs 1010: {
1011: Element child;
1012: ElementType elType;
1013: Attribute attr;
1014: AttributeType attrType;
1015:
1016: if (el == NULL)
1017: return;
1018: elType = TtaGetElementType (el);
1019: if (elType.ElTypeNum == MathML_EL_Construct &&
1.2 cvs 1020: elType.ElSSchema == GetMathMLSSchema (doc))
1.1 cvs 1021: {
1022: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 1023: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 1024: attr = TtaNewAttribute (attrType);
1025: TtaAttachAttribute (el, attr, doc);
1.22 cvs 1026: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, el, doc);
1.1 cvs 1027: }
1028: else
1029: {
1030: child = TtaGetFirstChild (el);
1031: while (child != NULL)
1032: {
1.22 cvs 1033: SetIntPlaceholderAttr (child, doc);
1.1 cvs 1034: TtaNextSibling (&child);
1035: }
1036: }
1037: }
1038:
1039: /*----------------------------------------------------------------------
1040: BuildMultiscript
1041:
1042: The content of a MMULTISCRIPT element has been created following
1043: the original MathML structure. Create all Thot elements defined
1044: in the MathML S schema.
1045: -----------------------------------------------------------------------*/
1046: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
1047: {
1048: Element elem, base, next, group, pair, script, prevPair, prevScript;
1049: ElementType elType, elTypeGroup, elTypePair, elTypeScript;
1.2 cvs 1050: SSchema MathMLSSchema;
1.1 cvs 1051: base = NULL;
1052: group = NULL;
1053: prevPair = NULL;
1054: prevScript = NULL;
1055:
1.2 cvs 1056: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 1057: elTypeGroup.ElSSchema = MathMLSSchema;
1058: elTypePair.ElSSchema = MathMLSSchema;
1059: elTypeScript.ElSSchema = MathMLSSchema;
1060:
1061: /* process all children of the MMULTISCRIPT element */
1062: elem = TtaGetFirstChild (elMMULTISCRIPT);
1063: while (elem != NULL)
1064: {
1065: /* remember the element to be processed after the current one */
1066: next = elem;
1067: TtaNextSibling (&next);
1068:
1069: /* remove the current element from the tree */
1070: TtaRemoveTree (elem, doc);
1071:
1072: if (base == NULL)
1073: /* the current element is the first child of the MMULTISCRIPT
1074: element */
1075: {
1076: /* Create a MultiscriptBase element as the first child of
1077: MMULTISCRIPT and move the current element as the first child
1078: of the MultiscriptBase element */
1079: elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
1080: base = TtaNewElement (doc, elTypeGroup);
1081: TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
1082: TtaInsertFirstChild (&elem, base, doc);
1083: }
1084: else
1085: /* the current element is a subscript or a superscript */
1086: {
1087: if (group == NULL)
1088: /* there is no PostscriptPairs element. Create one */
1089: {
1090: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1091: group = TtaNewElement (doc, elTypeGroup);
1092: TtaInsertSibling (group, base, FALSE, doc);
1093: elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
1094: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1095: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1096: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1097: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1098: prevPair = pair;
1.47 cvs 1099: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1100: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1101: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1102: prevScript = NULL;
1103: }
1104: if (prevScript == NULL)
1105: /* the current element is the first subscript or superscript
1106: in a pair */
1107: {
1108: /* create a PostscriptPair or PrescriptPair element */
1109: pair = TtaNewElement (doc, elTypePair);
1110: if (prevPair == NULL)
1111: TtaInsertFirstChild (&pair, group, doc);
1112: else
1113: TtaInsertSibling (pair, prevPair, FALSE, doc);
1114: prevPair = pair;
1115: /* create a MSubscript element */
1116: elTypeScript.ElTypeNum = MathML_EL_MSubscript;
1117: script = TtaNewElement (doc, elTypeScript);
1118: TtaInsertFirstChild (&script, pair, doc);
1119: prevScript = script;
1120: }
1121: else
1122: /* the current element is a superscript in a pair */
1123: {
1124: /* create a MSuperscript element */
1125: elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
1126: script = TtaNewElement (doc, elTypeScript);
1127: /* insert it as a sibling of the previous MSubscript element */
1128: TtaInsertSibling (script, prevScript, FALSE, doc);
1129: prevScript = NULL;
1130: }
1131: /* insert the current element as a child of the new MSuperscript or
1132: MSubscript element */
1133: TtaInsertFirstChild (&elem, script, doc);
1.22 cvs 1134: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1135: }
1136:
1137: CreatePlaceholders (elem, doc);
1138:
1139: /* get next child of the MMULTISCRIPT element */
1140: elem = next;
1141: if (elem != NULL)
1142: {
1143: elType = TtaGetElementType (elem);
1144: if (elType.ElSSchema == MathMLSSchema &&
1145: elType.ElTypeNum == MathML_EL_PrescriptPairs)
1146: /* the next element is a PrescriptPairs */
1147: {
1148: /* if there there is no PostscriptPairs element, create one as a
1149: placeholder */
1150: if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
1151: {
1152: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1.47 cvs 1153: group = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1154: TtaInsertSibling (group, elem, TRUE, doc);
1.22 cvs 1155: SetIntPlaceholderAttr (group, doc);
1.1 cvs 1156: }
1157: /* the following elements will be interpreted as sub- superscripts
1158: in PrescriptPair elements, wich will be children of this
1159: PrescriptPairs element */
1160: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1161: elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
1162: group = elem;
1163: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1164: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1165: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1166: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1167: prevPair = pair;
1.47 cvs 1168: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1169: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1170: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1171: prevScript = NULL;
1172: TtaNextSibling (&elem);
1173: }
1174: }
1175: }
1176: /* all children of element MMULTISCRIPTS have been processed */
1177: /* if the last group processed is not a PrescriptPairs element,
1178: create one as a placeholder */
1179: if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
1180: {
1181: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1.47 cvs 1182: elem = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1183: if (group == NULL)
1184: group = base;
1185: TtaInsertSibling (elem, group, TRUE, doc);
1.22 cvs 1186: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1187: }
1188: }
1189:
1.39 cvs 1190: /*----------------------------------------------------------------------
1191: CreateWrapper
1192:
1193: Create an element of type wrapperType as a child of element el and
1194: move all chidren of element el within the new element.
1195: -----------------------------------------------------------------------*/
1196: static void CreateWrapper (Element el, int wrapperType, Document doc)
1197: {
1198: Element wrapper, child, prevChild, nextChild;
1199: ElementType elType;
1200:
1201: child = TtaGetFirstChild (el);
1202: elType.ElSSchema = GetMathMLSSchema (doc);
1203: elType.ElTypeNum = wrapperType;
1204: wrapper = TtaNewElement (doc, elType);
1205: TtaInsertFirstChild (&wrapper, el, doc);
1206: prevChild = NULL;
1207: while (child)
1208: {
1209: nextChild = child;
1210: TtaNextSibling (&nextChild);
1211: TtaRemoveTree (child, doc);
1212: if (prevChild == NULL)
1213: TtaInsertFirstChild (&child, wrapper, doc);
1214: else
1215: TtaInsertSibling (child, prevChild, FALSE, doc);
1216: prevChild = child;
1217: child = nextChild;
1218: }
1219: }
1.5 cvs 1220:
1221: /*----------------------------------------------------------------------
1222: CheckMTable
1223:
1224: The content of a MTABLE element has been created following
1225: the original MathML structure. Create all Thot elements defined
1226: in the MathML S schema.
1.64 cvs 1227: If placeholder, associate an attribute IntPlaceholder with all
1.103 cvs 1228: cells generated in the MathML table.
1.5 cvs 1229: -----------------------------------------------------------------------*/
1.64 cvs 1230: void CheckMTable (Element elMTABLE, Document doc, ThotBool placeholder)
1.5 cvs 1231: {
1232: ElementType elType;
1233: Element MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
1.103 cvs 1234: nextCell, newMTD, firstColHead, label;
1.5 cvs 1235: SSchema MathMLSSchema;
1236:
1237: MathMLSSchema = GetMathMLSSchema (doc);
1238: row = TtaGetFirstChild (elMTABLE);
1239:
1240: /* create a MTable_head as the first child of element MTABLE */
1241: elType.ElSSchema = MathMLSSchema;
1242: elType.ElTypeNum = MathML_EL_MTable_head;
1243: MTableHead = TtaNewElement (doc, elType);
1244: TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
1245: elType.ElTypeNum = MathML_EL_MColumn_head;
1.47 cvs 1246: firstColHead = TtaNewTree (doc, elType, "");
1.5 cvs 1247: TtaInsertFirstChild (&firstColHead, MTableHead, doc);
1248:
1249: /* create a MTable_body */
1250: elType.ElTypeNum = MathML_EL_MTable_body;
1251: MTableBody = TtaNewElement (doc, elType);
1252: TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
1253:
1254: /* move all children of element MTABLE into the new MTable_body element
1.103 cvs 1255: and wrap each non-MTR element in a MTR, except comments */
1.5 cvs 1256: prevRow = NULL;
1257: while (row)
1258: {
1259: nextRow = row;
1260: TtaNextSibling (&nextRow);
1261: elType = TtaGetElementType (row);
1262: TtaRemoveTree (row, doc);
1263: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1264: (elType.ElTypeNum == MathML_EL_XMLcomment ||
1.101 cvs 1265: elType.ElTypeNum == MathML_EL_MTR ||
1266: elType.ElTypeNum == MathML_EL_MLABELEDTR))
1.5 cvs 1267: {
1268: if (prevRow == NULL)
1269: TtaInsertFirstChild (&row, MTableBody, doc);
1270: else
1271: TtaInsertSibling (row, prevRow, FALSE, doc);
1272: prevRow = row;
1.101 cvs 1273: if (elType.ElTypeNum == MathML_EL_MTR ||
1274: elType.ElTypeNum == MathML_EL_MLABELEDTR)
1.103 cvs 1275: {
1.5 cvs 1276: cell = TtaGetFirstChild (row);
1.103 cvs 1277: if (elType.ElTypeNum == MathML_EL_MLABELEDTR)
1278: /* skip the first significant child of the mlabeledtr element */
1279: {
1280: /* skip comments first */
1281: do
1282: {
1283: elType = TtaGetElementType (cell);
1284: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1285: elType.ElTypeNum == MathML_EL_XMLcomment)
1286: TtaNextSibling (&cell);
1287: }
1288: while (cell && elType.ElTypeNum == MathML_EL_XMLcomment);
1289: /* skip the first element after the comments: it's a label */
1290: if (cell)
1291: {
1.105 cvs 1292: /* if it's a MTD change its type into LabelCell */
1293: if (elType.ElTypeNum == MathML_EL_MTD &&
1294: elType.ElSSchema == MathMLSSchema)
1295: ChangeElementType (cell, MathML_EL_LabelCell);
1.103 cvs 1296: /* wrap this element in a RowLabel element */
1.105 cvs 1297: /* This will allow the P schema to specify the horizontal
1298: position of the label */
1.103 cvs 1299: elType.ElSSchema = MathMLSSchema;
1300: elType.ElTypeNum = MathML_EL_RowLabel;
1301: label = TtaNewElement (doc, elType);
1302: TtaInsertSibling (label, cell, TRUE, doc);
1303: TtaRemoveTree (cell, doc);
1304: TtaInsertFirstChild (&cell, label, doc);
1305: cell = label;
1306: TtaNextSibling (&cell);
1307: }
1308: }
1309: }
1.5 cvs 1310: else
1311: cell = NULL;
1312: }
1313: else
1.103 cvs 1314: /* this child is not a MTR, MLABELEDTR, or a comment.
1315: In MathML 2.0, this in an error, but we try to recover by
1316: creating a MTR element */
1.5 cvs 1317: {
1318: elType.ElSSchema = MathMLSSchema;
1319: elType.ElTypeNum = MathML_EL_MTR;
1320: el = TtaNewElement (doc, elType);
1321: if (prevRow == NULL)
1322: TtaInsertFirstChild (&el, MTableBody, doc);
1323: else
1324: TtaInsertSibling (el, prevRow, FALSE, doc);
1325: TtaInsertFirstChild (&row, el, doc);
1326: cell = row;
1327: prevRow = el;
1328: }
1329: while (cell)
1330: /* check all children of the current MTR element */
1331: {
1332: nextCell = cell;
1333: TtaNextSibling (&nextCell);
1334: elType = TtaGetElementType (cell);
1335: if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
1336: (elType.ElTypeNum != MathML_EL_XMLcomment &&
1337: elType.ElTypeNum != MathML_EL_MTD))
1338: /* this is not a MTD nor a comment, create a wrapping MTD */
1339: {
1340: elType.ElSSchema = MathMLSSchema;
1341: elType.ElTypeNum = MathML_EL_MTD;
1342: newMTD = TtaNewElement (doc, elType);
1343: TtaInsertSibling (newMTD, cell, TRUE, doc);
1344: TtaRemoveTree (cell, doc);
1345: TtaInsertFirstChild (&cell, newMTD, doc);
1346: cell = newMTD;
1347: }
1348: if (elType.ElTypeNum == MathML_EL_MTD)
1349: /* This is a MTD element. Wrap its contents with a CellWrapper */
1.162 quint 1350: {
1351: CreateWrapper (cell, MathML_EL_CellWrapper, doc);
1352: SetIntHorizStretchAttr (cell, doc);
1353: SetIntVertStretchAttr (cell, doc, MathML_EL_CellWrapper, NULL);
1354: }
1.5 cvs 1355: cell = nextCell;
1356: }
1357: row = nextRow;
1358: }
1.107 cvs 1359: CheckAllRows (elMTABLE, doc, placeholder, FALSE);
1.5 cvs 1360: }
1.12 cvs 1361:
1.46 cvs 1362: /*----------------------------------------------------------------------
1.1 cvs 1363: SetFontstyleAttr
1364: The content of a MI element has been created or modified.
1365: Create or change attribute IntFontstyle for that element accordingly.
1366: -----------------------------------------------------------------------*/
1367: void SetFontstyleAttr (Element el, Document doc)
1368: {
1369: ElementType elType;
1.157 quint 1370: AttributeType attrType, attrType1;
1.1 cvs 1371: Attribute attr, IntAttr;
1.157 quint 1372: Element ancestor, textEl;
1.1 cvs 1373: int len;
1.163 quint 1374: Language lang;
1375: #ifndef _I18N_
1376: char script;
1.166 quint 1377: char *value;
1.163 quint 1378: #endif
1.166 quint 1379: CHAR_T text[2];
1.54 cvs 1380: ThotBool italic;
1.1 cvs 1381:
1382: if (el != NULL)
1.142 quint 1383: {
1.157 quint 1384: /* search the (deprecated) fontstyle attribute or the mathvariant
1385: attribute on the element and its ancestors */
1.142 quint 1386: elType = TtaGetElementType (el);
1387: attrType.AttrSSchema = elType.ElSSchema;
1388: attrType.AttrTypeNum = MathML_ATTR_fontstyle;
1.157 quint 1389: attrType1.AttrSSchema = elType.ElSSchema;
1390: attrType1.AttrTypeNum = MathML_ATTR_mathvariant;
1391: ancestor = el;
1392: attr = NULL;
1393: do
1394: {
1395: attr = TtaGetAttribute (ancestor, attrType);
1396: if (!attr)
1397: attr = TtaGetAttribute (ancestor, attrType1);
1398: if (!attr)
1399: {
1400: ancestor = TtaGetParent (ancestor);
1401: if (ancestor)
1402: {
1403: elType = TtaGetElementType (ancestor);
1404: if (elType.ElSSchema != attrType.AttrSSchema)
1405: /* this ancestor is not in the MathML namespace */
1406: ancestor = NULL;
1407: }
1408: }
1409: }
1410: while (ancestor && !attr);
1411:
1.142 quint 1412: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1413: IntAttr = TtaGetAttribute (el, attrType);
1414: if (attr != NULL)
1.157 quint 1415: /* there is a fontstyle or mathvariant attribute. Remove the
1416: IntFontstyle internal attribute that is not needed */
1.1 cvs 1417: {
1.142 quint 1418: if (IntAttr != NULL)
1419: TtaRemoveAttribute (el, IntAttr, doc);
1.1 cvs 1420: }
1.142 quint 1421: else
1.157 quint 1422: /* there is no fontstyle or mathvariant attribute. Create an internal
1423: IntFontstyle attribute with a value that depends on the content of
1424: the MI element */
1.1 cvs 1425: {
1.142 quint 1426: /* get content length */
1427: len = TtaGetElementVolume (el);
1428: if (len > 1)
1429: /* put an attribute IntFontstyle = IntNormal */
1430: {
1431: if (IntAttr == NULL)
1432: {
1433: IntAttr = TtaNewAttribute (attrType);
1434: TtaAttachAttribute (el, IntAttr, doc);
1435: }
1436: TtaSetAttributeValue (IntAttr,
1437: MathML_ATTR_IntFontstyle_VAL_IntNormal,
1438: el, doc);
1439: }
1440: else
1441: /* MI contains a single character. Remove attribute IntFontstyle
1442: if it exists, except if it's ImaginaryI, ExponentialE or
1443: DifferentialD */
1444: {
1445: italic = TRUE;
1446: textEl = TtaGetFirstChild (el);
1447: if (textEl != NULL)
1448: {
1449: elType = TtaGetElementType (textEl);
1450: if (elType.ElTypeNum == MathML_EL_MGLYPH)
1451: /* the content of the MI element is a MGLYPH element */
1452: /* check the length if it's alt attribute */
1453: {
1454: /* by default, use normal style */
1455: italic = FALSE;
1456: attrType.AttrTypeNum = MathML_ATTR_alt;
1457: attr = TtaGetAttribute (textEl, attrType);
1458: if (attr)
1459: /* the MGLYPH element has an alt attribute */
1460: {
1461: len = TtaGetTextAttributeLength (attr);
1462: if (len == 1)
1463: italic = TRUE;
1464: }
1465: }
1.163 quint 1466: else if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1.142 quint 1467: {
1.166 quint 1468: len = TtaGetElementVolume (textEl);
1.163 quint 1469: if (len == 1)
1.166 quint 1470: /* the TEXT element contains a single character */
1.163 quint 1471: {
1.166 quint 1472: /* get that character */
1473: len = 2;
1474: TtaGiveBufferContent (textEl, text, len, &lang);
1.163 quint 1475: #ifndef _I18N_
1476: script = TtaGetScript (lang);
1477: #endif
1478: if (
1479: #ifndef _I18N_
1480: script == 'L' &&
1481: #endif
1482: text[0] >= '0' && text[0] <= '9')
1.166 quint 1483: /* that's a single digit */
1.163 quint 1484: italic = FALSE;
1.166 quint 1485: else
1486: #ifdef _I18N_
1487: /* is this the Unicode character for DifferentialD,
1488: ExponentialE or ImaginaryI? */
1489: if (text[0] == 0x2146 || text[0] == 0x2147 ||
1490: text[0] == 0x2148)
1491: italic = FALSE;
1492: #else
1.142 quint 1493: {
1.166 quint 1494: /* is there an attribute EntityName on that
1495: character? */
1496: attrType.AttrTypeNum = MathML_ATTR_EntityName;
1497: attr = TtaGetAttribute (textEl, attrType);
1498: if (attr)
1499: {
1500: len = TtaGetTextAttributeLength (attr);
1501: if (len > 0)
1502: {
1503: value = TtaGetMemory (len+1);
1504: TtaGiveTextAttributeValue (attr, value, &len);
1505: if (strcmp (&value[1], "ImaginaryI;") == 0 ||
1506: strcmp (&value[1], "ExponentialE;") == 0 ||
1507: strcmp (&value[1], "DifferentialD;") == 0)
1508: italic = FALSE;
1509: TtaFreeMemory (value);
1510: }
1511: }
1.142 quint 1512: }
1.166 quint 1513: #endif
1.142 quint 1514: }
1515: }
1516: if (italic)
1517: {
1518: if (IntAttr != NULL)
1519: TtaRemoveAttribute (el, IntAttr, doc);
1520: }
1521: else
1522: {
1523: /* put an attribute IntFontstyle = IntNormal */
1524: if (IntAttr == NULL)
1525: {
1526: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1527: IntAttr = TtaNewAttribute (attrType);
1528: TtaAttachAttribute (el, IntAttr, doc);
1529: }
1530: TtaSetAttributeValue (IntAttr,
1531: MathML_ATTR_IntFontstyle_VAL_IntNormal,
1532: el, doc);
1533: }
1534: }
1535: }
1.1 cvs 1536: }
1.142 quint 1537: }
1.1 cvs 1538: }
1539:
1540: /*----------------------------------------------------------------------
1.22 cvs 1541: SetIntAddSpaceAttr
1.1 cvs 1542: The content of a MO element has been created or modified.
1.22 cvs 1543: Create or change attribute IntAddSpace for that element accordingly.
1.1 cvs 1544: -----------------------------------------------------------------------*/
1.22 cvs 1545: void SetIntAddSpaceAttr (Element el, Document doc)
1.1 cvs 1546: {
1547: Element textEl, previous;
1548: ElementType elType;
1549: AttributeType attrType;
1.60 cvs 1550: Attribute attr, formAttr;
1.155 quint 1551: SSchema MathMLSSchema;
1.60 cvs 1552: int len, val, form;
1.146 quint 1553: CHAR_T text[2];
1.1 cvs 1554: Language lang;
1.143 vatton 1555: char script;
1.155 quint 1556: ThotBool comment;
1.1 cvs 1557:
1.155 quint 1558: MathMLSSchema = TtaGetElementType(el).ElSSchema;
1.60 cvs 1559: /* get the content of the mo element */
1.1 cvs 1560: textEl = TtaGetFirstChild (el);
1.155 quint 1561:
1562: /* skip comments if any */
1563: if (textEl)
1564: do
1565: {
1566: elType = TtaGetElementType (textEl);
1567: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1568: elType.ElTypeNum == MathML_EL_XMLcomment)
1569: /* it's a comment, skip it */
1570: TtaNextSibling (&textEl);
1571: }
1572: while (textEl && elType.ElTypeNum == MathML_EL_XMLcomment);
1573:
1574: if (textEl && elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1575: /* the mo element is not empty */
1576: {
1577: /* does the mo element have an IntAddSpace attribute? */
1578: attrType.AttrSSchema = MathMLSSchema;
1579: attrType.AttrTypeNum = MathML_ATTR_IntAddSpace;
1580: attr = TtaGetAttribute (el, attrType);
1581: if (attr == NULL)
1.60 cvs 1582: /* no IntAddSpace Attr, create one */
1.1 cvs 1583: {
1.155 quint 1584: attr = TtaNewAttribute (attrType);
1585: TtaAttachAttribute (el, attr, doc);
1586: }
1587: /* space on both sides by default */
1588: val = MathML_ATTR_IntAddSpace_VAL_both;
1589: /* does the mo element have a form attribute? */
1590: attrType.AttrTypeNum = MathML_ATTR_form;
1591: formAttr = TtaGetAttribute (el, attrType);
1592: if (formAttr)
1593: /* there is a form attribute */
1594: {
1595: form = TtaGetAttributeValue (formAttr);
1596: switch (form)
1597: {
1598: case MathML_ATTR_form_VAL_prefix:
1599: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1600: break;
1601: case MathML_ATTR_form_VAL_infix:
1602: val = MathML_ATTR_IntAddSpace_VAL_both;
1603: break;
1604: case MathML_ATTR_form_VAL_postfix:
1605: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
1606: break;
1607: default:
1608: val = MathML_ATTR_IntAddSpace_VAL_both;
1609: break;
1610: }
1.1 cvs 1611: }
1.155 quint 1612: else
1613: /* no form attribute. Analyze the content */
1614: {
1615: len = TtaGetElementVolume (textEl);
1616: if (len == 1)
1617: {
1618: TtaGiveBufferContent (textEl, text, len+1, &lang);
1619: script = TtaGetScript (lang);
1620: /* the mo element contains a single character */
1.146 quint 1621: #ifndef _I18N_
1.155 quint 1622: if (script == 'L')
1623: /* ISO-Latin 1 character */
1624: {
1.146 quint 1625: #endif
1.155 quint 1626: if (text[0] == '-'
1.153 quint 1627: #ifdef _I18N_
1.155 quint 1628: || text[0] == 0x2212 /* minus */
1.153 quint 1629: #endif
1.155 quint 1630: )
1631: /* prefix or infix operator? */
1632: {
1633: /* skip preceding comments if any */
1634: previous = el;
1635: do
1636: {
1637: comment = FALSE;
1638: TtaPreviousSibling (&previous);
1639: if (previous)
1640: {
1641: elType = TtaGetElementType (previous);
1642: comment = (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1643: elType.ElTypeNum == MathML_EL_XMLcomment);
1644: }
1645: }
1646: while (previous && comment);
1647:
1648: if (previous == NULL)
1649: /* no previous sibling => prefix operator */
1650: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1651: else
1652: {
1653: elType = TtaGetElementType (previous);
1.158 quint 1654: if (elType.ElTypeNum == MathML_EL_MO ||
1655: elType.ElTypeNum == MathML_EL_OpeningFence ||
1656: elType.ElTypeNum == MathML_EL_ClosingFence ||
1657: elType.ElTypeNum == MathML_EL_FencedSeparator)
1.155 quint 1658: /* after an operator => prefix operator */
1659: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1660: else
1661: /* infix operator */
1662: val = MathML_ATTR_IntAddSpace_VAL_both;
1663: }
1664: }
1665: else if (text[0] == '&' ||
1666: text[0] == '*' ||
1667: text[0] == '+' ||
1668: text[0] == '/' ||
1669: text[0] == '<' ||
1670: text[0] == '=' ||
1671: text[0] == '>' ||
1672: text[0] == '^' ||
1673: (int)text[0] == 177 || /* plus or minus */
1674: (int)text[0] == 215 || /* times */
1675: (int)text[0] == 247) /* divide */
1676: /* infix operator */
1677: val = MathML_ATTR_IntAddSpace_VAL_both;
1678: else if (text[0] == ',' ||
1679: text[0] == '!' ||
1680: text[0] == '&' ||
1681: text[0] == ':' ||
1682: text[0] == ';')
1683: /* separator */
1684: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
1685: else if (text[0] == '(' ||
1686: text[0] == ')' ||
1687: text[0] == '[' ||
1688: text[0] == ']' ||
1689: text[0] == '{' ||
1690: text[0] == '}' ||
1691: text[0] == '.' ||
1692: text[0] == '@' ||
1.165 quint 1693: #ifndef _I18N_
1694: text[0] == 'd' || /* probably DifferentialD */
1695: #endif
1.155 quint 1696: (int)text[0] == 129 || /* thin space */
1697: (int)text[0] == 130 || /* en space */
1698: (int)text[0] == 160) /* em space */
1699: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.146 quint 1700: #ifndef _I18N_
1.155 quint 1701: }
1702: else if (script == 'G')
1703: {
1704: /* Symbol character set */
1705: if ((int)text[0] == 163 || /* less or equal */
1706: (int)text[0] == 177 || /* plus or minus */
1707: (int)text[0] == 179 || /* greater or equal */
1708: (int)text[0] == 180 || /* times */
1709: (int)text[0] == 184 || /* divide */
1710: (int)text[0] == 185 || /* not equal */
1711: (int)text[0] == 186 || /* identical */
1712: (int)text[0] == 187 || /* equivalent */
1713: (int)text[0] == 196 || /* circle times */
1714: (int)text[0] == 197 || /* circle plus */
1715: ((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
1716: (int)text[0] == 217 || /* and */
1717: (int)text[0] == 218) /* or */
1.146 quint 1718: #else
1.155 quint 1719: else
1720: if ((int)text[0] == 0x2264 || /* less or equal */
1721: (int)text[0] == 0x00B1 || /* plus or minus */
1722: (int)text[0] == 0x2265 || /* greater or equal */
1723: (int)text[0] == 0x00D7 || /* times */
1724: (int)text[0] == 0x00F7 || /* divide */
1725: (int)text[0] == 0x2260 || /* not equal */
1726: (int)text[0] == 0x2261 || /* identical */
1727: (int)text[0] == 0x2248 || /* equivalent */
1728: (int)text[0] == 0x2297 || /* circle times */
1729: (int)text[0] == 0x2295 || /* circle plus */
1730: (int)text[0] == 0x2229 || /* Intersection */
1731: (int)text[0] == 0x222A || /* Union */
1732: (int)text[0] == 0x2283 || /* Superset of */
1733: (int)text[0] == 0x2287 || /* Superset of or equal to */
1734: (int)text[0] == 0x2284 || /* Not a subset of */
1735: (int)text[0] == 0x2282 || /* Subset of */
1736: (int)text[0] == 0x2286 || /* Subset of or equal to */
1737: (int)text[0] == 0x2208 || /* Element of */
1738: (int)text[0] == 0x2209 || /* Not an element of */
1739: (int)text[0] == 0x2220 || /* Angle */
1740: (int)text[0] == 0x2207 || /* Nabla */
1741: (int)text[0] == 0x2227 || /* and */
1742: (int)text[0] == 0x2228 || /* or */
1743: (int)text[0] == 0x2190 || /* left arrow */
1744: (int)text[0] == 0x2192 || /* right arrow */
1745: (int)text[0] == 0x2194) /* left right arrow */
1.146 quint 1746: #endif
1.155 quint 1747: /* infix operator */
1748: val = MathML_ATTR_IntAddSpace_VAL_both;
1749: else
1750: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.146 quint 1751: #ifndef _I18N_
1.155 quint 1752: }
1.146 quint 1753: #endif
1.155 quint 1754: }
1755: }
1756: TtaSetAttributeValue (attr, val, el, doc);
1757: }
1.1 cvs 1758: }
1759:
1760: /*----------------------------------------------------------------------
1.58 cvs 1761: ChildOfMRowOrInferred
1762: Return TRUE if element el is a child of a MROW element or an
1763: inferred MROW element
1764: ----------------------------------------------------------------------*/
1765: ThotBool ChildOfMRowOrInferred (Element el)
1766: {
1767: ElementType elType;
1768: Element parent;
1769: ThotBool result;
1770:
1771: result = FALSE;
1772: parent = TtaGetParent (el);
1773: if (parent)
1774: {
1775: elType = TtaGetElementType (parent);
1776: result = (elType.ElTypeNum == MathML_EL_MROW ||
1777: elType.ElTypeNum == MathML_EL_SqrtBase ||
1778: elType.ElTypeNum == MathML_EL_MSTYLE ||
1779: elType.ElTypeNum == MathML_EL_MERROR ||
1.92 cvs 1780: elType.ElTypeNum == MathML_EL_MENCLOSE ||
1.58 cvs 1781: elType.ElTypeNum == MathML_EL_MPADDED ||
1782: elType.ElTypeNum == MathML_EL_MPHANTOM ||
1.158 quint 1783: elType.ElTypeNum == MathML_EL_MFENCED ||
1.58 cvs 1784: elType.ElTypeNum == MathML_EL_CellWrapper ||
1.92 cvs 1785: elType.ElTypeNum == MathML_EL_MathML ||
1.58 cvs 1786: elType.ElTypeNum == MathML_EL_FencedExpression);
1787: }
1788: return result;
1789: }
1790:
1791: /*----------------------------------------------------------------------
1.1 cvs 1792: CheckFence
1.84 cvs 1793: If el is a MO element,
1794: - if it's a large operator (∑ for instance), put a presentation
1795: rule to enlarge the character.
1796: - if it's a child of a MROW (or equivalent) element and if it contains
1797: a single fence character, transform the MO into a MF and the fence
1798: character into a Thot stretchable symbol.
1.1 cvs 1799: ----------------------------------------------------------------------*/
1.84 cvs 1800: void CheckFence (Element el, Document doc)
1.1 cvs 1801: {
1.158 quint 1802: ElementType elType, contType;
1.128 vatton 1803: Element content;
1804: AttributeType attrType;
1805: Attribute attr, attrStretchy;
1806: Language lang;
1.84 cvs 1807: PresentationValue pval;
1808: PresentationContext ctxt;
1.128 vatton 1809: CHAR_T text[2];
1.143 vatton 1810: char script;
1.128 vatton 1811: unsigned char c;
1.158 quint 1812: int len, val, oldStructureChecking;
1.1 cvs 1813:
1814: elType = TtaGetElementType (el);
1.158 quint 1815: if (elType.ElTypeNum == MathML_EL_MO ||
1816: elType.ElTypeNum == MathML_EL_OpeningFence ||
1817: elType.ElTypeNum == MathML_EL_ClosingFence ||
1818: elType.ElTypeNum == MathML_EL_FencedSeparator)
1819: /* the element is a MO or equivalent */
1.58 cvs 1820: {
1.84 cvs 1821: content = TtaGetFirstChild (el);
1822: if (content != NULL)
1823: {
1.158 quint 1824: contType = TtaGetElementType (content);
1825: if (contType.ElTypeNum == MathML_EL_TEXT_UNIT)
1.84 cvs 1826: {
1.146 quint 1827: len = TtaGetElementVolume (content);
1.84 cvs 1828: if (len == 1)
1829: /* the MO element contains a single character */
1830: {
1.146 quint 1831: TtaGiveBufferContent (content, text, len+1, &lang);
1.143 vatton 1832: script = TtaGetScript (lang);
1.146 quint 1833: #ifdef _I18N_
1834: if (text[0] == 8721 || text[0] == 8719) /* large Sigma or Pi */
1835: #else
1.143 vatton 1836: if ((script == 'G') &&
1.158 quint 1837: (text[0] == 229 || text[0] == 213)) /* large Sigma or Pi */
1.146 quint 1838: #endif
1.84 cvs 1839: /* it's a large operator */
1840: {
1841: ctxt = TtaGetSpecificStyleContext (doc);
1842: ctxt->destroy = FALSE;
1843: /* the specific presentation to be created is not a CSS rule */
1.147 quint 1844: ctxt->cssSpecificity = 0;
1.84 cvs 1845: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1846: pval.typed_data.real = FALSE;
1847: pval.typed_data.value = 180;
1848: TtaSetStylePresentation (PRSize, content, NULL, ctxt, pval);
1849: }
1850: else if (ChildOfMRowOrInferred (el))
1851: /* the MO element is a child of a MROW element */
1.1 cvs 1852: {
1.146 quint 1853: if ((
1854: #ifndef _I18N_
1855: (script == 'L') &&
1856: #endif
1.115 cvs 1857: (text[0] == '(' || text[0] == ')' ||
1858: text[0] == '[' || text[0] == ']' ||
1859: text[0] == '{' || text[0] == '}' ||
1860: text[0] == '|')) ||
1.146 quint 1861: (
1862: /* test left and right angle brackets */
1863: #ifdef _I18N_
1864: (text[0] == 9001 || text[0] == 9002)
1865: #else
1866: (script == 'G') &&
1867: (text[0] == 225 || text[0] == 241)
1868: #endif
1869: ))
1.84 cvs 1870: /* it's a stretchable parenthesis or equivalent */
1871: {
1872: /* remove the content of the MO element */
1873: TtaDeleteTree (content, doc);
1874: /* change the MO element into a MF element */
1.158 quint 1875: if (elType.ElTypeNum == MathML_EL_MO)
1876: ChangeTypeOfElement (el, doc, MathML_EL_MF);
1.84 cvs 1877: /* is there an attribute stretchy on this mo element? */
1878: attrType.AttrSSchema = elType.ElSSchema;
1879: attrType.AttrTypeNum = MathML_ATTR_stretchy;
1880: attrStretchy = TtaGetAttribute (el, attrType);
1881: if (attrStretchy)
1882: val = TtaGetAttributeValue (attrStretchy);
1883: else
1884: val = MathML_ATTR_stretchy_VAL_true;
1885: if (val == MathML_ATTR_stretchy_VAL_true)
1886: {
1.158 quint 1887: /* attach a IntVertStretch attribute to the MF element */
1.84 cvs 1888: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
1.158 quint 1889: attr = TtaGetAttribute (el, attrType);
1890: if (!attr)
1891: {
1892: attr = TtaNewAttribute (attrType);
1893: TtaAttachAttribute (el, attr, doc);
1894: }
1.84 cvs 1895: TtaSetAttributeValue (attr,
1896: MathML_ATTR_IntVertStretch_VAL_yes_,
1897: el, doc);
1898: }
1899: /* create a new content for the MF element */
1.87 cvs 1900: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1.146 quint 1901: #ifdef _I18N_
1902: if (text[0] == 9002)
1903: #else
1.143 vatton 1904: if (script == 'G' && text[0] == 241)
1.146 quint 1905: #endif
1.102 cvs 1906: c = '>'; /* RightAngleBracket */
1907: else
1.146 quint 1908: #ifdef _I18N_
1909: if (text[0] == 9001)
1910: #else
1911: if (script == 'G' && text[0] == 225)
1912: #endif
1913: c = '<'; /* LeftAngleBracket */
1914: else
1915: c = (char) text[0];
1.84 cvs 1916: content = TtaNewElement (doc, elType);
1.158 quint 1917: /* do not check the Thot abstract tree against the structure
1918: schema while inserting this child element */
1919: oldStructureChecking = TtaGetStructureChecking (doc);
1920: TtaSetStructureChecking (0, doc);
1.84 cvs 1921: TtaInsertFirstChild (&content, el, doc);
1922: TtaSetGraphicsShape (content, c, doc);
1.158 quint 1923: /* resume structure checking */
1924: TtaSetStructureChecking ((ThotBool)oldStructureChecking, doc);
1.84 cvs 1925: }
1.1 cvs 1926: }
1.84 cvs 1927: }
1928: }
1.58 cvs 1929: }
1930: }
1.1 cvs 1931: }
1932:
1933: /*----------------------------------------------------------------------
1934: CreateFencedSeparators
1935: Create FencedSeparator elements within the fencedExpression
1936: according to attribute separators of the MFENCED element.
1937: ----------------------------------------------------------------------*/
1.110 cvs 1938: void CreateFencedSeparators (Element fencedExpression, Document doc, ThotBool record)
1.1 cvs 1939: {
1940: ElementType elType;
1941: Element child, separator, leaf, next, prev, mfenced;
1942: AttributeType attrType;
1943: Attribute attr;
1944: int length, sep, i;
1945: Language lang;
1.116 cvs 1946: char text[32], sepValue[4];
1.1 cvs 1947:
1948: /* get the separators attribute */
1949: mfenced = TtaGetParent (fencedExpression);
1950: elType = TtaGetElementType (fencedExpression);
1951: attrType.AttrSSchema = elType.ElSSchema;
1952: attrType.AttrTypeNum = MathML_ATTR_separators;
1953: text[0] = ','; /* default value is sparators="," */
1954: text[1] = EOS;
1955: length = 1;
1956: attr = TtaGetAttribute (mfenced, attrType);
1957: if (attr != NULL)
1958: {
1959: length = 31;
1960: TtaGiveTextAttributeValue (attr, text, &length);
1961: }
1962:
1963: /* create FencedSeparator elements in the FencedExpression */
1964: prev = NULL;
1965: sep = 0;
1966: /* skip leading spaces in attribute separators */
1967: while (text[sep] <= SPACE && text[sep] != EOS)
1968: sep++;
1969: /* if attribute separators is empty or contains only spaces, do not
1970: insert any separator element */
1971: if (text[sep] != EOS)
1972: {
1973: child = TtaGetFirstChild (fencedExpression);
1974: while (child != NULL)
1975: {
1976: next = child;
1977: TtaNextSibling (&next);
1978: elType = TtaGetElementType (child);
1979: if (elType.ElTypeNum != MathML_EL_Construct)
1980: {
1981: if (prev != NULL)
1982: {
1983: elType.ElTypeNum = MathML_EL_FencedSeparator;
1984: separator = TtaNewElement (doc, elType);
1985: TtaInsertSibling (separator, prev, FALSE, doc);
1986: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1987: leaf = TtaNewElement (doc, elType);
1988: TtaInsertFirstChild (&leaf, separator, doc);
1989: sepValue[0] = text[sep];
1.158 quint 1990: sepValue[1] = EOS;
1.143 vatton 1991: lang = TtaGetLanguageIdFromScript('L');
1.1 cvs 1992: TtaSetTextContent (leaf, sepValue, lang, doc);
1.158 quint 1993: SetIntAddSpaceAttr (separator, doc);
1994: SetIntVertStretchAttr (separator, doc, 0, NULL);
1995: CheckFence (separator, doc);
1996:
1.1 cvs 1997: /* is there a following non-space character in separators? */
1998: i = sep + 1;
1999: while (text[i] <= SPACE && text[i] != EOS)
2000: i++;
2001: if (text[i] > SPACE && text[i] != EOS)
2002: sep = i;
1.17 cvs 2003: if (record)
2004: TtaRegisterElementCreate (separator, doc);
1.1 cvs 2005: }
2006: prev = child;
2007: }
2008: child = next;
2009: }
2010: }
2011: }
2012:
1.124 cvs 2013: /*----------------------------------------------------------------------
2014: CreateOpeningOrClosingFence
2015: Create the OpeningFence or ClosingFence element (depending on parameter
2016: open) for the MFENCED element el which contain the fencedExpression
2017: element.
2018: ----------------------------------------------------------------------*/
2019: static void CreateOpeningOrClosingFence (Element fencedExpression,
2020: Element el, Document doc,
2021: ThotBool open)
2022: {
2023: ElementType elType;
2024: Element leaf, fence;
2025: AttributeType attrType;
2026: Attribute attr;
2027: int length;
2028: char text[32];
2029:
2030: elType = TtaGetElementType (el);
2031: attrType.AttrSSchema = elType.ElSSchema;
2032: if (open)
2033: {
1.158 quint 2034: text[0] = '('; /* default value of attribute 'open' */
1.124 cvs 2035: attrType.AttrTypeNum = MathML_ATTR_open;
2036: elType.ElTypeNum = MathML_EL_OpeningFence;
2037: }
2038: else
2039: {
1.158 quint 2040: text[0] = ')'; /* default value of attribute 'close' */
1.124 cvs 2041: attrType.AttrTypeNum = MathML_ATTR_close;
2042: elType.ElTypeNum = MathML_EL_ClosingFence;
2043: }
2044: attr = TtaGetAttribute (el, attrType);
2045: if (attr != NULL)
2046: {
2047: length = 31;
2048: TtaGiveTextAttributeValue (attr, text, &length);
2049: if (length != 1)
2050: /* content of attribute open or close should be a single character */
1.158 quint 2051: text[0] = '?';
1.124 cvs 2052: }
1.158 quint 2053: text[1] = EOS;
1.124 cvs 2054: fence = TtaNewElement (doc, elType);
2055: TtaInsertSibling (fence, fencedExpression, open, doc);
1.158 quint 2056: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1.124 cvs 2057: leaf = TtaNewElement (doc, elType);
2058: TtaInsertFirstChild (&leaf, fence, doc);
1.158 quint 2059: TtaSetTextContent (leaf, text, TtaGetLanguageIdFromScript('L'), doc);
2060: SetIntAddSpaceAttr (fence, doc);
2061: SetIntVertStretchAttr (fence, doc, 0, NULL);
2062: CheckFence (fence, doc);
1.124 cvs 2063: }
1.1 cvs 2064:
2065: /*----------------------------------------------------------------------
2066: TransformMFENCED
2067: Transform the content of a MFENCED element: create elements
2068: OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
2069: ----------------------------------------------------------------------*/
1.46 cvs 2070: static void TransformMFENCED (Element el, Document doc)
1.1 cvs 2071: {
2072: ElementType elType;
1.124 cvs 2073: Element child, fencedExpression, next, prev, firstChild;
1.1 cvs 2074:
2075: child = TtaGetFirstChild (el);
2076: if (child != NULL)
2077: elType = TtaGetElementType (child);
2078: if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
2079: /* The first child of this MFENCED element is an OpeningFence.
2080: This MFENCED expression has already been transformed, possibly
2081: by the Transform command */
2082: {
2083: TtaNextSibling (&child);
2084: fencedExpression = child;
2085: if (fencedExpression != NULL)
2086: elType = TtaGetElementType (fencedExpression);
2087: if (elType.ElTypeNum == MathML_EL_FencedExpression)
2088: /* the second child is a FencedExpression. OK.
2089: Remove all existing FencedSeparator elements */
2090: {
2091: child = TtaGetFirstChild (fencedExpression);
2092: prev = NULL;
2093: while (child != NULL)
2094: {
2095: elType = TtaGetElementType (child);
2096: next = child;
2097: TtaNextSibling (&next);
2098: if (elType.ElTypeNum == MathML_EL_FencedSeparator)
2099: /* Remove this separator */
2100: TtaDeleteTree (child, doc);
2101: child = next;
2102: }
2103: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 2104: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 2105: }
2106: }
2107: else
2108: /* this MFENCED element must be transformed */
2109: {
2110: /* create a FencedExpression element as a child of the MFENCED elem. */
2111: elType = TtaGetElementType (el);
2112: elType.ElTypeNum = MathML_EL_FencedExpression;
2113: fencedExpression = TtaNewElement (doc, elType);
2114: TtaInsertFirstChild (&fencedExpression, el, doc);
2115: if (child == NULL)
2116: /* empty MFENCED element */
2117: {
2118: elType.ElTypeNum = MathML_EL_Construct;
2119: child = TtaNewElement (doc, elType);
2120: TtaInsertFirstChild (&child, fencedExpression, doc);
1.22 cvs 2121: SetIntPlaceholderAttr (child, doc);
1.1 cvs 2122: }
2123: else
2124: {
2125: /* move the content of the MFENCED element within the new
2126: FencedExpression element */
2127: prev = NULL;
2128: firstChild = NULL;
2129: while (child != NULL)
2130: {
2131: next = child;
2132: TtaNextSibling (&next);
2133: TtaRemoveTree (child, doc);
2134: if (prev == NULL)
2135: {
2136: TtaInsertFirstChild (&child, fencedExpression, doc);
2137: firstChild = child;
2138: }
2139: else
2140: TtaInsertSibling (child, prev, FALSE, doc);
2141: prev = child;
2142: child = next;
2143: }
2144:
2145: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 2146: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 2147:
2148: /* Create placeholders within the FencedExpression element */
2149: CreatePlaceholders (firstChild, doc);
2150: }
2151:
2152: /* create the OpeningFence element according to the open attribute */
1.124 cvs 2153: CreateOpeningOrClosingFence (fencedExpression, el, doc, TRUE);
1.1 cvs 2154:
2155: /* create the ClosingFence element according to close attribute */
1.124 cvs 2156: CreateOpeningOrClosingFence (fencedExpression, el, doc, FALSE);
1.1 cvs 2157: }
2158: }
2159:
2160: /*----------------------------------------------------------------------
1.59 cvs 2161: MathMLScriptShift
2162: The MathML attribute attr (superscriptshift or subscriptshift) is associated
2163: with element el (a msub, msup or msubsup).
2164: If value is not NULL, generate the corresponding Thot VertPos rule for the
2165: Subscript or Superscript child of el.
2166: If value is NULL, remove the Thot VertPos rule.
2167: -----------------------------------------------------------------------*/
1.120 cvs 2168: void MathMLScriptShift (Document doc, Element el, char *value, int attr)
1.59 cvs 2169: {
2170: ElementType elType;
2171: Element script, child;
2172: int scrType;
2173: PresentationValue pval;
2174: PresentationContext ctxt;
2175:
2176: /* get the Superscript or Subscript child of el */
2177: if (attr == MathML_ATTR_superscriptshift)
2178: scrType = MathML_EL_Superscript;
2179: else if (attr == MathML_ATTR_subscriptshift)
2180: scrType = MathML_EL_Subscript;
2181: else
2182: return;
2183: script = NULL;
2184: child = TtaGetFirstChild (el);
2185: while (!script && child)
2186: {
2187: elType = TtaGetElementType (child);
2188: if (elType.ElTypeNum == scrType)
2189: script = child;
2190: else
2191: TtaNextSibling (&child);
2192: }
2193: if (script)
2194: /* Superscript or Subscript element found */
2195: {
2196: ctxt = TtaGetSpecificStyleContext (doc);
2197: if (!value)
2198: /* remove the presentation rule */
2199: {
2200: ctxt->destroy = TRUE;
1.75 cvs 2201: pval.typed_data.value = 0;
1.59 cvs 2202: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
2203: }
2204: else
2205: {
2206: ctxt->destroy = FALSE;
2207: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 2208: value = TtaSkipBlanks (value);
1.59 cvs 2209: value = ParseCSSUnit (value, &pval);
2210: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
2211: {
1.78 cvs 2212: /* the specific presentation to be created is not a CSS rule */
1.147 quint 2213: ctxt->cssSpecificity = 0;
1.59 cvs 2214: if (attr == MathML_ATTR_superscriptshift)
2215: pval.typed_data.value = - pval.typed_data.value;
2216: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
2217: }
2218: }
2219: TtaFreeMemory (ctxt);
2220: }
2221: }
2222:
2223: /*----------------------------------------------------------------------
2224: SetScriptShift
2225: If element el (which is a msup, msub or msubsup) has an attribute
2226: att (which is subscriptshift or superscriptshift), generate the
2227: corresponding Thot presentation rule.
2228: ----------------------------------------------------------------------*/
1.120 cvs 2229: static void SetScriptShift (Element el, Document doc, int att)
1.59 cvs 2230: {
2231: AttributeType attrType;
2232: ElementType elType;
2233: Attribute attr;
1.120 cvs 2234: char *value;
1.59 cvs 2235: int length;
2236:
2237: elType = TtaGetElementType (el);
2238: attrType.AttrSSchema = elType.ElSSchema;
2239: attrType.AttrTypeNum = att;
2240: attr = TtaGetAttribute (el, attrType);
2241: if (attr)
2242: {
2243: length = TtaGetTextAttributeLength (attr);
2244: if (length > 0)
2245: {
1.116 cvs 2246: value = TtaGetMemory (length+1);
1.59 cvs 2247: value[0] = EOS;
2248: TtaGiveTextAttributeValue (attr, value, &length);
2249: MathMLScriptShift (doc, el, value, att);
2250: TtaFreeMemory (value);
2251: }
2252: }
2253: }
2254:
2255: /*----------------------------------------------------------------------
1.159 quint 2256: DeleteIntRowAlign
2257: Remove attribute IntRowAlign from element row if there is no rowalign_mtr
2258: attribut on this element.
2259: -----------------------------------------------------------------------*/
2260: static void DeleteIntRowAlign (Element row, Document doc)
2261: {
2262: ElementType elType;
2263: AttributeType attrType;
2264: Attribute attr;
2265:
2266: elType = TtaGetElementType (row);
2267: attrType.AttrSSchema = elType.ElSSchema;
2268: attrType.AttrTypeNum = MathML_ATTR_rowalign_mtr;
2269: attr = TtaGetAttribute (row, attrType);
2270: if (!attr)
2271: {
2272: attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
2273: attr = TtaGetAttribute (row, attrType);
2274: if (attr)
2275: TtaRemoveAttribute (row, attr, doc);
2276: }
2277: }
2278:
2279: /*----------------------------------------------------------------------
2280: SetIntRowAlign
2281: Set attribute IntRowAlign for element row unless this element already has
2282: a rowalign_mtr attribute
2283: -----------------------------------------------------------------------*/
2284: static void SetIntRowAlign (Element row, int val, Document doc)
2285: {
2286: ElementType elType;
2287: AttributeType attrType;
2288: Attribute attr;
2289:
2290: elType = TtaGetElementType (row);
2291: attrType.AttrSSchema = elType.ElSSchema;
2292: attrType.AttrTypeNum = MathML_ATTR_rowalign_mtr;
2293: attr = TtaGetAttribute (row, attrType);
2294: if (!attr)
2295: {
2296: attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
2297: attr = TtaGetAttribute (row, attrType);
2298: if (!attr)
2299: {
2300: attr = TtaNewAttribute (attrType);
2301: TtaAttachAttribute (row, attr, doc);
2302: }
2303: TtaSetAttributeValue (attr, val, row, doc);
2304: }
2305: }
2306:
2307: /*----------------------------------------------------------------------
2308: HandleRowalignAttribute
2309: An attribute rowalign has been created, updated (if !delete) or deleted
2310: (if delete) for element el in document doc. Update the IntRowAlign
2311: attributes of all enclosed mrow elements accordingly.
2312: ----------------------------------------------------------------------*/
2313: void HandleRowalignAttribute (Attribute attr, Element el, Document doc,
2314: ThotBool delete)
2315: {
2316: char *value;
2317: char *ptr;
2318: int length, val;
2319: ElementType elType;
2320: Element row;
2321:
2322: elType = TtaGetElementType (el);
2323: if (elType.ElTypeNum != MathML_EL_MTABLE ||
2324: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
2325: /* ignore rowalign attribute on mstyle elements */
2326: /* process it only on mtable elements */
2327: return;
2328:
2329: value = NULL;
2330: if (!delete)
2331: {
2332: length = TtaGetTextAttributeLength (attr);
2333: if (length > 0)
2334: {
2335: value = TtaGetMemory (length+1);
2336: value[0] = EOS;
2337: TtaGiveTextAttributeValue (attr, value, &length);
2338: }
2339: }
2340: /* if attribute rowalign is created or updated but has no value, don't
2341: do anything */
2342: if (!delete && !value)
2343: return;
2344:
2345: ptr = value;
2346: val = 0;
2347: elType.ElTypeNum = MathML_EL_TableRow;
2348: row = TtaSearchTypedElement (elType, SearchInTree, el);
2349: while (row)
2350: {
2351: elType = TtaGetElementType (row);
2352: /* skip comments and other non row elements */
2353: if ((elType.ElTypeNum == MathML_EL_MTR ||
2354: elType.ElTypeNum == MathML_EL_MLABELEDTR) &&
2355: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
2356: {
2357: if (delete)
2358: DeleteIntRowAlign (row, doc);
2359: else
2360: {
2361: if (*ptr != EOS)
2362: {
2363: /* get next word in the attribute value */
2364: ptr = TtaSkipBlanks (ptr);
2365: /* process that word */
2366: if (*ptr != EOS && *ptr != ' ')
2367: {
2368: if (!strncasecmp (ptr, "top", 3))
2369: val = MathML_ATTR_IntRowAlign_VAL_IntTop;
2370: else if (!strncasecmp (ptr, "bottom", 6))
2371: val = MathML_ATTR_IntRowAlign_VAL_IntBottom;
2372: else if (!strncasecmp (ptr, "center", 6))
2373: val = MathML_ATTR_IntRowAlign_VAL_IntCenter;
2374: else if (!strncasecmp (ptr, "baseline", 8))
2375: val = MathML_ATTR_IntRowAlign_VAL_IntBaseline;
2376: else if (!strncasecmp (ptr, "axis", 4))
2377: val = MathML_ATTR_IntRowAlign_VAL_IntAxis;
2378: else
2379: val = 0;
2380: /* skip the word that has been processed */
2381: while (*ptr != EOS && *ptr != ' ')
2382: ptr++;
2383: }
2384: }
2385: if (val > 0)
2386: SetIntRowAlign (row, val, doc);
2387: }
2388: }
2389: TtaNextSibling (&row);
2390: }
2391: if (value)
2392: TtaFreeMemory (value);
2393: }
2394:
2395: /*----------------------------------------------------------------------
2396: DeleteIntColAlign
2397: Remove attribute IntColAlign from element cell if there is no columnalign_mtd
2398: attribut on this element.
2399: -----------------------------------------------------------------------*/
2400: static void DeleteIntColAlign (Element cell, Document doc)
2401: {
2402: ElementType elType;
2403: AttributeType attrType;
2404: Attribute attr;
2405:
2406: elType = TtaGetElementType (cell);
2407: attrType.AttrSSchema = elType.ElSSchema;
2408: attrType.AttrTypeNum = MathML_ATTR_columnalign_mtd;
2409: attr = TtaGetAttribute (cell, attrType);
2410: if (!attr)
2411: {
2412: attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
2413: attr = TtaGetAttribute (cell, attrType);
2414: if (attr)
2415: TtaRemoveAttribute (cell, attr, doc);
2416: }
2417: }
2418:
2419: /*----------------------------------------------------------------------
2420: SetIntColAlign
2421: Set attribute IntColAlign for element cell unless this element already has
2422: a columnalign_mtd attribute
2423: -----------------------------------------------------------------------*/
2424: static void SetIntColAlign (Element cell, int val, Document doc)
2425: {
2426: ElementType elType;
2427: AttributeType attrType;
2428: Attribute attr;
2429:
2430: elType = TtaGetElementType (cell);
2431: attrType.AttrSSchema = elType.ElSSchema;
2432: attrType.AttrTypeNum = MathML_ATTR_columnalign_mtd;
2433: attr = TtaGetAttribute (cell, attrType);
2434: if (!attr)
2435: {
2436: attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
2437: attr = TtaGetAttribute (cell, attrType);
2438: if (!attr)
2439: {
2440: attr = TtaNewAttribute (attrType);
2441: TtaAttachAttribute (cell, attr, doc);
2442: }
2443: TtaSetAttributeValue (attr, val, cell, doc);
2444: }
2445: }
2446:
2447: /*----------------------------------------------------------------------
2448: RowWithoutColalignAttr
2449: if skip: if element row has a columnalign attribute, get the next sibling row
2450: element without a columnalign attribute and return its first cell
2451: if not skip: always return the first cell in the row, and the columnalign
2452: attribute of that row if there is one.
2453: -----------------------------------------------------------------------*/
2454: static void RowWithoutColalignAttr (Element *row, Element *cell,
2455: Attribute *attr, ThotBool skip)
2456: {
2457: ElementType elType;
2458: AttributeType attrType;
2459:
2460: elType = TtaGetElementType (*row);
2461: attrType.AttrSSchema = elType.ElSSchema;
2462: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2463: *cell = NULL;
2464: *attr = NULL;
2465: while (*row != NULL && *cell == NULL)
2466: {
2467: elType = TtaGetElementType (*row);
2468: if ((elType.ElTypeNum != MathML_EL_MTR &&
2469: elType.ElTypeNum != MathML_EL_MLABELEDTR) ||
2470: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
2471: /* not a row. Skip it */
2472: TtaNextSibling (row);
2473: else
2474: {
2475: /* skip that row if it has a columnalign attribute */
2476: *attr = TtaGetAttribute (*row, attrType);
2477: if (skip && *attr != NULL)
2478: {
2479: TtaNextSibling (row);
2480: *attr = NULL;
2481: }
2482: else
2483: /* it's a row without a columnalign attribute */
2484: *cell = TtaGetFirstChild (*row);
2485: }
2486: }
2487: }
2488:
2489: /*----------------------------------------------------------------------
2490: HandleColalignAttribute
2491: An attribute columnalign has been created, updated (if !delete) or deleted
2492: (if delete) for element el in document doc. Update the IntColAlign
2493: attributes of all concerned cells accordingly.
2494: If allRows is TRUE, process also rows that have their own columnalign
2495: attribute, according to that attribute, otherwise skip those rows.
2496: ----------------------------------------------------------------------*/
2497: void HandleColalignAttribute (Attribute attr, Element el, Document doc,
2498: ThotBool delete, ThotBool allRows)
2499: {
2500: char *value, *localValue;
2501: char *ptr;
2502: int length, val;
2503: ElementType elType;
2504: Element cell, row;
2505: Attribute localAttr;
2506: ThotBool fullTable;
2507:
2508: elType = TtaGetElementType (el);
2509: if ((elType.ElTypeNum != MathML_EL_MTABLE &&
2510: elType.ElTypeNum != MathML_EL_MTR &&
2511: elType.ElTypeNum != MathML_EL_MLABELEDTR) ||
2512: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
2513: /* ignore columnalign attribute on mstyle elements */
2514: /* process it only on mtable elements */
2515: return;
2516:
2517: fullTable = (elType.ElTypeNum == MathML_EL_MTABLE);
2518: value = NULL;
2519: localValue = NULL;
2520: if (!delete)
2521: {
2522: length = TtaGetTextAttributeLength (attr);
2523: if (length > 0)
2524: {
2525: value = TtaGetMemory (length+1);
2526: value[0] = EOS;
2527: TtaGiveTextAttributeValue (attr, value, &length);
2528: }
2529: }
2530: /* if attribute columnalign is created or updated but has no value, don't
2531: do anything */
2532: if (!delete && !value)
2533: return;
2534:
2535: ptr = value;
2536: val = 0;
2537: /* get the first cell within the element */
2538: elType.ElTypeNum = MathML_EL_MTD;
2539: cell = TtaSearchTypedElement (elType, SearchInTree, el);
2540: if (cell && fullTable)
2541: {
2542: elType.ElTypeNum = MathML_EL_TableRow;
2543: row = TtaGetTypedAncestor (cell, elType);
2544: RowWithoutColalignAttr (&row, &cell, &localAttr, !allRows);
2545: if (localAttr)
2546: {
2547: length = TtaGetTextAttributeLength (localAttr);
2548: if (length > 0)
2549: {
2550: if (localValue)
2551: TtaFreeMemory (localValue);
2552: localValue = TtaGetMemory (length+1);
2553: localValue[0] = EOS;
2554: TtaGiveTextAttributeValue (localAttr, localValue, &length);
2555: ptr = localValue;
2556: }
2557: }
2558: }
2559: while (cell)
2560: {
2561: elType = TtaGetElementType (cell);
2562: /* skip comments and other non cell elements */
2563: if (elType.ElTypeNum == MathML_EL_MTD &&
2564: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
2565: {
2566: if (delete)
2567: DeleteIntColAlign (cell, doc);
2568: else
2569: {
2570: if (*ptr != EOS)
2571: {
2572: /* get next word in the attribute value */
2573: ptr = TtaSkipBlanks (ptr);
2574: /* process that word */
2575: if (*ptr != EOS && *ptr != ' ')
2576: {
2577: if (!strncasecmp (ptr, "left", 4))
2578: val = MathML_ATTR_IntColAlign_VAL_IntLeft;
2579: else if (!strncasecmp (ptr, "center", 6))
2580: val = MathML_ATTR_IntColAlign_VAL_IntCenter;
2581: else if (!strncasecmp (ptr, "right", 5))
2582: val = MathML_ATTR_IntColAlign_VAL_IntRight;
2583: else
2584: val = 0;
2585: /* skip the word that has been processed */
2586: while (*ptr != EOS && *ptr != ' ')
2587: ptr++;
2588: }
2589: }
2590: if (val > 0)
2591: SetIntColAlign (cell, val, doc);
2592: }
2593: }
2594: TtaNextSibling (&cell);
2595: if (!cell && fullTable && row)
2596: /* no more sibling cell. If the columnalign attribute is for the
2597: full table, get the first cell in the next row */
2598: {
2599: TtaNextSibling (&row);
2600: if (row)
2601: {
2602: /* parse value of columnalign attribute again from the beginning */
2603: ptr = value;
2604: RowWithoutColalignAttr (&row, &cell, &localAttr, !allRows);
2605: if (localAttr)
2606: {
2607: length = TtaGetTextAttributeLength (localAttr);
2608: if (length > 0)
2609: {
2610: if (localValue)
2611: TtaFreeMemory (localValue);
2612: localValue = TtaGetMemory (length+1);
2613: localValue[0] = EOS;
2614: TtaGiveTextAttributeValue (localAttr, localValue, &length);
2615: ptr = localValue;
2616: }
2617: }
2618: }
2619: }
2620: }
2621: if (value)
2622: TtaFreeMemory (value);
2623: if (localValue)
2624: TtaFreeMemory (localValue);
2625: }
2626:
2627: /*----------------------------------------------------------------------
1.167 quint 2628: HandleRowspacingAttribute
2629: An attribute rowspacing has been created, updated or deleted (if delete
2630: is TRUE) for element el in document doc. Update the top and bottom padding
2631: of all cells accordingly.
2632: ----------------------------------------------------------------------*/
2633: void HandleRowspacingAttribute (Attribute attr, Element el, Document doc,
2634: ThotBool delete)
2635: {
2636: ElementType elType, rowType, cellType;
2637: int length, val, topVal, topValUnit, bottomVal,
2638: bottomValUnit, rowspan, cellBottomVal, i;
2639: char *value, *ptr, *spanPtr;
2640: PresentationValue pval;
2641: PresentationContext ctxt;
2642: Element row, nextRow, cell;
2643: ThotBool stop, firstRow;
2644: AttributeType rowspanType;
2645: Attribute rowspanAttr;
2646:
2647: elType = TtaGetElementType (el);
2648: if (elType.ElTypeNum != MathML_EL_MTABLE ||
2649: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
2650: /* ignore rowspacing attribute on mstyle elements */
2651: /* process it only on mtable elements */
2652: return;
2653:
2654: value = NULL;
2655: if (!delete && attr)
2656: {
2657: length = TtaGetTextAttributeLength (attr);
2658: if (length > 0)
2659: {
2660: value = TtaGetMemory (length+1);
2661: value[0] = EOS;
2662: TtaGiveTextAttributeValue (attr, value, &length);
2663: }
2664: }
2665:
2666: ctxt = TtaGetSpecificStyleContext (doc);
2667: /* the specific presentation to be created is not a CSS rule */
2668: ctxt->cssSpecificity = 0;
2669: ptr = value;
2670: rowspanType.AttrSSchema = elType.ElSSchema;
2671: rowspanType.AttrTypeNum = MathML_ATTR_rowspan_;
2672:
2673: /* check all rows within the table */
2674: firstRow = TRUE;
2675: bottomVal = 0;
2676: elType.ElTypeNum = MathML_EL_TableRow;
2677: row = TtaSearchTypedElement (elType, SearchInTree, el);
2678: while (row)
2679: {
2680: /* get the next row to check if the current row is the last one */
2681: nextRow = row;
2682: stop = FALSE;
2683: do
2684: {
2685: TtaNextSibling (&nextRow);
2686: if (!nextRow)
2687: stop = TRUE;
2688: else
2689: {
2690: rowType = TtaGetElementType (nextRow);
2691: /* skip comments and other non mrow elements */
2692: if ((rowType.ElTypeNum == MathML_EL_MTR ||
2693: rowType.ElTypeNum == MathML_EL_MLABELEDTR) &&
2694: !strcmp (TtaGetSSchemaName (rowType.ElSSchema), "MathML"))
2695: /* it's the next mrow */
2696: stop = TRUE;
2697: }
2698: }
2699: while (!stop);
2700:
2701: /* prepare the value of the padding to be associated with the cells
2702: of that row */
2703: if (delete)
2704: /* remove the presentation rules */
2705: {
2706: pval.typed_data.value = 0;
2707: val = 0;
2708: }
2709: else
2710: {
2711: if (!value)
2712: {
2713: pval.typed_data.unit = STYLE_UNIT_PT;
2714: pval.typed_data.value = 0;
2715: pval.typed_data.real = FALSE;
2716: val = 0;
2717: }
2718: else
2719: {
2720: /* get the next field in the attribute value (a number followed
2721: by a unit) */
2722: ptr = TtaSkipBlanks (ptr);
2723: if (*ptr != EOS)
2724: {
2725: ptr = ParseCSSUnit (ptr, &pval);
2726: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
2727: {
2728: /* if the value is an integer, make it a real to avoid
2729: errors in dividing small integers, such as "1cm" */
2730: if (!pval.typed_data.real)
2731: {
2732: pval.typed_data.value *= 1000;
2733: pval.typed_data.real = TRUE;
2734: }
2735: val = pval.typed_data.value / 2;
2736: }
2737: }
2738: }
2739: }
2740:
2741: /* initialize the padding to be set at the top and at the bottom
2742: of each cell */
2743: /* the top padding of a row is the same as the bottom padding of the
2744: previous row */
2745: topVal = bottomVal;
2746: topValUnit = bottomValUnit;
2747: if (!nextRow)
2748: /* row is the last in the table. It must not have any padding
2749: at the bottom */
2750: bottomVal = 0;
2751: else
2752: {
2753: bottomVal = val;
2754: bottomValUnit = pval.typed_data.unit;
2755: }
2756:
2757: /* get the first cell of that row (ignoring Label cells) */
2758: elType.ElTypeNum = MathML_EL_MTD;
2759: cell = TtaSearchTypedElement (elType, SearchInTree, row);
2760: /* update attribute MLineBelowtop padding and bottom padding for all
2761: cells in that row */
2762: while (cell)
2763: {
2764: cellType = TtaGetElementType (cell);
2765: /* skip comments and other non mtd elements */
2766: if (cellType.ElTypeNum == MathML_EL_MTD &&
2767: !strcmp (TtaGetSSchemaName (cellType.ElSSchema), "MathML"))
2768: /* that's a mtd element. Process it */
2769: {
2770: /* by default, use the value for the current row */
2771: cellBottomVal = bottomVal;
2772: if (!delete && value)
2773: /* take row spanning into account */
2774: {
2775: /* is there a rowspan attribute on that cell? */
2776: rowspanAttr = TtaGetAttribute (cell, rowspanType);
2777: if (!rowspanAttr)
2778: rowspan = 1;
2779: else
2780: rowspan = TtaGetAttributeValue (rowspanAttr);
2781: if (!delete)
2782: {
2783: /* skip rowspan-1 words in the value of attribute
2784: rowlines */
2785: if (rowspan > 1)
2786: {
2787: spanPtr = ptr;
2788: for (i = 1; i < rowspan && *spanPtr != EOS; i++)
2789: {
2790: spanPtr = TtaSkipBlanks (spanPtr);
2791: spanPtr = ParseCSSUnit (spanPtr, &pval);
2792: }
2793: if (pval.typed_data.unit == STYLE_UNIT_INVALID)
2794: {
2795: val = 0;
2796: cellBottomVal = 0;
2797: bottomValUnit = STYLE_UNIT_PT;
2798: }
2799: else
2800: {
2801: /* if the value is an integer, make it a real to
2802: avoid errors in dividing small integers,
2803: such as "1cm" */
2804: if (!pval.typed_data.real)
2805: {
2806: pval.typed_data.value *= 1000;
2807: pval.typed_data.real = TRUE;
2808: }
2809: val = pval.typed_data.value / 2;
2810: cellBottomVal = val;
2811: bottomValUnit = pval.typed_data.unit;
2812: }
2813: }
2814: }
2815: }
2816:
2817: if ((delete || !value) && !firstRow)
2818: ctxt->destroy = TRUE;
2819: else
2820: {
2821: pval.typed_data.value = topVal;
2822: pval.typed_data.unit = topValUnit;
2823: ctxt->destroy = FALSE;
2824: }
2825: TtaSetStylePresentation (PRPaddingTop, cell, NULL, ctxt, pval);
2826: if ((delete || !value) && nextRow)
2827: ctxt->destroy = TRUE;
2828: else
2829: {
2830: pval.typed_data.value = cellBottomVal;
2831: pval.typed_data.unit = bottomValUnit;
2832: ctxt->destroy = FALSE;
2833: }
2834: TtaSetStylePresentation (PRPaddingBottom, cell, NULL, ctxt,pval);
2835: }
2836: TtaNextSibling (&cell);
2837: }
2838: row = nextRow;
2839: firstRow = FALSE;
2840: }
2841:
2842: TtaFreeMemory (ctxt);
2843: if (value)
2844: TtaFreeMemory (value);
2845: }
2846:
2847: /*----------------------------------------------------------------------
2848: ConvertNamedSpace
2849: if name is the name of a space, return the value of this space
2850: in value, otherwise return an empty string in value.
2851: -----------------------------------------------------------------------*/
2852: static char* ConvertNamedSpace (char *name, char *value)
2853: {
2854: if (strcmp (name, "veryverythinmathspace") == 0)
2855: {
2856: strcpy (value, "0.0555556em");
2857: return (name + strlen("veryverythinmathspace"));
2858: }
2859: else if (strcmp (name, "verythinmathspace") == 0)
2860: {
2861: strcpy (value, "0.111111em");
2862: return (name + strlen("verythinmathspace"));
2863: }
2864: else if (strcmp (name, "thinmathspace") == 0)
2865: {
2866: strcpy (value, "0.166667em");
2867: return (name + strlen("thinmathspace"));
2868: }
2869: else if (strcmp (name, "mediummathspace") == 0)
2870: {
2871: strcpy (value, "0.222222em");
2872: return (name + strlen("mediummathspace"));
2873: }
2874: else if (strcmp (name, "thickmathspace") == 0)
2875: {
2876: strcpy (value, "0.277778em");
2877: return (name + strlen("thickmathspace"));
2878: }
2879: else if (strcmp (name, "verythickmathspace") == 0)
2880: {
2881: strcpy (value, "0.333333em");
2882: return (name + strlen("verythickmathspace"));
2883: }
2884: else if (strcmp (name, "veryverythickmathspace") == 0)
2885: {
2886: strcpy (value, "0.388889em");
2887: return (name + strlen("veryverythickmathspace"));
2888: }
2889: else
2890: {
2891: value[0] = EOS;
2892: return name;
2893: }
2894: }
2895:
2896: /*----------------------------------------------------------------------
2897: HandleColumnspacingAttribute
2898: An attribute columnspacing has been created, updated or deleted (if delete
2899: is TRUE) for element el in document doc. Update the left and right padding
2900: of all cells accordingly.
2901: ----------------------------------------------------------------------*/
2902: void HandleColumnspacingAttribute (Attribute attr, Element el, Document doc,
2903: ThotBool delete)
2904: {
2905: ElementType elType;
2906: int length, val, valUnit, leftVal, leftValUnit,
2907: rightVal, rightValUnit, colspan, i;
2908: char *value, *ptr, valueOfNamedSpace[20];
2909: PresentationValue pval;
2910: PresentationContext ctxt;
2911: Element row, cell, nextCell;
2912: ThotBool stop, firstCell;
1.168 ! quint 2913: Attribute spanAttr;
1.167 quint 2914: AttributeType colspanType;
2915:
2916: elType = TtaGetElementType (el);
2917: if (elType.ElTypeNum != MathML_EL_MTABLE ||
2918: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
2919: /* ignore columnspacing attribute on mstyle elements */
2920: /* process it only on mtable elements */
2921: return;
2922:
2923: value = NULL;
2924: if (!delete && attr)
2925: {
2926: length = TtaGetTextAttributeLength (attr);
2927: if (length > 0)
2928: {
2929: value = TtaGetMemory (length+1);
2930: value[0] = EOS;
2931: TtaGiveTextAttributeValue (attr, value, &length);
2932: }
2933: }
2934:
2935: ctxt = TtaGetSpecificStyleContext (doc);
2936: /* the specific presentation to be created is not a CSS rule */
2937: ctxt->cssSpecificity = 0;
2938: val = 0;
2939: colspanType.AttrSSchema = elType.ElSSchema;
2940: colspanType.AttrTypeNum = MathML_ATTR_columnspan;
2941:
2942: /* check all cells in all rows within the table */
2943: elType.ElTypeNum = MathML_EL_TableRow;
2944: row = TtaSearchTypedElement (elType, SearchInTree, el);
2945: while (row)
2946: {
2947: elType = TtaGetElementType (row);
2948: if ((elType.ElTypeNum == MathML_EL_MTR ||
2949: elType.ElTypeNum == MathML_EL_MLABELEDTR) &&
2950: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
2951: /* that's a table row. check all its cells */
2952: {
2953: firstCell = TRUE;
2954: rightVal = 0;
2955: val = 0;
2956: valUnit = STYLE_UNIT_PT;
2957: ptr = value;
2958: /* get the first cell of that row (ignoring Label cells) */
2959: elType.ElTypeNum = MathML_EL_MTD;
2960: cell = TtaSearchTypedElement (elType, SearchInTree, row);
2961: while (cell)
2962: {
2963: /* prepare the value of the padding to be associated with the
2964: cells */
2965: if (delete)
2966: /* remove the presentation rules */
2967: {
2968: pval.typed_data.value = 0;
2969: val = 0;
2970: valUnit = STYLE_UNIT_PT;
2971: }
2972: else
2973: {
2974: if (!value)
2975: {
2976: pval.typed_data.unit = STYLE_UNIT_PT;
2977: pval.typed_data.value = 0;
2978: pval.typed_data.real = FALSE;
2979: val = 0;
2980: valUnit = STYLE_UNIT_PT;
2981: }
2982: else
2983: {
2984: /* parse the next field in the attribute value (a number
2985: followed by a unit or a named space) */
2986: ptr = TtaSkipBlanks (ptr);
2987: if (*ptr != EOS)
2988: {
2989: /* is there a columnspan attribute on that cell? */
2990: spanAttr = TtaGetAttribute (cell, colspanType);
2991: if (!spanAttr)
2992: colspan = 1;
2993: else
2994: colspan = TtaGetAttributeValue (spanAttr);
2995: /* skip (colspan - 1) words in the attribute */
2996: for (i = 1; i <= colspan && *ptr != EOS; i++)
2997: {
2998: ptr = TtaSkipBlanks (ptr);
2999: ptr = ConvertNamedSpace (ptr, valueOfNamedSpace);
3000: if (valueOfNamedSpace[0] != EOS)
3001: /* it's a named space */
3002: ptr = ParseCSSUnit (valueOfNamedSpace, &pval);
3003: else
3004: ptr = ParseCSSUnit (ptr, &pval);
3005: if (pval.typed_data.unit == STYLE_UNIT_INVALID)
3006: {
3007: val = 0;
3008: valUnit = STYLE_UNIT_PT;
3009: }
3010: else
3011: {
3012: /* if the value is an integer, make it a real
3013: to avoid errors in dividing small
3014: integers, such as "1cm" */
3015: if (!pval.typed_data.real)
3016: {
3017: pval.typed_data.value *= 1000;
3018: pval.typed_data.real = TRUE;
3019: }
3020: val = pval.typed_data.value / 2;
3021: valUnit = pval.typed_data.unit;
3022: }
3023: }
3024: }
3025: }
3026: }
3027:
3028: /* get the next cell in the current row to check if the current
3029: cell is the last one in the row */
3030: nextCell = cell;
3031: stop = FALSE;
3032: do
3033: {
3034: TtaNextSibling (&nextCell);
3035: if (!nextCell)
3036: stop = TRUE;
3037: else
3038: {
3039: elType = TtaGetElementType (nextCell);
3040: /* skip comments and other non mtd elements */
3041: if (elType.ElTypeNum == MathML_EL_MTD &&
3042: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
3043: /* it's the next cell */
3044: stop = TRUE;
3045: }
3046: }
3047: while (!stop);
3048:
3049: /* initialize the padding to be set at the right and at the left
3050: of each cell */
3051: /* the leftPadding of a cell is the same as the right padding
3052: of the previous cell */
3053: leftVal = rightVal;
3054: leftValUnit = rightValUnit;
3055: if (!nextCell)
3056: /* it's the last cell in the row. It must not have any
3057: padding on the right */
3058: {
3059: rightVal = 0;
3060: rightValUnit = STYLE_UNIT_PT;
3061: }
3062: else
3063: {
3064: rightVal = val;
3065: rightValUnit = valUnit;
3066: }
3067:
3068: /* set the left and right padding for this cell */
3069: if ((delete || !value) && !firstCell)
3070: ctxt->destroy = TRUE;
3071: else
3072: {
3073: pval.typed_data.value = leftVal;
3074: pval.typed_data.unit = leftValUnit;
3075: ctxt->destroy = FALSE;
3076: }
3077: TtaSetStylePresentation (PRPaddingLeft, cell, NULL, ctxt, pval);
3078: if ((delete || !value) && nextCell)
3079: ctxt->destroy = TRUE;
3080: else
3081: {
3082: pval.typed_data.value = rightVal;
3083: pval.typed_data.unit = rightValUnit;
3084: ctxt->destroy = FALSE;
3085: }
3086: TtaSetStylePresentation (PRPaddingRight, cell, NULL, ctxt, pval);
3087: cell = nextCell;
3088: firstCell = FALSE;
3089: }
3090: }
3091: TtaNextSibling (&row);
3092: }
3093:
3094: if (value)
3095: TtaFreeMemory (value);
3096: }
3097:
3098: /*----------------------------------------------------------------------
1.159 quint 3099: HandleRowlinesAttribute
3100: An attribute rowlines has been created, updated or deleted (if delete
3101: is TRUE) for element el in document doc. Update attribute MLineBelow
3102: of all cells accordingly.
3103: ----------------------------------------------------------------------*/
3104: void HandleRowlinesAttribute (Attribute attr, Element el, Document doc,
3105: ThotBool delete)
3106: {
3107: char *value;
1.160 quint 3108: char *ptr, *spanPtr;
3109: int length, val, rowspan, i, cellVal;
1.159 quint 3110: ElementType elType, rowType, cellType;
3111: Element row, nextRow, cell;
3112: ThotBool stop;
1.160 quint 3113: AttributeType attrType, rowspanType;
3114: Attribute intAttr, rowspanAttr;
1.159 quint 3115:
3116: elType = TtaGetElementType (el);
3117: if (elType.ElTypeNum != MathML_EL_MTABLE ||
3118: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
3119: /* ignore rowlines attribute on mstyle elements */
3120: /* process it only on mtable elements */
3121: return;
3122:
3123: value = NULL;
3124: if (!delete)
3125: {
3126: length = TtaGetTextAttributeLength (attr);
3127: if (length > 0)
3128: {
3129: value = TtaGetMemory (length+1);
3130: value[0] = EOS;
3131: TtaGiveTextAttributeValue (attr, value, &length);
3132: }
3133: }
3134: /* if attribute rowlines is created or updated but has no value, don't
3135: do anything */
3136: if (!delete && !value)
3137: return;
3138:
3139: ptr = value;
3140: val = 0;
3141: attrType.AttrSSchema = elType.ElSSchema;
1.160 quint 3142: rowspanType.AttrSSchema = elType.ElSSchema;
3143: rowspanType.AttrTypeNum = MathML_ATTR_rowspan_;
1.159 quint 3144:
3145: /* check all rows within the table */
3146: elType.ElTypeNum = MathML_EL_TableRow;
3147: row = TtaSearchTypedElement (elType, SearchInTree, el);
3148: while (row)
3149: {
3150: /* get the next row to check if the current row is the last one */
3151: nextRow = row;
3152: stop = FALSE;
3153: do
3154: {
3155: TtaNextSibling (&nextRow);
3156: if (!nextRow)
3157: stop = TRUE;
3158: else
3159: {
3160: rowType = TtaGetElementType (nextRow);
3161: /* skip comments and other non mrow elements */
3162: if ((rowType.ElTypeNum == MathML_EL_MTR ||
3163: rowType.ElTypeNum == MathML_EL_MLABELEDTR) &&
3164: !strcmp (TtaGetSSchemaName (rowType.ElSSchema), "MathML"))
3165: /* it's the next mrow */
3166: stop = TRUE;
3167: }
3168: }
3169: while (!stop);
3170:
3171: if (!nextRow)
3172: /* row is the last in the table. It must not have a line
3173: at the bottom. Delete it if there is one */
3174: val = 0;
3175: else
3176: {
3177: if (delete)
3178: val = 0;
3179: else
3180: if (*ptr != EOS)
3181: {
3182: /* get next word in the attribute value */
3183: ptr = TtaSkipBlanks (ptr);
3184: /* process that word */
3185: if (*ptr != EOS && *ptr != ' ')
3186: {
3187: if (!strncasecmp (ptr, "none", 4))
3188: val = 0;
3189: else if (!strncasecmp (ptr, "solid", 5))
3190: val = MathML_ATTR_MLineBelow_VAL_solid_;
3191: else if (!strncasecmp (ptr, "dashed", 6))
3192: val = MathML_ATTR_MLineBelow_VAL_dashed_;
3193: else
3194: val = 0;
3195: /* skip the word that has been processed */
3196: while (*ptr != EOS && *ptr != ' ')
3197: ptr++;
3198: }
3199: }
3200: }
3201: /* get the first cell of that row (ignoring Label cells) */
3202: elType.ElTypeNum = MathML_EL_MTD;
3203: cell = TtaSearchTypedElement (elType, SearchInTree, row);
3204: /* update attribute MLineBelow for all cells in that row */
3205: while (cell)
3206: {
3207: cellType = TtaGetElementType (cell);
3208: /* skip comments and other non mtd elements */
3209: if (cellType.ElTypeNum == MathML_EL_MTD &&
3210: !strcmp (TtaGetSSchemaName (cellType.ElSSchema), "MathML"))
3211: /* that's a mtd element. Process it */
3212: {
1.160 quint 3213: /* is there a rowspan attribute on that cell? */
3214: rowspanAttr = TtaGetAttribute (cell, rowspanType);
3215: if (!rowspanAttr)
3216: rowspan = 1;
3217: else
3218: rowspan = TtaGetAttributeValue (rowspanAttr);
1.161 quint 3219: /* by default, use the value for the current row */
3220: cellVal = val;
3221: if (!delete)
1.160 quint 3222: {
1.161 quint 3223: /* skip rowspan-1 words in the value of attribute rowlines */
3224: if (rowspan > 1)
1.160 quint 3225: {
1.161 quint 3226: spanPtr = ptr;
3227: for (i = 1; i < rowspan && *spanPtr != EOS; i++)
1.160 quint 3228: {
1.161 quint 3229: spanPtr = TtaSkipBlanks (spanPtr);
3230: if (*spanPtr != EOS && *spanPtr != ' ')
3231: {
3232: if (!strncasecmp (spanPtr, "none", 4))
3233: cellVal = 0;
3234: else if (!strncasecmp (spanPtr, "solid", 5))
3235: cellVal = MathML_ATTR_MLineBelow_VAL_solid_;
3236: else if (!strncasecmp (spanPtr, "dashed", 6))
3237: cellVal = MathML_ATTR_MLineBelow_VAL_dashed_;
3238: else
3239: cellVal = 0;
3240: }
3241: /* skip the word that has been processed */
3242: while (*spanPtr != EOS && *spanPtr != ' ')
3243: spanPtr++;
1.160 quint 3244: }
3245: }
3246: }
1.161 quint 3247: if (rowspan == 1)
3248: attrType.AttrTypeNum = MathML_ATTR_MLineBelow;
3249: else
3250: attrType.AttrTypeNum = MathML_ATTR_MLineBelowExt;
1.159 quint 3251: intAttr = TtaGetAttribute (cell, attrType);
1.160 quint 3252: if (cellVal == 0)
1.159 quint 3253: {
3254: if (intAttr)
3255: /* remove attribute MLineBelow */
3256: TtaRemoveAttribute (cell, intAttr, doc);
3257: }
3258: else
3259: /* set attribute MLineBelow */
3260: {
3261: if (!intAttr)
3262: {
3263: intAttr = TtaNewAttribute (attrType);
3264: TtaAttachAttribute (cell, intAttr, doc);
3265: }
1.160 quint 3266: TtaSetAttributeValue (intAttr, cellVal, cell, doc);
1.159 quint 3267: }
3268: }
3269: TtaNextSibling (&cell);
3270: }
3271: row = nextRow;
3272: }
3273: if (value)
3274: TtaFreeMemory (value);
3275: }
3276:
3277: /*----------------------------------------------------------------------
3278: HandleColumnlinesAttribute
3279: An attribute columnlines has been created, updated or deleted (if delete
3280: is TRUE) for element el in document doc. Update attribute MLineOnTheRight
3281: of all cells accordingly.
3282: ----------------------------------------------------------------------*/
3283: void HandleColumnlinesAttribute (Attribute attr, Element el, Document doc,
3284: ThotBool delete)
3285: {
3286: char *value;
3287: char *ptr;
1.161 quint 3288: int length, val, colspan, rowspan, i;
1.159 quint 3289: ElementType elType;
3290: Element row, cell, nextCell;
3291: ThotBool stop;
1.161 quint 3292: AttributeType attrType, colspanType, rowspanType;
3293: Attribute intAttr, spanAttr;
1.159 quint 3294:
3295: elType = TtaGetElementType (el);
3296: if (elType.ElTypeNum != MathML_EL_MTABLE ||
3297: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
3298: /* ignore rowlines attribute on mstyle elements */
3299: /* process it only on mtable elements */
3300: return;
3301:
3302: value = NULL;
3303: if (!delete)
3304: {
3305: length = TtaGetTextAttributeLength (attr);
3306: if (length > 0)
3307: {
3308: value = TtaGetMemory (length+1);
3309: value[0] = EOS;
3310: TtaGiveTextAttributeValue (attr, value, &length);
3311: }
3312: }
3313: /* if attribute columnlines is created or updated but has no value, don't
3314: do anything */
3315: if (!delete && !value)
3316: return;
3317:
3318: val = 0;
3319: attrType.AttrSSchema = elType.ElSSchema;
1.160 quint 3320: colspanType.AttrSSchema = elType.ElSSchema;
3321: colspanType.AttrTypeNum = MathML_ATTR_columnspan;
1.161 quint 3322: rowspanType.AttrSSchema = elType.ElSSchema;
3323: rowspanType.AttrTypeNum = MathML_ATTR_rowspan_;
1.159 quint 3324:
3325: /* check all cells in all rows in the table */
3326: elType.ElTypeNum = MathML_EL_TableRow;
3327: row = TtaSearchTypedElement (elType, SearchInTree, el);
3328: while (row)
3329: {
3330: elType = TtaGetElementType (row);
3331: if ((elType.ElTypeNum == MathML_EL_MTR ||
3332: elType.ElTypeNum == MathML_EL_MLABELEDTR) &&
3333: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
3334: /* that's a table row. check all its cells */
3335: {
3336: /* start from the beginning of the columnlines attribute */
3337: ptr = value;
3338: val = 0;
3339: /* get the first cell of that row (ignoring Label cells) */
3340: elType.ElTypeNum = MathML_EL_MTD;
3341: cell = TtaSearchTypedElement (elType, SearchInTree, row);
3342: while (cell)
3343: {
3344: /* get the next cell in the current row to check if the current
3345: cell is the last one in the row */
3346: nextCell = cell;
3347: stop = FALSE;
3348: do
3349: {
3350: TtaNextSibling (&nextCell);
3351: if (!nextCell)
3352: stop = TRUE;
3353: else
3354: {
3355: elType = TtaGetElementType (nextCell);
3356: /* skip comments and other non mtd elements */
3357: if (elType.ElTypeNum == MathML_EL_MTD &&
3358: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
3359: /* it's the next cell */
3360: stop = TRUE;
3361: }
3362: }
3363: while (!stop);
3364:
1.161 quint 3365: /* is there a rowspan attribute on that cell? */
3366: spanAttr = TtaGetAttribute (cell, rowspanType);
3367: if (!spanAttr)
3368: rowspan = 1;
3369: else
3370: rowspan = TtaGetAttributeValue (spanAttr);
3371:
1.159 quint 3372: if (!nextCell)
3373: /* it's the last cell in the row. It must not have a line
3374: on its right edge. Delete it if there is noe. */
3375: val = 0;
3376: else
3377: /* set the attribute MLineOnTheRight for this cell */
3378: {
3379: if (delete)
3380: val = 0;
3381: else
3382: if (*ptr != EOS)
3383: {
1.161 quint 3384: /* is there a columnspan attribute on that cell? */
3385: spanAttr = TtaGetAttribute (cell, colspanType);
3386: if (!spanAttr)
1.160 quint 3387: colspan = 1;
3388: else
1.161 quint 3389: colspan = TtaGetAttributeValue (spanAttr);
1.160 quint 3390: /* skip (colspan - 1) words in the attribute */
3391: for (i = 1; i <= colspan && *ptr != EOS; i++)
1.159 quint 3392: {
1.160 quint 3393: /* get next word in the attribute value */
3394: ptr = TtaSkipBlanks (ptr);
3395: /* process that word */
3396: if (*ptr != EOS && *ptr != ' ')
3397: {
3398: if (!strncasecmp (ptr, "none", 4))
3399: val = 0;
3400: else if (!strncasecmp (ptr, "solid", 5))
3401: val = MathML_ATTR_MLineOnTheRight_VAL_solid_;
3402: else if (!strncasecmp (ptr, "dashed", 6))
3403: val = MathML_ATTR_MLineOnTheRight_VAL_dashed_;
3404: else
3405: val = 0;
3406: /* skip the word that has been processed */
3407: while (*ptr != EOS && *ptr != ' ')
3408: ptr++;
3409: }
1.159 quint 3410: }
3411: }
3412: }
1.161 quint 3413: if (rowspan == 1)
3414: attrType.AttrTypeNum = MathML_ATTR_MLineOnTheRight;
3415: else
3416: attrType.AttrTypeNum = MathML_ATTR_MLineOnTheRightExt;
1.159 quint 3417: intAttr = TtaGetAttribute (cell, attrType);
3418: if (val == 0)
3419: {
3420: if (intAttr)
3421: /* remove attribute MLineOnTheRight */
3422: TtaRemoveAttribute (cell, intAttr, doc);
3423: }
3424: else
3425: /* set attribute MLineOnTheRight */
3426: {
3427: if (!intAttr)
3428: {
3429: intAttr = TtaNewAttribute (attrType);
3430: TtaAttachAttribute (cell, intAttr, doc);
3431: }
3432: TtaSetAttributeValue (intAttr, val, cell, doc);
3433: }
3434: cell = nextCell;
3435: }
3436: }
3437: TtaNextSibling (&row);
3438: }
3439: if (value)
3440: TtaFreeMemory (value);
3441: }
3442:
3443: /*----------------------------------------------------------------------
1.168 ! quint 3444: HandleFramespacingAttribute
! 3445: An attribute framespacing has been created, updated or deleted (if delete
! 3446: is TRUE) for element el in document doc. Update attribute the padding
! 3447: properties of the concerned table(s).
! 3448: ----------------------------------------------------------------------*/
! 3449: void HandleFramespacingAttribute (Attribute attr, Element el, Document doc,
! 3450: ThotBool delete)
! 3451: {
! 3452: ElementType elType;
! 3453: char *value, *ptr, valueOfNamedSpace[20];
! 3454: int length, vertPadding, horizPadding, vertPaddingUnit,
! 3455: horizPaddingUnit;
! 3456: Attribute attrFrame;
! 3457: AttributeType attrType;
! 3458: PresentationValue pval;
! 3459: PresentationContext ctxt;
! 3460: ThotBool vertPaddingReal, horizPaddingReal;
! 3461:
! 3462: if ((!delete && !attr) || !el)
! 3463: return;
! 3464: elType = TtaGetElementType (el);
! 3465: if (elType.ElTypeNum != MathML_EL_MTABLE ||
! 3466: strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
! 3467: /* ignore framespacing attribute on mstyle elements */
! 3468: /* process it only on mtable elements */
! 3469: return;
! 3470:
! 3471: value = NULL;
! 3472: if (!delete)
! 3473: {
! 3474: length = TtaGetTextAttributeLength (attr);
! 3475: if (length > 0)
! 3476: {
! 3477: value = TtaGetMemory (length+1);
! 3478: value[0] = EOS;
! 3479: TtaGiveTextAttributeValue (attr, value, &length);
! 3480: }
! 3481: }
! 3482: ctxt = TtaGetSpecificStyleContext (doc);
! 3483: /* the specific presentation to be created is not a CSS rule */
! 3484: ctxt->cssSpecificity = 0;
! 3485: vertPadding = 0;
! 3486: horizPadding = 0;
! 3487: vertPaddingUnit = STYLE_UNIT_PT;
! 3488: horizPaddingUnit = STYLE_UNIT_PT;
! 3489: vertPaddingReal = FALSE;
! 3490: horizPaddingReal = FALSE;
! 3491: /* is there a frame attribute? */
! 3492: attrType.AttrSSchema = elType.ElSSchema;
! 3493: attrType.AttrTypeNum = MathML_ATTR_frame;
! 3494: attrFrame = TtaGetAttribute (el, attrType);
! 3495: if (!delete && value && attrFrame)
! 3496: {
! 3497: ptr = value;
! 3498: /* parse the first part: horizontal spacing */
! 3499: ptr = TtaSkipBlanks (ptr);
! 3500: if (*ptr != EOS)
! 3501: {
! 3502: ptr = ConvertNamedSpace (ptr, valueOfNamedSpace);
! 3503: if (valueOfNamedSpace[0] != EOS)
! 3504: /* it's a named space */
! 3505: ptr = ParseCSSUnit (valueOfNamedSpace, &pval);
! 3506: else
! 3507: ptr = ParseCSSUnit (ptr, &pval);
! 3508: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
! 3509: {
! 3510: horizPadding = pval.typed_data.value;
! 3511: horizPaddingUnit = pval.typed_data.unit;
! 3512: horizPaddingReal = pval.typed_data.real;
! 3513: /* if there is no second part, the vertical spacing is the same
! 3514: as the horizontal spacing */
! 3515: vertPadding = horizPadding;
! 3516: vertPaddingUnit = horizPaddingUnit;
! 3517: vertPaddingReal = horizPaddingReal;
! 3518: /* parse the second part, if any */
! 3519: ptr = TtaSkipBlanks (ptr);
! 3520: if (*ptr != EOS)
! 3521: {
! 3522: ptr = ConvertNamedSpace (ptr, valueOfNamedSpace);
! 3523: if (valueOfNamedSpace[0] != EOS)
! 3524: /* it's a named space */
! 3525: ptr = ParseCSSUnit (valueOfNamedSpace, &pval);
! 3526: else
! 3527: ptr = ParseCSSUnit (ptr, &pval);
! 3528: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
! 3529: {
! 3530: vertPadding = pval.typed_data.value;
! 3531: vertPaddingUnit = pval.typed_data.unit;
! 3532: vertPaddingReal = pval.typed_data.real;
! 3533: }
! 3534: }
! 3535: }
! 3536: }
! 3537: }
! 3538: if (delete)
! 3539: ctxt->destroy = TRUE;
! 3540: else
! 3541: {
! 3542: ctxt->destroy = FALSE;
! 3543: pval.typed_data.value = horizPadding;
! 3544: pval.typed_data.unit = horizPaddingUnit;
! 3545: pval.typed_data.real = horizPaddingReal;
! 3546: }
! 3547: TtaSetStylePresentation (PRPaddingLeft, el, NULL, ctxt, pval);
! 3548: TtaSetStylePresentation (PRPaddingRight, el, NULL, ctxt, pval);
! 3549: if (!delete)
! 3550: {
! 3551: pval.typed_data.value = vertPadding;
! 3552: pval.typed_data.unit = vertPaddingUnit;
! 3553: pval.typed_data.real = vertPaddingReal;
! 3554: }
! 3555: TtaSetStylePresentation (PRPaddingTop, el, NULL, ctxt, pval);
! 3556: TtaSetStylePresentation (PRPaddingBottom, el, NULL, ctxt, pval);
! 3557:
! 3558: if (value)
! 3559: TtaFreeMemory (value);
! 3560: }
! 3561:
! 3562: /*----------------------------------------------------------------------
1.1 cvs 3563: MathMLElementComplete
3564: Check the Thot structure of the MathML element el.
3565: ----------------------------------------------------------------------*/
1.156 cvs 3566: void MathMLElementComplete (ParserData *context, Element el, int *error)
1.1 cvs 3567: {
1.156 cvs 3568: Document doc;
1.74 cvs 3569: ElementType elType, parentType;
1.1 cvs 3570: Element child, parent, new, prev, next;
1.101 cvs 3571: AttributeType attrType;
3572: Attribute attr;
1.56 cvs 3573: SSchema MathMLSSchema;
3574: ThotBool ok;
1.1 cvs 3575:
1.56 cvs 3576: ok = TRUE;
3577: *error = 0;
1.156 cvs 3578: doc = context->doc;
1.1 cvs 3579: elType = TtaGetElementType (el);
1.2 cvs 3580: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 3581:
1.76 cvs 3582: if (elType.ElSSchema == MathMLSSchema)
1.1 cvs 3583: {
3584: switch (elType.ElTypeNum)
3585: {
1.76 cvs 3586: case MathML_EL_MathML:
3587: /* Create placeholders within the MathML element */
3588: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.132 cvs 3589: break;
1.1 cvs 3590: case MathML_EL_MI:
3591: SetFontstyleAttr (el, doc);
3592: break;
3593: case MathML_EL_MO:
1.22 cvs 3594: SetIntAddSpaceAttr (el, doc);
3595: SetIntVertStretchAttr (el, doc, 0, NULL);
1.58 cvs 3596: /* if the MO element is a child of a MROW (or equivalent) and if it
3597: contains a fence character, transform this MO into MF and
3598: transform the fence character into a Thot SYMBOL */
3599: CheckFence (el, doc);
1.1 cvs 3600: break;
1.60 cvs 3601: case MathML_EL_MSPACE:
3602: break;
1.39 cvs 3603: case MathML_EL_MROW:
1.55 cvs 3604: /* Create placeholders within the MROW */
3605: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.39 cvs 3606: break;
3607: case MathML_EL_MFRAC:
1.54 cvs 3608: case MathML_EL_BevelledMFRAC:
1.39 cvs 3609: /* end of a fraction. Create a Numerator and a Denominator */
1.56 cvs 3610: ok = CheckMathSubExpressions (el, MathML_EL_Numerator,
3611: MathML_EL_Denominator, 0, doc);
1.39 cvs 3612: break;
3613: case MathML_EL_MSQRT:
1.50 cvs 3614: /* end of a Square Root */
3615: /* Create placeholders within the element */
3616: CreatePlaceholders (TtaGetFirstChild (el), doc);
3617: /* Create a SqrtBase that contains all children of the MSQRT */
1.39 cvs 3618: CreateWrapper (el, MathML_EL_SqrtBase, doc);
3619: break;
1.1 cvs 3620: case MathML_EL_MROOT:
3621: /* end of a Root. Create a RootBase and an Index */
1.56 cvs 3622: ok = CheckMathSubExpressions (el, MathML_EL_RootBase,
3623: MathML_EL_Index, 0, doc);
1.1 cvs 3624: break;
1.50 cvs 3625: case MathML_EL_MENCLOSE:
3626: /* Create placeholders within the element */
3627: CreatePlaceholders (TtaGetFirstChild (el), doc);
3628: break;
1.39 cvs 3629: case MathML_EL_MSTYLE:
3630: case MathML_EL_MERROR:
3631: case MathML_EL_MPADDED:
3632: case MathML_EL_MPHANTOM:
3633: /* Create placeholders within the element */
3634: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 3635: break;
3636: case MathML_EL_MFENCED:
3637: TransformMFENCED (el, doc);
3638: break;
3639: case MathML_EL_MSUB:
3640: /* end of a MSUB. Create Base and Subscript */
1.56 cvs 3641: ok = CheckMathSubExpressions (el, MathML_EL_Base,
3642: MathML_EL_Subscript, 0, doc);
1.59 cvs 3643: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
1.22 cvs 3644: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 3645: break;
3646: case MathML_EL_MSUP:
3647: /* end of a MSUP. Create Base and Superscript */
1.56 cvs 3648: ok = CheckMathSubExpressions (el, MathML_EL_Base,
3649: MathML_EL_Superscript, 0, doc);
1.59 cvs 3650: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.22 cvs 3651: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 3652: break;
1.39 cvs 3653: case MathML_EL_MSUBSUP:
3654: /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
1.56 cvs 3655: ok = CheckMathSubExpressions (el, MathML_EL_Base,
3656: MathML_EL_Subscript,
3657: MathML_EL_Superscript, doc);
1.59 cvs 3658: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
3659: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.39 cvs 3660: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 3661: break;
3662: case MathML_EL_MUNDER:
3663: /* end of a MUNDER. Create UnderOverBase, and Underscript */
1.56 cvs 3664: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
3665: MathML_EL_Underscript, 0, doc);
1.22 cvs 3666: SetIntHorizStretchAttr (el, doc);
3667: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 3668: break;
3669: case MathML_EL_MOVER:
3670: /* end of a MOVER. Create UnderOverBase, and Overscript */
1.56 cvs 3671: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
3672: MathML_EL_Overscript, 0, doc);
1.22 cvs 3673: SetIntHorizStretchAttr (el, doc);
3674: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 3675: break;
1.39 cvs 3676: case MathML_EL_MUNDEROVER:
3677: /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
3678: Overscript */
1.56 cvs 3679: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
3680: MathML_EL_Underscript,
3681: MathML_EL_Overscript, doc);
1.39 cvs 3682: SetIntHorizStretchAttr (el, doc);
3683: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
3684: break;
1.1 cvs 3685: case MathML_EL_MMULTISCRIPTS:
3686: /* end of a MMULTISCRIPTS. Create all elements defined in the
3687: MathML S schema */
3688: BuildMultiscript (el, doc);
1.5 cvs 3689: break;
3690: case MathML_EL_MTABLE:
3691: /* end of a MTABLE. Create all elements defined in the MathML S
3692: schema */
1.64 cvs 3693: CheckMTable (el, doc, TRUE);
1.101 cvs 3694: /* if the table has a rowalign attribute, process it */
3695: attrType.AttrSSchema = MathMLSSchema;
3696: attrType.AttrTypeNum = MathML_ATTR_rowalign;
3697: attr = TtaGetAttribute (el, attrType);
3698: if (attr)
3699: HandleRowalignAttribute (attr, el, doc, FALSE);
3700: /* if the table has a columnalign attribute, process it */
3701: attrType.AttrTypeNum = MathML_ATTR_columnalign;
3702: attr = TtaGetAttribute (el, attrType);
3703: if (attr)
1.108 cvs 3704: HandleColalignAttribute (attr, el, doc, FALSE, FALSE);
1.167 quint 3705: /* process the rowspacing attribute, or set the top padding of the
3706: first row and the bottom padding of the last row to 0. */
3707: attrType.AttrSSchema = MathMLSSchema;
3708: attrType.AttrTypeNum = MathML_ATTR_rowspacing;
3709: attr = TtaGetAttribute (el, attrType);
3710: HandleRowspacingAttribute (attr, el, doc, FALSE);
3711: /* process the columnspacing attribute, or set the left padding of
3712: the first column and the right padding of the last column to 0 */
3713: attrType.AttrSSchema = MathMLSSchema;
3714: attrType.AttrTypeNum = MathML_ATTR_columnspacing;
3715: attr = TtaGetAttribute (el, attrType);
3716: HandleColumnspacingAttribute (attr, el, doc, FALSE);
1.159 quint 3717: /* if the table has a rowlines attribute, process it */
3718: attrType.AttrSSchema = MathMLSSchema;
3719: attrType.AttrTypeNum = MathML_ATTR_rowlines;
3720: attr = TtaGetAttribute (el, attrType);
3721: if (attr)
1.167 quint 3722: HandleRowlinesAttribute (attr, el, doc, FALSE);
1.159 quint 3723: /* if the table has a columnlines attribute, process it */
3724: attrType.AttrTypeNum = MathML_ATTR_columnlines;
3725: attr = TtaGetAttribute (el, attrType);
3726: if (attr)
3727: HandleColumnlinesAttribute (attr, el, doc, FALSE);
1.101 cvs 3728: break;
3729: case MathML_EL_MTR:
3730: /* if the row has a columnalign attribute, process it */
3731: attrType.AttrSSchema = MathMLSSchema;
3732: attrType.AttrTypeNum = MathML_ATTR_columnalign;
3733: attr = TtaGetAttribute (el, attrType);
3734: if (attr)
1.108 cvs 3735: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.101 cvs 3736: break;
3737: case MathML_EL_MLABELEDTR:
3738: /* if the row has a columnalign attribute, process it */
3739: attrType.AttrSSchema = MathMLSSchema;
3740: attrType.AttrTypeNum = MathML_ATTR_columnalign;
3741: attr = TtaGetAttribute (el, attrType);
3742: if (attr)
1.108 cvs 3743: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.1 cvs 3744: break;
1.39 cvs 3745: case MathML_EL_MTD:
3746: /* Create placeholders within the table cell */
3747: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.46 cvs 3748: break;
1.39 cvs 3749: case MathML_EL_MACTION:
3750: /* Create placeholders within the MACTION element */
3751: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 3752: break;
3753: default:
3754: break;
3755: }
3756: parent = TtaGetParent (el);
1.118 cvs 3757: if (parent)
3758: {
3759: parentType = TtaGetElementType (parent);
3760: if (parentType.ElSSchema != elType.ElSSchema)
3761: /* root of a MathML tree, Create a MathML element if there is no */
3762: if (elType.ElTypeNum != MathML_EL_MathML)
3763: {
3764: elType.ElSSchema = MathMLSSchema;
3765: elType.ElTypeNum = MathML_EL_MathML;
3766: new = TtaNewElement (doc, elType);
3767: TtaInsertSibling (new, el, TRUE, doc);
3768: next = el;
3769: TtaNextSibling (&next);
3770: TtaRemoveTree (el, doc);
3771: TtaInsertFirstChild (&el, new, doc);
3772: prev = el;
3773: while (next != NULL)
3774: {
3775: child = next;
3776: TtaNextSibling (&next);
3777: TtaRemoveTree (child, doc);
3778: TtaInsertSibling (child, prev, FALSE, doc);
3779: prev = child;
3780: }
3781: /* Create placeholders within the MathML element */
3782: CreatePlaceholders (el, doc);
3783: }
3784: }
1.1 cvs 3785: }
1.56 cvs 3786: if (!ok)
3787: /* send an error message */
3788: *error = 1;
1.1 cvs 3789: }
3790:
3791: /*----------------------------------------------------------------------
1.126 cvs 3792: UnknownMathMLNameSpace
1.149 cvs 3793: The element doesn't belong to a supported namespace
1.126 cvs 3794: ----------------------------------------------------------------------*/
1.149 cvs 3795: void UnknownMathMLNameSpace (ParserData *context,
3796: Element *unknownEl,
3797: char* content)
1.126 cvs 3798: {
3799: ElementType elType;
1.149 cvs 3800: Element elText;
1.126 cvs 3801:
3802: /* Create a new Invalid_element */
3803: elType.ElSSchema = GetXMLSSchema (MATH_TYPE, context->doc);
3804: elType.ElTypeNum = MathML_EL_Unknown_namespace;
1.149 cvs 3805: *unknownEl = TtaNewElement (context->doc, elType);
3806: if (*unknownEl != NULL)
1.126 cvs 3807: {
1.149 cvs 3808: XmlSetElemLineNumber (*unknownEl);
3809: InsertXmlElement (unknownEl);
1.126 cvs 3810: context->lastElementClosed = TRUE;
3811: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
3812: elText = TtaNewElement (context->doc, elType);
3813: XmlSetElemLineNumber (elText);
1.149 cvs 3814: TtaInsertFirstChild (&elText, *unknownEl, context->doc);
1.126 cvs 3815: TtaSetTextContent (elText, content, context->language, context->doc);
3816: TtaSetAccessRight (elText, ReadOnly, context->doc);
3817: }
3818: }
3819:
3820: /*----------------------------------------------------------------------
1.24 cvs 3821: SetFontfamily
3822: -----------------------------------------------------------------------*/
1.120 cvs 3823: void SetFontfamily (Document doc, Element el, char *value)
1.24 cvs 3824: {
3825: #define buflen 50
1.116 cvs 3826: char css_command[buflen+20];
1.24 cvs 3827:
1.116 cvs 3828: sprintf (css_command, "font-family: %s", value);
1.72 cvs 3829: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 3830: }
3831:
3832: /*----------------------------------------------------------------------
1.83 cvs 3833: MathMLlinethickness
3834: The MathML attribute linthickness is associated with element el. Generate
3835: the corresponding style property for this element.
3836: -----------------------------------------------------------------------*/
1.120 cvs 3837: void MathMLlinethickness (Document doc, Element el, char *value)
1.83 cvs 3838: {
3839: #define buflen 50
1.116 cvs 3840: char css_command[buflen+20];
1.83 cvs 3841:
1.116 cvs 3842: if (strcmp (value, "thin") == 0)
3843: strcpy (value, "1pt");
3844: else if (strcmp (value, "medium") == 0)
3845: strcpy (value, "1pt");
3846: else if (strcmp (value, "thick") == 0)
3847: strcpy (value, "2pt");
3848: sprintf (css_command, "stroke-width: %s", value);
1.83 cvs 3849: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
3850: }
3851:
3852: /*----------------------------------------------------------------------
1.58 cvs 3853: MathMLAttrToStyleProperty
3854: The MathML attribute attr is associated with element el. Generate
3855: the corresponding style property for this element.
1.24 cvs 3856: -----------------------------------------------------------------------*/
1.138 cvs 3857: void MathMLAttrToStyleProperty (Document doc, Element el, char *value,
3858: int attr)
1.24 cvs 3859: {
1.167 quint 3860: char css_command[buflen+20], namedSpaceVal[20];
1.141 quint 3861: int i;
1.58 cvs 3862:
3863: switch (attr)
3864: {
3865: case MathML_ATTR_fontsize:
1.116 cvs 3866: sprintf (css_command, "font-size: %s", value);
1.58 cvs 3867: break;
1.93 cvs 3868: case MathML_ATTR_mathsize:
1.116 cvs 3869: if (strcmp (value, "small") == 0)
3870: strcpy (value, "80%");
3871: else if (strcmp (value, "normal") == 0)
3872: strcpy (value, "100%");
3873: else if (strcmp (value, "big") == 0)
3874: strcpy (value, "125%");
3875: sprintf (css_command, "font-size: %s", value);
1.93 cvs 3876: break;
1.58 cvs 3877: case MathML_ATTR_lspace:
3878: case MathML_ATTR_rspace:
1.141 quint 3879: if (attr == MathML_ATTR_lspace)
3880: strcpy (css_command, "padding-left: ");
3881: else
3882: strcpy (css_command, "padding-right: ");
1.167 quint 3883: ConvertNamedSpace (value, namedSpaceVal);
3884: if (namedSpaceVal[0] != EOS)
3885: /* it's a named space */
3886: strcat (css_command, namedSpaceVal);
1.141 quint 3887: else
3888: {
3889: strcat (css_command, value);
3890: /* does the value contain an unit at the end? */
3891: i = strlen (value) - 1;
3892: if ((value[i] <= '9' && value[i] >= '0') ||
3893: value[i] == '.')
3894: /* it's just a number. Add the (implicit) unit: em */
3895: strcat (css_command, "em");
3896: }
1.58 cvs 3897: break;
3898: }
1.72 cvs 3899: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 3900: }
3901:
3902: /*----------------------------------------------------------------------
1.60 cvs 3903: MathMLSetScriptLevel
3904: A scriptlevel attribute with value value is associated with element el.
3905: Generate the corresponding style property for this element.
3906: -----------------------------------------------------------------------*/
1.120 cvs 3907: void MathMLSetScriptLevel (Document doc, Element el, char *value)
1.60 cvs 3908: {
3909: PresentationValue pval;
3910: PresentationContext ctxt;
3911: ThotBool relative;
3912: int percentage;
3913:
3914: ctxt = TtaGetSpecificStyleContext (doc);
3915: if (!value)
3916: /* remove the presentation rule */
3917: {
3918: ctxt->destroy = TRUE;
1.75 cvs 3919: pval.typed_data.value = 0;
1.60 cvs 3920: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
3921: }
3922: else
3923: {
3924: ctxt->destroy = FALSE;
3925: /* parse the attribute value (an optional sign and an integer) */
1.119 cvs 3926: value = TtaSkipBlanks (value);
1.60 cvs 3927: relative = (value[0] == '-' || value[0] == '+');
3928: value = ParseCSSUnit (value, &pval);
3929: if (pval.typed_data.unit != STYLE_UNIT_REL &&
3930: pval.typed_data.real)
3931: /* this is an error: it should be an integer without any unit name */
3932: /* error */;
3933: else
3934: {
3935: if (relative)
3936: {
1.63 cvs 3937: percentage = 100;
1.60 cvs 3938: if (pval.typed_data.value == 0)
3939: /* scriptlevel="+0" */
3940: percentage = 100;
3941: else if (pval.typed_data.value == 1)
3942: /* scriptlevel="+1" */
3943: percentage = 71;
3944: else if (pval.typed_data.value == 2)
3945: /* scriptlevel="+2" */
3946: percentage = 50;
3947: else if (pval.typed_data.value >= 3)
3948: /* scriptlevel="+3" or more */
3949: percentage = 35;
3950: else if (pval.typed_data.value == -1)
3951: /* scriptlevel="-1" */
3952: percentage = 141;
3953: else if (pval.typed_data.value == -2)
3954: /* scriptlevel="-2" */
3955: percentage = 200;
3956: else if (pval.typed_data.value <= -3)
3957: /* scriptlevel="-3" or less */
3958: percentage = 282;
3959: pval.typed_data.value = percentage;
3960: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1.78 cvs 3961: /* the specific presentation to be created is not a CSS rule */
1.147 quint 3962: ctxt->cssSpecificity = 0;
1.60 cvs 3963: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
3964: }
3965: else
3966: /* absolute value */
3967: {
3968: /**** ****/;
3969: }
3970: }
3971: }
3972: TtaFreeMemory (ctxt);
3973: }
3974:
3975: /*----------------------------------------------------------------------
3976: MathMLSpacingAttr
3977: The MathML attribute attr (height, width or depth) is associated
3978: with element el (a mspace or mpadding).
3979: If value is not NULL, generate the corresponding Thot presentation rule for
3980: the element.
3981: If value is NULL, remove the corresponding Thot presentation rule.
3982: -----------------------------------------------------------------------*/
1.120 cvs 3983: void MathMLSpacingAttr (Document doc, Element el, char *value, int attr)
1.60 cvs 3984: {
3985: ElementType elType;
3986: PresentationValue pval;
3987: PresentationContext ctxt;
3988: int ruleType;
3989:
3990: /* provisionally, handles only mspace elements */
3991: elType = TtaGetElementType (el);
1.96 cvs 3992: if (elType.ElTypeNum != MathML_EL_MSPACE &&
1.97 cvs 3993: elType.ElTypeNum != MathML_EL_MPADDED &&
3994: elType.ElTypeNum != MathML_EL_MTABLE)
1.60 cvs 3995: return;
3996: switch (attr)
3997: {
3998: case MathML_ATTR_width_:
3999: ruleType = PRWidth;
4000: break;
4001: case MathML_ATTR_height_:
4002: ruleType = PRPaddingTop;
4003: break;
4004: case MathML_ATTR_depth_:
4005: ruleType = PRPaddingBottom;
4006: break;
4007: default:
4008: return;
4009: }
4010: ctxt = TtaGetSpecificStyleContext (doc);
1.116 cvs 4011: if (!value || (strcmp (value, "auto") == 0))
1.60 cvs 4012: /* remove the presentation rule */
4013: {
4014: ctxt->destroy = TRUE;
1.75 cvs 4015: pval.typed_data.value = 0;
1.60 cvs 4016: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
4017: }
4018: else
4019: {
4020: ctxt->destroy = FALSE;
4021: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 4022: value = TtaSkipBlanks (value);
1.60 cvs 4023: value = ParseCSSUnit (value, &pval);
4024: /***** we should accept namedspace for width *****/
4025: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
1.78 cvs 4026: {
4027: /* the specific presentation to be created is not a CSS rule */
1.147 quint 4028: ctxt->cssSpecificity = 0;
1.78 cvs 4029: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
4030: }
1.60 cvs 4031: }
4032: TtaFreeMemory (ctxt);
4033: }
4034:
4035: /*----------------------------------------------------------------------
1.153 quint 4036: MathMLSetDisplayAttr
4037: The MathML attribute display is associated with element el.
4038: Generate the corresponding Thot presentation rule for
4039: the element.
4040: ----------------------------------------------------------------------*/
4041: void MathMLSetDisplayAttr (Element el, Attribute attr, Document doc,
4042: ThotBool delete)
4043: {
4044: int val;
4045:
4046: val = TtaGetAttributeValue (attr);
4047: if (val == MathML_ATTR_display_VAL_block)
4048: ParseHTMLSpecificStyle (el, "display: block", doc, 0, delete);
4049: else if (val == MathML_ATTR_display_VAL_inline_)
4050: ParseHTMLSpecificStyle (el, "display: inline", doc, 0, delete);
4051: }
4052:
4053: /*----------------------------------------------------------------------
1.1 cvs 4054: MathMLAttributeComplete
1.58 cvs 4055: The XML parser has completed parsing attribute attr (as well as its value)
4056: that is associated with element el in document doc.
1.1 cvs 4057: ----------------------------------------------------------------------*/
1.120 cvs 4058: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
1.1 cvs 4059: {
1.134 cvs 4060: AttributeType attrType, depAttrType;
1.23 cvs 4061: int attrKind;
1.50 cvs 4062: ElementType elType;
1.120 cvs 4063: char *value;
1.50 cvs 4064: int val, length;
1.101 cvs 4065: Attribute intAttr;
1.23 cvs 4066:
1.58 cvs 4067: /* first get the type of that attribute */
1.23 cvs 4068: TtaGiveAttributeType (attr, &attrType, &attrKind);
1.153 quint 4069:
1.54 cvs 4070: if (attrType.AttrTypeNum == MathML_ATTR_bevelled)
1.58 cvs 4071: /* it's a bevelled attribute */
1.50 cvs 4072: {
4073: val = TtaGetAttributeValue (attr);
1.54 cvs 4074: if (val == MathML_ATTR_bevelled_VAL_true)
4075: /* bevelled = true. Transform MFRAC into BevelledMFRAC */
1.50 cvs 4076: {
4077: elType = TtaGetElementType (el);
4078: if (elType.ElTypeNum == MathML_EL_MFRAC)
1.54 cvs 4079: ChangeTypeOfElement (el, doc, MathML_EL_BevelledMFRAC);
1.50 cvs 4080: }
4081: }
1.101 cvs 4082:
4083: else if (attrType.AttrTypeNum == MathML_ATTR_rowalign_mtr)
4084: {
4085: /* create an equivalent IntRowAlign attribute on the same element */
4086: attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
4087: intAttr = TtaGetAttribute (el, attrType);
4088: if (!intAttr)
4089: /* no IntRowAlign attribute, create one */
4090: {
4091: intAttr = TtaNewAttribute (attrType);
4092: TtaAttachAttribute (el, intAttr, doc);
4093: }
4094: val = TtaGetAttributeValue (attr);
4095: TtaSetAttributeValue (intAttr, val, el, doc);
4096: }
4097:
4098: else if (attrType.AttrTypeNum == MathML_ATTR_columnalign_mtd)
4099: {
4100: /* create an equivalent IntColAlign attribute on the same element */
4101: attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
4102: intAttr = TtaGetAttribute (el, attrType);
4103: if (!intAttr)
4104: /* no IntColAlign attribute, create one */
4105: {
4106: intAttr = TtaNewAttribute (attrType);
4107: TtaAttachAttribute (el, intAttr, doc);
4108: }
4109: val = TtaGetAttributeValue (attr);
4110: TtaSetAttributeValue (intAttr, val, el, doc);
4111: }
4112:
1.159 quint 4113: /* don't handle attributes columnalign, rowalign, columnlines and rowlines
4114: now: the table or the row is not complete yet. Handle them when the
4115: element is complete.
1.104 cvs 4116: */
1.153 quint 4117:
4118: else if (attrType.AttrTypeNum == MathML_ATTR_display)
4119: /* it's a display attribute */
4120: MathMLSetDisplayAttr (el, attr, doc, FALSE);
1.138 cvs 4121:
1.168 ! quint 4122: else if (attrType.AttrTypeNum == MathML_ATTR_framespacing)
! 4123: /* it's a framespacing attribute */
! 4124: HandleFramespacingAttribute (attr, el, doc, FALSE);
! 4125:
1.138 cvs 4126: else if (attrType.AttrTypeNum == MathML_ATTR_Language)
4127: {
4128: if (el == TtaGetRootElement (doc))
4129: /* it's the lang attribute on the root element */
4130: /* set the RealLang attribute */
4131: {
4132: depAttrType.AttrSSchema = attrType.AttrSSchema ;
4133: depAttrType.AttrTypeNum = MathML_ATTR_RealLang;
4134: if (!TtaGetAttribute (el, depAttrType))
4135: /* it's not present. Add it */
4136: {
4137: intAttr = TtaNewAttribute (depAttrType);
4138: TtaAttachAttribute (el, intAttr, doc);
4139: TtaSetAttributeValue (intAttr, MathML_ATTR_RealLang_VAL_Yes_,
4140: el, doc);
4141: }
4142: }
4143: }
1.101 cvs 4144:
1.50 cvs 4145: else if (attrType.AttrTypeNum == MathML_ATTR_color ||
1.93 cvs 4146: attrType.AttrTypeNum == MathML_ATTR_mathcolor ||
4147: attrType.AttrTypeNum == MathML_ATTR_background_ ||
4148: attrType.AttrTypeNum == MathML_ATTR_mathbackground ||
4149: attrType.AttrTypeNum == MathML_ATTR_fontsize ||
4150: attrType.AttrTypeNum == MathML_ATTR_mathsize ||
4151: attrType.AttrTypeNum == MathML_ATTR_fontfamily ||
4152: attrType.AttrTypeNum == MathML_ATTR_linethickness ||
4153: attrType.AttrTypeNum == MathML_ATTR_lspace ||
4154: attrType.AttrTypeNum == MathML_ATTR_rspace ||
4155: attrType.AttrTypeNum == MathML_ATTR_scriptlevel ||
4156: attrType.AttrTypeNum == MathML_ATTR_width_ ||
4157: attrType.AttrTypeNum == MathML_ATTR_height_ ||
1.168 ! quint 4158: attrType.AttrTypeNum == MathML_ATTR_depth_)
1.93 cvs 4159: {
1.23 cvs 4160: length = TtaGetTextAttributeLength (attr);
4161: if (length >= buflen)
4162: length = buflen - 1;
4163: if (length > 0)
4164: {
1.116 cvs 4165: value = TtaGetMemory (buflen);
1.33 cvs 4166: value[0] = EOS;
4167: TtaGiveTextAttributeValue (attr, value, &length);
4168: switch (attrType.AttrTypeNum)
4169: {
4170: case MathML_ATTR_color:
1.134 cvs 4171: /* deprecated attribute */
4172: /* if the same element has a mathcolor attribute, ignore
4173: the color attribute */
4174: depAttrType.AttrSSchema = attrType.AttrSSchema ;
4175: depAttrType.AttrTypeNum = MathML_ATTR_mathcolor;
4176: if (!TtaGetAttribute (el, depAttrType))
4177: HTMLSetForegroundColor (doc, el, value);
4178: break;
1.93 cvs 4179: case MathML_ATTR_mathcolor:
1.24 cvs 4180: HTMLSetForegroundColor (doc, el, value);
4181: break;
1.33 cvs 4182: case MathML_ATTR_background_:
1.134 cvs 4183: /* deprecated attribute */
4184: /* if the same element has a mathbackground attribute, ignore
4185: the background attribute */
4186: depAttrType.AttrSSchema = attrType.AttrSSchema;
4187: depAttrType.AttrTypeNum = MathML_ATTR_mathbackground;
4188: if (!TtaGetAttribute (el, depAttrType))
4189: HTMLSetBackgroundColor (doc, el, value);
4190: break;
1.93 cvs 4191: case MathML_ATTR_mathbackground:
1.24 cvs 4192: HTMLSetBackgroundColor (doc, el, value);
4193: break;
1.33 cvs 4194: case MathML_ATTR_fontfamily:
1.24 cvs 4195: SetFontfamily (doc, el, value);
1.83 cvs 4196: break;
4197: case MathML_ATTR_linethickness:
4198: MathMLlinethickness (doc, el, value);
1.58 cvs 4199: break;
4200: case MathML_ATTR_fontsize:
1.134 cvs 4201: /* deprecated attribute */
4202: /* if the same element has a mathsize attribute, ignore
4203: the fontsize attribute */
4204: depAttrType.AttrSSchema = attrType.AttrSSchema;
4205: depAttrType.AttrTypeNum = MathML_ATTR_mathsize;
4206: if (!TtaGetAttribute (el, depAttrType))
4207: MathMLAttrToStyleProperty (doc, el, value,
4208: attrType.AttrTypeNum);
4209: break;
1.93 cvs 4210: case MathML_ATTR_mathsize:
1.58 cvs 4211: case MathML_ATTR_lspace:
4212: case MathML_ATTR_rspace:
1.60 cvs 4213: MathMLAttrToStyleProperty (doc, el, value,attrType.AttrTypeNum);
4214: break;
4215: case MathML_ATTR_scriptlevel:
4216: MathMLSetScriptLevel (doc, el, value);
4217: break;
4218: case MathML_ATTR_width_:
4219: case MathML_ATTR_height_:
4220: case MathML_ATTR_depth_:
4221: MathMLSpacingAttr (doc, el, value, attrType.AttrTypeNum);
1.59 cvs 4222: break;
4223: default:
1.24 cvs 4224: break;
1.33 cvs 4225: }
4226: TtaFreeMemory (value);
1.23 cvs 4227: }
4228: }
1.1 cvs 4229: }
4230:
4231: /*----------------------------------------------------------------------
4232: MathMLGetDTDName
4233: ----------------------------------------------------------------------*/
1.120 cvs 4234: void MathMLGetDTDName (char *DTDname, char *elementName)
1.1 cvs 4235: {
4236: /* no other DTD allowed within MathML elements */
1.116 cvs 4237: strcpy (DTDname, "");
1.1 cvs 4238: }
4239:
4240: /* end of module */
Webmaster