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