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