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