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