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