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