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