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