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