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