Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.4
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'},
135: {"lt", 62, 'L'},
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},
198: {"merror", SPACE, MathML_EL_MERROR},
199: {"mf", SPACE, MathML_EL_MF}, /* for compatibility with an old version of
200: MathML: WD-math-970704 */
201: {"mfenced", SPACE, MathML_EL_MFENCED},
202: {"mfrac", SPACE, MathML_EL_MFRAC},
203: {"mi", SPACE, MathML_EL_MI},
204: {"mmultiscripts", SPACE, MathML_EL_MMULTISCRIPTS},
205: {"mn", SPACE, MathML_EL_MN},
206: {"mo", SPACE, MathML_EL_MO},
207: {"mover", SPACE, MathML_EL_MOVER},
208: {"mpadded", SPACE, MathML_EL_MPADDED},
209: {"mphantom", SPACE, MathML_EL_MPHANTOM},
210: {"mprescripts", SPACE, MathML_EL_PrescriptPairs},
211: {"mroot", SPACE, MathML_EL_MROOT},
212: {"mrow", SPACE, MathML_EL_MROW},
213: {"ms", SPACE, MathML_EL_MS},
214: {"mspace", 'E', MathML_EL_MSPACE},
215: {"msqrt", SPACE, MathML_EL_MSQRT},
216: {"mstyle", SPACE, MathML_EL_MSTYLE},
217: {"msub", SPACE, MathML_EL_MSUB},
218: {"msubsup", SPACE, MathML_EL_MSUBSUP},
219: {"msup", SPACE, MathML_EL_MSUP},
220: {"mtext", SPACE, MathML_EL_MTEXT},
221: {"munder", SPACE, MathML_EL_MUNDER},
222: {"munderover", SPACE, MathML_EL_MUNDEROVER},
223: {"none", SPACE, MathML_EL_Construct},
224: {"sep", 'E', MathML_EL_SEP},
225: {"", SPACE, 0} /* Last entry. Mandatory */
226: };
227:
228: static AttributeMapping MathMLAttributeMappingTable[] =
229: {
230: /* The first entry MUST be unknown_attr */
231: /* The rest of this table MUST be in alphabetical order */
232: {"unknown_attr", "", 'A', MathML_ATTR_Invalid_attribute},
233: {"ZZGHOST", "", 'A', MathML_ATTR_Ghost_restruct},
234:
235: {"close", "mfenced", 'A', MathML_ATTR_close},
236: {"fence", "mo", 'A', MathML_ATTR_fence},
237: {"fontstyle", "mi", 'A', MathML_ATTR_fontstyle},
238: {"open", "mfenced", 'A', MathML_ATTR_open},
239: {"separators", "mfenced", 'A', MathML_ATTR_separators},
240:
241: {"", "", EOS, 0} /* Last entry. Mandatory */
242: };
243:
244: /* mapping table of attribute values */
245:
246: static AttrValueMapping MathMLAttrValueMappingTable[] =
247: {
248: {MathML_ATTR_fence, "true", MathML_ATTR_fence_VAL_true},
249: {MathML_ATTR_fence, "false", MathML_ATTR_fence_VAL_false},
250: {MathML_ATTR_fontstyle, "italic", MathML_ATTR_fontstyle_VAL_italic},
251: {MathML_ATTR_fontstyle, "normal", MathML_ATTR_fontstyle_VAL_normal},
252:
253: {0, "", 0} /* Last entry. Mandatory */
254: };
255:
256: #define MaxMsgLength 200
257:
258: /*----------------------------------------------------------------------
1.2 cvs 259: GetMathMLSSchema returns the MathML Thot schema for document doc.
1.1 cvs 260: ----------------------------------------------------------------------*/
261: #ifdef __STDC__
1.2 cvs 262: SSchema GetMathMLSSchema (Document doc)
1.1 cvs 263: #else
1.2 cvs 264: SSchema GetMathMLSSchema (doc)
1.1 cvs 265: Document doc;
266:
267: #endif
268: {
1.2 cvs 269: SSchema MathMLSSchema;
270:
271: MathMLSSchema = TtaGetSSchema ("MathML", doc);
1.1 cvs 272: if (MathMLSSchema == NULL)
273: MathMLSSchema = TtaNewNature(TtaGetDocumentSSchema(doc), "MathML", "MathMLP");
1.2 cvs 274: return (MathMLSSchema);
1.1 cvs 275: }
276:
277:
278: /*----------------------------------------------------------------------
279: MapMathMLElementType
280: search in the mapping tables the entry for the element type of
281: name XMLname and returns the corresponding Thot element type.
282: Returns -1 and schema = NULL if not found.
283: ----------------------------------------------------------------------*/
284: #ifdef __STDC__
1.2 cvs 285: void MapMathMLElementType (char *XMLname, ElementType *elType, char** mappedName, char* content, Document doc)
1.1 cvs 286: #else
1.2 cvs 287: void MapMathMLElementType (XMLname, elType, mappedName, content, doc)
1.1 cvs 288: char *XMLname;
289: ElementType *elType;
290: unsigned char **mappedName;
291: char *content;
1.2 cvs 292: Document doc;
1.1 cvs 293: #endif
294: {
295: int i;
296:
297: elType->ElTypeNum = 0;
298: /* search in MathMLElemMappingTable */
299: i = 0;
300: do
301: if (strcasecmp (MathMLElemMappingTable[i].XMLname, XMLname))
302: i++;
303: else
304: {
305: elType->ElTypeNum = MathMLElemMappingTable[i].ThotType;
1.3 cvs 306: if (elType->ElSSchema == NULL)
307: elType->ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 308: *mappedName = MathMLElemMappingTable[i].XMLname;
309: *content = MathMLElemMappingTable[i].XMLcontents;
310: }
311: while (elType->ElTypeNum <= 0 && MathMLElemMappingTable[i].XMLname[0] != EOS);
312: }
313:
314: /*----------------------------------------------------------------------
315: GetMathMLElementName
316: search in the mapping tables the XML name for a given Thot type
317: ----------------------------------------------------------------------*/
318: #ifdef __STDC__
319: void GetMathMLElementName (ElementType elType, char **buffer)
320: #else
321: void GetMathMLElementName (elType, buffer)
322: ElementType elType;
323: char* buffer;
324:
325: #endif
326: {
327: int i;
328:
329: if (elType.ElTypeNum > 0)
330: {
331: i = 0;
332: if (strcmp ("MathML", TtaGetSSchemaName (elType.ElSSchema)) == 0)
333: do
334: {
335: if (MathMLElemMappingTable[i].ThotType == elType.ElTypeNum)
336: {
337: *buffer = (char *) MathMLElemMappingTable[i].XMLname;
338: return;
339: }
340: i++;
341: }
342: while (MathMLElemMappingTable[i].XMLname[0] != EOS);
343: }
344: *buffer = "???";
345: return;
346: }
347:
348: /*----------------------------------------------------------------------
349: MapMathMLAttribute
350: Search in the Attribute Mapping Table the entry for the
351: attribute of name Attr and returns the corresponding Thot attribute type.
352: ----------------------------------------------------------------------*/
353: #ifdef __STDC__
1.2 cvs 354: void MapMathMLAttribute (char *Attr, AttributeType *attrType, char* elementName, Document doc)
1.1 cvs 355: #else
1.2 cvs 356: void MapMathMLAttribute (Attr, attrType, elementName, doc)
1.1 cvs 357: char *Attr;
358: AttributeType *attrType;
359: char *elementName;
1.2 cvs 360: Document doc;
1.1 cvs 361: #endif
362: {
363: int i;
364:
365: attrType->AttrTypeNum = 0;
366: attrType->AttrSSchema = NULL;
367: i = 0;
368: do
369: if (strcasecmp (MathMLAttributeMappingTable[i].XMLattribute, Attr))
370: i++;
371: else
372: if (MathMLAttributeMappingTable[i].XMLelement[0] == EOS)
373: {
374: attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
1.2 cvs 375: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 376: }
377: else if (!strcasecmp (MathMLAttributeMappingTable[i].XMLelement,
378: elementName))
379: {
380: attrType->AttrTypeNum = MathMLAttributeMappingTable[i].ThotAttribute;
1.2 cvs 381: attrType->AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 382: }
383: else
384: i++;
385: while (attrType->AttrTypeNum <= 0 && MathMLAttributeMappingTable[i].AttrOrContent != EOS);
386: }
387:
388: /*----------------------------------------------------------------------
389: MapMathMLAttributeValue
390: Search in the Attribute Value Mapping Table the entry for the attribute
391: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
392: ----------------------------------------------------------------------*/
393: #ifdef __STDC__
394: void MapMathMLAttributeValue (char *AttrVal, AttributeType attrType, int *value)
395: #else
396: void MapMathMLAttributeValue (AttrVal, attrType, value)
397: char *AttrVal;
398: AttributeType attrType;
399: int *value;
400: #endif
401: {
402: int i;
403:
404: *value = 0;
405: i = 0;
406: while (MathMLAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
407: MathMLAttrValueMappingTable[i].ThotAttr != 0)
408: i++;
409: if (MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
410: do
411: if (!strcasecmp (MathMLAttrValueMappingTable[i].XMLattrValue, AttrVal))
412: *value = MathMLAttrValueMappingTable[i].ThotAttrValue;
413: else
414: i++;
415: while (*value <= 0 && MathMLAttrValueMappingTable[i].ThotAttr != 0);
416: }
417:
418: /*----------------------------------------------------------------------
419: MapMathMLEntity
420: Search that entity in the entity table and return the corresponding value.
421: ----------------------------------------------------------------------*/
422: #ifdef __STDC__
423: void MapMathMLEntity (char *entityName, char *entityValue, int valueLength, char *alphabet)
424: #else
425: void MapMathMLEntity (entityName, entityValue, valueLength, alphabet)
426: char *entityName;
427: char *entityValue;
428: int valueLength;
429: char *alphabet;
430:
431: #endif
432:
433: {
434: int i;
435:
436: for (i = 0; MathEntityTable[i].charCode >= 0 &&
437: strcmp (MathEntityTable[i].MentityName, entityName);
438: i++);
439: if (!strcmp (MathEntityTable[i].MentityName, entityName))
440: /* entity found */
441: {
442: entityValue[0] = (unsigned char) MathEntityTable[i].charCode;
443: entityValue[1] = EOS;
444: *alphabet = MathEntityTable[i].alphabet;
445: }
446: else
447: {
448: entityValue[0] = EOS;
449: *alphabet = EOS;
450: }
451: }
452:
453: /*----------------------------------------------------------------------
454: MathMLEntityCreated
455: A MathML entity has been created by the XML parser.
456: Create a text element containing the entity name.
457: ----------------------------------------------------------------------*/
458: #ifdef __STDC__
459: void MathMLEntityCreated (unsigned char *entityValue, char *entityName, Document doc)
460: #else
461: void MathMLEntityCreated (entityValue, entityName, doc)
462: unsigned char *entityValue;
463: char *entityName;
464: Document doc;
465:
466: #endif
467: {
468: ElementType elType;
469: Element elText;
470: AttributeType attrType;
471: Attribute attr;
472: Language lang;
473: int len;
474: #define MAX_ENTITY_LENGTH 80
475: char buffer[MAX_ENTITY_LENGTH];
476:
477: if (strlen (entityValue) <= 1)
478: if (entityValue[0] == EOS || entityValue[0] == SPACE ||
479: ((int)entityValue[0]) == 129 || /* thin space */
480: ((int)entityValue[0]) == 130 || /* en space */
481: ((int)entityValue[0]) == 160) /* sticky space */
482: /* null character or space */
483: /* create a text element containing the entity name with an
484: attribute entity */
485: {
486: XMLTextToDocument ();
487: len = strlen (entityName);
488: if (len > MAX_ENTITY_LENGTH -3)
489: len = MAX_ENTITY_LENGTH -3;
490: buffer[0] = '&';
491: strncpy (&buffer[1], entityName, len);
492: buffer[len+1] = ';';
493: buffer[len+2] = EOS;
494: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1.2 cvs 495: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 496: elText = TtaNewElement (doc, elType);
497: XMLInsertElement (elText);
498: lang = TtaGetLanguageIdFromAlphabet('L');
499: TtaSetTextContent (elText, buffer, lang, doc);
1.2 cvs 500: attrType.AttrSSchema = GetMathMLSSchema (doc);
1.1 cvs 501: attrType.AttrTypeNum = MathML_ATTR_entity;
502: attr = TtaNewAttribute (attrType);
503: TtaAttachAttribute (elText, attr, doc);
504: TtaSetAttributeValue (attr, MathML_ATTR_entity_VAL_yes_, elText, doc);
505: }
506: }
507:
508: /*----------------------------------------------------------------------
509: CheckTextElement Put the content of input buffer into the document.
510: ----------------------------------------------------------------------*/
511: #ifdef __STDC__
512: static void CheckTextElement (Element *el, Document doc)
513: #else
514: static void CheckTextElement (el, doc)
515: Element *el;
516: Document doc;
517:
518: #endif
519: {
520: ElementType parentType, elType;
521: Element parent, new;
522: int len;
523: Language lang;
524: char alphabet;
525: char text[4];
526:
527: len = TtaGetTextLength (*el);
528: if (len == 1)
529: {
530: len = 2;
531: TtaGiveTextContent (*el, text, &len, &lang);
532: alphabet = TtaGetAlphabet (lang);
533: parent = TtaGetParent (*el);
534: if (text[0] != EOS)
535: {
536: parentType = TtaGetElementType (parent);
537: elType = parentType;
538: if (parentType.ElTypeNum == MathML_EL_MF &&
539: (text[0] == '(' ||
540: text[0] == ')' ||
541: text[0] == '[' ||
542: text[0] == ']' ||
543: text[0] == '{' ||
544: text[0] == '}'))
545: /* Transform the text element into a Thot SYMBOL */
546: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
547: else if (parentType.ElTypeNum == MathML_EL_MF &&
548: text[0] == '|')
549: /* Transform the text element into a Thot GRAPHIC */
550: {
551: elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
552: text[0] = 'v';
553: }
554: else
555: /* a TEXT element is OK */
556: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
557: if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
558: {
559: new = TtaNewElement (doc, elType);
560: TtaInsertSibling (new, *el, FALSE, doc);
561: TtaDeleteTree (*el, doc);
562: *el = new;
563: TtaSetGraphicsShape (new, text[0], doc);
564: }
565: }
566: }
567: }
568:
569: /*----------------------------------------------------------------------
570: ElementNeedsPlaceholder
571: returns TRUE if element el needs a sibling placeholder.
572: ----------------------------------------------------------------------*/
573: #ifdef __STDC__
574: boolean ElementNeedsPlaceholder (Element el)
575: #else
576: boolean ElementNeedsPlaceholder (el)
577: Element el;
578:
579: #endif
580: {
581: ElementType elType;
582: Element child, parent;
583: boolean ret;
584:
585: ret = FALSE;
586: elType = TtaGetElementType (el);
587: if (elType.ElTypeNum == MathML_EL_MROW ||
588: elType.ElTypeNum == MathML_EL_MF ||
589: elType.ElTypeNum == MathML_EL_MFENCED ||
590: elType.ElTypeNum == MathML_EL_MROOT ||
591: elType.ElTypeNum == MathML_EL_MSQRT ||
592: elType.ElTypeNum == MathML_EL_MFRAC ||
593: elType.ElTypeNum == MathML_EL_MSUBSUP ||
594: elType.ElTypeNum == MathML_EL_MSUB ||
595: elType.ElTypeNum == MathML_EL_MSUP ||
596: elType.ElTypeNum == MathML_EL_MUNDER ||
597: elType.ElTypeNum == MathML_EL_MOVER ||
598: elType.ElTypeNum == MathML_EL_MUNDEROVER ||
599: elType.ElTypeNum == MathML_EL_MMULTISCRIPTS)
600: ret = TRUE;
601: else
602: if (elType.ElTypeNum == MathML_EL_MO)
603: /* an operator that contains a single Symbol needs a placeholder,
604: except when it is in a Base or UnderOverBase */
605: {
606: child = TtaGetFirstChild (el);
607: if (child != NULL)
608: {
609: elType = TtaGetElementType (child);
610: if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
611: {
612: ret = TRUE;
613: parent = TtaGetParent (el);
614: if (parent != NULL)
615: {
616: elType = TtaGetElementType (parent);
617: if (elType.ElTypeNum == MathML_EL_Base ||
618: elType.ElTypeNum == MathML_EL_UnderOverBase)
619: ret = FALSE;
620: }
621: }
622: }
623: }
624: return ret;
625: }
626:
627: /*----------------------------------------------------------------------
628: CreatePlaceholders
629: ----------------------------------------------------------------------*/
630: #ifdef __STDC__
631: static void CreatePlaceholders (Element el, Document doc)
632: #else
633: static void CreatePlaceholders (el, doc)
634: Element el;
635: Document doc;
636: #endif
637: {
638: Element sibling, prev, constr, child;
639: Attribute attr;
640: ElementType elType;
641: AttributeType attrType;
642: boolean create;
643:
1.2 cvs 644: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 645: prev = NULL;
646: create = TRUE;
647: sibling = el;
648: while (sibling != NULL)
649: {
650: if (!ElementNeedsPlaceholder (sibling))
651: create = FALSE;
652: else
653: {
654: if (sibling == el)
655: /* first element */
656: {
657: elType = TtaGetElementType (sibling);
658: if (elType.ElTypeNum == MathML_EL_MF)
659: /* the first element is a MF. Don't create a placeholder
660: before */
661: create = FALSE;
662: else if (elType.ElTypeNum == MathML_EL_MROW)
663: /* the first element is a MROW */
664: {
665: child = TtaGetFirstChild (sibling);
666: if (child != NULL)
667: {
668: elType = TtaGetElementType (child);
669: if (elType.ElTypeNum != MathML_EL_MF)
670: /* the first child of the MROW element is not a MF */
671: /* Don't create a placeholder before */
672: create = FALSE;
673: }
674: }
675: }
676: if (create)
677: {
678: elType.ElTypeNum = MathML_EL_Construct;
679: constr = TtaNewElement (doc, elType);
680: TtaInsertSibling (constr, sibling, TRUE, doc);
681: attrType.AttrSSchema = elType.ElSSchema;
682: attrType.AttrTypeNum = MathML_ATTR_placeholder;
683: attr = TtaNewAttribute (attrType);
684: TtaAttachAttribute (constr, attr, doc);
685: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, constr, doc);
686: }
687: create = TRUE;
688: }
689: prev = sibling;
690: TtaNextSibling (&sibling);
691: }
692: if (prev != NULL && create)
693: {
694: elType = TtaGetElementType (prev);
695: /* don't insert a placeholder after the last element if it's a MF
696: or a SEP */
697: if (elType.ElTypeNum == MathML_EL_MF ||
698: elType.ElTypeNum == MathML_EL_SEP)
699: create = FALSE;
700: else if (elType.ElTypeNum == MathML_EL_MROW)
701: /* the last element is a MROW */
702: {
703: child = TtaGetLastChild (prev);
704: if (child != NULL)
705: {
706: elType = TtaGetElementType (child);
707: if (elType.ElTypeNum != MathML_EL_MF)
708: /* the last child of the MROW element is not a MF */
709: /* Don't create a placeholder before */
710: create = FALSE;
711: }
712: }
713: if (create)
714: {
715: elType.ElTypeNum = MathML_EL_Construct;
716: constr = TtaNewElement (doc, elType);
717: TtaInsertSibling (constr, prev, FALSE, doc);
718: attrType.AttrSSchema = elType.ElSSchema;
719: attrType.AttrTypeNum = MathML_ATTR_placeholder;
720: attr = TtaNewAttribute (attrType);
721: TtaAttachAttribute (constr, attr, doc);
722: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, constr, doc);
723: }
724: }
725: }
726:
727: /*----------------------------------------------------------------------
728: NextNotSep
729: Return the next sibling of element el that is not a SEP element
730: Return el itself if it's not a SEP
731: ----------------------------------------------------------------------*/
732: #ifdef __STDC__
733: static void NextNotSep (Element* el, Element* prev)
734: #else
735: static void NextNotSep (el, prev)
736: Element *el;
737: #endif
738: {
739: ElementType elType;
740:
741: if (*el == NULL)
742: return;
743: elType = TtaGetElementType (*el);
744: while (*el != NULL && elType.ElTypeNum == MathML_EL_SEP)
745: {
746: *prev = *el;
747: TtaNextSibling (el);
748: if (*el != NULL)
749: elType = TtaGetElementType (*el);
750: }
751: }
752:
753: /*----------------------------------------------------------------------
754: CheckMathSubExpressions
755: Children of element el should be of type type1, type2, and type3.
756: Create an element of that type.
757: ----------------------------------------------------------------------*/
758: #ifdef __STDC__
759: static void CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
760: #else
761: static void CheckMathSubExpressions (el, type1, type2, type3, doc)
762: Element el;
763: int type1;
764: int type2;
765: int type3;
766: Document doc;
767: #endif
768: {
769: Element child, new, prev;
770: ElementType elType, childType;
771:
1.2 cvs 772: elType.ElSSchema = GetMathMLSSchema (doc);
1.1 cvs 773: child = TtaGetFirstChild (el);
774: prev = NULL;
775: NextNotSep (&child, &prev);
776: if (child != NULL && type1 != 0)
777: {
778: elType.ElTypeNum = type1;
779: childType = TtaGetElementType (child);
780: if (TtaSameTypes (childType, elType) == 0)
781: {
782: TtaRemoveTree (child, doc);
783: new = TtaNewElement (doc, elType);
784: if (prev == NULL)
785: TtaInsertFirstChild (&new, el, doc);
786: else
787: TtaInsertSibling (new, prev, FALSE, doc);
788: TtaInsertFirstChild (&child, new, doc);
789: CreatePlaceholders (child, doc);
790: child = new;
791: }
792: if (type2 != 0)
793: {
794: prev = child;
795: TtaNextSibling (&child);
796: NextNotSep (&child, &prev);
797: if (child != NULL)
798: {
799: elType.ElTypeNum = type2;
800: childType = TtaGetElementType (child);
801: if (TtaSameTypes (childType, elType) == 0)
802: {
803: TtaRemoveTree (child, doc);
804: new = TtaNewElement (doc, elType);
805: TtaInsertSibling (new, prev, FALSE, doc);
806: TtaInsertFirstChild (&child, new, doc);
807: CreatePlaceholders (child, doc);
808: child = new;
809: }
810: if (type3 != 0)
811: {
812: prev = child;
813: TtaNextSibling (&child);
814: NextNotSep (&child, &prev);
815: if (child != NULL)
816: {
817: elType.ElTypeNum = type3;
818: childType = TtaGetElementType (child);
819: if (TtaSameTypes (childType, elType) == 0)
820: {
821: TtaRemoveTree (child, doc);
822: new = TtaNewElement (doc, elType);
823: TtaInsertSibling (new, prev, FALSE, doc);
824: TtaInsertFirstChild (&child, new, doc);
825: CreatePlaceholders (child, doc);
826: }
827: }
828: }
829: }
830: }
831: }
832: }
833:
834:
835: /*----------------------------------------------------------------------
836: SetSingleHorizStretchAttr
837:
838: Put a horizstretch attribute on element el if it contains only
839: a MO element that is a stretchable symbol.
840: -----------------------------------------------------------------------*/
841: #ifdef __STDC__
842: void SetSingleHorizStretchAttr (Element el, Document doc, Element* selEl)
843: #else /* __STDC__*/
844: void SetSingleHorizStretchAttr (el, doc, selEl)
845: Element el;
846: Document doc;
847: Element* selEl;
848: #endif /* __STDC__*/
849: {
850: Element child, sibling, textEl, symbolEl;
851: ElementType elType;
852: Attribute attr;
853: AttributeType attrType;
854: int len;
855: Language lang;
856: char alphabet;
857: unsigned char text[2], c;
858:
859: if (el == NULL)
860: return;
861: child = TtaGetFirstChild (el);
862: if (child != NULL)
863: {
864: elType = TtaGetElementType (child);
865: if (elType.ElTypeNum == MathML_EL_MO)
866: /* the first child is a MO */
867: {
868: sibling = child;
869: TtaNextSibling (&sibling);
870: if (sibling == NULL)
871: /* there is no other child */
872: {
873: textEl = TtaGetFirstChild (child);
874: elType = TtaGetElementType (textEl);
875: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
876: {
877: len = TtaGetTextLength (textEl);
878: if (len == 1)
879: {
880: len = 2;
881: TtaGiveTextContent (textEl, text, &len, &lang);
882: alphabet = TtaGetAlphabet (lang);
883: if (len == 1)
884: if (alphabet == 'G')
885: /* a single Symbol character */
886: if ((int)text[0] == 172 || (int)text[0] == 174)
887: /* horizontal arrow */
888: {
889: /* attach a horizstretch attribute */
890: attrType.AttrSSchema = elType.ElSSchema;
891: attrType.AttrTypeNum = MathML_ATTR_horizstretch;
892: attr = TtaNewAttribute (attrType);
893: TtaAttachAttribute (el, attr, doc);
894: TtaSetAttributeValue (attr, MathML_ATTR_horizstretch_VAL_yes_, el, doc);
895: /* replace the TEXT element by a Thot SYMBOL element */
896: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
897: symbolEl = TtaNewElement (doc, elType);
898: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
899: if (selEl != NULL)
900: if (*selEl == textEl)
901: *selEl = symbolEl;
902: TtaDeleteTree (textEl, doc);
903: if ((int)text[0] == 172)
904: c = '<';
905: if ((int)text[0] == 174)
906: c = '>';
907: TtaSetGraphicsShape (symbolEl, c, doc);
908: }
909: }
910: }
911: }
912: }
913: }
914: }
915:
916: /*----------------------------------------------------------------------
917: SetHorizStretchAttr
918:
919: Put a horizstretch attribute on all children of element el which
920: contain only a MO element that is a stretchable symbol.
921: -----------------------------------------------------------------------*/
922: #ifdef __STDC__
923: static void SetHorizStretchAttr (Element el, Document doc)
924: #else /* __STDC__*/
925: static void SetHorizStretchAttr (el, doc)
926: Element el;
927: Document doc;
928: #endif /* __STDC__*/
929: {
930: Element child;
931:
932: if (el == NULL)
933: return;
934: child = TtaGetFirstChild (el);
935: while (child != NULL)
936: {
937: SetSingleHorizStretchAttr (child, doc, NULL);
938: TtaNextSibling (&child);
939: }
940: }
941:
942: /*----------------------------------------------------------------------
943: SetVertStretchAttr
944:
945: Put a vertstretch attribute on element el if its base element
946: (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
947: a MUNDER of a MOVER) contains only a MO element that is a vertically
948: stretchable symbol.
949: -----------------------------------------------------------------------*/
950: #ifdef __STDC__
951: void SetVertStretchAttr (Element el, Document doc, int base, Element* selEl)
952: #else /* __STDC__*/
953: void SetVertStretchAttr (el, doc, base, selEl)
954: Element el;
955: Document doc;
956: int base;
957: Element* selEl;
958: #endif /* __STDC__*/
959: {
960: Element child, sibling, textEl, symbolEl, parent, operator;
961: ElementType elType;
962: Attribute attr;
963: AttributeType attrType;
964: int len;
965: Language lang;
966: char alphabet;
967: unsigned char text[2], c;
968:
969: if (el == NULL)
970: return;
971: operator = NULL;
972: if (base == 0)
973: /* it's a MO */
974: {
975: parent = TtaGetParent (el);
976: if (parent != NULL)
977: {
978: elType = TtaGetElementType (parent);
979: if (elType.ElTypeNum != MathML_EL_Base &&
980: elType.ElTypeNum != MathML_EL_UnderOverBase &&
981: elType.ElTypeNum != MathML_EL_MSUBSUP &&
982: elType.ElTypeNum != MathML_EL_MSUB &&
983: elType.ElTypeNum != MathML_EL_MSUP &&
984: elType.ElTypeNum != MathML_EL_MUNDEROVER &&
985: elType.ElTypeNum != MathML_EL_MUNDER &&
986: elType.ElTypeNum != MathML_EL_MUNDEROVER)
987: operator = el;
988: }
989: }
990: else
991: /* it's not a MO */
992: {
993: /* search the Base or UnderOverBase child */
994: child = TtaGetFirstChild (el);
995: if (child != NULL)
996: {
997: elType = TtaGetElementType (child);
998: if (elType.ElTypeNum == base)
999: /* the first child is a Base or UnderOverBase */
1000: {
1001: child = TtaGetFirstChild (child);
1002: if (child != NULL)
1003: {
1004: elType = TtaGetElementType (child);
1005: if (elType.ElTypeNum == MathML_EL_MO)
1006: /* its first child is a MO */
1007: {
1008: sibling = child;
1009: TtaNextSibling (&sibling);
1010: if (sibling == NULL)
1011: /* there is no other child */
1012: operator = child;
1013: }
1014: }
1015: }
1016: }
1017: }
1018: if (operator != NULL)
1019: {
1020: textEl = TtaGetFirstChild (operator);
1021: if (textEl != NULL)
1022: {
1023: elType = TtaGetElementType (textEl);
1024: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1025: {
1026: len = TtaGetTextLength (textEl);
1027: if (len == 1)
1028: {
1029: len = 2;
1030: TtaGiveTextContent (textEl, text, &len, &lang);
1031: alphabet = TtaGetAlphabet (lang);
1032: if (len == 1)
1033: if (alphabet == 'G')
1034: /* a single Symbol character */
1035: if ((int)text[0] == 242)
1036: /* Integral */
1037: {
1038: /* attach a vertstretch attribute */
1039: attrType.AttrSSchema = elType.ElSSchema;
1040: attrType.AttrTypeNum = MathML_ATTR_vertstretch;
1041: attr = TtaNewAttribute (attrType);
1042: TtaAttachAttribute (el, attr, doc);
1043: TtaSetAttributeValue (attr, MathML_ATTR_vertstretch_VAL_yes_, el, doc);
1044: /* replace the TEXT element by a Thot SYMBOL element*/
1045: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1046: symbolEl = TtaNewElement (doc, elType);
1047: TtaInsertSibling (symbolEl, textEl, FALSE, doc);
1048: if (selEl != NULL)
1049: if (*selEl == textEl)
1050: *selEl = symbolEl;
1051: TtaDeleteTree (textEl, doc);
1052: c = 'i';
1053: TtaSetGraphicsShape (symbolEl, c, doc);
1054: }
1055: }
1056: }
1057: }
1058: }
1059: }
1060:
1061: /*----------------------------------------------------------------------
1062: SetPlaceholderAttr
1063:
1064: Put a placeholder attribute on all Construct elements in the
1065: subtree of root el.
1066: -----------------------------------------------------------------------*/
1067: #ifdef __STDC__
1068: static void SetPlaceholderAttr (Element el, Document doc)
1069: #else /* __STDC__*/
1070: static void SetPlaceholderAttr (el, doc)
1071: Element el;
1072: Document doc;
1073: #endif /* __STDC__*/
1074: {
1075: Element child;
1076: ElementType elType;
1077: Attribute attr;
1078: AttributeType attrType;
1079:
1080: if (el == NULL)
1081: return;
1082: elType = TtaGetElementType (el);
1083: if (elType.ElTypeNum == MathML_EL_Construct &&
1.2 cvs 1084: elType.ElSSchema == GetMathMLSSchema (doc))
1.1 cvs 1085: {
1086: attrType.AttrSSchema = elType.ElSSchema;
1087: attrType.AttrTypeNum = MathML_ATTR_placeholder;
1088: attr = TtaNewAttribute (attrType);
1089: TtaAttachAttribute (el, attr, doc);
1090: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, el, doc);
1091: }
1092: else
1093: {
1094: child = TtaGetFirstChild (el);
1095: while (child != NULL)
1096: {
1097: SetPlaceholderAttr (child, doc);
1098: TtaNextSibling (&child);
1099: }
1100: }
1101: }
1102:
1103: /*----------------------------------------------------------------------
1104: BuildMultiscript
1105:
1106: The content of a MMULTISCRIPT element has been created following
1107: the original MathML structure. Create all Thot elements defined
1108: in the MathML S schema.
1109: -----------------------------------------------------------------------*/
1110: #ifdef __STDC__
1111: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
1112: #else /* __STDC__*/
1113: static void BuildMultiscript (elMMULTISCRIPT, doc)
1114: Element elMMULTISCRIPT;
1115: Document doc;
1116: #endif /* __STDC__*/
1117: {
1118: Element elem, base, next, group, pair, script, prevPair, prevScript;
1119: ElementType elType, elTypeGroup, elTypePair, elTypeScript;
1.2 cvs 1120: SSchema MathMLSSchema;
1.1 cvs 1121: base = NULL;
1122: group = NULL;
1123: prevPair = NULL;
1124: prevScript = NULL;
1125:
1.2 cvs 1126: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 1127: elTypeGroup.ElSSchema = MathMLSSchema;
1128: elTypePair.ElSSchema = MathMLSSchema;
1129: elTypeScript.ElSSchema = MathMLSSchema;
1130:
1131: /* process all children of the MMULTISCRIPT element */
1132: elem = TtaGetFirstChild (elMMULTISCRIPT);
1133: while (elem != NULL)
1134: {
1135: /* remember the element to be processed after the current one */
1136: next = elem;
1137: TtaNextSibling (&next);
1138:
1139: /* remove the current element from the tree */
1140: TtaRemoveTree (elem, doc);
1141:
1142: if (base == NULL)
1143: /* the current element is the first child of the MMULTISCRIPT
1144: element */
1145: {
1146: /* Create a MultiscriptBase element as the first child of
1147: MMULTISCRIPT and move the current element as the first child
1148: of the MultiscriptBase element */
1149: elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
1150: base = TtaNewElement (doc, elTypeGroup);
1151: TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
1152: TtaInsertFirstChild (&elem, base, doc);
1153: }
1154: else
1155: /* the current element is a subscript or a superscript */
1156: {
1157: if (group == NULL)
1158: /* there is no PostscriptPairs element. Create one */
1159: {
1160: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1161: group = TtaNewElement (doc, elTypeGroup);
1162: TtaInsertSibling (group, base, FALSE, doc);
1163: elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
1164: /* create a first and a last PostscriptPair as placeholders */
1165: pair = TtaNewTree (doc, elTypePair, "");
1166: TtaInsertFirstChild (&pair, group, doc);
1167: SetPlaceholderAttr (pair, doc);
1168: prevPair = pair;
1169: pair = TtaNewTree (doc, elTypePair, "");
1170: TtaInsertSibling (pair, prevPair, FALSE, doc);
1171: SetPlaceholderAttr (pair, doc);
1172: prevScript = NULL;
1173: }
1174: if (prevScript == NULL)
1175: /* the current element is the first subscript or superscript
1176: in a pair */
1177: {
1178: /* create a PostscriptPair or PrescriptPair element */
1179: pair = TtaNewElement (doc, elTypePair);
1180: if (prevPair == NULL)
1181: TtaInsertFirstChild (&pair, group, doc);
1182: else
1183: TtaInsertSibling (pair, prevPair, FALSE, doc);
1184: prevPair = pair;
1185: /* create a MSubscript element */
1186: elTypeScript.ElTypeNum = MathML_EL_MSubscript;
1187: script = TtaNewElement (doc, elTypeScript);
1188: TtaInsertFirstChild (&script, pair, doc);
1189: prevScript = script;
1190: }
1191: else
1192: /* the current element is a superscript in a pair */
1193: {
1194: /* create a MSuperscript element */
1195: elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
1196: script = TtaNewElement (doc, elTypeScript);
1197: /* insert it as a sibling of the previous MSubscript element */
1198: TtaInsertSibling (script, prevScript, FALSE, doc);
1199: prevScript = NULL;
1200: }
1201: /* insert the current element as a child of the new MSuperscript or
1202: MSubscript element */
1203: TtaInsertFirstChild (&elem, script, doc);
1204: SetPlaceholderAttr (elem, doc);
1205: }
1206:
1207: CreatePlaceholders (elem, doc);
1208:
1209: /* get next child of the MMULTISCRIPT element */
1210: elem = next;
1211: if (elem != NULL)
1212: {
1213: elType = TtaGetElementType (elem);
1214: if (elType.ElSSchema == MathMLSSchema &&
1215: elType.ElTypeNum == MathML_EL_PrescriptPairs)
1216: /* the next element is a PrescriptPairs */
1217: {
1218: /* if there there is no PostscriptPairs element, create one as a
1219: placeholder */
1220: if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
1221: {
1222: elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1223: group = TtaNewTree (doc, elTypeGroup, "");
1224: TtaInsertSibling (group, elem, TRUE, doc);
1225: SetPlaceholderAttr (group, doc);
1226: }
1227: /* the following elements will be interpreted as sub- superscripts
1228: in PrescriptPair elements, wich will be children of this
1229: PrescriptPairs element */
1230: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1231: elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
1232: group = elem;
1233: /* create a first and a last PostscriptPair as placeholders */
1234: pair = TtaNewTree (doc, elTypePair, "");
1235: TtaInsertFirstChild (&pair, group, doc);
1236: SetPlaceholderAttr (pair, doc);
1237: prevPair = pair;
1238: pair = TtaNewTree (doc, elTypePair, "");
1239: TtaInsertSibling (pair, prevPair, FALSE, doc);
1240: SetPlaceholderAttr (pair, doc);
1241: prevScript = NULL;
1242: TtaNextSibling (&elem);
1243: }
1244: }
1245: }
1246: /* all children of element MMULTISCRIPTS have been processed */
1247: /* if the last group processed is not a PrescriptPairs element,
1248: create one as a placeholder */
1249: if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
1250: {
1251: elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1252: elem = TtaNewTree (doc, elTypeGroup, "");
1253: if (group == NULL)
1254: group = base;
1255: TtaInsertSibling (elem, group, TRUE, doc);
1256: SetPlaceholderAttr (elem, doc);
1257: }
1258: }
1259:
1260:
1261: /*----------------------------------------------------------------------
1262: SetFontstyleAttr
1263: The content of a MI element has been created or modified.
1264: Create or change attribute IntFontstyle for that element accordingly.
1265: -----------------------------------------------------------------------*/
1266: #ifdef __STDC__
1267: void SetFontstyleAttr (Element el, Document doc)
1268: #else /* __STDC__*/
1269: void SetFontstyleAttr (el, doc)
1270: Element el;
1271: Document doc;
1272: #endif /* __STDC__*/
1273: {
1274: ElementType elType;
1275: AttributeType attrType;
1276: Attribute attr, IntAttr;
1277: int len;
1278:
1279: if (el != NULL)
1280: {
1281: /* search the fontstyle attribute */
1282: elType = TtaGetElementType (el);
1283: attrType.AttrSSchema = elType.ElSSchema;
1284: attrType.AttrTypeNum = MathML_ATTR_fontstyle;
1285: attr = TtaGetAttribute (el, attrType);
1286: attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
1287: IntAttr = TtaGetAttribute (el, attrType);
1288: if (attr != NULL)
1289: /* there is a fontstyle attribute. Remove the corresponding
1290: internal attribute that is not needed */
1291: {
1292: if (IntAttr != NULL)
1293: TtaRemoveAttribute (el, IntAttr, doc);
1294: }
1295: else
1296: /* there is no fontstyle attribute. Create an internal attribute
1297: IntFontstyle with a value that depends on the content of the MI */
1298: {
1299: /* get content length */
1300: len = TtaGetElementVolume (el);
1301: if (len > 1)
1302: /* put an attribute IntFontstyle = IntNormal */
1303: {
1304: if (IntAttr == NULL)
1305: {
1306: IntAttr = TtaNewAttribute (attrType);
1307: TtaAttachAttribute (el, IntAttr, doc);
1308: }
1309: TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
1310: el, doc);
1311: }
1312: else
1313: /* MI contains a single character. Remove attribute IntFontstyle
1314: if it exists */
1315: {
1316: if (IntAttr != NULL)
1317: TtaRemoveAttribute (el, IntAttr, doc);
1318: }
1319: }
1320: }
1321: }
1322:
1323: /*----------------------------------------------------------------------
1324: SetAddspaceAttr
1325: The content of a MO element has been created or modified.
1326: Create or change attribute addspace for that element accordingly.
1327: -----------------------------------------------------------------------*/
1328: #ifdef __STDC__
1329: void SetAddspaceAttr (Element el, Document doc)
1330: #else /* __STDC__*/
1331: void SetAddspaceAttr (el, doc)
1332: Element el;
1333: Document doc;
1334: #endif /* __STDC__*/
1335: {
1336: Element textEl, previous;
1337: ElementType elType;
1338: AttributeType attrType;
1339: Attribute attr;
1340: int len, val;
1341: #define BUFLEN 10
1342: unsigned char text[BUFLEN];
1343: Language lang;
1344: char alphabet;
1345:
1346: textEl = TtaGetFirstChild (el);
1347: if (textEl != NULL)
1348: {
1349: /* search the addspace attribute */
1350: elType = TtaGetElementType (el);
1351: attrType.AttrSSchema = elType.ElSSchema;
1352: attrType.AttrTypeNum = MathML_ATTR_addspace;
1353: attr = TtaGetAttribute (el, attrType);
1354: if (attr == NULL)
1355: {
1356: attr = TtaNewAttribute (attrType);
1357: TtaAttachAttribute (el, attr, doc);
1358: }
1359: val = MathML_ATTR_addspace_VAL_nospace;
1360: len = TtaGetTextLength (textEl);
1361: if (len > 0 && len < BUFLEN)
1362: {
1363: len = BUFLEN;
1364: TtaGiveTextContent (textEl, text, &len, &lang);
1365: alphabet = TtaGetAlphabet (lang);
1366: if (len == 1)
1367: if (alphabet == 'L')
1368: /* ISO-Latin 1 character */
1369: {
1370: if (text[0] == '-')
1371: /* unary or binary operator? */
1372: {
1373: previous = el;
1374: TtaPreviousSibling (&previous);
1375: if (previous == NULL)
1376: /* no previous sibling => unary operator */
1377: val = MathML_ATTR_addspace_VAL_nospace;
1378: else
1379: {
1380: elType = TtaGetElementType (previous);
1381: if (elType.ElTypeNum == MathML_EL_MO)
1382: /* after an operator => unary operator */
1383: val = MathML_ATTR_addspace_VAL_nospace;
1384: else
1385: /* binary operator */
1386: val = MathML_ATTR_addspace_VAL_both;
1387: }
1388: }
1389: else if (text[0] == '+' ||
1390: text[0] == '&' ||
1391: text[0] == '*' ||
1392: text[0] == '<' ||
1393: text[0] == '=' ||
1394: text[0] == '>' ||
1395: text[0] == '^')
1396: /* binary operator */
1397: val = MathML_ATTR_addspace_VAL_both;
1398: else if (text[0] == ',' ||
1399: text[0] == ';')
1400: val = MathML_ATTR_addspace_VAL_spaceafter;
1401: }
1402: else if (alphabet == 'G')
1403: /* Symbol character set */
1404: if ((int)text[0] == 163 || /* less or equal */
1405: (int)text[0] == 177 || /* plus or minus */
1406: (int)text[0] == 179 || /* greater or equal */
1407: (int)text[0] == 180 || /* times */
1408: (int)text[0] == 184 || /* divide */
1409: (int)text[0] == 185 || /* not equal */
1410: (int)text[0] == 186 || /* identical */
1411: (int)text[0] == 187 || /* equivalent */
1412: (int)text[0] == 196 || /* circle times */
1413: (int)text[0] == 197 || /* circle plus */
1414: ((int)text[0] >= 199 && (int)text[0] <= 209) || /* */
1415: (int)text[0] == 217 || /* and */
1416: (int)text[0] == 218 ) /* or */
1417: val = MathML_ATTR_addspace_VAL_both;
1418: }
1419: TtaSetAttributeValue (attr, val, el, doc);
1420: }
1421: }
1422:
1423:
1424: /*----------------------------------------------------------------------
1425: ChangeTypeOfElement
1426: Change the type of element elem into newTypeNum
1427: -----------------------------------------------------------------------*/
1428: #ifdef __STDC__
1429: void ChangeTypeOfElement (Element elem, Document doc, int newTypeNum)
1430: #else /* __STDC__*/
1431: void ChangeTypeOfElement (elem, doc, newTypeNum)
1432: Element elem;
1433: Document doc;
1434: int newTypeNum;
1435: #endif /* __STDC__*/
1436:
1437: {
1438: Element prev, next, parent;
1439:
1440: prev = elem;
1441: TtaPreviousSibling (&prev);
1442: if (prev == NULL)
1443: {
1444: next = elem;
1445: TtaNextSibling (&next);
1446: if (next == NULL)
1447: parent = TtaGetParent (elem);
1448: }
1449: TtaRemoveTree (elem, doc);
1450: ChangeElementType (elem, newTypeNum);
1451: if (prev != NULL)
1452: TtaInsertSibling (elem, prev, FALSE, doc);
1453: else if (next != NULL)
1454: TtaInsertSibling (elem, next, TRUE, doc);
1455: else
1456: TtaInsertFirstChild (&elem, parent, doc);
1457: }
1458:
1459:
1460: /*----------------------------------------------------------------------
1461: CheckFence
1462: If el is a MO element that contains a single fence character,
1463: transform the MO into a MF and the character into a Thot symbol.
1464: ----------------------------------------------------------------------*/
1465: #ifdef __STDC__
1466: void CheckFence (Element el, Document doc)
1467: #else
1468: void CheckFence (el, doc)
1469: Element el;
1470: Document doc;
1471:
1472: #endif
1473: {
1474: ElementType elType;
1475: Element content;
1476: AttributeType attrType;
1477: Attribute attr;
1478: int len;
1479: Language lang;
1480: char alphabet;
1481: unsigned char text[2], c;
1482:
1483: elType = TtaGetElementType (el);
1484: if (elType.ElTypeNum == MathML_EL_MO)
1485: {
1486: content = TtaGetFirstChild (el);
1487: if (content != NULL)
1488: {
1489: elType = TtaGetElementType (content);
1490: if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1491: {
1492: len = TtaGetTextLength (content);
1493: if (len == 1)
1494: {
1495: len = 2;
1496: TtaGiveTextContent (content, text, &len, &lang);
1497: alphabet = TtaGetAlphabet (lang);
1498: if (len == 1)
1499: if (alphabet == 'L')
1500: /* a single character */
1501: if (text[0] == '(' || text[0] == ')' ||
1502: text[0] == '[' || text[0] == ']' ||
1503: text[0] == '{' || text[0] == '}' ||
1504: text[0] == '|' )
1505: {
1506: /* remove the content of the MO element */
1507: TtaDeleteTree (content, doc);
1508: /* change the MO element into a MF element */
1509: ChangeTypeOfElement (el, doc, MathML_EL_MF);
1510: /* attach a vertstretch attribute to the MF element */
1511: attrType.AttrSSchema = elType.ElSSchema;
1512: attrType.AttrTypeNum = MathML_ATTR_vertstretch;
1513: attr = TtaNewAttribute (attrType);
1514: TtaAttachAttribute (el, attr, doc);
1515: TtaSetAttributeValue (attr, MathML_ATTR_vertstretch_VAL_yes_, el, doc);
1516: /* create a new content for the MF element */
1517: if (text[0] == '|')
1518: {
1519: elType.ElTypeNum = MathML_EL_GRAPHICS_UNIT;
1520: c = 'v';
1521: }
1522: else
1523: {
1524: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1525: c = text[0];
1526: }
1527: content = TtaNewElement (doc, elType);
1528: TtaInsertFirstChild (&content, el, doc);
1529: TtaSetGraphicsShape (content, c, doc);
1530: }
1531: }
1532: }
1533: }
1534: }
1535: }
1536:
1537: /*----------------------------------------------------------------------
1538: CreateFencedSeparators
1539: Create FencedSeparator elements within the fencedExpression
1540: according to attribute separators of the MFENCED element.
1541: ----------------------------------------------------------------------*/
1542: #ifdef __STDC__
1543: void CreateFencedSeparators (Element fencedExpression, Document doc)
1544: #else
1545: void CreateFencedSeparators (fencedExpression, doc)
1546: Element fencedExpression;
1547: Document doc;
1548:
1549: #endif
1550: {
1551: ElementType elType;
1552: Element child, separator, leaf, next, prev, mfenced;
1553: AttributeType attrType;
1554: Attribute attr;
1555: int length, sep, i;
1556: Language lang;
1557: char text[32], sepValue[4];
1558:
1559: /* get the separators attribute */
1560: mfenced = TtaGetParent (fencedExpression);
1561: elType = TtaGetElementType (fencedExpression);
1562: attrType.AttrSSchema = elType.ElSSchema;
1563: attrType.AttrTypeNum = MathML_ATTR_separators;
1564: text[0] = ','; /* default value is sparators="," */
1565: text[1] = EOS;
1566: length = 1;
1567: attr = TtaGetAttribute (mfenced, attrType);
1568: if (attr != NULL)
1569: {
1570: length = 31;
1571: TtaGiveTextAttributeValue (attr, text, &length);
1572: }
1573:
1574: /* create FencedSeparator elements in the FencedExpression */
1575: prev = NULL;
1576: sep = 0;
1577: /* skip leading spaces in attribute separators */
1578: while (text[sep] <= SPACE && text[sep] != EOS)
1579: sep++;
1580: /* if attribute separators is empty or contains only spaces, do not
1581: insert any separator element */
1582: if (text[sep] != EOS)
1583: {
1584: child = TtaGetFirstChild (fencedExpression);
1585: while (child != NULL)
1586: {
1587: next = child;
1588: TtaNextSibling (&next);
1589: elType = TtaGetElementType (child);
1590: if (elType.ElTypeNum != MathML_EL_Construct)
1591: {
1592: if (prev != NULL)
1593: {
1594: elType.ElTypeNum = MathML_EL_FencedSeparator;
1595: separator = TtaNewElement (doc, elType);
1596: TtaInsertSibling (separator, prev, FALSE, doc);
1597: elType.ElTypeNum = MathML_EL_TEXT_UNIT;
1598: leaf = TtaNewElement (doc, elType);
1599: TtaInsertFirstChild (&leaf, separator, doc);
1600: sepValue[0] = text[sep];
1601: sepValue[1] = SPACE;
1602: sepValue[2] = EOS;
1603: lang = TtaGetLanguageIdFromAlphabet('L');
1604: TtaSetTextContent (leaf, sepValue, lang, doc);
1605: /* is there a following non-space character in separators? */
1606: i = sep + 1;
1607: while (text[i] <= SPACE && text[i] != EOS)
1608: i++;
1609: if (text[i] > SPACE && text[i] != EOS)
1610: sep = i;
1611: }
1612: prev = child;
1613: }
1614: child = next;
1615: }
1616: }
1617: }
1618:
1619:
1620: /*----------------------------------------------------------------------
1621: TransformMFENCED
1622: Transform the content of a MFENCED element: create elements
1623: OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
1624: ----------------------------------------------------------------------*/
1625: #ifdef __STDC__
1626: void TransformMFENCED (Element el, Document doc)
1627: #else
1628: void TransformMFENCED (el, doc)
1629: Element el;
1630: Document doc;
1631:
1632: #endif
1633: {
1634: ElementType elType;
1635: Element child, fencedExpression, leaf, fence, next, prev,
1636: firstChild;
1637: AttributeType attrType;
1638: Attribute attr;
1639: int length;
1640: char text[32], c;
1641:
1642: child = TtaGetFirstChild (el);
1643: if (child != NULL)
1644: elType = TtaGetElementType (child);
1645: if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
1646: /* The first child of this MFENCED element is an OpeningFence.
1647: This MFENCED expression has already been transformed, possibly
1648: by the Transform command */
1649: {
1650: TtaNextSibling (&child);
1651: fencedExpression = child;
1652: if (fencedExpression != NULL)
1653: elType = TtaGetElementType (fencedExpression);
1654: if (elType.ElTypeNum == MathML_EL_FencedExpression)
1655: /* the second child is a FencedExpression. OK.
1656: Remove all existing FencedSeparator elements */
1657: {
1658: child = TtaGetFirstChild (fencedExpression);
1659: prev = NULL;
1660: while (child != NULL)
1661: {
1662: elType = TtaGetElementType (child);
1663: next = child;
1664: TtaNextSibling (&next);
1665: if (elType.ElTypeNum == MathML_EL_FencedSeparator)
1666: /* Remove this separator */
1667: TtaDeleteTree (child, doc);
1668: child = next;
1669: }
1670: /* create FencedSeparator elements in the FencedExpression */
1671: CreateFencedSeparators (fencedExpression, doc);
1672: }
1673: }
1674: else
1675: /* this MFENCED element must be transformed */
1676: {
1677: /* create a FencedExpression element as a child of the MFENCED elem. */
1678: elType = TtaGetElementType (el);
1679: elType.ElTypeNum = MathML_EL_FencedExpression;
1680: fencedExpression = TtaNewElement (doc, elType);
1681: TtaInsertFirstChild (&fencedExpression, el, doc);
1682: if (child == NULL)
1683: /* empty MFENCED element */
1684: {
1685: elType.ElTypeNum = MathML_EL_Construct;
1686: child = TtaNewElement (doc, elType);
1687: TtaInsertFirstChild (&child, fencedExpression, doc);
1688: SetPlaceholderAttr (child, doc);
1689: }
1690: else
1691: {
1692: /* move the content of the MFENCED element within the new
1693: FencedExpression element */
1694: prev = NULL;
1695: firstChild = NULL;
1696: while (child != NULL)
1697: {
1698: next = child;
1699: TtaNextSibling (&next);
1700: TtaRemoveTree (child, doc);
1701: if (prev == NULL)
1702: {
1703: TtaInsertFirstChild (&child, fencedExpression, doc);
1704: firstChild = child;
1705: }
1706: else
1707: TtaInsertSibling (child, prev, FALSE, doc);
1708: prev = child;
1709: child = next;
1710: }
1711:
1712: /* create FencedSeparator elements in the FencedExpression */
1713: CreateFencedSeparators (fencedExpression, doc);
1714:
1715: /* Create placeholders within the FencedExpression element */
1716: CreatePlaceholders (firstChild, doc);
1717: }
1718:
1719: /* create the OpeningFence element according to the open attribute */
1720: c = '(';
1721: attrType.AttrSSchema = elType.ElSSchema;
1722: attrType.AttrTypeNum = MathML_ATTR_open;
1723: attr = TtaGetAttribute (el, attrType);
1724: if (attr != NULL)
1725: {
1726: length = 7;
1727: TtaGiveTextAttributeValue (attr, text, &length);
1728: c = text[0];
1729: }
1730: elType.ElTypeNum = MathML_EL_OpeningFence;
1731: fence = TtaNewElement (doc, elType);
1732: TtaInsertSibling (fence, fencedExpression, TRUE, doc);
1733: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1734: leaf = TtaNewElement (doc, elType);
1735: TtaInsertFirstChild (&leaf, fence, doc);
1736: TtaSetGraphicsShape (leaf, c, doc);
1737:
1738: /* create the ClosingFence element according to close attribute */
1739: c = ')';
1740: attrType.AttrTypeNum = MathML_ATTR_close;
1741: attr = TtaGetAttribute (el, attrType);
1742: if (attr != NULL)
1743: {
1744: length = 7;
1745: TtaGiveTextAttributeValue (attr, text, &length);
1746: c = text[0];
1747: }
1748: elType.ElTypeNum = MathML_EL_ClosingFence;
1749: fence = TtaNewElement (doc, elType);
1750: TtaInsertSibling (fence, fencedExpression, FALSE, doc);
1751: elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1752: leaf = TtaNewElement (doc, elType);
1753: TtaInsertFirstChild (&leaf, fence, doc);
1754: TtaSetGraphicsShape (leaf, c, doc);
1755: }
1756: }
1757:
1758: /*----------------------------------------------------------------------
1759: MathMLElementComplete
1760: Check the Thot structure of the MathML element el.
1761: ----------------------------------------------------------------------*/
1762: #ifdef __STDC__
1763: void MathMLElementComplete (Element el, Document doc)
1764: #else
1765: void MathMLElementComplete (el, doc)
1766: Element el;
1767: Document doc;
1768:
1769: #endif
1770: {
1771: ElementType elType, parentType;
1772: Element child, parent, new, prev, next;
1773: AttributeType attrType;
1774: Attribute attr;
1.2 cvs 1775: SSchema MathMLSSchema;
1.1 cvs 1776:
1777: elType = TtaGetElementType (el);
1.2 cvs 1778: MathMLSSchema = GetMathMLSSchema (doc);
1.1 cvs 1779:
1780: if (elType.ElSSchema != MathMLSSchema)
1781: /* this is not a MathML element. It's the HTML element <math>, or
1782: any other element containing a MathML expression */
1783: {
1784: if (TtaGetFirstChild (el) == NULL && !TtaIsLeaf (elType))
1785: /* this element is empty. Create a MathML element as it's child */
1786: {
1787: elType.ElSSchema = MathMLSSchema;
1788: elType.ElTypeNum = MathML_EL_MathML;
1789: new = TtaNewElement (doc, elType);
1790: TtaInsertFirstChild (&new, el, doc);
1791: /* Create a placeholder within the MathML element */
1792: elType.ElTypeNum = MathML_EL_Construct;
1793: child = TtaNewElement (doc, elType);
1794: TtaInsertFirstChild (&child, new, doc);
1795: attrType.AttrSSchema = elType.ElSSchema;
1796: attrType.AttrTypeNum = MathML_ATTR_placeholder;
1797: attr = TtaNewAttribute (attrType);
1798: TtaAttachAttribute (child, attr, doc);
1799: TtaSetAttributeValue (attr, MathML_ATTR_placeholder_VAL_yes_, child, doc);
1800: }
1801: }
1802: else
1803: {
1804: switch (elType.ElTypeNum)
1805: {
1806: case MathML_EL_TEXT_UNIT:
1807: CheckTextElement (&el, doc);
1808: break;
1809: case MathML_EL_MI:
1810: SetFontstyleAttr (el, doc);
1811: break;
1812: case MathML_EL_MO:
1813: SetAddspaceAttr (el, doc);
1814: SetVertStretchAttr (el, doc, 0, NULL);
1815: break;
1816: case MathML_EL_MROOT:
1817: /* end of a Root. Create a RootBase and an Index */
1818: CheckMathSubExpressions (el, MathML_EL_RootBase, MathML_EL_Index,
1819: 0, doc);
1820: break;
1821: case MathML_EL_MSQRT:
1822: /* end od a Square Root. Create a RootBase */
1823: CheckMathSubExpressions (el, MathML_EL_RootBase, 0, 0, doc);
1824: break;
1825: case MathML_EL_MFRAC:
1826: /* end of a fraction. Create a Numerator and a Denominator */
1827: CheckMathSubExpressions (el, MathML_EL_Numerator,
1828: MathML_EL_Denominator, 0, doc);
1829: break;
1830: case MathML_EL_MFENCED:
1831: TransformMFENCED (el, doc);
1832: break;
1833: case MathML_EL_MSUBSUP:
1834: /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
1835: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
1836: MathML_EL_Superscript, doc);
1837: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1838: break;
1839: case MathML_EL_MSUB:
1840: /* end of a MSUB. Create Base and Subscript */
1841: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Subscript,
1842: 0, doc);
1843: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1844: break;
1845: case MathML_EL_MSUP:
1846: /* end of a MSUP. Create Base and Superscript */
1847: CheckMathSubExpressions (el, MathML_EL_Base, MathML_EL_Superscript,
1848: 0, doc);
1849: SetVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1850: break;
1851: case MathML_EL_MUNDEROVER:
1852: /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
1853: Overscript */
1854: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
1855: MathML_EL_Underscript, MathML_EL_Overscript, doc);
1856: SetHorizStretchAttr (el, doc);
1857: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1858: break;
1859: case MathML_EL_MUNDER:
1860: /* end of a MUNDER. Create UnderOverBase, and Underscript */
1861: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
1862: MathML_EL_Underscript, 0, doc);
1863: SetHorizStretchAttr (el, doc);
1864: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1865: break;
1866: case MathML_EL_MOVER:
1867: /* end of a MOVER. Create UnderOverBase, and Overscript */
1868: CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
1869: MathML_EL_Overscript, 0, doc);
1870: SetHorizStretchAttr (el, doc);
1871: SetVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1872: break;
1873: case MathML_EL_MMULTISCRIPTS:
1874: /* end of a MMULTISCRIPTS. Create all elements defined in the
1875: MathML S schema */
1876: BuildMultiscript (el, doc);
1877: break;
1878: case MathML_EL_MROW:
1879: /* end of MROW */
1880: /*if the first and the last child are MO containing a fence character
1881: transform the MO into a MF and the character into a Thot SYMBOL */
1882: child = TtaGetFirstChild (el);
1883: if (child != NULL)
1884: {
1885: CheckFence (child, doc);
1886: child = TtaGetLastChild (el);
1887: if (child != NULL)
1888: CheckFence (child, doc);
1889: /* Create placeholders within the MROW */
1890: CreatePlaceholders (TtaGetFirstChild (el), doc);
1891: }
1892: break;
1893: default:
1894: break;
1895: }
1896: parent = TtaGetParent (el);
1897: parentType = TtaGetElementType (parent);
1898: if (parentType.ElSSchema != elType.ElSSchema)
1899: /* root of a MathML tree, Create a MathML element if there is no */
1900: if (elType.ElTypeNum != MathML_EL_MathML)
1901: {
1902: elType.ElSSchema = MathMLSSchema;
1903: elType.ElTypeNum = MathML_EL_MathML;
1904: new = TtaNewElement (doc, elType);
1905: TtaInsertSibling (new, el, TRUE, doc);
1906: next = el;
1907: TtaNextSibling (&next);
1908: TtaRemoveTree (el, doc);
1909: TtaInsertFirstChild (&el, new, doc);
1910: prev = el;
1911: while (next != NULL)
1912: {
1913: child = next;
1914: TtaNextSibling (&next);
1915: TtaRemoveTree (child, doc);
1916: TtaInsertSibling (child, prev, FALSE, doc);
1917: prev = child;
1918: }
1919: /* Create placeholders within the MathML element */
1920: CreatePlaceholders (el, doc);
1921: }
1922: }
1923: }
1924:
1925: /*----------------------------------------------------------------------
1926: MathMLAttributeComplete
1927: ----------------------------------------------------------------------*/
1928: #ifdef __STDC__
1929: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
1930: #else
1931: void MathMLAttributeComplete (attr, el, doc)
1932: Attribute attr;
1933: Element el;
1934: Document doc;
1935:
1936: #endif
1937: {
1938: }
1939:
1940: /*----------------------------------------------------------------------
1941: MathMLGetDTDName
1942: ----------------------------------------------------------------------*/
1943: #ifdef __STDC__
1944: void MathMLGetDTDName (char* DTDname, char *elementName)
1945: #else
1946: void MathMLGetDTDName (DTDname, elementName)
1947: char* DTDname;
1948: char *elementName;
1949:
1950: #endif
1951: {
1952: /* no other DTD allowed within MathML elements */
1953: strcpy (DTDname, "");
1954: }
1955:
1956: /* end of module */
Webmaster