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