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