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