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