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