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