Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.7
1.1 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
8: /*
9: *
10: * MathMLbuilder
11: *
12: * Author: V. Quint
13: */
14:
15:
16: #define THOT_EXPORT extern
1.4 cvs 17: #include "amaya.h"
1.1 cvs 18:
19: #include "Mathedit_f.h"
20: #include "XMLparser_f.h"
21:
22: #include "MathML.h"
23: #include "parser.h"
24:
25: #define EOS '\0'
26: #define SPACE ' '
27:
28: typedef unsigned char MathEntityName[20];
29: typedef struct _MathEntity
30: { /* a Math entity representing an operator char */
31: MathEntityName MentityName; /* entity name */
32: int charCode; /* decimal code of char */
33: char alphabet; /* 'L' = ISO-Latin-1, 'G' = Symbol */
34: }
35: MathEntity;
36:
37: static MathEntity MathEntityTable[] =
38: {
39: /* This table MUST be in alphabetical order */
40: /* This table contains characters from the Symbol font plus some
41: specific MathML entities */
42: {"Agr", 65, 'G'},
43: {"ApplyFunction", 32, 'L'}, /* render as white space */
44: {"Bgr", 66, 'G'},
45: {"Cap", 199, 'G'},
46: {"Cup", 200, 'G'},
47: {"Delta", 68, 'G'},
48: {"EEgr", 72, 'G'},
49: {"Egr", 69, 'G'},
50: {"Gamma", 71, 'G'},
51: {"Igr", 73, 'G'},
52: {"Integral", 242, 'G'},
53: {"InvisibleTimes", 0, SPACE},
54: {"Kgr", 75, 'G'},
55: {"KHgr", 67, 'G'},
56: {"Lambda", 76, 'G'},
57: {"LeftArrow", 172, 'G'},
58: {"Mgr", 77, 'G'},
59: {"Ngr", 78, 'G'},
60: {"Ogr", 79, 'G'},
61: {"Omega", 87, 'G'},
62: {"PI", 213, 'G'},
63: {"Phi", 70, 'G'},
64: {"Pi", 80, 'G'},
65: {"PlusMinus", 177, 'G'},
66: {"Psi", 89, 'G'},
67: {"Rgr", 82, 'G'},
68: {"RightArrow", 174, 'G'},
69: {"Sigma", 83, 'G'},
70: {"Sol", 164, 'G'},
71: {"Sum", 229, 'G'},
72: {"Tgr", 84, 'G'},
73: {"Theta", 81, 'G'},
74: {"Upsi", 85, 'G'},
75: {"Upsi1", 161, 'G'},
76: {"Verbar", 189, 'G'},
77: {"Xi", 88, 'G'},
78: {"Zgr", 90, 'G'},
79: {"af", 32, 'L'}, /* render as white space */
80: {"aleph", 192, 'G'},
81: {"alpha", 97, 'G'},
82: {"and", 217, 'G'},
83: {"angle", 208, 'G'},
84: {"ap", 187, 'G'},
85: {"beta", 98, 'G'},
86: {"bottom", 94, 'G'},
87: {"bull", 183, 'G'},
88: {"cap", 199, 'G'},
89: {"chi", 99, 'G'},
90: {"clubs", 167, 'G'},
91: {"cong", 64, 'G'},
92: {"copysf", 211, 'G'},
93: {"copyssf", 227, 'G'},
94: {"cr", 191, 'G'},
95: {"cup", 200, 'G'},
96: {"darr", 175, 'G'},
97: {"dArr", 223, 'G'},
98: {"dd", 100, 'L'},
99: {"deg", 176, 'G'},
100: {"delta", 100, 'G'},
101: {"diams", 168, 'G'},
102: {"divide", 184, 'G'},
103: {"dtri", 209, 'G'},
104: {"ee", 101, 'L'},
105: {"empty", 198, 'G'},
106: {"emsp", 32, 'G'},
107: {"epsiv", 101, 'G'},
108: {"equiv", 186, 'G'},
109: {"eta", 104, 'G'},
110: {"exist", 36, 'G'},
111: {"florin", 166, 'G'},
112: {"forall", 34, 'G'},
113: {"gamma", 103, 'G'},
114: {"ge", 179, 'G'},
115: {"gt", 62, 'L'},
116: {"hearts", 169, 'G'},
117: {"horbar", 190, 'G'},
118: {"ifraktur", 225, 'G'},
119: {"infin", 165, 'G'},
120: {"int", 242, 'G'},
121: {"iota", 105, 'G'},
122: {"isin", 206, 'G'},
123: {"it", 242, 'G'},
124: {"kappa", 107, 'G'},
125: {"lambda", 108, 'G'},
126: {"lang", 225, 'G'},
127: {"larr", 172, 'G'},
128: {"lArr", 220, 'G'},
129: {"le", 163, 'G'},
130: {"lowbar", 95, 'G'},
131: {"loz", 224, 'G'},
132: {"lrarr", 171, 'G'},
133: {"lrArr", 219, 'G'},
134: {"lsqb", 91, 'G'},
1.6 cvs 135: {"lt", 60, 'L'},
1.1 cvs 136: {"middot", 215, 'G'},
137: {"mldr", 188, 'G'},
138: {"mu", 109, 'G'},
139: {"ne", 185, 'G'},
140: {"not", 216, 'G'},
141: {"notin", 207, 'G'},
142: {"nu", 107, 'G'},
143: {"ogr", 111, 'G'},
144: {"omega", 119, 'G'},
145: {"oplus", 197, 'G'},
146: {"or", 218, 'G'},
147: {"otimes", 196, 'G'},
148: {"part", 182, 'G'},
149: {"phi", 102, 'G'},
150: {"phiv", 106, 'G'},
151: {"pi", 112, 'G'},
152: {"piv", 118, 'G'},
153: {"prop", 181, 'G'},
154: {"psi", 121, 'G'},
155: {"radic", 214, 'G'},
156: {"rarr", 174, 'G'},
157: {"rArr", 222, 'G'},
158: {"rdquo", 178, 'G'},
159: {"regsf", 210, 'G'},
160: {"regssf", 226, 'G'},
161: {"rfraktur", 194, 'G'},
162: {"rho", 114, 'G'},
163: {"rsqb", 93, 'G'},
164: {"sigma", 115, 'G'},
165: {"sigmav", 86, 'G'},
166: {"spades", 170, 'G'},
167: {"sub", 204, 'G'},
168: {"sube", 205, 'G'},
169: {"subne", 203, 'G'},
170: {"sum", 229, 'G'},
171: {"sup", 201, 'G'},
172: {"supe", 202, 'G'},
173: {"tau", 116, 'G'},
174: {"there4", 92, 'G'},
175: {"theta", 113, 'G'},
176: {"thetav", 74, 'G'},
177: {"thickspace", 32, 'L'},
178: {"times", 180, 'G'},
179: {"trade", 212, 'G'},
180: {"tradesf", 212, 'G'},
181: {"tradessf", 228, 'G'},
182: {"uarr", 173, 'G'},
183: {"uArr", 221, 'G'},
184: {"upsi", 117, 'G'},
185: {"weierp", 195, 'G'},
186: {"xi", 120, 'G'},
187: {"zeta", 122, 'G'},
188: {"zzzz", -1, SPACE} /* this last entry is required */
189: };
190:
191: /* mapping table of MathML elements */
192:
193: static ElemMapping MathMLElemMappingTable[] =
194: {
195: /* This table MUST be in alphabetical order */
196: {"XMLcomment", SPACE, MathML_EL_XMLcomment},
197: {"XMLcomment_line", SPACE, MathML_EL_XMLcomment_line},
1.5 cvs 198: {"maligngroup", 'E', MathML_EL_MALIGNGROUP},
199: {"malignmark", 'E', MathML_EL_MALIGNMARK},
1.1 cvs 200: {"merror", SPACE, MathML_EL_MERROR},
201: {"mf", SPACE, MathML_EL_MF}, /* for compatibility with an old version of
202: MathML: WD-math-970704 */
203: {"mfenced", SPACE, MathML_EL_MFENCED},
204: {"mfrac", SPACE, MathML_EL_MFRAC},
205: {"mi", SPACE, MathML_EL_MI},
206: {"mmultiscripts", SPACE, MathML_EL_MMULTISCRIPTS},
207: {"mn", SPACE, MathML_EL_MN},
208: {"mo", SPACE, MathML_EL_MO},
209: {"mover", SPACE, MathML_EL_MOVER},
210: {"mpadded", SPACE, MathML_EL_MPADDED},
211: {"mphantom", SPACE, MathML_EL_MPHANTOM},
212: {"mprescripts", SPACE, MathML_EL_PrescriptPairs},
213: {"mroot", SPACE, MathML_EL_MROOT},
214: {"mrow", SPACE, MathML_EL_MROW},
215: {"ms", SPACE, MathML_EL_MS},
216: {"mspace", 'E', MathML_EL_MSPACE},
217: {"msqrt", SPACE, MathML_EL_MSQRT},
218: {"mstyle", SPACE, MathML_EL_MSTYLE},
219: {"msub", SPACE, MathML_EL_MSUB},
220: {"msubsup", SPACE, MathML_EL_MSUBSUP},
221: {"msup", SPACE, MathML_EL_MSUP},
1.5 cvs 222: {"mtable", SPACE, MathML_EL_MTABLE},
223: {"mtd", SPACE, MathML_EL_MTD},
1.1 cvs 224: {"mtext", SPACE, MathML_EL_MTEXT},
1.5 cvs 225: {"mtr", SPACE, MathML_EL_MTR},
1.1 cvs 226: {"munder", SPACE, MathML_EL_MUNDER},
227: {"munderover", SPACE, MathML_EL_MUNDEROVER},
228: {"none", SPACE, MathML_EL_Construct},
229: {"sep", 'E', MathML_EL_SEP},
230: {"", SPACE, 0} /* Last entry. Mandatory */
231: };
232:
233: static AttributeMapping MathMLAttributeMappingTable[] =
234: {
235: /* The first entry MUST be unknown_attr */
236: /* The rest of this table MUST be in alphabetical order */
237: {"unknown_attr", "", 'A', MathML_ATTR_Invalid_attribute},
238: {"ZZGHOST", "", 'A', MathML_ATTR_Ghost_restruct},
239:
240: {"close", "mfenced", 'A', MathML_ATTR_close},
241: {"fence", "mo", 'A', MathML_ATTR_fence},
242: {"fontstyle", "mi", 'A', MathML_ATTR_fontstyle},
1.7 ! cvs 243: {"link", "", 'A', MathML_ATTR_link},
1.1 cvs 244: {"open", "mfenced", 'A', MathML_ATTR_open},
245: {"separators", "mfenced", 'A', MathML_ATTR_separators},
246:
247: {"", "", EOS, 0} /* Last entry. Mandatory */
248: };
249:
250: /* mapping table of attribute values */
251:
252: static AttrValueMapping MathMLAttrValueMappingTable[] =
253: {
254: {MathML_ATTR_fence, "true", MathML_ATTR_fence_VAL_true},
255: {MathML_ATTR_fence, "false", MathML_ATTR_fence_VAL_false},
256: {MathML_ATTR_fontstyle, "italic", MathML_ATTR_fontstyle_VAL_italic},
257: {MathML_ATTR_fontstyle, "normal", MathML_ATTR_fontstyle_VAL_normal},
1.7 ! cvs 258: {MathML_ATTR_link, "document", MathML_ATTR_link_VAL_document},
! 259: {MathML_ATTR_link, "extended", MathML_ATTR_link_VAL_extended},
! 260: {MathML_ATTR_link, "group", MathML_ATTR_link_VAL_group},
! 261: {MathML_ATTR_link, "locator", MathML_ATTR_link_VAL_locator},
! 262: {MathML_ATTR_link, "simple", MathML_ATTR_link_VAL_simple},
1.1 cvs 263:
264: {0, "", 0} /* Last entry. Mandatory */
265: };
266:
267: #define MaxMsgLength 200
268:
269: /*----------------------------------------------------------------------
1.2 cvs 270: GetMathMLSSchema returns the MathML Thot schema for document doc.
1.1 cvs 271: ----------------------------------------------------------------------*/
272: #ifdef __STDC__
1.2 cvs 273: SSchema GetMathMLSSchema (Document doc)
1.1 cvs 274: #else
1.2 cvs 275: SSchema GetMathMLSSchema (doc)
1.1 cvs 276: Document doc;
277:
278: #endif
279: {
1.2 cvs 280: SSchema MathMLSSchema;
281:
282: MathMLSSchema = TtaGetSSchema ("MathML", doc);
1.1 cvs 283: if (MathMLSSchema == NULL)
284: MathMLSSchema = TtaNewNature(TtaGetDocumentSSchema(doc), "MathML", "MathMLP");
1.2 cvs 285: return (MathMLSSchema);
1.1 cvs 286: }
287:
288:
289: /*----------------------------------------------------------------------
290: MapMathMLElementType
291: search in the mapping tables the entry for the element type of
292: name XMLname and returns the corresponding Thot element type.
293: Returns -1 and schema = NULL if not found.
294: ----------------------------------------------------------------------*/
295: #ifdef __STDC__
1.2 cvs 296: void MapMathMLElementType (char *XMLname, ElementType *elType, char** mappedName, char* content, Document doc)
1.1 cvs 297: #else
1.2 cvs 298: void MapMathMLElementType (XMLname, elType, mappedName, content, doc)
1.1 cvs 299: char *XMLname;
300: ElementType *elType;
301: unsigned char **mappedName;
302: char *content;
1.2 cvs 303: Document doc;
1.1 cvs 304: #endif
305: {
306: int i;
307:
308: elType->ElTypeNum = 0;
309: /* search in MathMLElemMappingTable */
310: i = 0;
311: do
312: if (strcasecmp (MathMLElemMappingTable[i].XMLname, XMLname))
313: i++;
314: else
315: {
316: elType->ElTypeNum = MathMLElemMappingTable[i].ThotType;
1.3 cvs 317: if (elType->ElSSchema == NULL)
318: elType->ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 319: *mappedName = MathMLElemMappingTable[i].XMLname;
320: *content = MathMLElemMappingTable[i].XMLcontents;
321: }
322: while (elType->ElTypeNum <= 0 && MathMLElemMappingTable[i].XMLname[0] != EOS);
323: }
324:
325: /*----------------------------------------------------------------------
326: GetMathMLElementName
327: search in the mapping tables the XML name for a given Thot type
328: ----------------------------------------------------------------------*/
329: #ifdef __STDC__
330: void GetMathMLElementName (ElementType elType, char **buffer)
331: #else
332: void GetMathMLElementName (elType, buffer)
333: ElementType elType;
334: char* buffer;
335:
336: #endif
337: {
338: int i;
339:
340: if (elType.ElTypeNum > 0)
341: {
342: i = 0;
343: if (strcmp ("MathML", TtaGetSSchemaName (elType.ElSSchema)) == 0)
344: do
345: {
346: if (MathMLElemMappingTable[i].ThotType == elType.ElTypeNum)
347: {
348: *buffer = (char *) MathMLElemMappingTable[i].XMLname;
349: return;
350: }
351: i++;
352: }
353: while (MathMLElemMappingTable[i].XMLname[0] != EOS);
354: }
355: *buffer = "???";
356: return;
357: }
358:
359: /*----------------------------------------------------------------------
360: MapMathMLAttribute
361: Search in the Attribute Mapping Table the entry for the
362: attribute of name Attr and returns the corresponding Thot attribute type.
363: ----------------------------------------------------------------------*/
364: #ifdef __STDC__
1.2 cvs 365: void MapMathMLAttribute (char *Attr, AttributeType *attrType, char* elementName, Document doc)
1.1 cvs 366: #else
1.2 cvs 367: void MapMathMLAttribute (Attr, attrType, elementName, doc)
1.1 cvs 368: char *Attr;
369: AttributeType *attrType;
370: char *elementName;
1.2 cvs 371: Document doc;
1.1 cvs 372: #endif
373: {
374: int i;
375:
376: attrType->AttrTypeNum = 0;
377: attrType->AttrSSchema = NULL;
378: i = 0;
379: do
380: if (strcasecmp (MathMLAttributeMappingTable[i].XMLattribute, Attr))
381: i++;
382: else
383: if (MathMLAttributeMappingTable[i].XMLelement[0] == EOS)
384: {
385: attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
1.2 cvs 386: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 387: }
388: else if (!strcasecmp (MathMLAttributeMappingTable[i].XMLelement,
389: elementName))
390: {
391: attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
1.2 cvs 392: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 393: }
394: else
395: i++;
396: while (attrType->AttrTypeNum <= 0 && MathMLAttributeMappingTable[i].AttrOrContent != EOS);
397: }
398:
399: /*----------------------------------------------------------------------
400: MapMathMLAttributeValue
401: Search in the Attribute Value Mapping Table the entry for the attribute
402: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
403: ----------------------------------------------------------------------*/
404: #ifdef __STDC__
405: void MapMathMLAttributeValue (char *AttrVal, AttributeType attrType, int *value)
406: #else
407: void MapMathMLAttributeValue (AttrVal, attrType, value)
408: char *AttrVal;
409: AttributeType attrType;
410: int *value;
411: #endif
412: {
413: int i;
414:
415: *value = 0;
416: i = 0;
417: while (MathMLAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
418: MathMLAttrValueMappingTable[i].ThotAttr != 0)
419: i++;
420: if (MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
421: do
422: if (!strcasecmp (MathMLAttrValueMappingTable[i].XMLattrValue, AttrVal))
423: *value = MathMLAttrValueMappingTable[i].ThotAttrValue;
424: else
425: i++;
426: while (*value <= 0 && MathMLAttrValueMappingTable[i].ThotAttr != 0);
427: }
428:
429: /*----------------------------------------------------------------------
430: MapMathMLEntity
431: Search that entity in the entity table and return the corresponding value.
432: ----------------------------------------------------------------------*/
433: #ifdef __STDC__
434: void MapMathMLEntity (char *entityName, char *entityValue, int valueLength, char *alphabet)
435: #else
436: void MapMathMLEntity (entityName, entityValue, valueLength, alphabet)
437: char *entityName;
438: char *entityValue;
439: int valueLength;
440: char *alphabet;
441:
442: #endif
443:
444: {
445: int i;
446:
447: for (i = 0; MathEntityTable[i].charCode >= 0 &&
448: strcmp (MathEntityTable[i].MentityName, entityName);
449: i++);
450: if (!strcmp (MathEntityTable[i].MentityName, entityName))
451: /* entity found */
452: {
453: entityValue[0] = (unsigned char) MathEntityTable[i].charCode;
454: entityValue[1] = EOS;
455: *alphabet = MathEntityTable[i].alphabet;
456: }
457: else
458: {
459: entityValue[0] = EOS;
460: *alphabet = EOS;
461: }
462: }
463:
464: /*----------------------------------------------------------------------
465: MathMLEntityCreated
466: A MathML entity has been created by the XML parser.
467: Create a text element containing the entity name.
468: ----------------------------------------------------------------------*/
469: #ifdef __STDC__
470: void MathMLEntityCreated (unsigned char *entityValue, char *entityName, Document doc)
471: #else
472: void MathMLEntityCreated (entityValue, entityName, doc)
473: unsigned char *entityValue;
474: char *entityName;
475: Document doc;
476:
477: #endif
478: {
479: ElementType elType;
480: Element elText;
481: AttributeType attrType;
482: Attribute attr;
483: Language lang;
484: int len;
485: #define MAX_ENTITY_LENGTH 80
486: char buffer[MAX_ENTITY_LENGTH];
487:
488: if (strlen (entityValue) <= 1)
489: if (entityValue[0] == EOS || entityValue[0] == SPACE ||
490: ((int)entityValue[0]) == 129 || /* thin space */
491: ((int)entityValue[0]) == 130 || /* en space */
492: ((int)entityValue[0]) == 160) /* sticky space */
493: /* null character or space */
494: /* create a text element containing the entity name with an
495: attribute entity */
496: {
497: XMLTextToDocument ();
498: len = strlen (entityName);
499: if (len > MAX_ENTITY_LENGTH -3)
500: len = MAX_ENTITY_LENGTH -3;
501: buffer[0] = '&';
502: strncpy (&buffer[1], entityName, len);
503: buffer[len+1] = ';';
504: buffer[len+2] = EOS;
505: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1.2 cvs 506: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 507: elText = TtaNewElement (doc, elType);
508: XMLInsertElement (elText);
509: lang = TtaGetLanguageIdFromAlphabet('L');
510: TtaSetTextContent (elText, buffer, lang, doc);
1.2 cvs 511: attrType.AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 512: attrType.AttrTypeNum = MathML_ATTR_entity;
513: attr = TtaNewAttribute (attrType);
514: TtaAttachAttribute (elText, attr, doc);
515: TtaSetAttributeValue (attr, MathML_ATTR_entity_VAL_yes_, elText, doc);
516: }
517: }
518:
519: /*----------------------------------------------------------------------
520: CheckTextElement Put the content of input buffer into the document.
521: ----------------------------------------------------------------------*/
522: #ifdef __STDC__
523: static void CheckTextElement (Element *el, Document doc)
524: #else
525: static void CheckTextElement (el, doc)
526: Element *el;
527: Document doc;
528:
529: #endif
530: {
531: ElementType parentType, elType;
532: Element parent, new;
533: int len;
534: Language lang;
535: char alphabet;
536: char text[4];
537:
538: len = TtaGetTextLength (*el);
539: if (len == 1)
540: {
541: len = 2;
542: TtaGiveTextContent (*el, text, &len, &lang);
543: alphabet = TtaGetAlphabet (lang);
544: parent = TtaGetParent (*el);
545: if (text[0] != EOS)
546: {
547: parentType = TtaGetElementType (parent);
548: elType = parentType;
549: if (parentType.ElTypeNum == MathML_EL_MF &&
550: (text[0] == '(' ||
551: text[0] == ')' ||
552: text[0] == '[' ||
553: text[0] == ']' ||
554: text[0] == '{' ||
555: text[0] == '}'))
556: /* Transform the text element into a Thot SYMBOL */
557: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
558: else if (parentType.ElTypeNum == MathML_EL_MF &&
559: text[0] == '|')
560: /* Transform the text element into a Thot GRAPHIC */
561: {
562: elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
563: text[0] = 'v';
564: }
565: else
566: /* a TEXT element is OK */
567: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
568: if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
569: {
570: new = TtaNewElement (doc, elType);
571: TtaInsertSibling (new, *el, FALSE, doc);
572: TtaDeleteTree (*el, doc);
573: *el = new;
574: TtaSetGraphicsShape (new, text[0], doc);
575: }
576: }
577: }
578: }
579:
580: /*----------------------------------------------------------------------
581: ElementNeedsPlaceholder
582: returns TRUE if element el needs a sibling placeholder.
583: ----------------------------------------------------------------------*/
584: #ifdef __STDC__
585: boolean ElementNeedsPlaceholder (Element el)
586: #else
587: boolean ElementNeedsPlaceholder (el)
588: Element el;
589:
590: #endif
591: {
592: ElementType elType;
593: Element child, parent;
594: boolean ret;
595:
596: ret = FALSE;
597: elType = TtaGetElementType (el);
598: if (elType.ElTypeNum == MathML_EL_MROW ||
599: elType.ElTypeNum == MathML_EL_MF ||
600: elType.ElTypeNum == MathML_EL_MFENCED ||
601: elType.ElTypeNum == MathML_EL_MROOT ||
602: elType.ElTypeNum == MathML_EL_MSQRT ||
603: elType.ElTypeNum == MathML_EL_MFRAC ||
604: elType.ElTypeNum == MathML_EL_MSUBSUP ||
605: elType.ElTypeNum == MathML_EL_MSUB ||
606: elType.ElTypeNum == MathML_EL_MSUP ||
607: elType.ElTypeNum == MathML_EL_MUNDER ||
608: elType.ElTypeNum == MathML_EL_MOVER ||
609: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
610: elType.ElTypeNum == MathML_EL_MMULTISCRIPTS)
611: ret = TRUE;
612: else
613: if (elType.ElTypeNum == MathML_EL_MO)
614: /* an operator that contains a single Symbol needs a placeholder,
615: except when it is in a Base or UnderOverBase */
616: {
617: child = TtaGetFirstChild (el);
618: if (child != NULL)
619: {
620: elType = TtaGetElementType (child);
621: if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
622: {
623: ret = TRUE;
624: parent = TtaGetParent (el);
625: if (parent != NULL)
626: {
627: elType = TtaGetElementType (parent);
628: if (elType.ElTypeNum == MathML_EL_Base ||
629: elType.ElTypeNum == MathML_EL_UnderOverBase)
630: ret = FALSE;
631: }
632: }
633: }
634: }
635: return ret;
636: }
637:
638: /*----------------------------------------------------------------------
639: CreatePlaceholders
640: ----------------------------------------------------------------------*/
641: #ifdef __STDC__
642: static void CreatePlaceholders (Element el, Document doc)
643: #else
644: static void CreatePlaceholders (el, doc)
645: Element el;
646: Document doc;
647: #endif
648: {
649: Element sibling, prev, constr, child;
650: Attribute attr;
651: ElementType elType;
652: AttributeType attrType;
653: boolean create;
654:
1.2 cvs 655: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 656: prev = NULL;
657: create = TRUE;
658: sibling = el;
659: while (sibling != NULL)
660: {
661: if (!ElementNeedsPlaceholder (sibling))
662: create = FALSE;
663: else
664: {
665: if (sibling == el)
666: /* first element */
667: {
668: elType = TtaGetElementType (sibling);
669: if (elType.ElTypeNum == MathML_EL_MF)
670: /* the first element is a MF. Don't create a placeholder
671: before */
672: create = FALSE;
673: else if (elType.ElTypeNum == MathML_EL_MROW)
674: /* the first element is a MROW */
675: {
676: child = TtaGetFirstChild (sibling);
677: if (child != NULL)
678: {
679: elType = TtaGetElementType (child);
680: if (elType.ElTypeNum != MathML_EL_MF)
681: /* the first child of the MROW element is not a MF */
682: /* Don't create a placeholder before */
683: create = FALSE;
684: }
685: }
686: }
687: if (create)
688: {
689: elType.ElTypeNum = MathML_EL_Construct;
690: constr = TtaNewElement (doc, elType);
691: TtaInsertSibling (constr, sibling, TRUE, doc);
692: attrType.AttrSSchema = elType.ElSSchema;
693: attrType.AttrTypeNum = MathML_ATTR_placeholder;
694: attr = TtaNewAttribute (attrType);
695: TtaAttachAttribute (constr, attr, doc);
696: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, constr, doc);
697: }
698: create = TRUE;
699: }
700: prev = sibling;
701: TtaNextSibling (&sibling);
702: }
703: if (prev != NULL && create)
704: {
705: elType = TtaGetElementType (prev);
706: /* don't insert a placeholder after the last element if it's a MF
707: or a SEP */
708: if (elType.ElTypeNum == MathML_EL_MF ||
709: elType.ElTypeNum == MathML_EL_SEP)
710: create = FALSE;
711: else if (elType.ElTypeNum == MathML_EL_MROW)
712: /* the last element is a MROW */
713: {
714: child = TtaGetLastChild (prev);
715: if (child != NULL)
716: {
717: elType = TtaGetElementType (child);
718: if (elType.ElTypeNum != MathML_EL_MF)
719: /* the last child of the MROW element is not a MF */
720: /* Don't create a placeholder before */
721: create = FALSE;
722: }
723: }
724: if (create)
725: {
726: elType.ElTypeNum = MathML_EL_Construct;
727: constr = TtaNewElement (doc, elType);
728: TtaInsertSibling (constr, prev, FALSE, doc);
729: attrType.AttrSSchema = elType.ElSSchema;
730: attrType.AttrTypeNum = MathML_ATTR_placeholder;
731: attr = TtaNewAttribute (attrType);
732: TtaAttachAttribute (constr, attr, doc);
733: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, constr, doc);
734: }
735: }
736: }
737:
738: /*----------------------------------------------------------------------
739: NextNotSep
740: Return the next sibling of element el that is not a SEP element
741: Return el itself if it's not a SEP
742: ----------------------------------------------------------------------*/
743: #ifdef __STDC__
744: static void NextNotSep (Element* el, Element* prev)
745: #else
746: static void NextNotSep (el, prev)
747: Element *el;
748: #endif
749: {
750: ElementType elType;
751:
752: if (*el == NULL)
753: return;
754: elType = TtaGetElementType (*el);
755: while (*el != NULL && elType.ElTypeNum == MathML_EL_SEP)
756: {
757: *prev = *el;
758: TtaNextSibling (el);
759: if (*el != NULL)
760: elType = TtaGetElementType (*el);
761: }
762: }
763:
764: /*----------------------------------------------------------------------
765: CheckMathSubExpressions
766: Children of element el should be of type type1, type2, and type3.
767: Create an element of that type.
768: ----------------------------------------------------------------------*/
769: #ifdef __STDC__
770: static void CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
771: #else
772: static void CheckMathSubExpressions (el, type1, type2, type3, doc)
773: Element el;
774: int type1;
775: int type2;
776: int type3;
777: Document doc;
778: #endif
779: {
780: Element child, new, prev;
781: ElementType elType, childType;
782:
1.2 cvs 783: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 784: child = TtaGetFirstChild (el);
785: prev = NULL;
786: NextNotSep (&child, &prev);
787: if (child != NULL && type1 != 0)
788: {
789: elType.ElTypeNum = type1;
790: childType = TtaGetElementType (child);
791: if (TtaSameTypes (childType, elType) == 0)
792: {
793: TtaRemoveTree (child, doc);
794: new = TtaNewElement (doc, elType);
795: if (prev == NULL)
796: TtaInsertFirstChild (&new, el, doc);
797: else
798: TtaInsertSibling (new, prev, FALSE, doc);
799: TtaInsertFirstChild (&child, new, doc);
800: CreatePlaceholders (child, doc);
801: child = new;
802: }
803: if (type2 != 0)
804: {
805: prev = child;
806: TtaNextSibling (&child);
807: NextNotSep (&child, &prev);
808: if (child != NULL)
809: {
810: elType.ElTypeNum = type2;
811: childType = TtaGetElementType (child);
812: if (TtaSameTypes (childType, elType) == 0)
813: {
814: TtaRemoveTree (child, doc);
815: new = TtaNewElement (doc, elType);
816: TtaInsertSibling (new, prev, FALSE, doc);
817: TtaInsertFirstChild (&child, new, doc);
818: CreatePlaceholders (child, doc);
819: child = new;
820: }
821: if (type3 != 0)
822: {
823: prev = child;
824: TtaNextSibling (&child);
825: NextNotSep (&child, &prev);
826: if (child != NULL)
827: {
828: elType.ElTypeNum = type3;
829: childType = TtaGetElementType (child);
830: if (TtaSameTypes (childType, elType) == 0)
831: {
832: TtaRemoveTree (child, doc);
833: new = TtaNewElement (doc, elType);
834: TtaInsertSibling (new, prev, FALSE, doc);
835: TtaInsertFirstChild (&child, new, doc);
836: CreatePlaceholders (child, doc);
837: }
838: }
839: }
840: }
841: }
842: }
843: }
844:
845:
846: /*----------------------------------------------------------------------
847: SetSingleHorizStretchAttr
848:
849: Put a horizstretch attribute on element el if it contains only
850: a MO element that is a stretchable symbol.
851: -----------------------------------------------------------------------*/
852: #ifdef __STDC__
853: void SetSingleHorizStretchAttr (Element el, Document doc, Element* selEl)
854: #else /* __STDC__*/
855: void SetSingleHorizStretchAttr (el, doc, selEl)
856: Element el;
857: Document doc;
858: Element* selEl;
859: #endif /* __STDC__*/
860: {
861: Element child, sibling, textEl, symbolEl;
862: ElementType elType;
863: Attribute attr;
864: AttributeType attrType;
865: int len;
866: Language lang;
867: char alphabet;
868: unsigned char text[2], c;
869:
870: if (el == NULL)
871: return;
872: child = TtaGetFirstChild (el);
873: if (child != NULL)
874: {
875: elType = TtaGetElementType (child);
876: if (elType.ElTypeNum == MathML_EL_MO)
877: /* the first child is a MO */
878: {
879: sibling = child;
880: TtaNextSibling (&sibling);
881: if (sibling == NULL)
882: /* there is no other child */
883: {
884: textEl = TtaGetFirstChild (child);
885: elType = TtaGetElementType (textEl);
886: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
887: {
888: len = TtaGetTextLength (textEl);
889: if (len == 1)
890: {
891: len = 2;
892: TtaGiveTextContent (textEl, text, &len, &lang);
893: alphabet = TtaGetAlphabet (lang);
894: if (len == 1)
895: if (alphabet == 'G')
896: /* a single Symbol character */
897: if ((int)text[0] == 172 || (int)text[0] == 174)
898: /* horizontal arrow */
899: {
900: /* attach a horizstretch attribute */
901: attrType.AttrSSchema = elType.ElSSchema;
902: attrType.AttrTypeNum = MathML_ATTR_horizstretch;
903: attr = TtaNewAttribute (attrType);
904: TtaAttachAttribute (el, attr, doc);
905: TtaSetAttributeValue (attr, MathML_ATTR_horizstretch_VAL_yes_, el, doc);
906: /* replace the TEXT element by a Thot SYMBOL element */
907: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
908: symbolEl = TtaNewElement (doc, elType);
909: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
910: if (selEl != NULL)
911: if (*selEl == textEl)
912: *selEl = symbolEl;
913: TtaDeleteTree (textEl, doc);
914: if ((int)text[0] == 172)
915: c = '<';
916: if ((int)text[0] == 174)
917: c = '>';
918: TtaSetGraphicsShape (symbolEl, c, doc);
919: }
920: }
921: }
922: }
923: }
924: }
925: }
926:
927: /*----------------------------------------------------------------------
928: SetHorizStretchAttr
929:
930: Put a horizstretch attribute on all children of element el which
931: contain only a MO element that is a stretchable symbol.
932: -----------------------------------------------------------------------*/
933: #ifdef __STDC__
934: static void SetHorizStretchAttr (Element el, Document doc)
935: #else /* __STDC__*/
936: static void SetHorizStretchAttr (el, doc)
937: Element el;
938: Document doc;
939: #endif /* __STDC__*/
940: {
941: Element child;
942:
943: if (el == NULL)
944: return;
945: child = TtaGetFirstChild (el);
946: while (child != NULL)
947: {
948: SetSingleHorizStretchAttr (child, doc, NULL);
949: TtaNextSibling (&child);
950: }
951: }
952:
953: /*----------------------------------------------------------------------
954: SetVertStretchAttr
955:
956: Put a vertstretch attribute on element el if its base element
957: (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
958: a MUNDER of a MOVER) contains only a MO element that is a vertically
959: stretchable symbol.
960: -----------------------------------------------------------------------*/
961: #ifdef __STDC__
962: void SetVertStretchAttr (Element el, Document doc, int base, Element* selEl)
963: #else /* __STDC__*/
964: void SetVertStretchAttr (el, doc, base, selEl)
965: Element el;
966: Document doc;
967: int base;
968: Element* selEl;
969: #endif /* __STDC__*/
970: {
971: Element child, sibling, textEl, symbolEl, parent, operator;
972: ElementType elType;
973: Attribute attr;
974: AttributeType attrType;
975: int len;
976: Language lang;
977: char alphabet;
978: unsigned char text[2], c;
979:
980: if (el == NULL)
981: return;
982: operator = NULL;
983: if (base == 0)
984: /* it's a MO */
985: {
986: parent = TtaGetParent (el);
987: if (parent != NULL)
988: {
989: elType = TtaGetElementType (parent);
990: if (elType.ElTypeNum != MathML_EL_Base &&
991: elType.ElTypeNum != MathML_EL_UnderOverBase &&
992: elType.ElTypeNum != MathML_EL_MSUBSUP &&
993: elType.ElTypeNum != MathML_EL_MSUB &&
994: elType.ElTypeNum != MathML_EL_MSUP &&
995: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
996: elType.ElTypeNum != MathML_EL_MUNDER &&
997: elType.ElTypeNum != MathML_EL_MUNDEROVER)
998: operator = el;
999: }
1000: }
1001: else
1002: /* it's not a MO */
1003: {
1004: /* search the Base or UnderOverBase child */
1005: child = TtaGetFirstChild (el);
1006: if (child != NULL)
1007: {
1008: elType = TtaGetElementType (child);
1009: if (elType.ElTypeNum == base)
1010: /* the first child is a Base or UnderOverBase */
1011: {
1012: child = TtaGetFirstChild (child);
1013: if (child != NULL)
1014: {
1015: elType = TtaGetElementType (child);
1016: if (elType.ElTypeNum == MathML_EL_MO)
1017: /* its first child is a MO */
1018: {
1019: sibling = child;
1020: TtaNextSibling (&sibling);
1021: if (sibling == NULL)
1022: /* there is no other child */
1023: operator = child;
1024: }
1025: }
1026: }
1027: }
1028: }
1029: if (operator != NULL)
1030: {
1031: textEl = TtaGetFirstChild (operator);
1032: if (textEl != NULL)
1033: {
1034: elType = TtaGetElementType (textEl);
1035: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1036: {
1037: len = TtaGetTextLength (textEl);
1038: if (len == 1)
1039: {
1040: len = 2;
1041: TtaGiveTextContent (textEl, text, &len, &lang);
1042: alphabet = TtaGetAlphabet (lang);
1043: if (len == 1)
1044: if (alphabet == 'G')
1045: /* a single Symbol character */
1046: if ((int)text[0] == 242)
1047: /* Integral */
1048: {
1049: /* attach a vertstretch attribute */
1050: attrType.AttrSSchema = elType.ElSSchema;
1051: attrType.AttrTypeNum = MathML_ATTR_vertstretch;
1052: attr = TtaNewAttribute (attrType);
1053: TtaAttachAttribute (el, attr, doc);
1054: TtaSetAttributeValue (attr, MathML_ATTR_vertstretch_VAL_yes_, el, doc);
1055: /* replace the TEXT element by a Thot SYMBOL element*/
1056: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1057: symbolEl = TtaNewElement (doc, elType);
1058: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
1059: if (selEl != NULL)
1060: if (*selEl == textEl)
1061: *selEl = symbolEl;
1062: TtaDeleteTree (textEl, doc);
1063: c = 'i';
1064: TtaSetGraphicsShape (symbolEl, c, doc);
1065: }
1066: }
1067: }
1068: }
1069: }
1070: }
1071:
1072: /*----------------------------------------------------------------------
1073: SetPlaceholderAttr
1074:
1075: Put a placeholder attribute on all Construct elements in the
1076: subtree of root el.
1077: -----------------------------------------------------------------------*/
1078: #ifdef __STDC__
1079: static void SetPlaceholderAttr (Element el, Document doc)
1080: #else /* __STDC__*/
1081: static void SetPlaceholderAttr (el, doc)
1082: Element el;
1083: Document doc;
1084: #endif /* __STDC__*/
1085: {
1086: Element child;
1087: ElementType elType;
1088: Attribute attr;
1089: AttributeType attrType;
1090:
1091: if (el == NULL)
1092: return;
1093: elType = TtaGetElementType (el);
1094: if (elType.ElTypeNum == MathML_EL_Construct &&
1.2 cvs 1095: elType.ElSSchema == GetMathMLSSchema (doc))
1.1 cvs 1096: {
1097: attrType.AttrSSchema = elType.ElSSchema;
1098: attrType.AttrTypeNum = MathML_ATTR_placeholder;
1099: attr = TtaNewAttribute (attrType);
1100: TtaAttachAttribute (el, attr, doc);
1101: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, el, doc);
1102: }
1103: else
1104: {
1105: child = TtaGetFirstChild (el);
1106: while (child != NULL)
1107: {
1108: SetPlaceholderAttr (child, doc);
1109: TtaNextSibling (&child);
1110: }
1111: }
1112: }
1113:
1114: /*----------------------------------------------------------------------
1115: BuildMultiscript
1116:
1117: The content of a MMULTISCRIPT element has been created following
1118: the original MathML structure. Create all Thot elements defined
1119: in the MathML S schema.
1120: -----------------------------------------------------------------------*/
1121: #ifdef __STDC__
1122: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
1123: #else /* __STDC__*/
1124: static void BuildMultiscript (elMMULTISCRIPT, doc)
1125: Element elMMULTISCRIPT;
1126: Document doc;
1127: #endif /* __STDC__*/
1128: {
1129: Element elem, base, next, group, pair, script, prevPair, prevScript;
1130: ElementType elType, elTypeGroup, elTypePair, elTypeScript;
1.2 cvs 1131: SSchema MathMLSSchema;
1.1 cvs 1132: base = NULL;
1133: group = NULL;
1134: prevPair = NULL;
1135: prevScript = NULL;
1136:
1.2 cvs 1137: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 1138: elTypeGroup.ElSSchema = MathMLSSchema;
1139: elTypePair.ElSSchema = MathMLSSchema;
1140: elTypeScript.ElSSchema = MathMLSSchema;
1141:
1142: /* process all children of the MMULTISCRIPT element */
1143: elem = TtaGetFirstChild (elMMULTISCRIPT);
1144: while (elem != NULL)
1145: {
1146: /* remember the element to be processed after the current one */
1147: next = elem;
1148: TtaNextSibling (&next);
1149:
1150: /* remove the current element from the tree */
1151: TtaRemoveTree (elem, doc);
1152:
1153: if (base == NULL)
1154: /* the current element is the first child of the MMULTISCRIPT
1155: element */
1156: {
1157: /* Create a MultiscriptBase element as the first child of
1158: MMULTISCRIPT and move the current element as the first child
1159: of the MultiscriptBase element */
1160: elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
1161: base = TtaNewElement (doc, elTypeGroup);
1162: TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
1163: TtaInsertFirstChild (&elem, base, doc);
1164: }
1165: else
1166: /* the current element is a subscript or a superscript */
1167: {
1168: if (group == NULL)
1169: /* there is no PostscriptPairs element. Create one */
1170: {
1171: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1172: group = TtaNewElement (doc, elTypeGroup);
1173: TtaInsertSibling (group, base, FALSE, doc);
1174: elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
1175: /* create a first and a last PostscriptPair as placeholders */
1176: pair = TtaNewTree (doc, elTypePair, "");
1177: TtaInsertFirstChild (&pair, group, doc);
1178: SetPlaceholderAttr (pair, doc);
1179: prevPair = pair;
1180: pair = TtaNewTree (doc, elTypePair, "");
1181: TtaInsertSibling (pair, prevPair, FALSE, doc);
1182: SetPlaceholderAttr (pair, doc);
1183: prevScript = NULL;
1184: }
1185: if (prevScript == NULL)
1186: /* the current element is the first subscript or superscript
1187: in a pair */
1188: {
1189: /* create a PostscriptPair or PrescriptPair element */
1190: pair = TtaNewElement (doc, elTypePair);
1191: if (prevPair == NULL)
1192: TtaInsertFirstChild (&pair, group, doc);
1193: else
1194: TtaInsertSibling (pair, prevPair, FALSE, doc);
1195: prevPair = pair;
1196: /* create a MSubscript element */
1197: elTypeScript.ElTypeNum = MathML_EL_MSubscript;
1198: script = TtaNewElement (doc, elTypeScript);
1199: TtaInsertFirstChild (&script, pair, doc);
1200: prevScript = script;
1201: }
1202: else
1203: /* the current element is a superscript in a pair */
1204: {
1205: /* create a MSuperscript element */
1206: elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
1207: script = TtaNewElement (doc, elTypeScript);
1208: /* insert it as a sibling of the previous MSubscript element */
1209: TtaInsertSibling (script, prevScript, FALSE, doc);
1210: prevScript = NULL;
1211: }
1212: /* insert the current element as a child of the new MSuperscript or
1213: MSubscript element */
1214: TtaInsertFirstChild (&elem, script, doc);
1215: SetPlaceholderAttr (elem, doc);
1216: }
1217:
1218: CreatePlaceholders (elem, doc);
1219:
1220: /* get next child of the MMULTISCRIPT element */
1221: elem = next;
1222: if (elem != NULL)
1223: {
1224: elType = TtaGetElementType (elem);
1225: if (elType.ElSSchema == MathMLSSchema &&
1226: elType.ElTypeNum == MathML_EL_PrescriptPairs)
1227: /* the next element is a PrescriptPairs */
1228: {
1229: /* if there there is no PostscriptPairs element, create one as a
1230: placeholder */
1231: if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
1232: {
1233: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1234: group = TtaNewTree (doc, elTypeGroup, "");
1235: TtaInsertSibling (group, elem, TRUE, doc);
1236: SetPlaceholderAttr (group, doc);
1237: }
1238: /* the following elements will be interpreted as sub- superscripts
1239: in PrescriptPair elements, wich will be children of this
1240: PrescriptPairs element */
1241: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1242: elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
1243: group = elem;
1244: /* create a first and a last PostscriptPair as placeholders */
1245: pair = TtaNewTree (doc, elTypePair, "");
1246: TtaInsertFirstChild (&pair, group, doc);
1247: SetPlaceholderAttr (pair, doc);
1248: prevPair = pair;
1249: pair = TtaNewTree (doc, elTypePair, "");
1250: TtaInsertSibling (pair, prevPair, FALSE, doc);
1251: SetPlaceholderAttr (pair, doc);
1252: prevScript = NULL;
1253: TtaNextSibling (&elem);
1254: }
1255: }
1256: }
1257: /* all children of element MMULTISCRIPTS have been processed */
1258: /* if the last group processed is not a PrescriptPairs element,
1259: create one as a placeholder */
1260: if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
1261: {
1262: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1263: elem = TtaNewTree (doc, elTypeGroup, "");
1264: if (group == NULL)
1265: group = base;
1266: TtaInsertSibling (elem, group, TRUE, doc);
1267: SetPlaceholderAttr (elem, doc);
1268: }
1269: }
1270:
1.5 cvs 1271: /*----------------------------------------------------------------------
1272: LinkMathCellsWithColumnHeads
1273:
1274: -----------------------------------------------------------------------*/
1275: #ifdef __STDC__
1276: void LinkMathCellsWithColumnHeads (Element elMTABLE, Document doc)
1277: #else /* __STDC__*/
1278: void LinkMathCellsWithColumnHeads (elMTABLE, doc)
1279: Element elMTABLE;
1280: Document doc;
1281: #endif /* __STDC__*/
1282: {
1283: ElementType elType;
1284: Element firstColHead, head, prevHead, nextHead, row, cell, prevCell,
1285: MTableHead, MTableBody;
1286: SSchema MathMLSSchema;
1287: AttributeType attrType;
1288: Attribute attr;
1289: int nCol, nCell, nHead;
1290:
1291: MathMLSSchema = GetMathMLSSchema (doc);
1292: MTableHead = TtaGetFirstChild (elMTABLE);
1293: MTableBody = MTableHead;
1294: TtaNextSibling (&MTableBody);
1295: firstColHead = TtaGetFirstChild (MTableHead);
1296:
1297: /* first, create a MColumn_head for each column in the table and
1298: count columns */
1299: row = TtaGetFirstChild (MTableBody);
1300: nCol = 0;
1301: while (row)
1302: {
1303: elType = TtaGetElementType (row);
1304: if (elType.ElTypeNum == MathML_EL_MTR &&
1305: TtaSameSSchemas (elType.ElSSchema, MathMLSSchema))
1306: {
1307: head = firstColHead;
1308: prevHead = NULL;
1309: cell = TtaGetFirstChild (row);
1310: nCell = 0;
1311: while (cell)
1312: {
1313: elType = TtaGetElementType (cell);
1314: if (elType.ElTypeNum == MathML_EL_MTD &&
1315: TtaSameSSchemas (elType.ElSSchema, MathMLSSchema))
1316: {
1317: if (!head)
1318: {
1319: elType.ElTypeNum = MathML_EL_MColumn_head;
1320: head = TtaNewTree (doc, elType, "");
1321: TtaInsertSibling (head, prevHead, FALSE, doc);
1322: }
1323: nCell++;
1324: prevHead = head;
1325: TtaNextSibling (&head);
1326: }
1327: TtaNextSibling (&cell);
1328: }
1329: }
1330: if (nCell > nCol)
1331: nCol = nCell;
1332: TtaNextSibling (&row);
1333: }
1334:
1335: /* delete the last MColumn_heads if there are more MColumn_heads than
1336: columns */
1337: head = firstColHead;
1338: nHead = 0;
1339: while (head)
1340: {
1341: nHead++;
1342: nextHead = head;
1343: TtaNextSibling (&nextHead);
1344: if (nHead > nCol)
1345: TtaDeleteTree (head, doc);
1346: head = nextHead;
1347: }
1348:
1349: /* relate each cell with the corresponding MColumn_head and create
1350: additional cells in incomplete rows */
1351: attrType.AttrSSchema = MathMLSSchema;
1352: attrType.AttrTypeNum = MathML_ATTR_MRef_column;
1353: row = TtaGetFirstChild (MTableBody);
1354: while (row)
1355: {
1356: elType = TtaGetElementType (row);
1357: if (elType.ElTypeNum == MathML_EL_MTR &&
1358: TtaSameSSchemas (elType.ElSSchema, MathMLSSchema))
1359: {
1360: head = firstColHead;
1361: prevCell = NULL;
1362: cell = TtaGetFirstChild (row);
1363: while (head)
1364: {
1365: if (cell)
1366: elType = TtaGetElementType (cell);
1367: while (cell &&
1368: (elType.ElTypeNum != MathML_EL_MTD ||
1369: !TtaSameSSchemas (elType.ElSSchema, MathMLSSchema)))
1370: {
1371: TtaNextSibling (&cell);
1372: if (cell)
1373: elType = TtaGetElementType (cell);
1374: }
1375: if (!cell)
1376: {
1377: elType.ElTypeNum = MathML_EL_MTD;
1378: cell = TtaNewTree (doc, elType, "");
1379: if (prevCell)
1380: TtaInsertSibling (cell, prevCell, FALSE, doc);
1381: else
1382: TtaInsertFirstChild (&cell, row, doc);
1383: }
1384: attr = TtaGetAttribute (cell, attrType);
1385: if (!attr)
1386: {
1387: attr = TtaNewAttribute (attrType);
1388: TtaAttachAttribute (cell, attr, doc);
1389: }
1390: TtaSetAttributeReference (attr, cell, doc, head, doc);
1391: prevCell = cell;
1392: TtaNextSibling (&cell);
1393: TtaNextSibling (&head);
1394: }
1395: }
1396: TtaNextSibling (&row);
1397: }
1398: }
1399:
1400: /*----------------------------------------------------------------------
1401: CheckMTable
1402:
1403: The content of a MTABLE element has been created following
1404: the original MathML structure. Create all Thot elements defined
1405: in the MathML S schema.
1406: -----------------------------------------------------------------------*/
1407: #ifdef __STDC__
1408: static void CheckMTable (Element elMTABLE, Document doc)
1409: #else /* __STDC__*/
1410: static void CheckMTable (elMTABLE, doc)
1411: Element elMTABLE;
1412: Document doc;
1413: #endif /* __STDC__*/
1414: {
1415: ElementType elType;
1416: Element MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
1417: nextCell, newMTD, firstColHead, child, prevChild, nextChild,
1418: wrapper;
1419: SSchema MathMLSSchema;
1420:
1421: MathMLSSchema = GetMathMLSSchema (doc);
1422: row = TtaGetFirstChild (elMTABLE);
1423:
1424: /* create a MTable_head as the first child of element MTABLE */
1425: elType.ElSSchema = MathMLSSchema;
1426: elType.ElTypeNum = MathML_EL_MTable_head;
1427: MTableHead = TtaNewElement (doc, elType);
1428: TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
1429: elType.ElTypeNum = MathML_EL_MColumn_head;
1430: firstColHead = TtaNewTree (doc, elType, "");
1431: TtaInsertFirstChild (&firstColHead, MTableHead, doc);
1432:
1433: /* create a MTable_body */
1434: elType.ElSSchema = MathMLSSchema;
1435: elType.ElTypeNum = MathML_EL_MTable_body;
1436: MTableBody = TtaNewElement (doc, elType);
1437: TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
1438:
1439: /* move all children of element MTABLE into the new MTable_body element
1440: and wrap each non-MTR element with a MTR */
1441: prevRow = NULL;
1442: while (row)
1443: {
1444: nextRow = row;
1445: TtaNextSibling (&nextRow);
1446: elType = TtaGetElementType (row);
1447: TtaRemoveTree (row, doc);
1448: if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
1449: (elType.ElTypeNum == MathML_EL_XMLcomment ||
1450: elType.ElTypeNum == MathML_EL_MTR))
1451: {
1452: if (prevRow == NULL)
1453: TtaInsertFirstChild (&row, MTableBody, doc);
1454: else
1455: TtaInsertSibling (row, prevRow, FALSE, doc);
1456: prevRow = row;
1457: if (elType.ElTypeNum == MathML_EL_MTR)
1458: cell = TtaGetFirstChild (row);
1459: else
1460: cell = NULL;
1461: }
1462: else
1463: /* this child is not a MTR nor a comment, create a MTR element */
1464: {
1465: elType.ElSSchema = MathMLSSchema;
1466: elType.ElTypeNum = MathML_EL_MTR;
1467: el = TtaNewElement (doc, elType);
1468: if (prevRow == NULL)
1469: TtaInsertFirstChild (&el, MTableBody, doc);
1470: else
1471: TtaInsertSibling (el, prevRow, FALSE, doc);
1472: TtaInsertFirstChild (&row, el, doc);
1473: cell = row;
1474: prevRow = el;
1475: }
1476: while (cell)
1477: /* check all children of the current MTR element */
1478: {
1479: nextCell = cell;
1480: TtaNextSibling (&nextCell);
1481: elType = TtaGetElementType (cell);
1482: if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
1483: (elType.ElTypeNum != MathML_EL_XMLcomment &&
1484: elType.ElTypeNum != MathML_EL_MTD))
1485: /* this is not a MTD nor a comment, create a wrapping MTD */
1486: {
1487: elType.ElSSchema = MathMLSSchema;
1488: elType.ElTypeNum = MathML_EL_MTD;
1489: newMTD = TtaNewElement (doc, elType);
1490: TtaInsertSibling (newMTD, cell, TRUE, doc);
1491: TtaRemoveTree (cell, doc);
1492: TtaInsertFirstChild (&cell, newMTD, doc);
1493: cell = newMTD;
1494: }
1495: if (elType.ElTypeNum == MathML_EL_MTD)
1496: /* This is a MTD element. Wrap its contents with a CellWrapper */
1497: {
1498: child = TtaGetFirstChild (cell);
1499: elType.ElSSchema = MathMLSSchema;
1500: elType.ElTypeNum = MathML_EL_CellWrapper;
1501: wrapper = TtaNewElement (doc, elType);
1502: TtaInsertFirstChild (&wrapper, cell, doc);
1503: prevChild = NULL;
1504: while (child)
1505: {
1506: nextChild = child;
1507: TtaNextSibling (&nextChild);
1508: TtaRemoveTree (child, doc);
1509: if (prevChild == NULL)
1510: TtaInsertFirstChild (&child, wrapper, doc);
1511: else
1512: TtaInsertSibling (child, prevChild, FALSE, doc);
1513: prevChild = child;
1514: child = nextChild;
1515: }
1516: }
1517: cell = nextCell;
1518: }
1519: row = nextRow;
1520: }
1521: LinkMathCellsWithColumnHeads (elMTABLE, doc);
1522: }
1.1 cvs 1523:
1524: /*----------------------------------------------------------------------
1525: SetFontstyleAttr
1526: The content of a MI element has been created or modified.
1527: Create or change attribute IntFontstyle for that element accordingly.
1528: -----------------------------------------------------------------------*/
1529: #ifdef __STDC__
1530: void SetFontstyleAttr (Element el, Document doc)
1531: #else /* __STDC__*/
1532: void SetFontstyleAttr (el, doc)
1533: Element el;
1534: Document doc;
1535: #endif /* __STDC__*/
1536: {
1537: ElementType elType;
1538: AttributeType attrType;
1539: Attribute attr, IntAttr;
1540: int len;
1541:
1542: if (el != NULL)
1543: {
1544: /* search the fontstyle attribute */
1545: elType = TtaGetElementType (el);
1546: attrType.AttrSSchema = elType.ElSSchema;
1547: attrType.AttrTypeNum = MathML_ATTR_fontstyle;
1548: attr = TtaGetAttribute (el, attrType);
1549: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1550: IntAttr = TtaGetAttribute (el, attrType);
1551: if (attr != NULL)
1552: /* there is a fontstyle attribute. Remove the corresponding
1553: internal attribute that is not needed */
1554: {
1555: if (IntAttr != NULL)
1556: TtaRemoveAttribute (el, IntAttr, doc);
1557: }
1558: else
1559: /* there is no fontstyle attribute. Create an internal attribute
1560: IntFontstyle with a value that depends on the content of the MI */
1561: {
1562: /* get content length */
1563: len = TtaGetElementVolume (el);
1564: if (len > 1)
1565: /* put an attribute IntFontstyle = IntNormal */
1566: {
1567: if (IntAttr == NULL)
1568: {
1569: IntAttr = TtaNewAttribute (attrType);
1570: TtaAttachAttribute (el, IntAttr, doc);
1571: }
1572: TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
1573: el, doc);
1574: }
1575: else
1576: /* MI contains a single character. Remove attribute IntFontstyle
1577: if it exists */
1578: {
1579: if (IntAttr != NULL)
1580: TtaRemoveAttribute (el, IntAttr, doc);
1581: }
1582: }
1583: }
1584: }
1585:
1586: /*----------------------------------------------------------------------
1587: SetAddspaceAttr
1588: The content of a MO element has been created or modified.
1589: Create or change attribute addspace for that element accordingly.
1590: -----------------------------------------------------------------------*/
1591: #ifdef __STDC__
1592: void SetAddspaceAttr (Element el, Document doc)
1593: #else /* __STDC__*/
1594: void SetAddspaceAttr (el, doc)
1595: Element el;
1596: Document doc;
1597: #endif /* __STDC__*/
1598: {
1599: Element textEl, previous;
1600: ElementType elType;
1601: AttributeType attrType;
1602: Attribute attr;
1603: int len, val;
1604: #define BUFLEN 10
1605: unsigned char text[BUFLEN];
1606: Language lang;
1607: char alphabet;
1608:
1609: textEl = TtaGetFirstChild (el);
1610: if (textEl != NULL)
1611: {
1612: /* search the addspace attribute */
1613: elType = TtaGetElementType (el);
1614: attrType.AttrSSchema = elType.ElSSchema;
1615: attrType.AttrTypeNum = MathML_ATTR_addspace;
1616: attr = TtaGetAttribute (el, attrType);
1617: if (attr == NULL)
1618: {
1619: attr = TtaNewAttribute (attrType);
1620: TtaAttachAttribute (el, attr, doc);
1621: }
1622: val = MathML_ATTR_addspace_VAL_nospace;
1623: len = TtaGetTextLength (textEl);
1624: if (len > 0 && len < BUFLEN)
1625: {
1626: len = BUFLEN;
1627: TtaGiveTextContent (textEl, text, &len, &lang);
1628: alphabet = TtaGetAlphabet (lang);
1629: if (len == 1)
1630: if (alphabet == 'L')
1631: /* ISO-Latin 1 character */
1632: {
1633: if (text[0] == '-')
1634: /* unary or binary operator? */
1635: {
1636: previous = el;
1637: TtaPreviousSibling (&previous);
1638: if (previous == NULL)
1639: /* no previous sibling => unary operator */
1640: val = MathML_ATTR_addspace_VAL_nospace;
1641: else
1642: {
1643: elType = TtaGetElementType (previous);
1644: if (elType.ElTypeNum == MathML_EL_MO)
1645: /* after an operator => unary operator */
1646: val = MathML_ATTR_addspace_VAL_nospace;
1647: else
1648: /* binary operator */
1649: val = MathML_ATTR_addspace_VAL_both;
1650: }
1651: }
1652: else if (text[0] == '+' ||
1653: text[0] == '&' ||
1654: text[0] == '*' ||
1655: text[0] == '<' ||
1656: text[0] == '=' ||
1657: text[0] == '>' ||
1658: text[0] == '^')
1659: /* binary operator */
1660: val = MathML_ATTR_addspace_VAL_both;
1661: else if (text[0] == ',' ||
1662: text[0] == ';')
1663: val = MathML_ATTR_addspace_VAL_spaceafter;
1664: }
1665: else if (alphabet == 'G')
1666: /* Symbol character set */
1667: if ((int)text[0] == 163 || /* less or equal */
1668: (int)text[0] == 177 || /* plus or minus */
1669: (int)text[0] == 179 || /* greater or equal */
1670: (int)text[0] == 180 || /* times */
1671: (int)text[0] == 184 || /* divide */
1672: (int)text[0] == 185 || /* not equal */
1673: (int)text[0] == 186 || /* identical */
1674: (int)text[0] == 187 || /* equivalent */
1675: (int)text[0] == 196 || /* circle times */
1676: (int)text[0] == 197 || /* circle plus */
1677: ((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
1678: (int)text[0] == 217 || /* and */
1679: (int)text[0] == 218 ) /* or */
1680: val = MathML_ATTR_addspace_VAL_both;
1681: }
1682: TtaSetAttributeValue (attr, val, el, doc);
1683: }
1684: }
1685:
1686:
1687: /*----------------------------------------------------------------------
1688: ChangeTypeOfElement
1689: Change the type of element elem into newTypeNum
1690: -----------------------------------------------------------------------*/
1691: #ifdef __STDC__
1692: void ChangeTypeOfElement (Element elem, Document doc, int newTypeNum)
1693: #else /* __STDC__*/
1694: void ChangeTypeOfElement (elem, doc, newTypeNum)
1695: Element elem;
1696: Document doc;
1697: int newTypeNum;
1698: #endif /* __STDC__*/
1699:
1700: {
1701: Element prev, next, parent;
1702:
1703: prev = elem;
1704: TtaPreviousSibling (&prev);
1705: if (prev == NULL)
1706: {
1707: next = elem;
1708: TtaNextSibling (&next);
1709: if (next == NULL)
1710: parent = TtaGetParent (elem);
1711: }
1712: TtaRemoveTree (elem, doc);
1713: ChangeElementType (elem, newTypeNum);
1714: if (prev != NULL)
1715: TtaInsertSibling (elem, prev, FALSE, doc);
1716: else if (next != NULL)
1717: TtaInsertSibling (elem, next, TRUE, doc);
1718: else
1719: TtaInsertFirstChild (&elem, parent, doc);
1720: }
1721:
1722:
1723: /*----------------------------------------------------------------------
1724: CheckFence
1725: If el is a MO element that contains a single fence character,
1726: transform the MO into a MF and the character into a Thot symbol.
1727: ----------------------------------------------------------------------*/
1728: #ifdef __STDC__
1729: void CheckFence (Element el, Document doc)
1730: #else
1731: void CheckFence (el, doc)
1732: Element el;
1733: Document doc;
1734:
1735: #endif
1736: {
1737: ElementType elType;
1738: Element content;
1739: AttributeType attrType;
1740: Attribute attr;
1741: int len;
1742: Language lang;
1743: char alphabet;
1744: unsigned char text[2], c;
1745:
1746: elType = TtaGetElementType (el);
1747: if (elType.ElTypeNum == MathML_EL_MO)
1748: {
1749: content = TtaGetFirstChild (el);
1750: if (content != NULL)
1751: {
1752: elType = TtaGetElementType (content);
1753: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1754: {
1755: len = TtaGetTextLength (content);
1756: if (len == 1)
1757: {
1758: len = 2;
1759: TtaGiveTextContent (content, text, &len, &lang);
1760: alphabet = TtaGetAlphabet (lang);
1761: if (len == 1)
1762: if (alphabet == 'L')
1763: /* a single character */
1764: if (text[0] == '(' || text[0] == ')' ||
1765: text[0] == '[' || text[0] == ']' ||
1766: text[0] == '{' || text[0] == '}' ||
1767: text[0] == '|' )
1768: {
1769: /* remove the content of the MO element */
1770: TtaDeleteTree (content, doc);
1771: /* change the MO element into a MF element */
1772: ChangeTypeOfElement (el, doc, MathML_EL_MF);
1773: /* attach a vertstretch attribute to the MF element */
1774: attrType.AttrSSchema = elType.ElSSchema;
1775: attrType.AttrTypeNum = MathML_ATTR_vertstretch;
1776: attr = TtaNewAttribute (attrType);
1777: TtaAttachAttribute (el, attr, doc);
1778: TtaSetAttributeValue (attr, MathML_ATTR_vertstretch_VAL_yes_, el, doc);
1779: /* create a new content for the MF element */
1780: if (text[0] == '|')
1781: {
1782: elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
1783: c = 'v';
1784: }
1785: else
1786: {
1787: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1788: c = text[0];
1789: }
1790: content = TtaNewElement (doc, elType);
1791: TtaInsertFirstChild (&content, el, doc);
1792: TtaSetGraphicsShape (content, c, doc);
1793: }
1794: }
1795: }
1796: }
1797: }
1798: }
1799:
1800: /*----------------------------------------------------------------------
1801: CreateFencedSeparators
1802: Create FencedSeparator elements within the fencedExpression
1803: according to attribute separators of the MFENCED element.
1804: ----------------------------------------------------------------------*/
1805: #ifdef __STDC__
1806: void CreateFencedSeparators (Element fencedExpression, Document doc)
1807: #else
1808: void CreateFencedSeparators (fencedExpression, doc)
1809: Element fencedExpression;
1810: Document doc;
1811:
1812: #endif
1813: {
1814: ElementType elType;
1815: Element child, separator, leaf, next, prev, mfenced;
1816: AttributeType attrType;
1817: Attribute attr;
1818: int length, sep, i;
1819: Language lang;
1820: char text[32], sepValue[4];
1821:
1822: /* get the separators attribute */
1823: mfenced = TtaGetParent (fencedExpression);
1824: elType = TtaGetElementType (fencedExpression);
1825: attrType.AttrSSchema = elType.ElSSchema;
1826: attrType.AttrTypeNum = MathML_ATTR_separators;
1827: text[0] = ','; /* default value is sparators="," */
1828: text[1] = EOS;
1829: length = 1;
1830: attr = TtaGetAttribute (mfenced, attrType);
1831: if (attr != NULL)
1832: {
1833: length = 31;
1834: TtaGiveTextAttributeValue (attr, text, &length);
1835: }
1836:
1837: /* create FencedSeparator elements in the FencedExpression */
1838: prev = NULL;
1839: sep = 0;
1840: /* skip leading spaces in attribute separators */
1841: while (text[sep] <= SPACE && text[sep] != EOS)
1842: sep++;
1843: /* if attribute separators is empty or contains only spaces, do not
1844: insert any separator element */
1845: if (text[sep] != EOS)
1846: {
1847: child = TtaGetFirstChild (fencedExpression);
1848: while (child != NULL)
1849: {
1850: next = child;
1851: TtaNextSibling (&next);
1852: elType = TtaGetElementType (child);
1853: if (elType.ElTypeNum != MathML_EL_Construct)
1854: {
1855: if (prev != NULL)
1856: {
1857: elType.ElTypeNum = MathML_EL_FencedSeparator;
1858: separator = TtaNewElement (doc, elType);
1859: TtaInsertSibling (separator, prev, FALSE, doc);
1860: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1861: leaf = TtaNewElement (doc, elType);
1862: TtaInsertFirstChild (&leaf, separator, doc);
1863: sepValue[0] = text[sep];
1864: sepValue[1] = SPACE;
1865: sepValue[2] = EOS;
1866: lang = TtaGetLanguageIdFromAlphabet('L');
1867: TtaSetTextContent (leaf, sepValue, lang, doc);
1868: /* is there a following non-space character in separators? */
1869: i = sep + 1;
1870: while (text[i] <= SPACE && text[i] != EOS)
1871: i++;
1872: if (text[i] > SPACE && text[i] != EOS)
1873: sep = i;
1874: }
1875: prev = child;
1876: }
1877: child = next;
1878: }
1879: }
1880: }
1881:
1882:
1883: /*----------------------------------------------------------------------
1884: TransformMFENCED
1885: Transform the content of a MFENCED element: create elements
1886: OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
1887: ----------------------------------------------------------------------*/
1888: #ifdef __STDC__
1889: void TransformMFENCED (Element el, Document doc)
1890: #else
1891: void TransformMFENCED (el, doc)
1892: Element el;
1893: Document doc;
1894:
1895: #endif
1896: {
1897: ElementType elType;
1898: Element child, fencedExpression, leaf, fence, next, prev,
1899: firstChild;
1900: AttributeType attrType;
1901: Attribute attr;
1902: int length;
1903: char text[32], c;
1904:
1905: child = TtaGetFirstChild (el);
1906: if (child != NULL)
1907: elType = TtaGetElementType (child);
1908: if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
1909: /* The first child of this MFENCED element is an OpeningFence.
1910: This MFENCED expression has already been transformed, possibly
1911: by the Transform command */
1912: {
1913: TtaNextSibling (&child);
1914: fencedExpression = child;
1915: if (fencedExpression != NULL)
1916: elType = TtaGetElementType (fencedExpression);
1917: if (elType.ElTypeNum == MathML_EL_FencedExpression)
1918: /* the second child is a FencedExpression. OK.
1919: Remove all existing FencedSeparator elements */
1920: {
1921: child = TtaGetFirstChild (fencedExpression);
1922: prev = NULL;
1923: while (child != NULL)
1924: {
1925: elType = TtaGetElementType (child);
1926: next = child;
1927: TtaNextSibling (&next);
1928: if (elType.ElTypeNum == MathML_EL_FencedSeparator)
1929: /* Remove this separator */
1930: TtaDeleteTree (child, doc);
1931: child = next;
1932: }
1933: /* create FencedSeparator elements in the FencedExpression */
1934: CreateFencedSeparators (fencedExpression, doc);
1935: }
1936: }
1937: else
1938: /* this MFENCED element must be transformed */
1939: {
1940: /* create a FencedExpression element as a child of the MFENCED elem. */
1941: elType = TtaGetElementType (el);
1942: elType.ElTypeNum = MathML_EL_FencedExpression;
1943: fencedExpression = TtaNewElement (doc, elType);
1944: TtaInsertFirstChild (&fencedExpression, el, doc);
1945: if (child == NULL)
1946: /* empty MFENCED element */
1947: {
1948: elType.ElTypeNum = MathML_EL_Construct;
1949: child = TtaNewElement (doc, elType);
1950: TtaInsertFirstChild (&child, fencedExpression, doc);
1951: SetPlaceholderAttr (child, doc);
1952: }
1953: else
1954: {
1955: /* move the content of the MFENCED element within the new
1956: FencedExpression element */
1957: prev = NULL;
1958: firstChild = NULL;
1959: while (child != NULL)
1960: {
1961: next = child;
1962: TtaNextSibling (&next);
1963: TtaRemoveTree (child, doc);
1964: if (prev == NULL)
1965: {
1966: TtaInsertFirstChild (&child, fencedExpression, doc);
1967: firstChild = child;
1968: }
1969: else
1970: TtaInsertSibling (child, prev, FALSE, doc);
1971: prev = child;
1972: child = next;
1973: }
1974:
1975: /* create FencedSeparator elements in the FencedExpression */
1976: CreateFencedSeparators (fencedExpression, doc);
1977:
1978: /* Create placeholders within the FencedExpression element */
1979: CreatePlaceholders (firstChild, doc);
1980: }
1981:
1982: /* create the OpeningFence element according to the open attribute */
1983: c = '(';
1984: attrType.AttrSSchema = elType.ElSSchema;
1985: attrType.AttrTypeNum = MathML_ATTR_open;
1986: attr = TtaGetAttribute (el, attrType);
1987: if (attr != NULL)
1988: {
1989: length = 7;
1990: TtaGiveTextAttributeValue (attr, text, &length);
1991: c = text[0];
1992: }
1993: elType.ElTypeNum = MathML_EL_OpeningFence;
1994: fence = TtaNewElement (doc, elType);
1995: TtaInsertSibling (fence, fencedExpression, TRUE, doc);
1996: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1997: leaf = TtaNewElement (doc, elType);
1998: TtaInsertFirstChild (&leaf, fence, doc);
1999: TtaSetGraphicsShape (leaf, c, doc);
2000:
2001: /* create the ClosingFence element according to close attribute */
2002: c = ')';
2003: attrType.AttrTypeNum = MathML_ATTR_close;
2004: attr = TtaGetAttribute (el, attrType);
2005: if (attr != NULL)
2006: {
2007: length = 7;
2008: TtaGiveTextAttributeValue (attr, text, &length);
2009: c = text[0];
2010: }
2011: elType.ElTypeNum = MathML_EL_ClosingFence;
2012: fence = TtaNewElement (doc, elType);
2013: TtaInsertSibling (fence, fencedExpression, FALSE, doc);
2014: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
2015: leaf = TtaNewElement (doc, elType);
2016: TtaInsertFirstChild (&leaf, fence, doc);
2017: TtaSetGraphicsShape (leaf, c, doc);
2018: }
2019: }
2020:
2021: /*----------------------------------------------------------------------
2022: MathMLElementComplete
2023: Check the Thot structure of the MathML element el.
2024: ----------------------------------------------------------------------*/
2025: #ifdef __STDC__
2026: void MathMLElementComplete (Element el, Document doc)
2027: #else
2028: void MathMLElementComplete (el, doc)
2029: Element el;
2030: Document doc;
2031:
2032: #endif
2033: {
2034: ElementType elType, parentType;
2035: Element child, parent, new, prev, next;
2036: AttributeType attrType;
2037: Attribute attr;
1.2 cvs 2038: SSchema MathMLSSchema;
1.1 cvs 2039:
2040: elType = TtaGetElementType (el);
1.2 cvs 2041: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 2042:
2043: if (elType.ElSSchema != MathMLSSchema)
2044: /* this is not a MathML element. It's the HTML element <math>, or
2045: any other element containing a MathML expression */
2046: {
2047: if (TtaGetFirstChild (el) == NULL && !TtaIsLeaf (elType))
2048: /* this element is empty. Create a MathML element as it's child */
2049: {
2050: elType.ElSSchema = MathMLSSchema;
2051: elType.ElTypeNum = MathML_EL_MathML;
2052: new = TtaNewElement (doc, elType);
2053: TtaInsertFirstChild (&new, el, doc);
2054: /* Create a placeholder within the MathML element */
2055: elType.ElTypeNum = MathML_EL_Construct;
2056: child = TtaNewElement (doc, elType);
2057: TtaInsertFirstChild (&child, new, doc);
2058: attrType.AttrSSchema = elType.ElSSchema;
2059: attrType.AttrTypeNum = MathML_ATTR_placeholder;
2060: attr = TtaNewAttribute (attrType);
2061: TtaAttachAttribute (child, attr, doc);
2062: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, child, doc);
2063: }
2064: }
2065: else
2066: {
2067: switch (elType.ElTypeNum)
2068: {
2069: case MathML_EL_TEXT_UNIT:
2070: CheckTextElement (&el, doc);
2071: break;
2072: case MathML_EL_MI:
2073: SetFontstyleAttr (el, doc);
2074: break;
2075: case MathML_EL_MO:
2076: SetAddspaceAttr (el, doc);
2077: SetVertStretchAttr (el, doc, 0, NULL);
2078: break;
2079: case MathML_EL_MROOT:
2080: /* end of a Root. Create a RootBase and an Index */
2081: CheckMathSubExpressions (el, MathML_EL_RootBase, MathML_EL_Index,
2082: 0, doc);
2083: break;
2084: case MathML_EL_MSQRT:
2085: /* end od a Square Root. Create a RootBase */
2086: CheckMathSubExpressions (el, MathML_EL_RootBase, 0, 0, doc);
2087: break;
2088: case MathML_EL_MFRAC:
2089: /* end of a fraction. Create a Numerator and a Denominator */
2090: CheckMathSubExpressions (el, MathML_EL_Numerator,
2091: MathML_EL_Denominator, 0, doc);
2092: break;
2093: case MathML_EL_MFENCED:
2094: TransformMFENCED (el, doc);
2095: break;
2096: case MathML_EL_MSUBSUP:
2097: /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
2098: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
2099: MathML_EL_Superscript, doc);
2100: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
2101: break;
2102: case MathML_EL_MSUB:
2103: /* end of a MSUB. Create Base and Subscript */
2104: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
2105: 0, doc);
2106: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
2107: break;
2108: case MathML_EL_MSUP:
2109: /* end of a MSUP. Create Base and Superscript */
2110: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Superscript,
2111: 0, doc);
2112: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
2113: break;
2114: case MathML_EL_MUNDEROVER:
2115: /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
2116: Overscript */
2117: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2118: MathML_EL_Underscript, MathML_EL_Overscript, doc);
2119: SetHorizStretchAttr (el, doc);
2120: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
2121: break;
2122: case MathML_EL_MUNDER:
2123: /* end of a MUNDER. Create UnderOverBase, and Underscript */
2124: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2125: MathML_EL_Underscript, 0, doc);
2126: SetHorizStretchAttr (el, doc);
2127: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
2128: break;
2129: case MathML_EL_MOVER:
2130: /* end of a MOVER. Create UnderOverBase, and Overscript */
2131: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
2132: MathML_EL_Overscript, 0, doc);
2133: SetHorizStretchAttr (el, doc);
2134: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
2135: break;
2136: case MathML_EL_MMULTISCRIPTS:
2137: /* end of a MMULTISCRIPTS. Create all elements defined in the
2138: MathML S schema */
2139: BuildMultiscript (el, doc);
1.5 cvs 2140: break;
2141: case MathML_EL_MTABLE:
2142: /* end of a MTABLE. Create all elements defined in the MathML S
2143: schema */
2144: CheckMTable (el, doc);
1.1 cvs 2145: break;
2146: case MathML_EL_MROW:
2147: /* end of MROW */
2148: /*if the first and the last child are MO containing a fence character
2149: transform the MO into a MF and the character into a Thot SYMBOL */
2150: child = TtaGetFirstChild (el);
2151: if (child != NULL)
2152: {
2153: CheckFence (child, doc);
2154: child = TtaGetLastChild (el);
2155: if (child != NULL)
2156: CheckFence (child, doc);
2157: /* Create placeholders within the MROW */
2158: CreatePlaceholders (TtaGetFirstChild (el), doc);
2159: }
2160: break;
2161: default:
2162: break;
2163: }
2164: parent = TtaGetParent (el);
2165: parentType = TtaGetElementType (parent);
2166: if (parentType.ElSSchema != elType.ElSSchema)
2167: /* root of a MathML tree, Create a MathML element if there is no */
2168: if (elType.ElTypeNum != MathML_EL_MathML)
2169: {
2170: elType.ElSSchema = MathMLSSchema;
2171: elType.ElTypeNum = MathML_EL_MathML;
2172: new = TtaNewElement (doc, elType);
2173: TtaInsertSibling (new, el, TRUE, doc);
2174: next = el;
2175: TtaNextSibling (&next);
2176: TtaRemoveTree (el, doc);
2177: TtaInsertFirstChild (&el, new, doc);
2178: prev = el;
2179: while (next != NULL)
2180: {
2181: child = next;
2182: TtaNextSibling (&next);
2183: TtaRemoveTree (child, doc);
2184: TtaInsertSibling (child, prev, FALSE, doc);
2185: prev = child;
2186: }
2187: /* Create placeholders within the MathML element */
2188: CreatePlaceholders (el, doc);
2189: }
2190: }
2191: }
2192:
2193: /*----------------------------------------------------------------------
2194: MathMLAttributeComplete
2195: ----------------------------------------------------------------------*/
2196: #ifdef __STDC__
2197: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
2198: #else
2199: void MathMLAttributeComplete (attr, el, doc)
2200: Attribute attr;
2201: Element el;
2202: Document doc;
2203:
2204: #endif
2205: {
2206: }
2207:
2208: /*----------------------------------------------------------------------
2209: MathMLGetDTDName
2210: ----------------------------------------------------------------------*/
2211: #ifdef __STDC__
2212: void MathMLGetDTDName (char* DTDname, char *elementName)
2213: #else
2214: void MathMLGetDTDName (DTDname, elementName)
2215: char* DTDname;
2216: char *elementName;
2217:
2218: #endif
2219: {
2220: /* no other DTD allowed within MathML elements */
2221: strcpy (DTDname, "");
2222: }
2223:
2224: /* end of module */
Webmaster