Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.155
1.1 cvs 1: /*
2: *
1.144 vatton 3: * (c) COPYRIGHT MIT and INRIA, 1996-2002
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
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.133 cvs 18: #include "HTMLactions_f.h"
1.25 cvs 19: #include "MathML.h"
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.12 cvs 31: #include "HTMLtable_f.h"
1.29 cvs 32: #include "Mathedit_f.h"
33: #include "styleparser_f.h"
34: #include "fetchXMLname_f.h"
1.1 cvs 35:
36: /*----------------------------------------------------------------------
37: MapMathMLAttribute
38: Search in the Attribute Mapping Table the entry for the
39: attribute of name Attr and returns the corresponding Thot attribute type.
40: ----------------------------------------------------------------------*/
1.120 cvs 41: void MapMathMLAttribute (char *attrName, AttributeType *attrType,
42: char *elementName, ThotBool *level, Document doc)
1.1 cvs 43: {
1.68 cvs 44: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.91 cvs 45: MapXMLAttribute (MATH_TYPE, attrName, elementName, level, doc, &(attrType->AttrTypeNum));
1.1 cvs 46: }
47:
48: /*----------------------------------------------------------------------
49: MapMathMLAttributeValue
50: Search in the Attribute Value Mapping Table the entry for the attribute
51: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
52: ----------------------------------------------------------------------*/
1.150 vatton 53: void MapMathMLAttributeValue (char *attVal, AttributeType attrType, int *value)
1.1 cvs 54: {
1.150 vatton 55: MapXMLAttributeValue (MATH_TYPE, attVal, attrType, value);
1.1 cvs 56: }
57:
58: /*----------------------------------------------------------------------
1.130 carcone 59: MathMLEntityCreated
60: ----------------------------------------------------------------------*/
61: void MathMLEntityCreated (unsigned char *entityValue, Language lang,
62: char *entityName, Document doc)
63: {
64: }
65:
66: /*----------------------------------------------------------------------
1.1 cvs 67: ElementNeedsPlaceholder
68: returns TRUE if element el needs a sibling placeholder.
69: ----------------------------------------------------------------------*/
1.18 cvs 70: ThotBool ElementNeedsPlaceholder (Element el)
1.1 cvs 71: {
72: ElementType elType;
1.138 cvs 73: Element child, parent, sibling;
1.18 cvs 74: ThotBool ret;
1.139 quint 75:
1.1 cvs 76: ret = FALSE;
77: elType = TtaGetElementType (el);
1.43 cvs 78: if (elType.ElTypeNum == MathML_EL_MS ||
1.39 cvs 79: elType.ElTypeNum == MathML_EL_MFRAC ||
1.54 cvs 80: elType.ElTypeNum == MathML_EL_BevelledMFRAC ||
1.39 cvs 81: elType.ElTypeNum == MathML_EL_MSQRT ||
82: elType.ElTypeNum == MathML_EL_MROOT ||
83: elType.ElTypeNum == MathML_EL_MSTYLE ||
84: elType.ElTypeNum == MathML_EL_MERROR ||
85: elType.ElTypeNum == MathML_EL_MPADDED ||
86: elType.ElTypeNum == MathML_EL_MPHANTOM ||
87: elType.ElTypeNum == MathML_EL_MFENCED ||
1.1 cvs 88: elType.ElTypeNum == MathML_EL_MF ||
89: elType.ElTypeNum == MathML_EL_MSUB ||
90: elType.ElTypeNum == MathML_EL_MSUP ||
1.39 cvs 91: elType.ElTypeNum == MathML_EL_MSUBSUP ||
1.1 cvs 92: elType.ElTypeNum == MathML_EL_MUNDER ||
93: elType.ElTypeNum == MathML_EL_MOVER ||
94: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
1.28 cvs 95: elType.ElTypeNum == MathML_EL_MMULTISCRIPTS ||
1.39 cvs 96: elType.ElTypeNum == MathML_EL_MTABLE ||
97: elType.ElTypeNum == MathML_EL_MACTION)
1.1 cvs 98: ret = TRUE;
1.138 cvs 99: else if (elType.ElTypeNum == MathML_EL_MROW)
100: /* a mrow needs a place holder only if it's not the sole child of
101: an element such as Numerator, Denominator, RootBase, Index, etc. */
102: {
103: ret = TRUE;
104: sibling = el; TtaNextSibling (&sibling);
105: if (!sibling)
106: {
1.139 quint 107: sibling = el; TtaPreviousSibling (&sibling);
1.138 cvs 108: if (!sibling)
109: {
110: parent = TtaGetParent (el);
111: if (parent)
112: {
113: elType = TtaGetElementType (parent);
114: if (elType.ElTypeNum == MathML_EL_Numerator ||
115: elType.ElTypeNum == MathML_EL_Denominator ||
116: elType.ElTypeNum == MathML_EL_RootBase ||
117: elType.ElTypeNum == MathML_EL_Index ||
118: elType.ElTypeNum == MathML_EL_FencedExpression ||
119: elType.ElTypeNum == MathML_EL_Base ||
120: elType.ElTypeNum == MathML_EL_Subscript ||
121: elType.ElTypeNum == MathML_EL_Superscript ||
122: elType.ElTypeNum == MathML_EL_UnderOverBase ||
123: elType.ElTypeNum == MathML_EL_Underscript ||
124: elType.ElTypeNum == MathML_EL_Overscript ||
125: elType.ElTypeNum == MathML_EL_MultiscriptBase ||
126: elType.ElTypeNum == MathML_EL_MSubscript ||
127: elType.ElTypeNum == MathML_EL_MSuperscript)
128: ret = FALSE;
129: }
130: }
131: }
132: }
133: else if (elType.ElTypeNum == MathML_EL_MO)
134: /* an operator that contains a single Symbol needs a placeholder,
135: except when it is in a Base or UnderOverBase */
136: {
137: child = TtaGetFirstChild (el);
138: if (child != NULL)
1.1 cvs 139: {
1.138 cvs 140: elType = TtaGetElementType (child);
141: if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
142: {
1.1 cvs 143: ret = TRUE;
144: parent = TtaGetParent (el);
145: if (parent != NULL)
146: {
1.138 cvs 147: elType = TtaGetElementType (parent);
148: if (elType.ElTypeNum == MathML_EL_Base ||
149: elType.ElTypeNum == MathML_EL_UnderOverBase)
1.139 quint 150: ret = FALSE;
151: }
152: }
153: }
154: }
155: else if (elType.ElTypeNum == MathML_EL_MSPACE)
156: {
157: /* in principle mspace needs a placeholder sibling */
158: ret = TRUE;
159: /* but if it's the only child of a mstyle element, the placeholders
160: would change the height and width of the mstyle. Consider for
161: instance:
162: <mstyle background="#000099">
163: <mspace depth="2mm" width=".2in"/>
164: </mstyle> */
165: sibling = el; TtaNextSibling (&sibling);
166: if (!sibling)
167: {
168: sibling = el; TtaPreviousSibling (&sibling);
169: if (!sibling)
170: {
171: parent = TtaGetParent (el);
172: if (parent)
173: {
174: elType = TtaGetElementType (parent);
175: if (elType.ElTypeNum == MathML_EL_MSTYLE)
1.138 cvs 176: ret = FALSE;
1.1 cvs 177: }
1.138 cvs 178: }
1.1 cvs 179: }
1.138 cvs 180: }
1.1 cvs 181: return ret;
182: }
1.132 cvs 183:
1.1 cvs 184: /*----------------------------------------------------------------------
185: CreatePlaceholders
186: ----------------------------------------------------------------------*/
187: static void CreatePlaceholders (Element el, Document doc)
188: {
1.132 cvs 189: Element sibling, prev, constr, child;
190: Attribute attr;
191: ElementType elType;
192: AttributeType attrType;
193: ThotBool create, stretchableSubsup;
1.1 cvs 194:
1.55 cvs 195: if (!el)
196: return;
1.2 cvs 197: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 198: prev = NULL;
199: create = TRUE;
200: sibling = el;
201: while (sibling != NULL)
202: {
203: if (!ElementNeedsPlaceholder (sibling))
204: create = FALSE;
205: else
206: {
207: if (sibling == el)
208: /* first element */
209: {
210: elType = TtaGetElementType (sibling);
211: if (elType.ElTypeNum == MathML_EL_MF)
212: /* the first element is a MF. Don't create a placeholder
213: before */
214: create = FALSE;
215: else if (elType.ElTypeNum == MathML_EL_MROW)
216: /* the first element is a MROW */
217: {
218: child = TtaGetFirstChild (sibling);
219: if (child != NULL)
220: {
221: elType = TtaGetElementType (child);
222: if (elType.ElTypeNum != MathML_EL_MF)
223: /* the first child of the MROW element is not a MF */
224: /* Don't create a placeholder before */
225: create = FALSE;
226: }
227: }
228: }
229: if (create)
230: {
231: elType.ElTypeNum = MathML_EL_Construct;
232: constr = TtaNewElement (doc, elType);
233: TtaInsertSibling (constr, sibling, TRUE, doc);
234: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 235: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 236: attr = TtaNewAttribute (attrType);
237: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 238: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
239: constr, doc);
1.1 cvs 240: }
241: create = TRUE;
242: }
243: prev = sibling;
244: TtaNextSibling (&sibling);
245: }
246: if (prev != NULL && create)
247: {
1.132 cvs 248: stretchableSubsup = FALSE;
1.1 cvs 249: elType = TtaGetElementType (prev);
1.95 cvs 250: /* don't insert a placeholder after the last element if it's a MF */
251: if (elType.ElTypeNum == MathML_EL_MF)
1.1 cvs 252: create = FALSE;
253: else if (elType.ElTypeNum == MathML_EL_MROW)
254: /* the last element is a MROW */
255: {
256: child = TtaGetLastChild (prev);
257: if (child != NULL)
258: {
259: elType = TtaGetElementType (child);
260: if (elType.ElTypeNum != MathML_EL_MF)
261: /* the last child of the MROW element is not a MF */
262: /* Don't create a placeholder before */
263: create = FALSE;
264: }
265: }
1.132 cvs 266: else if (elType.ElTypeNum == MathML_EL_MSUBSUP ||
267: elType.ElTypeNum == MathML_EL_MSUB ||
268: elType.ElTypeNum == MathML_EL_MSUP ||
269: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
270: elType.ElTypeNum == MathML_EL_MUNDER ||
271: elType.ElTypeNum == MathML_EL_MUNDEROVER)
272: {
273: attrType.AttrSSchema = elType.ElSSchema;
274: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
275: if (TtaGetAttribute (prev, attrType))
276: stretchableSubsup = TRUE;
277: }
278:
1.1 cvs 279: if (create)
280: {
1.132 cvs 281: if (stretchableSubsup)
282: elType.ElTypeNum = MathML_EL_Construct1;
283: else
284: elType.ElTypeNum = MathML_EL_Construct;
1.1 cvs 285: constr = TtaNewElement (doc, elType);
286: TtaInsertSibling (constr, prev, FALSE, doc);
287: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 288: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 289: attr = TtaNewAttribute (attrType);
290: TtaAttachAttribute (constr, attr, doc);
1.55 cvs 291: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
292: constr, doc);
1.132 cvs 293: }
1.1 cvs 294: }
295: }
296:
297: /*----------------------------------------------------------------------
1.95 cvs 298: NextNotComment
299: Return the next sibling of element el that is not an XMLcomment element.
300: Return el itself if it's not a comment.
1.1 cvs 301: ----------------------------------------------------------------------*/
1.95 cvs 302: static void NextNotComment (Element* el, Element* prev)
1.1 cvs 303: {
304: ElementType elType;
305:
306: if (*el == NULL)
307: return;
308: elType = TtaGetElementType (*el);
1.95 cvs 309: while (*el != NULL && elType.ElTypeNum == MathML_EL_XMLcomment)
1.1 cvs 310: {
311: *prev = *el;
312: TtaNextSibling (el);
313: if (*el != NULL)
314: elType = TtaGetElementType (*el);
315: }
316: }
317:
318: /*----------------------------------------------------------------------
319: CheckMathSubExpressions
320: Children of element el should be of type type1, type2, and type3.
1.56 cvs 321: If they are not, wrap them in elements of these types.
1.124 cvs 322: If element el has too many or not enough children, return FALSE.
1.1 cvs 323: ----------------------------------------------------------------------*/
1.56 cvs 324: static ThotBool CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
1.1 cvs 325: {
326: Element child, new, prev;
327: ElementType elType, childType;
1.124 cvs 328: char msgBuffer[200];
1.56 cvs 329: ThotBool result;
1.1 cvs 330:
1.56 cvs 331: result = TRUE;
1.2 cvs 332: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 333: child = TtaGetFirstChild (el);
334: prev = NULL;
1.95 cvs 335: NextNotComment (&child, &prev);
1.56 cvs 336: if (type1 == 0)
1.1 cvs 337: {
1.56 cvs 338: if (child)
339: /* no child expected and there is one, error */
1.124 cvs 340: {
341: sprintf (msgBuffer, "No subexpression allowed in %s",
342: TtaGetElementTypeName (TtaGetElementType (el)));
343: XmlParseError (errorParsing, msgBuffer, 0);
344: result = FALSE;
345: }
1.56 cvs 346: }
347: else
348: if (!child)
349: /* a first child is expected and it's missing */
1.124 cvs 350: {
351: sprintf (msgBuffer, "Missing subexpression in %s",
352: TtaGetElementTypeName (TtaGetElementType (el)));
353: XmlParseError (errorParsing, msgBuffer, 0);
354: result = FALSE;
355: }
1.56 cvs 356: else
357: {
1.1 cvs 358: elType.ElTypeNum = type1;
359: childType = TtaGetElementType (child);
360: if (TtaSameTypes (childType, elType) == 0)
361: {
362: TtaRemoveTree (child, doc);
363: new = TtaNewElement (doc, elType);
364: if (prev == NULL)
365: TtaInsertFirstChild (&new, el, doc);
366: else
367: TtaInsertSibling (new, prev, FALSE, doc);
368: TtaInsertFirstChild (&child, new, doc);
369: CreatePlaceholders (child, doc);
370: child = new;
371: }
1.56 cvs 372: prev = child;
373: TtaNextSibling (&child);
1.95 cvs 374: NextNotComment (&child, &prev);
1.56 cvs 375: if (type2 == 0)
376: {
377: if (child)
378: /* this second child is not expected, error */
1.124 cvs 379: {
380: sprintf (msgBuffer, "Only 1 subexpression allowed in %s",
381: TtaGetElementTypeName (TtaGetElementType (el)));
382: XmlParseError (errorParsing, msgBuffer, 0);
383: result = FALSE;
384: }
1.56 cvs 385: }
386: else
1.1 cvs 387: {
1.56 cvs 388: if (!child)
389: /* a second child is expected and it's missing */
1.124 cvs 390: {
391: sprintf (msgBuffer, "2 subexpressions required in %s",
392: TtaGetElementTypeName (TtaGetElementType (el)));
393: XmlParseError (errorParsing, msgBuffer, 0);
394: result = FALSE;
395: }
1.56 cvs 396: else
1.1 cvs 397: {
398: elType.ElTypeNum = type2;
399: childType = TtaGetElementType (child);
400: if (TtaSameTypes (childType, elType) == 0)
401: {
402: TtaRemoveTree (child, doc);
403: new = TtaNewElement (doc, elType);
404: TtaInsertSibling (new, prev, FALSE, doc);
405: TtaInsertFirstChild (&child, new, doc);
406: CreatePlaceholders (child, doc);
407: child = new;
408: }
1.56 cvs 409: prev = child;
410: TtaNextSibling (&child);
1.95 cvs 411: NextNotComment (&child, &prev);
1.56 cvs 412: if (type3 == 0)
1.1 cvs 413: {
1.56 cvs 414: if (child)
415: /* this third child is not expected, error */
1.124 cvs 416: {
417: sprintf (msgBuffer, "Only 2 subexpressions allowed in %s",
418: TtaGetElementTypeName (TtaGetElementType (el)));
419: XmlParseError (errorParsing, msgBuffer, 0);
420: result = FALSE;
421: }
1.56 cvs 422: }
423: else
424: {
425: if (!child)
426: /* a third child is expected and it's missing */
1.124 cvs 427: {
428: sprintf (msgBuffer, "3 subexpressions required in %s",
429: TtaGetElementTypeName (TtaGetElementType (el)));
430: XmlParseError (errorParsing, msgBuffer, 0);
431: result = FALSE;
432: }
1.56 cvs 433: else
1.1 cvs 434: {
435: elType.ElTypeNum = type3;
436: childType = TtaGetElementType (child);
437: if (TtaSameTypes (childType, elType) == 0)
438: {
439: TtaRemoveTree (child, doc);
440: new = TtaNewElement (doc, elType);
441: TtaInsertSibling (new, prev, FALSE, doc);
442: TtaInsertFirstChild (&child, new, doc);
443: CreatePlaceholders (child, doc);
1.56 cvs 444: child = new;
1.1 cvs 445: }
446: }
1.56 cvs 447: prev = child;
448: TtaNextSibling (&child);
1.95 cvs 449: NextNotComment (&child, &prev);
1.56 cvs 450: if (child)
451: /* this fourth child is unexpected */
1.124 cvs 452: {
453: sprintf (msgBuffer,"Only 3 subexpressions allowed in %s",
454: TtaGetElementTypeName (TtaGetElementType (el)));
455: XmlParseError (errorParsing, msgBuffer, 0);
456: result = FALSE;
457: }
1.1 cvs 458: }
459: }
460: }
1.56 cvs 461: }
462: return result;
1.1 cvs 463: }
464:
465: /*----------------------------------------------------------------------
1.22 cvs 466: SetSingleIntHorizStretchAttr
1.1 cvs 467:
1.22 cvs 468: Put a IntHorizStretch attribute on element el if it contains only
1.1 cvs 469: a MO element that is a stretchable symbol.
470: -----------------------------------------------------------------------*/
1.22 cvs 471: void SetSingleIntHorizStretchAttr (Element el, Document doc, Element* selEl)
1.1 cvs 472: {
473: Element child, sibling, textEl, symbolEl;
1.152 quint 474: ElementType elType, childType, siblingType;
1.1 cvs 475: Attribute attr;
476: AttributeType attrType;
1.55 cvs 477: Language lang;
1.128 vatton 478: CHAR_T text[2];
1.143 vatton 479: char script;
1.49 cvs 480: unsigned char c;
1.128 vatton 481: int len;
1.152 quint 482: ThotBool doit;
1.1 cvs 483:
484: if (el == NULL)
485: return;
486: child = TtaGetFirstChild (el);
1.154 vatton 487: textEl = NULL;
1.55 cvs 488: if (child)
1.1 cvs 489: {
490: elType = TtaGetElementType (child);
1.152 quint 491: /* skip a possible empty Construct (placeholder) */
492: if (elType.ElTypeNum == MathML_EL_Construct)
493: {
494: TtaNextSibling (&child);
495: if (child)
496: elType = TtaGetElementType (child);
497: }
498: while (child && elType.ElTypeNum == MathML_EL_MROW)
499: /* the first child is a mrow. Check whether it has a single child */
1.98 cvs 500: {
501: child = TtaGetFirstChild (child);
502: if (child)
503: {
1.152 quint 504: elType = TtaGetElementType (child);
505: /* skip a possible empty Construct (placeholder) */
506: if (elType.ElTypeNum == MathML_EL_Construct)
507: {
508: TtaNextSibling (&child);
509: if (child)
510: elType = TtaGetElementType (child);
511: }
1.98 cvs 512: sibling = child;
513: TtaNextSibling (&sibling);
1.152 quint 514: if (sibling)
515: /* there are other children */
516: {
517: siblingType = TtaGetElementType (sibling);
518: if (siblingType.ElTypeNum == MathML_EL_Construct)
519: /* its a construct, skip it */
520: TtaNextSibling (&sibling);
521: if (sibling)
522: child = NULL;
523: }
1.98 cvs 524: }
525: }
1.152 quint 526: if (child && (elType.ElTypeNum == MathML_EL_MO ||
527: elType.ElTypeNum == MathML_EL_MOVER ||
528: elType.ElTypeNum == MathML_EL_MUNDER))
529: /* the first child is a MO, a MUNDER or a MOVER */
1.1 cvs 530: {
531: sibling = child;
532: TtaNextSibling (&sibling);
1.152 quint 533: /* skip a possible empty Construct (placeholder) */
534: if (sibling)
535: {
536: siblingType = TtaGetElementType (sibling);
537: if (siblingType.ElTypeNum == MathML_EL_Construct)
538: TtaNextSibling (&sibling);
539: }
1.1 cvs 540: if (sibling == NULL)
541: /* there is no other child */
542: {
1.152 quint 543: c = EOS;
544: doit = FALSE;
545: attrType.AttrSSchema = elType.ElSSchema;
546: attrType.AttrTypeNum = MathML_ATTR_IntHorizStretch;
547:
548: if (elType.ElTypeNum == MathML_EL_MOVER ||
549: elType.ElTypeNum == MathML_EL_MUNDER)
550: /* check if the UnderOverBase has a IntHorizStretch attribute */
551: {
552: childType.ElTypeNum = MathML_EL_UnderOverBase;
553: textEl = TtaSearchTypedElement (childType, SearchInTree, child);
554: if (textEl)
555: {
556: if (TtaGetAttribute (textEl, attrType))
557: doit = TRUE;
558: }
559: }
560: else if (elType.ElTypeNum == MathML_EL_MO)
561: {
562: textEl = TtaGetFirstChild (child);
563: childType = TtaGetElementType (textEl);
564: if (childType.ElTypeNum == MathML_EL_TEXT_UNIT)
565: /* the MO child contains a TEXT element */
566: {
567: len = TtaGetElementVolume (textEl);
568: if (len == 1)
1.123 cvs 569: /* the TEXT element contains a single character */
570: {
1.152 quint 571: /* get that character */
572: len = 2;
573: TtaGiveBufferContent (textEl, text, len, &lang);
574: script = TtaGetScript (lang);
575: if (
1.146 quint 576: #ifndef _I18N_
1.152 quint 577: (script == 'L') &&
1.146 quint 578: #endif
1.152 quint 579: (text[0] == '-' || text[0] == '_' ||
580: text[0] == 175))
1.146 quint 581: /* a horizontal line in the middle of the box */
582: c = 'h';
1.152 quint 583: else
584: #ifdef _I18N_
585: if (text[0] == 0x2190)
586: c = 'L'; /* arrow left */
587: else if (text[0] == 0x2192)
588: c = 'R'; /* arrow right */
1.153 quint 589: else if (text[0] == 45) /* - (minus) */
590: /* a horizontal line in the middle of the box */
591: c = 'h';
592: else if (text[0] == 0x2212) /* - (minus) */
1.152 quint 593: /* a horizontal line in the middle of the box */
594: c = 'h';
595: else if (text[0] == 0x0332) /* UnderBar */
596: /* a horizontal line */
597: c = 'h';
598: else if (text[0] == 65079)
599: c = 'o'; /* Over brace */
600: else if (text[0] == 65080)
601: c = 'u'; /* Under brace */
1.146 quint 602: #else
603: if (script == 'G')
604: /* a single Symbol character */
605: {
606: if (text[0] == 172)
607: c = 'L'; /* arrow left */
608: else if (text[0] == 174)
609: c = 'R'; /* arrow right */
610: else if (text[0] == 45) /* - (minus) */
611: /* a horizontal line in the middle of the box */
612: c = 'h';
613: else if (text[0] == 132)
614: c = 'o'; /* Over brace */
615: else if (text[0] == 133)
616: c = 'u'; /* Under brace */
617: }
618: #endif
1.152 quint 619: if (c != EOS)
620: doit = TRUE;
1.123 cvs 621: }
1.152 quint 622: }
623: }
624: if (doit)
625: {
626: /* attach a IntHorizStretch attribute to the element
627: (UnderOverBase, Underscript, or Overscript) */
628: attr = TtaNewAttribute (attrType);
629: TtaAttachAttribute (el, attr, doc);
630: TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, el, doc);
631: attr = TtaNewAttribute (attrType);
632: TtaAttachAttribute (child, attr, doc);
633: TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, child, doc);
634: }
635: if (c != EOS)
636: {
637: /* replace the TEXT element by a Thot SYMBOL element */
638: childType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
639: symbolEl = TtaNewElement (doc, childType);
640: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
641: if (selEl != NULL)
642: if (*selEl == textEl)
643: *selEl = symbolEl;
644: TtaDeleteTree (textEl, doc);
645: if (c != EOS)
646: TtaSetGraphicsShape (symbolEl, c, doc);
647: }
1.1 cvs 648: }
649: }
650: }
651: }
1.123 cvs 652:
1.1 cvs 653: /*----------------------------------------------------------------------
1.22 cvs 654: SetIntHorizStretchAttr
1.1 cvs 655:
1.152 quint 656: Put a IntHorizStretch attribute on all children of element el that
1.1 cvs 657: contain only a MO element that is a stretchable symbol.
658: -----------------------------------------------------------------------*/
1.22 cvs 659: static void SetIntHorizStretchAttr (Element el, Document doc)
1.1 cvs 660: {
661: Element child;
662:
663: if (el == NULL)
664: return;
665: child = TtaGetFirstChild (el);
666: while (child != NULL)
667: {
1.22 cvs 668: SetSingleIntHorizStretchAttr (child, doc, NULL);
1.1 cvs 669: TtaNextSibling (&child);
670: }
671: }
672:
673: /*----------------------------------------------------------------------
1.22 cvs 674: SetIntVertStretchAttr
1.1 cvs 675:
1.22 cvs 676: Put a IntVertStretch attribute on element el if its base element
1.1 cvs 677: (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
678: a MUNDER of a MOVER) contains only a MO element that is a vertically
1.132 cvs 679: stretchable symbol (integral).
1.1 cvs 680: -----------------------------------------------------------------------*/
1.22 cvs 681: void SetIntVertStretchAttr (Element el, Document doc, int base, Element* selEl)
1.1 cvs 682: {
1.132 cvs 683: Element child, sibling, textEl, symbolEl, parent, operator, next;
1.1 cvs 684: ElementType elType;
685: Attribute attr;
686: AttributeType attrType;
1.131 cvs 687: SSchema MathMLSSchema;
1.128 vatton 688: Language lang;
1.143 vatton 689: char script;
1.131 cvs 690: #define buflen 50
691: CHAR_T text[buflen];
1.49 cvs 692: unsigned char c;
1.131 cvs 693: int len, i;
694: ThotBool inbase, integral;
1.1 cvs 695:
696: if (el == NULL)
1.131 cvs 697: return;
1.1 cvs 698: operator = NULL;
1.131 cvs 699: inbase = FALSE;
700: MathMLSSchema = TtaGetElementType(el).ElSSchema;
1.154 vatton 701: symbolEl = parent = NULL;
1.1 cvs 702: if (base == 0)
1.131 cvs 703: /* it's a MO */
704: {
705: parent = TtaGetParent (el);
706: if (parent != NULL)
1.1 cvs 707: {
1.131 cvs 708: /* don't process the mo if it is within a base. It will be processed
709: when the enclosing construct is processed (see below) */
710: elType = TtaGetElementType (parent);
711: if (elType.ElSSchema != MathMLSSchema ||
712: (elType.ElTypeNum != MathML_EL_Base &&
713: elType.ElTypeNum != MathML_EL_UnderOverBase &&
714: elType.ElTypeNum != MathML_EL_MSUBSUP &&
715: elType.ElTypeNum != MathML_EL_MSUB &&
716: elType.ElTypeNum != MathML_EL_MSUP &&
717: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
718: elType.ElTypeNum != MathML_EL_MUNDER &&
719: elType.ElTypeNum != MathML_EL_MUNDEROVER))
720: operator = el;
1.1 cvs 721: }
1.131 cvs 722: }
1.1 cvs 723: else
1.131 cvs 724: /* it's not a MO */
725: {
726: /* search the Base or UnderOverBase child */
727: child = TtaGetFirstChild (el);
728: if (child != NULL)
1.1 cvs 729: {
1.131 cvs 730: elType = TtaGetElementType (child);
731: if (elType.ElTypeNum == base && elType.ElSSchema == MathMLSSchema)
732: /* the first child is a Base or UnderOverBase */
733: {
734: child = TtaGetFirstChild (child);
735: if (child != NULL)
736: {
737: elType = TtaGetElementType (child);
738: if (elType.ElTypeNum == MathML_EL_MO &&
739: elType.ElSSchema == MathMLSSchema)
740: /* its first child is a MO */
741: {
742: sibling = child;
743: TtaNextSibling (&sibling);
744: if (sibling == NULL)
745: /* there is no other child */
746: {
747: operator = child;
748: if (base == MathML_EL_Base ||
749: base == MathML_EL_UnderOverBase)
750: {
751: parent = el;
752: inbase = TRUE;
753: }
754: }
755: }
756: }
757: }
1.1 cvs 758: }
1.131 cvs 759: }
760: if (operator)
761: {
762: textEl = TtaGetFirstChild (operator);
763: if (textEl != NULL)
1.84 cvs 764: {
1.131 cvs 765: elType = TtaGetElementType (textEl);
766: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
767: {
1.146 quint 768: len = TtaGetElementVolume (textEl);
1.131 cvs 769: if (len >= 1)
770: {
771: if (len >= buflen)
772: len = buflen-1;
1.146 quint 773: TtaGiveBufferContent (textEl, text, len+1, &lang);
1.143 vatton 774: script = TtaGetScript (lang);
1.146 quint 775: #ifdef _I18N_
776: integral = TRUE;
777: for (i = 0; i < len; i++)
778: if (text[i] < 0x222B || text[i] > 0x2233)
779: /* accept only symbols like simple integral, double or
780: triple integral, contour integral, etc. */
781: integral = FALSE;
782: #else
783: integral = FALSE;
1.143 vatton 784: if (script == 'G')
1.131 cvs 785: /* Adobe Symbol character set */
1.55 cvs 786: {
1.131 cvs 787: integral = TRUE;
788: /* check all characters in this TEXT element */
789: for (i = 0; i < len; i++)
790: if (text[i] != 242)
791: /**** accept also other symbols like double or triple
792: integral, contour integral, etc. ****/
793: integral = FALSE;
1.146 quint 794: }
795: #endif
796: if (integral)
797: /* the operator contains only integral symbols */
798: {
799: /* attach a IntVertStretch attribute */
800: attrType.AttrSSchema = MathMLSSchema;
801: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
802: attr = TtaNewAttribute (attrType);
803: TtaAttachAttribute (el, attr, doc);
804: TtaSetAttributeValue (attr,
1.131 cvs 805: MathML_ATTR_IntVertStretch_VAL_yes_,
806: el, doc);
1.146 quint 807: TtaRegisterAttributeCreate (attr, el, doc);
808:
809: /* replace the Integral characters by a Thot SYMBOL
810: element. If there are several such characters in
811: the mo (multiple integral), replace them too. */
812: do
813: {
814: /* replace the TEXT element by a Thot SYMBOL */
815: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
816: elType.ElSSchema = MathMLSSchema;
817: for (i = 0; i < len; i++)
818: #ifdef _I18N_
819: if (text[i] >= 0x222B && text[i] <= 0x2233)
820: #else
821: if (text[i] == 242)
822: #endif
823: {
1.131 cvs 824: symbolEl = TtaNewElement (doc, elType);
825: TtaInsertSibling (symbolEl, textEl, TRUE,doc);
826: if (selEl != NULL)
827: if (*selEl == textEl)
828: *selEl = symbolEl;
829: c = 'i';
830: TtaSetGraphicsShape (symbolEl, c, doc);
831: TtaRegisterElementCreate (symbolEl, doc);
832: }
1.146 quint 833: TtaRegisterElementDelete (textEl, doc);
834: TtaDeleteTree (textEl, doc);
835: /* is there an other text element after the
836: integral symbol? */
837: textEl = symbolEl; TtaNextSibling (&textEl);
838: if (textEl)
839: {
840: elType = TtaGetElementType (textEl);
841: if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
842: textEl = NULL;
843: else
844: /* there is another text element.
845: Is it a single integral symbol? */
846: {
847: len = TtaGetElementVolume (textEl);
848: if (len < 1)
849: /* not a single character */
850: textEl = NULL;
851: else
852: {
853: if (len >= buflen)
854: len = buflen-1;
855: TtaGiveBufferContent (textEl, text,
856: len+1, &lang);
857: script = TtaGetScript (lang);
858: #ifdef _I18N_
859: if (text[i] < 0x222B || text[i] > 0x2233)
860: #else
861: if (script != 'G' || text[0] != 242)
862: #endif
863: /* not an integral*/
864: textEl = NULL;
865: }
866: }
867: }
868: }
869: while (textEl);
870:
871: if (inbase)
872: /* it's within a Base or UnderOverBase element */
873: {
874: sibling = parent;
875: TtaNextSibling (&sibling);
876: if (sibling)
877: /* the msubsup of munderover element has a next
878: sibling */
879: {
880: elType = TtaGetElementType (sibling);
881: if (elType.ElTypeNum == MathML_EL_Construct &&
882: elType.ElSSchema == MathMLSSchema)
883: /* the next sibling is a Construct */
884: {
885: next = sibling;
886: TtaNextSibling (&next);
887: if (!next)
888: /* there is no other sibling after the
889: Construct. Change it into Construct1*/
890: {
891: TtaRegisterElementDelete (sibling, doc);
892: TtaRemoveTree (sibling, doc);
893: ChangeElementType (sibling,
1.132 cvs 894: MathML_EL_Construct1);
1.146 quint 895: TtaInsertSibling (sibling, parent,
896: FALSE, doc);
897: TtaRegisterElementCreate (sibling, doc);
898: /* force the msubsup element to be
899: reformatted and to take into account
900: its new next sibling */
901: TtaRemoveTree (parent, doc);
902: TtaInsertSibling (parent, sibling, TRUE,
903: doc);
904: }
905: }
906: }
907: }
1.55 cvs 908: }
1.131 cvs 909: }
910: }
1.84 cvs 911: }
1.131 cvs 912: }
1.1 cvs 913: }
914:
915: /*----------------------------------------------------------------------
1.22 cvs 916: SetIntPlaceholderAttr
1.1 cvs 917:
1.22 cvs 918: Put a IntPlaceholder attribute on all Construct elements in the
1.1 cvs 919: subtree of root el.
920: -----------------------------------------------------------------------*/
1.22 cvs 921: static void SetIntPlaceholderAttr (Element el, Document doc)
1.1 cvs 922: {
923: Element child;
924: ElementType elType;
925: Attribute attr;
926: AttributeType attrType;
927:
928: if (el == NULL)
929: return;
930: elType = TtaGetElementType (el);
931: if (elType.ElTypeNum == MathML_EL_Construct &&
1.2 cvs 932: elType.ElSSchema == GetMathMLSSchema (doc))
1.1 cvs 933: {
934: attrType.AttrSSchema = elType.ElSSchema;
1.22 cvs 935: attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1 cvs 936: attr = TtaNewAttribute (attrType);
937: TtaAttachAttribute (el, attr, doc);
1.22 cvs 938: TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, el, doc);
1.1 cvs 939: }
940: else
941: {
942: child = TtaGetFirstChild (el);
943: while (child != NULL)
944: {
1.22 cvs 945: SetIntPlaceholderAttr (child, doc);
1.1 cvs 946: TtaNextSibling (&child);
947: }
948: }
949: }
950:
951: /*----------------------------------------------------------------------
952: BuildMultiscript
953:
954: The content of a MMULTISCRIPT element has been created following
955: the original MathML structure. Create all Thot elements defined
956: in the MathML S schema.
957: -----------------------------------------------------------------------*/
958: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
959: {
960: Element elem, base, next, group, pair, script, prevPair, prevScript;
961: ElementType elType, elTypeGroup, elTypePair, elTypeScript;
1.2 cvs 962: SSchema MathMLSSchema;
1.1 cvs 963: base = NULL;
964: group = NULL;
965: prevPair = NULL;
966: prevScript = NULL;
967:
1.2 cvs 968: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 969: elTypeGroup.ElSSchema = MathMLSSchema;
970: elTypePair.ElSSchema = MathMLSSchema;
971: elTypeScript.ElSSchema = MathMLSSchema;
972:
973: /* process all children of the MMULTISCRIPT element */
974: elem = TtaGetFirstChild (elMMULTISCRIPT);
975: while (elem != NULL)
976: {
977: /* remember the element to be processed after the current one */
978: next = elem;
979: TtaNextSibling (&next);
980:
981: /* remove the current element from the tree */
982: TtaRemoveTree (elem, doc);
983:
984: if (base == NULL)
985: /* the current element is the first child of the MMULTISCRIPT
986: element */
987: {
988: /* Create a MultiscriptBase element as the first child of
989: MMULTISCRIPT and move the current element as the first child
990: of the MultiscriptBase element */
991: elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
992: base = TtaNewElement (doc, elTypeGroup);
993: TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
994: TtaInsertFirstChild (&elem, base, doc);
995: }
996: else
997: /* the current element is a subscript or a superscript */
998: {
999: if (group == NULL)
1000: /* there is no PostscriptPairs element. Create one */
1001: {
1002: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1003: group = TtaNewElement (doc, elTypeGroup);
1004: TtaInsertSibling (group, base, FALSE, doc);
1005: elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
1006: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1007: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1008: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1009: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1010: prevPair = pair;
1.47 cvs 1011: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1012: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1013: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1014: prevScript = NULL;
1015: }
1016: if (prevScript == NULL)
1017: /* the current element is the first subscript or superscript
1018: in a pair */
1019: {
1020: /* create a PostscriptPair or PrescriptPair element */
1021: pair = TtaNewElement (doc, elTypePair);
1022: if (prevPair == NULL)
1023: TtaInsertFirstChild (&pair, group, doc);
1024: else
1025: TtaInsertSibling (pair, prevPair, FALSE, doc);
1026: prevPair = pair;
1027: /* create a MSubscript element */
1028: elTypeScript.ElTypeNum = MathML_EL_MSubscript;
1029: script = TtaNewElement (doc, elTypeScript);
1030: TtaInsertFirstChild (&script, pair, doc);
1031: prevScript = script;
1032: }
1033: else
1034: /* the current element is a superscript in a pair */
1035: {
1036: /* create a MSuperscript element */
1037: elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
1038: script = TtaNewElement (doc, elTypeScript);
1039: /* insert it as a sibling of the previous MSubscript element */
1040: TtaInsertSibling (script, prevScript, FALSE, doc);
1041: prevScript = NULL;
1042: }
1043: /* insert the current element as a child of the new MSuperscript or
1044: MSubscript element */
1045: TtaInsertFirstChild (&elem, script, doc);
1.22 cvs 1046: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1047: }
1048:
1049: CreatePlaceholders (elem, doc);
1050:
1051: /* get next child of the MMULTISCRIPT element */
1052: elem = next;
1053: if (elem != NULL)
1054: {
1055: elType = TtaGetElementType (elem);
1056: if (elType.ElSSchema == MathMLSSchema &&
1057: elType.ElTypeNum == MathML_EL_PrescriptPairs)
1058: /* the next element is a PrescriptPairs */
1059: {
1060: /* if there there is no PostscriptPairs element, create one as a
1061: placeholder */
1062: if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
1063: {
1064: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1.47 cvs 1065: group = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1066: TtaInsertSibling (group, elem, TRUE, doc);
1.22 cvs 1067: SetIntPlaceholderAttr (group, doc);
1.1 cvs 1068: }
1069: /* the following elements will be interpreted as sub- superscripts
1070: in PrescriptPair elements, wich will be children of this
1071: PrescriptPairs element */
1072: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1073: elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
1074: group = elem;
1075: /* create a first and a last PostscriptPair as placeholders */
1.47 cvs 1076: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1077: TtaInsertFirstChild (&pair, group, doc);
1.22 cvs 1078: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1079: prevPair = pair;
1.47 cvs 1080: pair = TtaNewTree (doc, elTypePair, "");
1.1 cvs 1081: TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22 cvs 1082: SetIntPlaceholderAttr (pair, doc);
1.1 cvs 1083: prevScript = NULL;
1084: TtaNextSibling (&elem);
1085: }
1086: }
1087: }
1088: /* all children of element MMULTISCRIPTS have been processed */
1089: /* if the last group processed is not a PrescriptPairs element,
1090: create one as a placeholder */
1091: if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
1092: {
1093: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1.47 cvs 1094: elem = TtaNewTree (doc, elTypeGroup, "");
1.1 cvs 1095: if (group == NULL)
1096: group = base;
1097: TtaInsertSibling (elem, group, TRUE, doc);
1.22 cvs 1098: SetIntPlaceholderAttr (elem, doc);
1.1 cvs 1099: }
1100: }
1101:
1.39 cvs 1102: /*----------------------------------------------------------------------
1103: CreateWrapper
1104:
1105: Create an element of type wrapperType as a child of element el and
1106: move all chidren of element el within the new element.
1107: -----------------------------------------------------------------------*/
1108: static void CreateWrapper (Element el, int wrapperType, Document doc)
1109: {
1110: Element wrapper, child, prevChild, nextChild;
1111: ElementType elType;
1112:
1113: child = TtaGetFirstChild (el);
1114: elType.ElSSchema = GetMathMLSSchema (doc);
1115: elType.ElTypeNum = wrapperType;
1116: wrapper = TtaNewElement (doc, elType);
1117: TtaInsertFirstChild (&wrapper, el, doc);
1118: prevChild = NULL;
1119: while (child)
1120: {
1121: nextChild = child;
1122: TtaNextSibling (&nextChild);
1123: TtaRemoveTree (child, doc);
1124: if (prevChild == NULL)
1125: TtaInsertFirstChild (&child, wrapper, doc);
1126: else
1127: TtaInsertSibling (child, prevChild, FALSE, doc);
1128: prevChild = child;
1129: child = nextChild;
1130: }
1131: }
1.5 cvs 1132:
1133: /*----------------------------------------------------------------------
1134: CheckMTable
1135:
1136: The content of a MTABLE element has been created following
1137: the original MathML structure. Create all Thot elements defined
1138: in the MathML S schema.
1.64 cvs 1139: If placeholder, associate an attribute IntPlaceholder with all
1.103 cvs 1140: cells generated in the MathML table.
1.5 cvs 1141: -----------------------------------------------------------------------*/
1.64 cvs 1142: void CheckMTable (Element elMTABLE, Document doc, ThotBool placeholder)
1.5 cvs 1143: {
1144: ElementType elType;
1145: Element MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
1.103 cvs 1146: nextCell, newMTD, firstColHead, label;
1.5 cvs 1147: SSchema MathMLSSchema;
1148:
1149: MathMLSSchema = GetMathMLSSchema (doc);
1150: row = TtaGetFirstChild (elMTABLE);
1151:
1152: /* create a MTable_head as the first child of element MTABLE */
1153: elType.ElSSchema = MathMLSSchema;
1154: elType.ElTypeNum = MathML_EL_MTable_head;
1155: MTableHead = TtaNewElement (doc, elType);
1156: TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
1157: elType.ElTypeNum = MathML_EL_MColumn_head;
1.47 cvs 1158: firstColHead = TtaNewTree (doc, elType, "");
1.5 cvs 1159: TtaInsertFirstChild (&firstColHead, MTableHead, doc);
1160:
1161: /* create a MTable_body */
1162: elType.ElTypeNum = MathML_EL_MTable_body;
1163: MTableBody = TtaNewElement (doc, elType);
1164: TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
1165:
1166: /* move all children of element MTABLE into the new MTable_body element
1.103 cvs 1167: and wrap each non-MTR element in a MTR, except comments */
1.5 cvs 1168: prevRow = NULL;
1169: while (row)
1170: {
1171: nextRow = row;
1172: TtaNextSibling (&nextRow);
1173: elType = TtaGetElementType (row);
1174: TtaRemoveTree (row, doc);
1175: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1176: (elType.ElTypeNum == MathML_EL_XMLcomment ||
1.101 cvs 1177: elType.ElTypeNum == MathML_EL_MTR ||
1178: elType.ElTypeNum == MathML_EL_MLABELEDTR))
1.5 cvs 1179: {
1180: if (prevRow == NULL)
1181: TtaInsertFirstChild (&row, MTableBody, doc);
1182: else
1183: TtaInsertSibling (row, prevRow, FALSE, doc);
1184: prevRow = row;
1.101 cvs 1185: if (elType.ElTypeNum == MathML_EL_MTR ||
1186: elType.ElTypeNum == MathML_EL_MLABELEDTR)
1.103 cvs 1187: {
1.5 cvs 1188: cell = TtaGetFirstChild (row);
1.103 cvs 1189: if (elType.ElTypeNum == MathML_EL_MLABELEDTR)
1190: /* skip the first significant child of the mlabeledtr element */
1191: {
1192: /* skip comments first */
1193: do
1194: {
1195: elType = TtaGetElementType (cell);
1196: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1197: elType.ElTypeNum == MathML_EL_XMLcomment)
1198: TtaNextSibling (&cell);
1199: }
1200: while (cell && elType.ElTypeNum == MathML_EL_XMLcomment);
1201: /* skip the first element after the comments: it's a label */
1202: if (cell)
1203: {
1.105 cvs 1204: /* if it's a MTD change its type into LabelCell */
1205: if (elType.ElTypeNum == MathML_EL_MTD &&
1206: elType.ElSSchema == MathMLSSchema)
1207: ChangeElementType (cell, MathML_EL_LabelCell);
1.103 cvs 1208: /* wrap this element in a RowLabel element */
1.105 cvs 1209: /* This will allow the P schema to specify the horizontal
1210: position of the label */
1.103 cvs 1211: elType.ElSSchema = MathMLSSchema;
1212: elType.ElTypeNum = MathML_EL_RowLabel;
1213: label = TtaNewElement (doc, elType);
1214: TtaInsertSibling (label, cell, TRUE, doc);
1215: TtaRemoveTree (cell, doc);
1216: TtaInsertFirstChild (&cell, label, doc);
1217: cell = label;
1218: TtaNextSibling (&cell);
1219: }
1220: }
1221: }
1.5 cvs 1222: else
1223: cell = NULL;
1224: }
1225: else
1.103 cvs 1226: /* this child is not a MTR, MLABELEDTR, or a comment.
1227: In MathML 2.0, this in an error, but we try to recover by
1228: creating a MTR element */
1.5 cvs 1229: {
1230: elType.ElSSchema = MathMLSSchema;
1231: elType.ElTypeNum = MathML_EL_MTR;
1232: el = TtaNewElement (doc, elType);
1233: if (prevRow == NULL)
1234: TtaInsertFirstChild (&el, MTableBody, doc);
1235: else
1236: TtaInsertSibling (el, prevRow, FALSE, doc);
1237: TtaInsertFirstChild (&row, el, doc);
1238: cell = row;
1239: prevRow = el;
1240: }
1241: while (cell)
1242: /* check all children of the current MTR element */
1243: {
1244: nextCell = cell;
1245: TtaNextSibling (&nextCell);
1246: elType = TtaGetElementType (cell);
1247: if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
1248: (elType.ElTypeNum != MathML_EL_XMLcomment &&
1249: elType.ElTypeNum != MathML_EL_MTD))
1250: /* this is not a MTD nor a comment, create a wrapping MTD */
1251: {
1252: elType.ElSSchema = MathMLSSchema;
1253: elType.ElTypeNum = MathML_EL_MTD;
1254: newMTD = TtaNewElement (doc, elType);
1255: TtaInsertSibling (newMTD, cell, TRUE, doc);
1256: TtaRemoveTree (cell, doc);
1257: TtaInsertFirstChild (&cell, newMTD, doc);
1258: cell = newMTD;
1259: }
1260: if (elType.ElTypeNum == MathML_EL_MTD)
1261: /* This is a MTD element. Wrap its contents with a CellWrapper */
1.39 cvs 1262: CreateWrapper (cell, MathML_EL_CellWrapper, doc);
1.5 cvs 1263: cell = nextCell;
1264: }
1265: row = nextRow;
1266: }
1.107 cvs 1267: CheckAllRows (elMTABLE, doc, placeholder, FALSE);
1.5 cvs 1268: }
1.12 cvs 1269:
1.46 cvs 1270: /*----------------------------------------------------------------------
1.1 cvs 1271: SetFontstyleAttr
1272: The content of a MI element has been created or modified.
1273: Create or change attribute IntFontstyle for that element accordingly.
1274: -----------------------------------------------------------------------*/
1275: void SetFontstyleAttr (Element el, Document doc)
1276: {
1277: ElementType elType;
1278: AttributeType attrType;
1279: Attribute attr, IntAttr;
1.54 cvs 1280: Element textEl;
1.1 cvs 1281: int len;
1.120 cvs 1282: char *value;
1.54 cvs 1283: ThotBool italic;
1.1 cvs 1284:
1285: if (el != NULL)
1.142 quint 1286: {
1287: /* search the fontstyle attribute */
1288: elType = TtaGetElementType (el);
1289: attrType.AttrSSchema = elType.ElSSchema;
1290: attrType.AttrTypeNum = MathML_ATTR_fontstyle;
1291: attr = TtaGetAttribute (el, attrType);
1292: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1293: IntAttr = TtaGetAttribute (el, attrType);
1294: if (attr != NULL)
1.1 cvs 1295: /* there is a fontstyle attribute. Remove the corresponding
1296: internal attribute that is not needed */
1297: {
1.142 quint 1298: if (IntAttr != NULL)
1299: TtaRemoveAttribute (el, IntAttr, doc);
1.1 cvs 1300: }
1.142 quint 1301: else
1.1 cvs 1302: /* there is no fontstyle attribute. Create an internal attribute
1303: IntFontstyle with a value that depends on the content of the MI */
1304: {
1.142 quint 1305: /* get content length */
1306: len = TtaGetElementVolume (el);
1307: if (len > 1)
1308: /* put an attribute IntFontstyle = IntNormal */
1309: {
1310: if (IntAttr == NULL)
1311: {
1312: IntAttr = TtaNewAttribute (attrType);
1313: TtaAttachAttribute (el, IntAttr, doc);
1314: }
1315: TtaSetAttributeValue (IntAttr,
1316: MathML_ATTR_IntFontstyle_VAL_IntNormal,
1317: el, doc);
1318: }
1319: else
1320: /* MI contains a single character. Remove attribute IntFontstyle
1321: if it exists, except if it's ImaginaryI, ExponentialE or
1322: DifferentialD */
1323: {
1324: italic = TRUE;
1325: textEl = TtaGetFirstChild (el);
1326: if (textEl != NULL)
1327: {
1328: elType = TtaGetElementType (textEl);
1329: if (elType.ElTypeNum == MathML_EL_MGLYPH)
1330: /* the content of the MI element is a MGLYPH element */
1331: /* check the length if it's alt attribute */
1332: {
1333: /* by default, use normal style */
1334: italic = FALSE;
1335: attrType.AttrTypeNum = MathML_ATTR_alt;
1336: attr = TtaGetAttribute (textEl, attrType);
1337: if (attr)
1338: /* the MGLYPH element has an alt attribute */
1339: {
1340: len = TtaGetTextAttributeLength (attr);
1341: if (len == 1)
1342: italic = TRUE;
1343: }
1344: }
1345: else
1346: {
1347: /* is there an attribute EntityName on that character? */
1348: attrType.AttrTypeNum = MathML_ATTR_EntityName;
1349: attr = TtaGetAttribute (textEl, attrType);
1350: if (attr)
1351: {
1352: len = TtaGetTextAttributeLength (attr);
1353: if (len > 0)
1354: {
1355: value = TtaGetMemory (len+1);
1356: TtaGiveTextAttributeValue (attr, value, &len);
1357: if (strcmp (&value[1], "ImaginaryI;") == 0 ||
1358: strcmp (&value[1], "ExponentialE;") == 0 ||
1359: strcmp (&value[1], "DifferentialD;") == 0)
1360: italic = FALSE;
1361: TtaFreeMemory (value);
1362: }
1363: }
1364: }
1365: if (italic)
1366: {
1367: if (IntAttr != NULL)
1368: TtaRemoveAttribute (el, IntAttr, doc);
1369: }
1370: else
1371: {
1372: /* put an attribute IntFontstyle = IntNormal */
1373: if (IntAttr == NULL)
1374: {
1375: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1376: IntAttr = TtaNewAttribute (attrType);
1377: TtaAttachAttribute (el, IntAttr, doc);
1378: }
1379: TtaSetAttributeValue (IntAttr,
1380: MathML_ATTR_IntFontstyle_VAL_IntNormal,
1381: el, doc);
1382: }
1383: }
1384: }
1.1 cvs 1385: }
1.142 quint 1386: }
1.1 cvs 1387: }
1388:
1389: /*----------------------------------------------------------------------
1.22 cvs 1390: SetIntAddSpaceAttr
1.1 cvs 1391: The content of a MO element has been created or modified.
1.22 cvs 1392: Create or change attribute IntAddSpace for that element accordingly.
1.1 cvs 1393: -----------------------------------------------------------------------*/
1.22 cvs 1394: void SetIntAddSpaceAttr (Element el, Document doc)
1.1 cvs 1395: {
1396: Element textEl, previous;
1397: ElementType elType;
1398: AttributeType attrType;
1.60 cvs 1399: Attribute attr, formAttr;
1.155 ! quint 1400: SSchema MathMLSSchema;
1.60 cvs 1401: int len, val, form;
1.146 quint 1402: CHAR_T text[2];
1.1 cvs 1403: Language lang;
1.143 vatton 1404: char script;
1.155 ! quint 1405: ThotBool comment;
1.1 cvs 1406:
1.155 ! quint 1407: MathMLSSchema = TtaGetElementType(el).ElSSchema;
1.60 cvs 1408: /* get the content of the mo element */
1.1 cvs 1409: textEl = TtaGetFirstChild (el);
1.155 ! quint 1410:
! 1411: /* skip comments if any */
! 1412: if (textEl)
! 1413: do
! 1414: {
! 1415: elType = TtaGetElementType (textEl);
! 1416: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
! 1417: elType.ElTypeNum == MathML_EL_XMLcomment)
! 1418: /* it's a comment, skip it */
! 1419: TtaNextSibling (&textEl);
! 1420: }
! 1421: while (textEl && elType.ElTypeNum == MathML_EL_XMLcomment);
! 1422:
! 1423: if (textEl && elType.ElTypeNum == MathML_EL_TEXT_UNIT)
! 1424: /* the mo element is not empty */
! 1425: {
! 1426: /* does the mo element have an IntAddSpace attribute? */
! 1427: attrType.AttrSSchema = MathMLSSchema;
! 1428: attrType.AttrTypeNum = MathML_ATTR_IntAddSpace;
! 1429: attr = TtaGetAttribute (el, attrType);
! 1430: if (attr == NULL)
1.60 cvs 1431: /* no IntAddSpace Attr, create one */
1.1 cvs 1432: {
1.155 ! quint 1433: attr = TtaNewAttribute (attrType);
! 1434: TtaAttachAttribute (el, attr, doc);
! 1435: }
! 1436: /* space on both sides by default */
! 1437: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1438: /* does the mo element have a form attribute? */
! 1439: attrType.AttrTypeNum = MathML_ATTR_form;
! 1440: formAttr = TtaGetAttribute (el, attrType);
! 1441: if (formAttr)
! 1442: /* there is a form attribute */
! 1443: {
! 1444: form = TtaGetAttributeValue (formAttr);
! 1445: switch (form)
! 1446: {
! 1447: case MathML_ATTR_form_VAL_prefix:
! 1448: val = MathML_ATTR_IntAddSpace_VAL_nospace;
! 1449: break;
! 1450: case MathML_ATTR_form_VAL_infix:
! 1451: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1452: break;
! 1453: case MathML_ATTR_form_VAL_postfix:
! 1454: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
! 1455: break;
! 1456: default:
! 1457: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1458: break;
! 1459: }
1.1 cvs 1460: }
1.155 ! quint 1461: else
! 1462: /* no form attribute. Analyze the content */
! 1463: {
! 1464: len = TtaGetElementVolume (textEl);
! 1465: if (len == 1)
! 1466: {
! 1467: TtaGiveBufferContent (textEl, text, len+1, &lang);
! 1468: script = TtaGetScript (lang);
! 1469: /* the mo element contains a single character */
1.146 quint 1470: #ifndef _I18N_
1.155 ! quint 1471: if (script == 'L')
! 1472: /* ISO-Latin 1 character */
! 1473: {
1.146 quint 1474: #endif
1.155 ! quint 1475: if (text[0] == '-'
1.153 quint 1476: #ifdef _I18N_
1.155 ! quint 1477: || text[0] == 0x2212 /* minus */
1.153 quint 1478: #endif
1.155 ! quint 1479: )
! 1480: /* prefix or infix operator? */
! 1481: {
! 1482: /* skip preceding comments if any */
! 1483: previous = el;
! 1484: do
! 1485: {
! 1486: comment = FALSE;
! 1487: TtaPreviousSibling (&previous);
! 1488: if (previous)
! 1489: {
! 1490: elType = TtaGetElementType (previous);
! 1491: comment = (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
! 1492: elType.ElTypeNum == MathML_EL_XMLcomment);
! 1493: }
! 1494: }
! 1495: while (previous && comment);
! 1496:
! 1497: if (previous == NULL)
! 1498: /* no previous sibling => prefix operator */
! 1499: val = MathML_ATTR_IntAddSpace_VAL_nospace;
! 1500: else
! 1501: {
! 1502: elType = TtaGetElementType (previous);
! 1503: if (elType.ElTypeNum == MathML_EL_MO)
! 1504: /* after an operator => prefix operator */
! 1505: val = MathML_ATTR_IntAddSpace_VAL_nospace;
! 1506: else
! 1507: /* infix operator */
! 1508: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1509: }
! 1510: }
! 1511: else if (text[0] == '&' ||
! 1512: text[0] == '*' ||
! 1513: text[0] == '+' ||
! 1514: text[0] == '/' ||
! 1515: text[0] == '<' ||
! 1516: text[0] == '=' ||
! 1517: text[0] == '>' ||
! 1518: text[0] == '^' ||
! 1519: (int)text[0] == 177 || /* plus or minus */
! 1520: (int)text[0] == 215 || /* times */
! 1521: (int)text[0] == 247) /* divide */
! 1522: /* infix operator */
! 1523: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1524: else if (text[0] == ',' ||
! 1525: text[0] == '!' ||
! 1526: text[0] == '&' ||
! 1527: text[0] == ':' ||
! 1528: text[0] == ';')
! 1529: /* separator */
! 1530: val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
! 1531: else if (text[0] == '(' ||
! 1532: text[0] == ')' ||
! 1533: text[0] == '[' ||
! 1534: text[0] == ']' ||
! 1535: text[0] == '{' ||
! 1536: text[0] == '}' ||
! 1537: text[0] == '.' ||
! 1538: text[0] == '@' ||
! 1539: (int)text[0] == 129 || /* thin space */
! 1540: (int)text[0] == 130 || /* en space */
! 1541: (int)text[0] == 160) /* em space */
! 1542: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.146 quint 1543: #ifndef _I18N_
1.155 ! quint 1544: }
! 1545: else if (script == 'G')
! 1546: {
! 1547: /* Symbol character set */
! 1548: if ((int)text[0] == 163 || /* less or equal */
! 1549: (int)text[0] == 177 || /* plus or minus */
! 1550: (int)text[0] == 179 || /* greater or equal */
! 1551: (int)text[0] == 180 || /* times */
! 1552: (int)text[0] == 184 || /* divide */
! 1553: (int)text[0] == 185 || /* not equal */
! 1554: (int)text[0] == 186 || /* identical */
! 1555: (int)text[0] == 187 || /* equivalent */
! 1556: (int)text[0] == 196 || /* circle times */
! 1557: (int)text[0] == 197 || /* circle plus */
! 1558: ((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
! 1559: (int)text[0] == 217 || /* and */
! 1560: (int)text[0] == 218) /* or */
1.146 quint 1561: #else
1.155 ! quint 1562: else
! 1563: if ((int)text[0] == 0x2264 || /* less or equal */
! 1564: (int)text[0] == 0x00B1 || /* plus or minus */
! 1565: (int)text[0] == 0x2265 || /* greater or equal */
! 1566: (int)text[0] == 0x00D7 || /* times */
! 1567: (int)text[0] == 0x00F7 || /* divide */
! 1568: (int)text[0] == 0x2260 || /* not equal */
! 1569: (int)text[0] == 0x2261 || /* identical */
! 1570: (int)text[0] == 0x2248 || /* equivalent */
! 1571: (int)text[0] == 0x2297 || /* circle times */
! 1572: (int)text[0] == 0x2295 || /* circle plus */
! 1573: (int)text[0] == 0x2229 || /* Intersection */
! 1574: (int)text[0] == 0x222A || /* Union */
! 1575: (int)text[0] == 0x2283 || /* Superset of */
! 1576: (int)text[0] == 0x2287 || /* Superset of or equal to */
! 1577: (int)text[0] == 0x2284 || /* Not a subset of */
! 1578: (int)text[0] == 0x2282 || /* Subset of */
! 1579: (int)text[0] == 0x2286 || /* Subset of or equal to */
! 1580: (int)text[0] == 0x2208 || /* Element of */
! 1581: (int)text[0] == 0x2209 || /* Not an element of */
! 1582: (int)text[0] == 0x2220 || /* Angle */
! 1583: (int)text[0] == 0x2207 || /* Nabla */
! 1584: (int)text[0] == 0x2227 || /* and */
! 1585: (int)text[0] == 0x2228 || /* or */
! 1586: (int)text[0] == 0x2190 || /* left arrow */
! 1587: (int)text[0] == 0x2192 || /* right arrow */
! 1588: (int)text[0] == 0x2194) /* left right arrow */
1.146 quint 1589: #endif
1.155 ! quint 1590: /* infix operator */
! 1591: val = MathML_ATTR_IntAddSpace_VAL_both;
! 1592: else
! 1593: val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.146 quint 1594: #ifndef _I18N_
1.155 ! quint 1595: }
1.146 quint 1596: #endif
1.155 ! quint 1597: }
! 1598: }
! 1599: TtaSetAttributeValue (attr, val, el, doc);
! 1600: }
1.1 cvs 1601: }
1602:
1603: /*----------------------------------------------------------------------
1.58 cvs 1604: ChildOfMRowOrInferred
1605: Return TRUE if element el is a child of a MROW element or an
1606: inferred MROW element
1607: ----------------------------------------------------------------------*/
1608: ThotBool ChildOfMRowOrInferred (Element el)
1609: {
1610: ElementType elType;
1611: Element parent;
1612: ThotBool result;
1613:
1614: result = FALSE;
1615: parent = TtaGetParent (el);
1616: if (parent)
1617: {
1618: elType = TtaGetElementType (parent);
1619: result = (elType.ElTypeNum == MathML_EL_MROW ||
1620: elType.ElTypeNum == MathML_EL_SqrtBase ||
1621: elType.ElTypeNum == MathML_EL_MSTYLE ||
1622: elType.ElTypeNum == MathML_EL_MERROR ||
1.92 cvs 1623: elType.ElTypeNum == MathML_EL_MENCLOSE ||
1.58 cvs 1624: elType.ElTypeNum == MathML_EL_MPADDED ||
1625: elType.ElTypeNum == MathML_EL_MPHANTOM ||
1626: elType.ElTypeNum == MathML_EL_CellWrapper ||
1.92 cvs 1627: elType.ElTypeNum == MathML_EL_MathML ||
1.58 cvs 1628: elType.ElTypeNum == MathML_EL_FencedExpression);
1629: }
1630: return result;
1631: }
1632:
1633: /*----------------------------------------------------------------------
1.1 cvs 1634: CheckFence
1.84 cvs 1635: If el is a MO element,
1636: - if it's a large operator (∑ for instance), put a presentation
1637: rule to enlarge the character.
1638: - if it's a child of a MROW (or equivalent) element and if it contains
1639: a single fence character, transform the MO into a MF and the fence
1640: character into a Thot stretchable symbol.
1.1 cvs 1641: ----------------------------------------------------------------------*/
1.84 cvs 1642: void CheckFence (Element el, Document doc)
1.1 cvs 1643: {
1.128 vatton 1644: ElementType elType;
1645: Element content;
1646: AttributeType attrType;
1647: Attribute attr, attrStretchy;
1648: Language lang;
1.84 cvs 1649: PresentationValue pval;
1650: PresentationContext ctxt;
1.128 vatton 1651: CHAR_T text[2];
1.143 vatton 1652: char script;
1.128 vatton 1653: unsigned char c;
1654: int len, val;
1.1 cvs 1655:
1656: elType = TtaGetElementType (el);
1657: if (elType.ElTypeNum == MathML_EL_MO)
1.58 cvs 1658: /* the element is a MO */
1659: {
1.84 cvs 1660: content = TtaGetFirstChild (el);
1661: if (content != NULL)
1662: {
1663: elType = TtaGetElementType (content);
1664: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1665: {
1.146 quint 1666: len = TtaGetElementVolume (content);
1.84 cvs 1667: if (len == 1)
1668: /* the MO element contains a single character */
1669: {
1.146 quint 1670: TtaGiveBufferContent (content, text, len+1, &lang);
1.143 vatton 1671: script = TtaGetScript (lang);
1.146 quint 1672: #ifdef _I18N_
1673: if (text[0] == 8721 || text[0] == 8719) /* large Sigma or Pi */
1674: #else
1.143 vatton 1675: if ((script == 'G') &&
1.146 quint 1676: (text[0] == 229 || text[0] == 213)) /* large Sigma or Pi */
1677: #endif
1.84 cvs 1678: /* it's a large operator */
1679: {
1680: ctxt = TtaGetSpecificStyleContext (doc);
1681: ctxt->destroy = FALSE;
1682: /* the specific presentation to be created is not a CSS rule */
1.147 quint 1683: ctxt->cssSpecificity = 0;
1.84 cvs 1684: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1685: pval.typed_data.real = FALSE;
1686: pval.typed_data.value = 180;
1687: TtaSetStylePresentation (PRSize, content, NULL, ctxt, pval);
1688: }
1689: else if (ChildOfMRowOrInferred (el))
1690: /* the MO element is a child of a MROW element */
1.1 cvs 1691: {
1.146 quint 1692: if ((
1693: #ifndef _I18N_
1694: (script == 'L') &&
1695: #endif
1.115 cvs 1696: (text[0] == '(' || text[0] == ')' ||
1697: text[0] == '[' || text[0] == ']' ||
1698: text[0] == '{' || text[0] == '}' ||
1699: text[0] == '|')) ||
1.146 quint 1700: (
1701: /* test left and right angle brackets */
1702: #ifdef _I18N_
1703: (text[0] == 9001 || text[0] == 9002)
1704: #else
1705: (script == 'G') &&
1706: (text[0] == 225 || text[0] == 241)
1707: #endif
1708: ))
1.84 cvs 1709: /* it's a stretchable parenthesis or equivalent */
1710: {
1711: /* remove the content of the MO element */
1712: TtaDeleteTree (content, doc);
1713: /* change the MO element into a MF element */
1714: ChangeTypeOfElement (el, doc, MathML_EL_MF);
1.55 cvs 1715:
1.84 cvs 1716: /* is there an attribute stretchy on this mo element? */
1717: attrType.AttrSSchema = elType.ElSSchema;
1718: attrType.AttrTypeNum = MathML_ATTR_stretchy;
1719: attrStretchy = TtaGetAttribute (el, attrType);
1720: if (attrStretchy)
1721: val = TtaGetAttributeValue (attrStretchy);
1722: else
1723: val = MathML_ATTR_stretchy_VAL_true;
1724: if (val == MathML_ATTR_stretchy_VAL_true)
1725: {
1726: /* attach a IntVertStretch attribute to the MF element*/
1727: attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
1728: attr = TtaNewAttribute (attrType);
1729: TtaAttachAttribute (el, attr, doc);
1730: TtaSetAttributeValue (attr,
1731: MathML_ATTR_IntVertStretch_VAL_yes_,
1732: el, doc);
1733: }
1734: /* create a new content for the MF element */
1.87 cvs 1735: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1.146 quint 1736: #ifdef _I18N_
1737: if (text[0] == 9002)
1738: #else
1.143 vatton 1739: if (script == 'G' && text[0] == 241)
1.146 quint 1740: #endif
1.102 cvs 1741: c = '>'; /* RightAngleBracket */
1742: else
1.146 quint 1743: #ifdef _I18N_
1744: if (text[0] == 9001)
1745: #else
1746: if (script == 'G' && text[0] == 225)
1747: #endif
1748: c = '<'; /* LeftAngleBracket */
1749: else
1750: c = (char) text[0];
1.84 cvs 1751: content = TtaNewElement (doc, elType);
1752: TtaInsertFirstChild (&content, el, doc);
1753: TtaSetGraphicsShape (content, c, doc);
1754: }
1.1 cvs 1755: }
1.84 cvs 1756: }
1757: }
1.58 cvs 1758: }
1759: }
1.1 cvs 1760: }
1761:
1762: /*----------------------------------------------------------------------
1763: CreateFencedSeparators
1764: Create FencedSeparator elements within the fencedExpression
1765: according to attribute separators of the MFENCED element.
1766: ----------------------------------------------------------------------*/
1.110 cvs 1767: void CreateFencedSeparators (Element fencedExpression, Document doc, ThotBool record)
1.1 cvs 1768: {
1769: ElementType elType;
1770: Element child, separator, leaf, next, prev, mfenced;
1771: AttributeType attrType;
1772: Attribute attr;
1773: int length, sep, i;
1774: Language lang;
1.116 cvs 1775: char text[32], sepValue[4];
1.1 cvs 1776:
1777: /* get the separators attribute */
1778: mfenced = TtaGetParent (fencedExpression);
1779: elType = TtaGetElementType (fencedExpression);
1780: attrType.AttrSSchema = elType.ElSSchema;
1781: attrType.AttrTypeNum = MathML_ATTR_separators;
1782: text[0] = ','; /* default value is sparators="," */
1783: text[1] = EOS;
1784: length = 1;
1785: attr = TtaGetAttribute (mfenced, attrType);
1786: if (attr != NULL)
1787: {
1788: length = 31;
1789: TtaGiveTextAttributeValue (attr, text, &length);
1790: }
1791:
1792: /* create FencedSeparator elements in the FencedExpression */
1793: prev = NULL;
1794: sep = 0;
1795: /* skip leading spaces in attribute separators */
1796: while (text[sep] <= SPACE && text[sep] != EOS)
1797: sep++;
1798: /* if attribute separators is empty or contains only spaces, do not
1799: insert any separator element */
1800: if (text[sep] != EOS)
1801: {
1802: child = TtaGetFirstChild (fencedExpression);
1803: while (child != NULL)
1804: {
1805: next = child;
1806: TtaNextSibling (&next);
1807: elType = TtaGetElementType (child);
1808: if (elType.ElTypeNum != MathML_EL_Construct)
1809: {
1810: if (prev != NULL)
1811: {
1812: elType.ElTypeNum = MathML_EL_FencedSeparator;
1813: separator = TtaNewElement (doc, elType);
1814: TtaInsertSibling (separator, prev, FALSE, doc);
1815: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1816: leaf = TtaNewElement (doc, elType);
1817: TtaInsertFirstChild (&leaf, separator, doc);
1818: sepValue[0] = text[sep];
1819: sepValue[1] = SPACE;
1820: sepValue[2] = EOS;
1.143 vatton 1821: lang = TtaGetLanguageIdFromScript('L');
1.1 cvs 1822: TtaSetTextContent (leaf, sepValue, lang, doc);
1823: /* is there a following non-space character in separators? */
1824: i = sep + 1;
1825: while (text[i] <= SPACE && text[i] != EOS)
1826: i++;
1827: if (text[i] > SPACE && text[i] != EOS)
1828: sep = i;
1.17 cvs 1829: if (record)
1830: TtaRegisterElementCreate (separator, doc);
1.1 cvs 1831: }
1832: prev = child;
1833: }
1834: child = next;
1835: }
1836: }
1837: }
1838:
1.124 cvs 1839: /*----------------------------------------------------------------------
1840: CreateOpeningOrClosingFence
1841: Create the OpeningFence or ClosingFence element (depending on parameter
1842: open) for the MFENCED element el which contain the fencedExpression
1843: element.
1844: ----------------------------------------------------------------------*/
1845: static void CreateOpeningOrClosingFence (Element fencedExpression,
1846: Element el, Document doc,
1847: ThotBool open)
1848: {
1849: ElementType elType;
1850: Element leaf, fence;
1851: AttributeType attrType;
1852: Attribute attr;
1853: int length;
1854: char text[32];
1855: char c;
1856:
1857: elType = TtaGetElementType (el);
1858: attrType.AttrSSchema = elType.ElSSchema;
1859: if (open)
1860: {
1861: c = '('; /* default value of attribute 'open' */
1862: attrType.AttrTypeNum = MathML_ATTR_open;
1863: elType.ElTypeNum = MathML_EL_OpeningFence;
1864: }
1865: else
1866: {
1867: c = ')'; /* default value of attribute 'close' */
1868: attrType.AttrTypeNum = MathML_ATTR_close;
1869: elType.ElTypeNum = MathML_EL_ClosingFence;
1870: }
1871: attr = TtaGetAttribute (el, attrType);
1872: if (attr != NULL)
1873: {
1874: length = 31;
1875: TtaGiveTextAttributeValue (attr, text, &length);
1876: if (length != 1)
1877: /* content of attribute open or close should be a single character */
1878: c = '?';
1879: else
1880: {
1.128 vatton 1881: c = text[0];
1.124 cvs 1882: /* filter characters that would represent strange symbols, such
1883: as root, integrals, arrows, etc. */
1884: if (c == 'r' || c == 'i' || c == 'c' || c == 'd' || c == 'S' ||
1885: c == 'P' || c == 'I' || c == 'U' || c == 'o' || c == 'u' ||
1886: c == 'h' || c == 'v' || c == 'R' || c == '^' || c == 'L' ||
1887: c == 'V' || c == 'D')
1888: c = '?';
1889: }
1890: }
1891: fence = TtaNewElement (doc, elType);
1892: TtaInsertSibling (fence, fencedExpression, open, doc);
1893: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1894: leaf = TtaNewElement (doc, elType);
1895: TtaInsertFirstChild (&leaf, fence, doc);
1896: TtaSetGraphicsShape (leaf, c, doc);
1897: }
1.1 cvs 1898:
1899: /*----------------------------------------------------------------------
1900: TransformMFENCED
1901: Transform the content of a MFENCED element: create elements
1902: OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
1903: ----------------------------------------------------------------------*/
1.46 cvs 1904: static void TransformMFENCED (Element el, Document doc)
1.1 cvs 1905: {
1906: ElementType elType;
1.124 cvs 1907: Element child, fencedExpression, next, prev, firstChild;
1.1 cvs 1908:
1909: child = TtaGetFirstChild (el);
1910: if (child != NULL)
1911: elType = TtaGetElementType (child);
1912: if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
1913: /* The first child of this MFENCED element is an OpeningFence.
1914: This MFENCED expression has already been transformed, possibly
1915: by the Transform command */
1916: {
1917: TtaNextSibling (&child);
1918: fencedExpression = child;
1919: if (fencedExpression != NULL)
1920: elType = TtaGetElementType (fencedExpression);
1921: if (elType.ElTypeNum == MathML_EL_FencedExpression)
1922: /* the second child is a FencedExpression. OK.
1923: Remove all existing FencedSeparator elements */
1924: {
1925: child = TtaGetFirstChild (fencedExpression);
1926: prev = NULL;
1927: while (child != NULL)
1928: {
1929: elType = TtaGetElementType (child);
1930: next = child;
1931: TtaNextSibling (&next);
1932: if (elType.ElTypeNum == MathML_EL_FencedSeparator)
1933: /* Remove this separator */
1934: TtaDeleteTree (child, doc);
1935: child = next;
1936: }
1937: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 1938: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 1939: }
1940: }
1941: else
1942: /* this MFENCED element must be transformed */
1943: {
1944: /* create a FencedExpression element as a child of the MFENCED elem. */
1945: elType = TtaGetElementType (el);
1946: elType.ElTypeNum = MathML_EL_FencedExpression;
1947: fencedExpression = TtaNewElement (doc, elType);
1948: TtaInsertFirstChild (&fencedExpression, el, doc);
1949: if (child == NULL)
1950: /* empty MFENCED element */
1951: {
1952: elType.ElTypeNum = MathML_EL_Construct;
1953: child = TtaNewElement (doc, elType);
1954: TtaInsertFirstChild (&child, fencedExpression, doc);
1.22 cvs 1955: SetIntPlaceholderAttr (child, doc);
1.1 cvs 1956: }
1957: else
1958: {
1959: /* move the content of the MFENCED element within the new
1960: FencedExpression element */
1961: prev = NULL;
1962: firstChild = NULL;
1963: while (child != NULL)
1964: {
1965: next = child;
1966: TtaNextSibling (&next);
1967: TtaRemoveTree (child, doc);
1968: if (prev == NULL)
1969: {
1970: TtaInsertFirstChild (&child, fencedExpression, doc);
1971: firstChild = child;
1972: }
1973: else
1974: TtaInsertSibling (child, prev, FALSE, doc);
1975: prev = child;
1976: child = next;
1977: }
1978:
1979: /* create FencedSeparator elements in the FencedExpression */
1.17 cvs 1980: CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1 cvs 1981:
1982: /* Create placeholders within the FencedExpression element */
1983: CreatePlaceholders (firstChild, doc);
1984: }
1985:
1986: /* create the OpeningFence element according to the open attribute */
1.124 cvs 1987: CreateOpeningOrClosingFence (fencedExpression, el, doc, TRUE);
1.1 cvs 1988:
1989: /* create the ClosingFence element according to close attribute */
1.124 cvs 1990: CreateOpeningOrClosingFence (fencedExpression, el, doc, FALSE);
1.1 cvs 1991: }
1992: }
1993:
1994: /*----------------------------------------------------------------------
1.59 cvs 1995: MathMLScriptShift
1996: The MathML attribute attr (superscriptshift or subscriptshift) is associated
1997: with element el (a msub, msup or msubsup).
1998: If value is not NULL, generate the corresponding Thot VertPos rule for the
1999: Subscript or Superscript child of el.
2000: If value is NULL, remove the Thot VertPos rule.
2001: -----------------------------------------------------------------------*/
1.120 cvs 2002: void MathMLScriptShift (Document doc, Element el, char *value, int attr)
1.59 cvs 2003: {
2004: ElementType elType;
2005: Element script, child;
2006: int scrType;
2007: PresentationValue pval;
2008: PresentationContext ctxt;
2009:
2010: /* get the Superscript or Subscript child of el */
2011: if (attr == MathML_ATTR_superscriptshift)
2012: scrType = MathML_EL_Superscript;
2013: else if (attr == MathML_ATTR_subscriptshift)
2014: scrType = MathML_EL_Subscript;
2015: else
2016: return;
2017: script = NULL;
2018: child = TtaGetFirstChild (el);
2019: while (!script && child)
2020: {
2021: elType = TtaGetElementType (child);
2022: if (elType.ElTypeNum == scrType)
2023: script = child;
2024: else
2025: TtaNextSibling (&child);
2026: }
2027: if (script)
2028: /* Superscript or Subscript element found */
2029: {
2030: ctxt = TtaGetSpecificStyleContext (doc);
2031: if (!value)
2032: /* remove the presentation rule */
2033: {
2034: ctxt->destroy = TRUE;
1.75 cvs 2035: pval.typed_data.value = 0;
1.59 cvs 2036: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
2037: }
2038: else
2039: {
2040: ctxt->destroy = FALSE;
2041: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 2042: value = TtaSkipBlanks (value);
1.59 cvs 2043: value = ParseCSSUnit (value, &pval);
2044: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
2045: {
1.78 cvs 2046: /* the specific presentation to be created is not a CSS rule */
1.147 quint 2047: ctxt->cssSpecificity = 0;
1.59 cvs 2048: if (attr == MathML_ATTR_superscriptshift)
2049: pval.typed_data.value = - pval.typed_data.value;
2050: TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
2051: }
2052: }
2053: TtaFreeMemory (ctxt);
2054: }
2055: }
2056:
2057: /*----------------------------------------------------------------------
2058: SetScriptShift
2059: If element el (which is a msup, msub or msubsup) has an attribute
2060: att (which is subscriptshift or superscriptshift), generate the
2061: corresponding Thot presentation rule.
2062: ----------------------------------------------------------------------*/
1.120 cvs 2063: static void SetScriptShift (Element el, Document doc, int att)
1.59 cvs 2064: {
2065: AttributeType attrType;
2066: ElementType elType;
2067: Attribute attr;
1.120 cvs 2068: char *value;
1.59 cvs 2069: int length;
2070:
2071: elType = TtaGetElementType (el);
2072: attrType.AttrSSchema = elType.ElSSchema;
2073: attrType.AttrTypeNum = att;
2074: attr = TtaGetAttribute (el, attrType);
2075: if (attr)
2076: {
2077: length = TtaGetTextAttributeLength (attr);
2078: if (length > 0)
2079: {
1.116 cvs 2080: value = TtaGetMemory (length+1);
1.59 cvs 2081: value[0] = EOS;
2082: TtaGiveTextAttributeValue (attr, value, &length);
2083: MathMLScriptShift (doc, el, value, att);
2084: TtaFreeMemory (value);
2085: }
2086: }
2087: }
2088:
2089: /*----------------------------------------------------------------------
1.1 cvs 2090: MathMLElementComplete
2091: Check the Thot structure of the MathML element el.
2092: ----------------------------------------------------------------------*/
1.56 cvs 2093: void MathMLElementComplete (Element el, Document doc, int *error)
1.1 cvs 2094: {
1.74 cvs 2095: ElementType elType, parentType;
1.1 cvs 2096: Element child, parent, new, prev, next;
1.101 cvs 2097: AttributeType attrType;
2098: Attribute attr;
1.56 cvs 2099: SSchema MathMLSSchema;
2100: ThotBool ok;
1.1 cvs 2101:
1.56 cvs 2102: ok = TRUE;
2103: *error = 0;
1.1 cvs 2104: elType = TtaGetElementType (el);
1.2 cvs 2105: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 2106:
1.76 cvs 2107: if (elType.ElSSchema == MathMLSSchema)
1.1 cvs 2108: {
2109: switch (elType.ElTypeNum)
2110: {
1.76 cvs 2111: case MathML_EL_MathML:
2112: /* Create placeholders within the MathML element */
2113: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.132 cvs 2114: break;
1.1 cvs 2115: case MathML_EL_MI:
2116: SetFontstyleAttr (el, doc);
2117: break;
2118: case MathML_EL_MO:
1.22 cvs 2119: SetIntAddSpaceAttr (el, doc);
2120: SetIntVertStretchAttr (el, doc, 0, NULL);
1.58 cvs 2121: /* if the MO element is a child of a MROW (or equivalent) and if it
2122: contains a fence character, transform this MO into MF and
2123: transform the fence character into a Thot SYMBOL */
2124: CheckFence (el, doc);
1.1 cvs 2125: break;
1.60 cvs 2126: case MathML_EL_MSPACE:
2127: break;
1.39 cvs 2128: case MathML_EL_MROW:
1.55 cvs 2129: /* Create placeholders within the MROW */
2130: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.39 cvs 2131: break;
2132: case MathML_EL_MFRAC:
1.54 cvs 2133: case MathML_EL_BevelledMFRAC:
1.39 cvs 2134: /* end of a fraction. Create a Numerator and a Denominator */
1.56 cvs 2135: ok = CheckMathSubExpressions (el, MathML_EL_Numerator,
2136: MathML_EL_Denominator, 0, doc);
1.39 cvs 2137: break;
2138: case MathML_EL_MSQRT:
1.50 cvs 2139: /* end of a Square Root */
2140: /* Create placeholders within the element */
2141: CreatePlaceholders (TtaGetFirstChild (el), doc);
2142: /* Create a SqrtBase that contains all children of the MSQRT */
1.39 cvs 2143: CreateWrapper (el, MathML_EL_SqrtBase, doc);
2144: break;
1.1 cvs 2145: case MathML_EL_MROOT:
2146: /* end of a Root. Create a RootBase and an Index */
1.56 cvs 2147: ok = CheckMathSubExpressions (el, MathML_EL_RootBase,
2148: MathML_EL_Index, 0, doc);
1.1 cvs 2149: break;
1.50 cvs 2150: case MathML_EL_MENCLOSE:
2151: /* Create placeholders within the element */
2152: CreatePlaceholders (TtaGetFirstChild (el), doc);
2153: break;
1.39 cvs 2154: case MathML_EL_MSTYLE:
2155: case MathML_EL_MERROR:
2156: case MathML_EL_MPADDED:
2157: case MathML_EL_MPHANTOM:
2158: /* Create placeholders within the element */
2159: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 2160: break;
2161: case MathML_EL_MFENCED:
2162: TransformMFENCED (el, doc);
2163: break;
2164: case MathML_EL_MSUB:
2165: /* end of a MSUB. Create Base and Subscript */
1.56 cvs 2166: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2167: MathML_EL_Subscript, 0, doc);
1.59 cvs 2168: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
1.22 cvs 2169: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2170: break;
2171: case MathML_EL_MSUP:
2172: /* end of a MSUP. Create Base and Superscript */
1.56 cvs 2173: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2174: MathML_EL_Superscript, 0, doc);
1.59 cvs 2175: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.22 cvs 2176: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2177: break;
1.39 cvs 2178: case MathML_EL_MSUBSUP:
2179: /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
1.56 cvs 2180: ok = CheckMathSubExpressions (el, MathML_EL_Base,
2181: MathML_EL_Subscript,
2182: MathML_EL_Superscript, doc);
1.59 cvs 2183: SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
2184: SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.39 cvs 2185: SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1 cvs 2186: break;
2187: case MathML_EL_MUNDER:
2188: /* end of a MUNDER. Create UnderOverBase, and Underscript */
1.56 cvs 2189: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2190: MathML_EL_Underscript, 0, doc);
1.22 cvs 2191: SetIntHorizStretchAttr (el, doc);
2192: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 2193: break;
2194: case MathML_EL_MOVER:
2195: /* end of a MOVER. Create UnderOverBase, and Overscript */
1.56 cvs 2196: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2197: MathML_EL_Overscript, 0, doc);
1.22 cvs 2198: SetIntHorizStretchAttr (el, doc);
2199: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1 cvs 2200: break;
1.39 cvs 2201: case MathML_EL_MUNDEROVER:
2202: /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
2203: Overscript */
1.56 cvs 2204: ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2205: MathML_EL_Underscript,
2206: MathML_EL_Overscript, doc);
1.39 cvs 2207: SetIntHorizStretchAttr (el, doc);
2208: SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
2209: break;
1.1 cvs 2210: case MathML_EL_MMULTISCRIPTS:
2211: /* end of a MMULTISCRIPTS. Create all elements defined in the
2212: MathML S schema */
2213: BuildMultiscript (el, doc);
1.5 cvs 2214: break;
2215: case MathML_EL_MTABLE:
2216: /* end of a MTABLE. Create all elements defined in the MathML S
2217: schema */
1.64 cvs 2218: CheckMTable (el, doc, TRUE);
1.101 cvs 2219: /* if the table has a rowalign attribute, process it */
2220: attrType.AttrSSchema = MathMLSSchema;
2221: attrType.AttrTypeNum = MathML_ATTR_rowalign;
2222: attr = TtaGetAttribute (el, attrType);
2223: if (attr)
2224: HandleRowalignAttribute (attr, el, doc, FALSE);
2225: /* if the table has a columnalign attribute, process it */
2226: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2227: attr = TtaGetAttribute (el, attrType);
2228: if (attr)
1.108 cvs 2229: HandleColalignAttribute (attr, el, doc, FALSE, FALSE);
1.101 cvs 2230: break;
2231: case MathML_EL_MTR:
2232: /* if the row has a columnalign attribute, process it */
2233: attrType.AttrSSchema = MathMLSSchema;
2234: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2235: attr = TtaGetAttribute (el, attrType);
2236: if (attr)
1.108 cvs 2237: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.101 cvs 2238: break;
2239: case MathML_EL_MLABELEDTR:
2240: /* if the row has a columnalign attribute, process it */
2241: attrType.AttrSSchema = MathMLSSchema;
2242: attrType.AttrTypeNum = MathML_ATTR_columnalign;
2243: attr = TtaGetAttribute (el, attrType);
2244: if (attr)
1.108 cvs 2245: HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.1 cvs 2246: break;
1.39 cvs 2247: case MathML_EL_MTD:
2248: /* Create placeholders within the table cell */
2249: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.46 cvs 2250: break;
1.39 cvs 2251: case MathML_EL_MACTION:
2252: /* Create placeholders within the MACTION element */
2253: CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1 cvs 2254: break;
2255: default:
2256: break;
2257: }
2258: parent = TtaGetParent (el);
1.118 cvs 2259: if (parent)
2260: {
2261: parentType = TtaGetElementType (parent);
2262: if (parentType.ElSSchema != elType.ElSSchema)
2263: /* root of a MathML tree, Create a MathML element if there is no */
2264: if (elType.ElTypeNum != MathML_EL_MathML)
2265: {
2266: elType.ElSSchema = MathMLSSchema;
2267: elType.ElTypeNum = MathML_EL_MathML;
2268: new = TtaNewElement (doc, elType);
2269: TtaInsertSibling (new, el, TRUE, doc);
2270: next = el;
2271: TtaNextSibling (&next);
2272: TtaRemoveTree (el, doc);
2273: TtaInsertFirstChild (&el, new, doc);
2274: prev = el;
2275: while (next != NULL)
2276: {
2277: child = next;
2278: TtaNextSibling (&next);
2279: TtaRemoveTree (child, doc);
2280: TtaInsertSibling (child, prev, FALSE, doc);
2281: prev = child;
2282: }
2283: /* Create placeholders within the MathML element */
2284: CreatePlaceholders (el, doc);
2285: }
2286: }
1.1 cvs 2287: }
1.56 cvs 2288: if (!ok)
2289: /* send an error message */
2290: *error = 1;
1.1 cvs 2291: }
2292:
2293: /*----------------------------------------------------------------------
1.126 cvs 2294: UnknownMathMLNameSpace
1.149 cvs 2295: The element doesn't belong to a supported namespace
1.126 cvs 2296: ----------------------------------------------------------------------*/
1.149 cvs 2297: void UnknownMathMLNameSpace (ParserData *context,
2298: Element *unknownEl,
2299: char* content)
1.126 cvs 2300: {
2301: ElementType elType;
1.149 cvs 2302: Element elText;
1.126 cvs 2303:
2304: /* Create a new Invalid_element */
2305: elType.ElSSchema = GetXMLSSchema (MATH_TYPE, context->doc);
2306: elType.ElTypeNum = MathML_EL_Unknown_namespace;
1.149 cvs 2307: *unknownEl = TtaNewElement (context->doc, elType);
2308: if (*unknownEl != NULL)
1.126 cvs 2309: {
1.149 cvs 2310: XmlSetElemLineNumber (*unknownEl);
2311: InsertXmlElement (unknownEl);
1.126 cvs 2312: context->lastElementClosed = TRUE;
2313: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
2314: elText = TtaNewElement (context->doc, elType);
2315: XmlSetElemLineNumber (elText);
1.149 cvs 2316: TtaInsertFirstChild (&elText, *unknownEl, context->doc);
1.126 cvs 2317: TtaSetTextContent (elText, content, context->language, context->doc);
2318: TtaSetAccessRight (elText, ReadOnly, context->doc);
2319: }
2320: }
2321:
2322: /*----------------------------------------------------------------------
1.24 cvs 2323: SetFontfamily
2324: -----------------------------------------------------------------------*/
1.120 cvs 2325: void SetFontfamily (Document doc, Element el, char *value)
1.24 cvs 2326: {
2327: #define buflen 50
1.116 cvs 2328: char css_command[buflen+20];
1.24 cvs 2329:
1.116 cvs 2330: sprintf (css_command, "font-family: %s", value);
1.72 cvs 2331: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 2332: }
2333:
2334: /*----------------------------------------------------------------------
1.83 cvs 2335: MathMLlinethickness
2336: The MathML attribute linthickness is associated with element el. Generate
2337: the corresponding style property for this element.
2338: -----------------------------------------------------------------------*/
1.120 cvs 2339: void MathMLlinethickness (Document doc, Element el, char *value)
1.83 cvs 2340: {
2341: #define buflen 50
1.116 cvs 2342: char css_command[buflen+20];
1.83 cvs 2343:
1.116 cvs 2344: if (strcmp (value, "thin") == 0)
2345: strcpy (value, "1pt");
2346: else if (strcmp (value, "medium") == 0)
2347: strcpy (value, "1pt");
2348: else if (strcmp (value, "thick") == 0)
2349: strcpy (value, "2pt");
2350: sprintf (css_command, "stroke-width: %s", value);
1.83 cvs 2351: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
2352: }
2353:
2354: /*----------------------------------------------------------------------
1.58 cvs 2355: MathMLAttrToStyleProperty
2356: The MathML attribute attr is associated with element el. Generate
2357: the corresponding style property for this element.
1.24 cvs 2358: -----------------------------------------------------------------------*/
1.138 cvs 2359: void MathMLAttrToStyleProperty (Document doc, Element el, char *value,
2360: int attr)
1.24 cvs 2361: {
1.116 cvs 2362: char css_command[buflen+20];
1.141 quint 2363: int i;
1.58 cvs 2364:
2365: switch (attr)
2366: {
2367: case MathML_ATTR_fontsize:
1.116 cvs 2368: sprintf (css_command, "font-size: %s", value);
1.58 cvs 2369: break;
1.93 cvs 2370: case MathML_ATTR_mathsize:
1.116 cvs 2371: if (strcmp (value, "small") == 0)
2372: strcpy (value, "80%");
2373: else if (strcmp (value, "normal") == 0)
2374: strcpy (value, "100%");
2375: else if (strcmp (value, "big") == 0)
2376: strcpy (value, "125%");
2377: sprintf (css_command, "font-size: %s", value);
1.93 cvs 2378: break;
1.58 cvs 2379: case MathML_ATTR_lspace:
2380: case MathML_ATTR_rspace:
1.141 quint 2381: if (attr == MathML_ATTR_lspace)
2382: strcpy (css_command, "padding-left: ");
2383: else
2384: strcpy (css_command, "padding-right: ");
2385: /* is the value a named space? */
2386: if (strcmp (value, "veryverythinmathspace") == 0)
2387: strcat (css_command, "0.0555556em");
2388: else if (strcmp (value, "verythinmathspace") == 0)
2389: strcat (css_command, "0.111111em");
2390: else if (strcmp (value, "thinmathspace") == 0)
2391: strcat (css_command, "0.166667em");
2392: else if (strcmp (value, "mediummathspace") == 0)
2393: strcat (css_command, "0.222222em");
2394: else if (strcmp (value, "thickmathspace") == 0)
2395: strcat (css_command, "0.277778em");
2396: else if (strcmp (value, "verythickmathspace") == 0)
2397: strcat (css_command, "0.333333em");
2398: else if (strcmp (value, "veryverythickmathspace") == 0)
2399: strcat (css_command, "0.388889em");
2400: else
2401: {
2402: strcat (css_command, value);
2403: /* does the value contain an unit at the end? */
2404: i = strlen (value) - 1;
2405: if ((value[i] <= '9' && value[i] >= '0') ||
2406: value[i] == '.')
2407: /* it's just a number. Add the (implicit) unit: em */
2408: strcat (css_command, "em");
2409: }
1.58 cvs 2410: break;
2411: }
1.72 cvs 2412: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24 cvs 2413: }
2414:
2415: /*----------------------------------------------------------------------
1.60 cvs 2416: MathMLSetScriptLevel
2417: A scriptlevel attribute with value value is associated with element el.
2418: Generate the corresponding style property for this element.
2419: -----------------------------------------------------------------------*/
1.120 cvs 2420: void MathMLSetScriptLevel (Document doc, Element el, char *value)
1.60 cvs 2421: {
2422: PresentationValue pval;
2423: PresentationContext ctxt;
2424: ThotBool relative;
2425: int percentage;
2426:
2427: ctxt = TtaGetSpecificStyleContext (doc);
2428: if (!value)
2429: /* remove the presentation rule */
2430: {
2431: ctxt->destroy = TRUE;
1.75 cvs 2432: pval.typed_data.value = 0;
1.60 cvs 2433: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
2434: }
2435: else
2436: {
2437: ctxt->destroy = FALSE;
2438: /* parse the attribute value (an optional sign and an integer) */
1.119 cvs 2439: value = TtaSkipBlanks (value);
1.60 cvs 2440: relative = (value[0] == '-' || value[0] == '+');
2441: value = ParseCSSUnit (value, &pval);
2442: if (pval.typed_data.unit != STYLE_UNIT_REL &&
2443: pval.typed_data.real)
2444: /* this is an error: it should be an integer without any unit name */
2445: /* error */;
2446: else
2447: {
2448: if (relative)
2449: {
1.63 cvs 2450: percentage = 100;
1.60 cvs 2451: if (pval.typed_data.value == 0)
2452: /* scriptlevel="+0" */
2453: percentage = 100;
2454: else if (pval.typed_data.value == 1)
2455: /* scriptlevel="+1" */
2456: percentage = 71;
2457: else if (pval.typed_data.value == 2)
2458: /* scriptlevel="+2" */
2459: percentage = 50;
2460: else if (pval.typed_data.value >= 3)
2461: /* scriptlevel="+3" or more */
2462: percentage = 35;
2463: else if (pval.typed_data.value == -1)
2464: /* scriptlevel="-1" */
2465: percentage = 141;
2466: else if (pval.typed_data.value == -2)
2467: /* scriptlevel="-2" */
2468: percentage = 200;
2469: else if (pval.typed_data.value <= -3)
2470: /* scriptlevel="-3" or less */
2471: percentage = 282;
2472: pval.typed_data.value = percentage;
2473: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1.78 cvs 2474: /* the specific presentation to be created is not a CSS rule */
1.147 quint 2475: ctxt->cssSpecificity = 0;
1.60 cvs 2476: TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
2477: }
2478: else
2479: /* absolute value */
2480: {
2481: /**** ****/;
2482: }
2483: }
2484: }
2485: TtaFreeMemory (ctxt);
2486: }
2487:
2488: /*----------------------------------------------------------------------
2489: MathMLSpacingAttr
2490: The MathML attribute attr (height, width or depth) is associated
2491: with element el (a mspace or mpadding).
2492: If value is not NULL, generate the corresponding Thot presentation rule for
2493: the element.
2494: If value is NULL, remove the corresponding Thot presentation rule.
2495: -----------------------------------------------------------------------*/
1.120 cvs 2496: void MathMLSpacingAttr (Document doc, Element el, char *value, int attr)
1.60 cvs 2497: {
2498: ElementType elType;
2499: PresentationValue pval;
2500: PresentationContext ctxt;
2501: int ruleType;
2502:
2503: /* provisionally, handles only mspace elements */
2504: elType = TtaGetElementType (el);
1.96 cvs 2505: if (elType.ElTypeNum != MathML_EL_MSPACE &&
1.97 cvs 2506: elType.ElTypeNum != MathML_EL_MPADDED &&
2507: elType.ElTypeNum != MathML_EL_MTABLE)
1.60 cvs 2508: return;
2509: switch (attr)
2510: {
2511: case MathML_ATTR_width_:
2512: ruleType = PRWidth;
2513: break;
2514: case MathML_ATTR_height_:
2515: ruleType = PRPaddingTop;
2516: break;
2517: case MathML_ATTR_depth_:
2518: ruleType = PRPaddingBottom;
2519: break;
2520: default:
2521: return;
2522: }
2523: ctxt = TtaGetSpecificStyleContext (doc);
1.116 cvs 2524: if (!value || (strcmp (value, "auto") == 0))
1.60 cvs 2525: /* remove the presentation rule */
2526: {
2527: ctxt->destroy = TRUE;
1.75 cvs 2528: pval.typed_data.value = 0;
1.60 cvs 2529: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
2530: }
2531: else
2532: {
2533: ctxt->destroy = FALSE;
2534: /* parse the attribute value (a number followed by a unit) */
1.119 cvs 2535: value = TtaSkipBlanks (value);
1.60 cvs 2536: value = ParseCSSUnit (value, &pval);
2537: /***** we should accept namedspace for width *****/
2538: if (pval.typed_data.unit != STYLE_UNIT_INVALID)
1.78 cvs 2539: {
2540: /* the specific presentation to be created is not a CSS rule */
1.147 quint 2541: ctxt->cssSpecificity = 0;
1.78 cvs 2542: TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
2543: }
1.60 cvs 2544: }
2545: TtaFreeMemory (ctxt);
2546: }
2547:
2548: /*----------------------------------------------------------------------
1.153 quint 2549: MathMLSetDisplayAttr
2550: The MathML attribute display is associated with element el.
2551: Generate the corresponding Thot presentation rule for
2552: the element.
2553: ----------------------------------------------------------------------*/
2554: void MathMLSetDisplayAttr (Element el, Attribute attr, Document doc,
2555: ThotBool delete)
2556: {
2557: int val;
2558:
2559: val = TtaGetAttributeValue (attr);
2560: if (val == MathML_ATTR_display_VAL_block)
2561: ParseHTMLSpecificStyle (el, "display: block", doc, 0, delete);
2562: else if (val == MathML_ATTR_display_VAL_inline_)
2563: ParseHTMLSpecificStyle (el, "display: inline", doc, 0, delete);
2564: }
2565:
2566: /*----------------------------------------------------------------------
1.1 cvs 2567: MathMLAttributeComplete
1.58 cvs 2568: The XML parser has completed parsing attribute attr (as well as its value)
2569: that is associated with element el in document doc.
1.1 cvs 2570: ----------------------------------------------------------------------*/
1.120 cvs 2571: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
1.1 cvs 2572: {
1.134 cvs 2573: AttributeType attrType, depAttrType;
1.23 cvs 2574: int attrKind;
1.50 cvs 2575: ElementType elType;
1.120 cvs 2576: char *value;
1.50 cvs 2577: int val, length;
1.101 cvs 2578: Attribute intAttr;
1.23 cvs 2579:
1.58 cvs 2580: /* first get the type of that attribute */
1.23 cvs 2581: TtaGiveAttributeType (attr, &attrType, &attrKind);
1.153 quint 2582:
1.54 cvs 2583: if (attrType.AttrTypeNum == MathML_ATTR_bevelled)
1.58 cvs 2584: /* it's a bevelled attribute */
1.50 cvs 2585: {
2586: val = TtaGetAttributeValue (attr);
1.54 cvs 2587: if (val == MathML_ATTR_bevelled_VAL_true)
2588: /* bevelled = true. Transform MFRAC into BevelledMFRAC */
1.50 cvs 2589: {
2590: elType = TtaGetElementType (el);
2591: if (elType.ElTypeNum == MathML_EL_MFRAC)
1.54 cvs 2592: ChangeTypeOfElement (el, doc, MathML_EL_BevelledMFRAC);
1.50 cvs 2593: }
2594: }
1.101 cvs 2595:
2596: else if (attrType.AttrTypeNum == MathML_ATTR_rowalign_mtr)
2597: {
2598: /* create an equivalent IntRowAlign attribute on the same element */
2599: attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
2600: intAttr = TtaGetAttribute (el, attrType);
2601: if (!intAttr)
2602: /* no IntRowAlign attribute, create one */
2603: {
2604: intAttr = TtaNewAttribute (attrType);
2605: TtaAttachAttribute (el, intAttr, doc);
2606: }
2607: val = TtaGetAttributeValue (attr);
2608: TtaSetAttributeValue (intAttr, val, el, doc);
2609: }
2610:
2611: else if (attrType.AttrTypeNum == MathML_ATTR_rowalign)
2612: {
2613: /* parse the attribute value and create a IntRowAlign attribute
2614: for each mrow contained in the element */
2615: HandleRowalignAttribute (attr, el, doc, FALSE);
2616: }
2617:
2618: else if (attrType.AttrTypeNum == MathML_ATTR_columnalign_mtd)
2619: {
2620: /* create an equivalent IntColAlign attribute on the same element */
2621: attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
2622: intAttr = TtaGetAttribute (el, attrType);
2623: if (!intAttr)
2624: /* no IntColAlign attribute, create one */
2625: {
2626: intAttr = TtaNewAttribute (attrType);
2627: TtaAttachAttribute (el, intAttr, doc);
2628: }
2629: val = TtaGetAttributeValue (attr);
2630: TtaSetAttributeValue (intAttr, val, el, doc);
2631: }
2632:
1.104 cvs 2633: /* don't handle attribute columnalign now: the table or the row is not
2634: complete yet. Handle it when the element is complete.
1.101 cvs 2635: else if (attrType.AttrTypeNum == MathML_ATTR_columnalign)
1.104 cvs 2636: */
1.153 quint 2637:
2638: else if (attrType.AttrTypeNum == MathML_ATTR_display)
2639: /* it's a display attribute */
2640: MathMLSetDisplayAttr (el, attr, doc, FALSE);
1.138 cvs 2641:
2642: else if (attrType.AttrTypeNum == MathML_ATTR_Language)
2643: {
2644: if (el == TtaGetRootElement (doc))
2645: /* it's the lang attribute on the root element */
2646: /* set the RealLang attribute */
2647: {
2648: depAttrType.AttrSSchema = attrType.AttrSSchema ;
2649: depAttrType.AttrTypeNum = MathML_ATTR_RealLang;
2650: if (!TtaGetAttribute (el, depAttrType))
2651: /* it's not present. Add it */
2652: {
2653: intAttr = TtaNewAttribute (depAttrType);
2654: TtaAttachAttribute (el, intAttr, doc);
2655: TtaSetAttributeValue (intAttr, MathML_ATTR_RealLang_VAL_Yes_,
2656: el, doc);
2657: }
2658: }
2659: }
1.101 cvs 2660:
1.50 cvs 2661: else if (attrType.AttrTypeNum == MathML_ATTR_color ||
1.93 cvs 2662: attrType.AttrTypeNum == MathML_ATTR_mathcolor ||
2663: attrType.AttrTypeNum == MathML_ATTR_background_ ||
2664: attrType.AttrTypeNum == MathML_ATTR_mathbackground ||
2665: attrType.AttrTypeNum == MathML_ATTR_fontsize ||
2666: attrType.AttrTypeNum == MathML_ATTR_mathsize ||
2667: attrType.AttrTypeNum == MathML_ATTR_fontfamily ||
2668: attrType.AttrTypeNum == MathML_ATTR_linethickness ||
2669: attrType.AttrTypeNum == MathML_ATTR_lspace ||
2670: attrType.AttrTypeNum == MathML_ATTR_rspace ||
2671: attrType.AttrTypeNum == MathML_ATTR_scriptlevel ||
2672: attrType.AttrTypeNum == MathML_ATTR_width_ ||
2673: attrType.AttrTypeNum == MathML_ATTR_height_ ||
2674: attrType.AttrTypeNum == MathML_ATTR_depth_ )
2675: {
1.23 cvs 2676: length = TtaGetTextAttributeLength (attr);
2677: if (length >= buflen)
2678: length = buflen - 1;
2679: if (length > 0)
2680: {
1.116 cvs 2681: value = TtaGetMemory (buflen);
1.33 cvs 2682: value[0] = EOS;
2683: TtaGiveTextAttributeValue (attr, value, &length);
2684: switch (attrType.AttrTypeNum)
2685: {
2686: case MathML_ATTR_color:
1.134 cvs 2687: /* deprecated attribute */
2688: /* if the same element has a mathcolor attribute, ignore
2689: the color attribute */
2690: depAttrType.AttrSSchema = attrType.AttrSSchema ;
2691: depAttrType.AttrTypeNum = MathML_ATTR_mathcolor;
2692: if (!TtaGetAttribute (el, depAttrType))
2693: HTMLSetForegroundColor (doc, el, value);
2694: break;
1.93 cvs 2695: case MathML_ATTR_mathcolor:
1.24 cvs 2696: HTMLSetForegroundColor (doc, el, value);
2697: break;
1.33 cvs 2698: case MathML_ATTR_background_:
1.134 cvs 2699: /* deprecated attribute */
2700: /* if the same element has a mathbackground attribute, ignore
2701: the background attribute */
2702: depAttrType.AttrSSchema = attrType.AttrSSchema;
2703: depAttrType.AttrTypeNum = MathML_ATTR_mathbackground;
2704: if (!TtaGetAttribute (el, depAttrType))
2705: HTMLSetBackgroundColor (doc, el, value);
2706: break;
1.93 cvs 2707: case MathML_ATTR_mathbackground:
1.24 cvs 2708: HTMLSetBackgroundColor (doc, el, value);
2709: break;
1.33 cvs 2710: case MathML_ATTR_fontfamily:
1.24 cvs 2711: SetFontfamily (doc, el, value);
1.83 cvs 2712: break;
2713: case MathML_ATTR_linethickness:
2714: MathMLlinethickness (doc, el, value);
1.58 cvs 2715: break;
2716: case MathML_ATTR_fontsize:
1.134 cvs 2717: /* deprecated attribute */
2718: /* if the same element has a mathsize attribute, ignore
2719: the fontsize attribute */
2720: depAttrType.AttrSSchema = attrType.AttrSSchema;
2721: depAttrType.AttrTypeNum = MathML_ATTR_mathsize;
2722: if (!TtaGetAttribute (el, depAttrType))
2723: MathMLAttrToStyleProperty (doc, el, value,
2724: attrType.AttrTypeNum);
2725: break;
1.93 cvs 2726: case MathML_ATTR_mathsize:
1.58 cvs 2727: case MathML_ATTR_lspace:
2728: case MathML_ATTR_rspace:
1.60 cvs 2729: MathMLAttrToStyleProperty (doc, el, value,attrType.AttrTypeNum);
2730: break;
2731: case MathML_ATTR_scriptlevel:
2732: MathMLSetScriptLevel (doc, el, value);
2733: break;
2734: case MathML_ATTR_width_:
2735: case MathML_ATTR_height_:
2736: case MathML_ATTR_depth_:
2737: MathMLSpacingAttr (doc, el, value, attrType.AttrTypeNum);
1.59 cvs 2738: break;
2739: default:
1.24 cvs 2740: break;
1.33 cvs 2741: }
2742: TtaFreeMemory (value);
1.23 cvs 2743: }
2744: }
1.1 cvs 2745: }
2746:
2747: /*----------------------------------------------------------------------
2748: MathMLGetDTDName
2749: ----------------------------------------------------------------------*/
1.120 cvs 2750: void MathMLGetDTDName (char *DTDname, char *elementName)
1.1 cvs 2751: {
2752: /* no other DTD allowed within MathML elements */
1.116 cvs 2753: strcpy (DTDname, "");
1.1 cvs 2754: }
2755:
2756: /* end of module */
Webmaster