diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/xml_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/xml_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1454 @@ + + + + +TB9.2 Example Applications: examples/PIPS/antiword/src/xml.c Source File + + + + + +

examples/PIPS/antiword/src/xml.c

00001 /*
+00002  * xml.c
+00003  * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
+00004  *
+00005  * Description:
+00006  * Functions to deal with the XML/DocBook format
+00007  *
+00008  */
+00009 
+00010 #include <string.h>
+00011 #include "antiword.h"
+00012 
+00013 
+00014 #define vAddEndTagsUntil1(p,t)  vAddEndTagsUntil2(p,t,TAG_NOTAG)        
+00015 
+00016 #if defined(DEBUG)
+00017 #define vStackTrace()   __vStackTrace(__LINE__)
+00018 #else
+00019 #define vStackTrace()   /* EMPTY */
+00020 #endif /* DEBUG */
+00021 
+00022 /* The character set */
+00023 static encoding_type    eEncoding = encoding_neutral;
+00024 /* Word version */
+00025 static int      iWordVersion = -1;
+00026 /* Special treatment for files from Word 4/5/6 on an Apple Macintosh */
+00027 static BOOL     bOldMacFile = FALSE;
+00028 /* Text is emphasised */
+00029 static BOOL     bEmphasisOpen = FALSE;
+00030 /* Text is superscript */
+00031 static BOOL     bSuperscriptOpen = FALSE;
+00032 /* Text is subscript */
+00033 static BOOL     bSubscriptOpen = FALSE;
+00034 /* Title is open */
+00035 static BOOL     bTitleOpen = FALSE;
+00036 /* Table is open */
+00037 static BOOL     bTableOpen = FALSE;
+00038 /* Footnote is open */
+00039 static BOOL     bFootnoteOpen = FALSE;
+00040 /* Current paragraph level */
+00041 static UINT     uiParagraphLevel = 0;
+00042 /* Current list level */
+00043 static UINT     uiListLevel = 0;
+00044 /* Current list level is still empty */
+00045 static BOOL     bEmptyListLevel = TRUE;
+00046 /* Current header level */
+00047 static USHORT   usHeaderLevelCurrent = 0;
+00048 /* Current header level is still empty */
+00049 static BOOL     bEmptyHeaderLevel = TRUE;
+00050 /* Number of columns in the current table */
+00051 static int      iTableColumnsCurrent = 0;
+00052 /* Footnote number */
+00053 static UINT     uiFootnoteNumber = 0;
+00054 
+00055 /* Constants for the stack */
+00056 #define INITIAL_STACK_SIZE      10
+00057 #if defined(DEBUG)
+00058 #define EXTENSION_STACK_SIZE     2
+00059 #else
+00060 #define EXTENSION_STACK_SIZE    10
+00061 #endif /* DEBUG */
+00062 
+00063 /* Variables for the stack */
+00064 static UCHAR    *aucStack = NULL;
+00065 static size_t   tStacksize = 0;
+00066 static size_t   tStackNextFree = 0;
+00067 
+00068 /* Constants for the tags */
+00069 #define TAG_NOTAG               (UCHAR)0
+00070 #define TAG_AUTHOR              (UCHAR)1
+00071 #define TAG_BEGINPAGE           (UCHAR)2
+00072 #define TAG_BOOK                (UCHAR)3
+00073 #define TAG_BOOKINFO            (UCHAR)4
+00074 #define TAG_CHAPTER             (UCHAR)5
+00075 #define TAG_COLSPEC             (UCHAR)6
+00076 #define TAG_CORPNAME            (UCHAR)7
+00077 #define TAG_DATE                (UCHAR)8
+00078 #define TAG_EMPHASIS            (UCHAR)9
+00079 #define TAG_ENTRY               (UCHAR)10
+00080 #define TAG_FILENAME            (UCHAR)11
+00081 #define TAG_FOOTNOTE            (UCHAR)12
+00082 #define TAG_INFORMALTABLE       (UCHAR)13
+00083 #define TAG_ITEMIZEDLIST        (UCHAR)14
+00084 #define TAG_LISTITEM            (UCHAR)15
+00085 #define TAG_ORDEREDLIST         (UCHAR)16
+00086 #define TAG_PARA                (UCHAR)17
+00087 #define TAG_ROW                 (UCHAR)18
+00088 #define TAG_SECT1               (UCHAR)19
+00089 #define TAG_SECT2               (UCHAR)20
+00090 #define TAG_SECT3               (UCHAR)21
+00091 #define TAG_SECT4               (UCHAR)22
+00092 #define TAG_SECT5               (UCHAR)23
+00093 #define TAG_SUBSCRIPT           (UCHAR)24
+00094 #define TAG_SUBTITLE            (UCHAR)25
+00095 #define TAG_SUPERSCRIPT         (UCHAR)26
+00096 #define TAG_SURNAME             (UCHAR)27
+00097 #define TAG_TBODY               (UCHAR)28
+00098 #define TAG_TGROUP              (UCHAR)29
+00099 #define TAG_TITLE               (UCHAR)30
+00100 
+00101 typedef struct docbooktags_tag {
+00102         UCHAR   ucTagnumber;
+00103         char    szTagname[15];
+00104         BOOL    bAddNewlineStart;
+00105         BOOL    bAddNewlineEnd;
+00106 } docbooktags_type;
+00107 
+00108 static const docbooktags_type atDocBookTags[] = {
+00109         {       TAG_NOTAG,              "!ERROR!",      TRUE,   TRUE    },
+00110         {       TAG_AUTHOR,             "author",       TRUE,   TRUE    },
+00111         {       TAG_BEGINPAGE,          "beginpage",    TRUE,   TRUE    },
+00112         {       TAG_BOOK,               "book",         TRUE,   TRUE    },
+00113         {       TAG_BOOKINFO,           "bookinfo",     TRUE,   TRUE    },
+00114         {       TAG_CHAPTER,            "chapter",      TRUE,   TRUE    },
+00115         {       TAG_COLSPEC,            "colspec",      TRUE,   TRUE    },
+00116         {       TAG_CORPNAME,           "corpname",     FALSE,  FALSE   },
+00117         {       TAG_DATE,               "date",         FALSE,  FALSE   },
+00118         {       TAG_EMPHASIS,           "emphasis",     FALSE,  FALSE   },
+00119         {       TAG_ENTRY,              "entry",        TRUE,   TRUE    },
+00120         {       TAG_FILENAME,           "filename",     FALSE,  FALSE   },
+00121         {       TAG_FOOTNOTE,           "footnote",     FALSE,  FALSE   },
+00122         {       TAG_INFORMALTABLE,      "informaltable",TRUE,   TRUE    },
+00123         {       TAG_ITEMIZEDLIST,       "itemizedlist", TRUE,   TRUE    },
+00124         {       TAG_LISTITEM,           "listitem",     TRUE,   TRUE    },
+00125         {       TAG_ORDEREDLIST,        "orderedlist",  TRUE,   TRUE    },
+00126         {       TAG_PARA,               "para",         TRUE,   TRUE    },
+00127         {       TAG_ROW,                "row",          TRUE,   TRUE    },
+00128         {       TAG_SECT1,              "sect1",        TRUE,   TRUE    },
+00129         {       TAG_SECT2,              "sect2",        TRUE,   TRUE    },
+00130         {       TAG_SECT3,              "sect3",        TRUE,   TRUE    },
+00131         {       TAG_SECT4,              "sect4",        TRUE,   TRUE    },
+00132         {       TAG_SECT5,              "sect5",        TRUE,   TRUE    },
+00133         {       TAG_SUBSCRIPT,          "subscript",    FALSE,  FALSE   },
+00134         {       TAG_SUBTITLE,           "subtitle",     FALSE,  FALSE   },
+00135         {       TAG_SUPERSCRIPT,        "superscript",  FALSE,  FALSE   },
+00136         {       TAG_SURNAME,            "surname",      FALSE,  FALSE   },
+00137         {       TAG_TBODY,              "tbody",        TRUE,   TRUE    },
+00138         {       TAG_TGROUP,             "tgroup",       TRUE,   TRUE    },
+00139         {       TAG_TITLE,              "title",        FALSE,  FALSE   },
+00140 };
+00141 
+00142 static void     vAddStartTag(diagram_type *, UCHAR, const char *);
+00143 static void     vAddEndTag(diagram_type *, UCHAR);
+00144 static void     vAddCombinedTag(diagram_type *, UCHAR, const char *);
+00145 static void     vPrintChar(diagram_type *, char);
+00146 
+00147 
+00148 #if defined(DEBUG)
+00149 /*
+00150  * vCheckTagTable - check the tag table
+00151  */
+00152 static void
+00153 vCheckTagTable(void)
+00154 {
+00155         size_t  tIndex;
+00156 
+00157         for (tIndex = 0; tIndex < elementsof(atDocBookTags); tIndex++) {
+00158                 if (tIndex != (size_t)atDocBookTags[tIndex].ucTagnumber) {
+00159                         DBG_DEC(tIndex);
+00160                         werr(1, "Array atDocBookTags is broken");
+00161                 }
+00162         }
+00163 } /* end of vCheckTagTable */
+00164 
+00165 /*
+00166  * __vStackTrace - show a stack trace
+00167  */
+00168 static void
+00169 __vStackTrace(int iLine)
+00170 {
+00171         int     iIndex;
+00172 
+00173         fprintf(stderr, "%s[%3d]:\n", __FILE__, iLine);
+00174 
+00175         if (tStackNextFree == 0) {
+00176                 fprintf(stderr, "The stack is empty\n");
+00177                 return;
+00178         }
+00179         for (iIndex = (int)tStackNextFree - 1; iIndex >= 0; iIndex--) {
+00180                 fprintf(stderr, "%2d: %2d: '%s'\n",
+00181                         iIndex,
+00182                         (int)atDocBookTags[(UINT)aucStack[iIndex]].ucTagnumber,
+00183                         atDocBookTags[(UINT)aucStack[iIndex]].szTagname);
+00184         }
+00185 } /* end of __vStackTrace */
+00186 #endif /* DEBUG */
+00187 
+00188 /*
+00189  * vPushStack - push a tag onto the stack
+00190  */
+00191 static void
+00192 vPushStack(UCHAR ucTag)
+00193 {
+00194         fail(tStackNextFree > tStacksize);
+00195 
+00196         if (tStackNextFree == tStacksize) {
+00197                 /* The stack is full; enlarge the stack */
+00198                 tStacksize += EXTENSION_STACK_SIZE;
+00199                 aucStack = xrealloc(aucStack, tStacksize * sizeof(UCHAR));
+00200                 DBG_DEC(tStacksize);
+00201         }
+00202 
+00203         fail(tStackNextFree >= tStacksize);
+00204 
+00205         aucStack[tStackNextFree++] = ucTag;
+00206 } /* end of vPushStack */
+00207 
+00208 /*
+00209  * vPopStack - pop a tag from the stack
+00210  */
+00211 static UCHAR
+00212 ucPopStack(void)
+00213 {
+00214         DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree);
+00215         DBG_DEC_C(tStackNextFree > tStacksize, tStacksize);
+00216         fail(tStackNextFree > tStacksize);
+00217         fail(tStackNextFree == 0);
+00218 
+00219         if (tStackNextFree == 0) {
+00220                 werr(1, "The stack is empty, unable to continue");
+00221                 return TAG_NOTAG;
+00222         }
+00223         return aucStack[--tStackNextFree];
+00224 } /* end of ucPopStack */
+00225 
+00226 /*
+00227  * vReadStack - read a tag from the top of the stack
+00228  */
+00229 static UCHAR
+00230 ucReadStack(void)
+00231 {
+00232         DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree);
+00233         DBG_DEC_C(tStackNextFree > tStacksize, tStacksize);
+00234         fail(tStackNextFree > tStacksize);
+00235 
+00236         if (tStackNextFree == 0) {
+00237                 /* The stack is empty */
+00238                 return TAG_NOTAG;
+00239         }
+00240         return aucStack[tStackNextFree - 1];
+00241 } /* end of ucReadStack */
+00242 
+00243 /*
+00244  * vPrintLevel - print the tag level
+00245  */
+00246 static void
+00247 vPrintLevel(FILE *pOutFile)
+00248 {
+00249         size_t  tIndex;
+00250 
+00251         fail(pOutFile == NULL);
+00252 
+00253         for (tIndex = 0; tIndex < tStackNextFree; tIndex++) {
+00254                 (void)putc(' ', pOutFile);
+00255         }
+00256 } /* end of vPrintLevel */
+00257 
+00258 /*
+00259  * vPrintFootnote - print a footnote
+00260  */
+00261 static void
+00262 vPrintFootnote(diagram_type *pDiag, UINT uiFootnoteIndex)
+00263 {
+00264         const char      *szText, *pcTmp;
+00265         BOOL    bSuScript;
+00266         UCHAR   ucTopTag;
+00267 
+00268         TRACE_MSG("vPrintFootnote");
+00269 
+00270         szText = szGetFootnootText(uiFootnoteIndex);
+00271 
+00272         if (szText == NULL) {
+00273                 szText = "";
+00274         }
+00275 
+00276         /* Remove the subscript/superscript (if any) */
+00277         ucTopTag = ucReadStack();
+00278         bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT;
+00279         if (bSuScript) {
+00280                 vAddEndTag(pDiag, ucTopTag);
+00281         }
+00282 
+00283         /* Start a footnote */
+00284         vAddStartTag(pDiag, TAG_FOOTNOTE, NULL);
+00285         vAddStartTag(pDiag, TAG_PARA, NULL);
+00286 
+00287         /* Print a footnote */
+00288         for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) {
+00289                 if (*pcTmp == PAR_END) {
+00290                         if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') {
+00291                                 /* PAR_END is not empty and not last */
+00292                                 vAddEndTag(pDiag, TAG_PARA);
+00293                                 vAddStartTag(pDiag, TAG_PARA, NULL);
+00294                         }
+00295                 } else {
+00296                         vPrintChar(pDiag, *pcTmp);
+00297                 }
+00298         }
+00299 
+00300         /* End a footnote */
+00301         vAddEndTag(pDiag, TAG_PARA);
+00302         vAddEndTag(pDiag, TAG_FOOTNOTE);
+00303 
+00304         /* Repair the subscript/superscript (if any) */
+00305         if (bSuScript) {
+00306                 vAddStartTag(pDiag, ucTopTag, NULL);
+00307         }
+00308 } /* end of vPrintFootnote */
+00309 
+00310 /*
+00311  * vPrintChar - print a character with XML encoding
+00312  */
+00313 static void
+00314 vPrintChar(diagram_type *pDiag, char cChar)
+00315 {
+00316         fail(pDiag == NULL);
+00317         fail(pDiag->pOutFile == NULL);
+00318 
+00319         switch (cChar) {
+00320         case FOOTNOTE_OR_ENDNOTE:
+00321                 uiFootnoteNumber++;
+00322                 vPrintFootnote(pDiag, uiFootnoteNumber - 1);
+00323                 break;
+00324         case '<':
+00325                 fprintf(pDiag->pOutFile, "%s", "&lt;");
+00326                 break;
+00327         case '>':
+00328                 fprintf(pDiag->pOutFile, "%s", "&gt;");
+00329                 break;
+00330         case '&':
+00331                 fprintf(pDiag->pOutFile, "%s", "&amp;");
+00332                 break;
+00333         default:
+00334                 (void)putc(cChar, pDiag->pOutFile);
+00335                 break;
+00336         }
+00337 } /* end of vPrintChar */
+00338 
+00339 /*
+00340  * vPrintSpecialChar - convert and print a character
+00341  */
+00342 static void
+00343 vPrintSpecialChar(diagram_type *pDiag, USHORT usChar)
+00344 {
+00345         ULONG   ulChar;
+00346         size_t  tLen, tIndex;
+00347         char    szResult[4];
+00348 
+00349         fail(pDiag == NULL);
+00350         fail(pDiag->pOutFile == NULL);
+00351         fail(iWordVersion < 0);
+00352         fail(eEncoding == encoding_neutral);
+00353 
+00354         ulChar = ulTranslateCharacters(usChar, 0, iWordVersion,
+00355                                 conversion_xml, eEncoding, bOldMacFile);
+00356         tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
+00357         if (tLen == 1) {
+00358                 vPrintChar(pDiag, szResult[0]);
+00359         } else {
+00360                 for (tIndex = 0; tIndex < tLen; tIndex++) {
+00361                         (void)putc(szResult[tIndex], pDiag->pOutFile);
+00362                 }
+00363         }
+00364 } /* end of vPrintSpecialChar */
+00365 
+00366 /*
+00367  * vPrintSpecialString - convert and print a string
+00368  */
+00369 static void
+00370 vPrintSpecialString(diagram_type *pDiag, const char *szString)
+00371 {
+00372         int     iIndex;
+00373         USHORT  usChar;
+00374 
+00375         fail(pDiag == NULL);
+00376         fail(pDiag->pOutFile == NULL);
+00377         fail(szString == NULL);
+00378 
+00379         for (iIndex = 0; szString[iIndex] != '\0'; iIndex++) {
+00380                 usChar = (USHORT)(UCHAR)szString[iIndex];
+00381                 vPrintSpecialChar(pDiag, usChar);
+00382         }
+00383 } /* end of vPrintSpecialString */
+00384 
+00385 /*
+00386  * vAddStartTag - add the specified start tag to the file
+00387  */
+00388 static void
+00389 vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
+00390 {
+00391         fail(pDiag == NULL);
+00392         fail(pDiag->pOutFile == NULL);
+00393         fail((size_t)ucTag >= elementsof(atDocBookTags));
+00394 
+00395         if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
+00396                 fprintf(pDiag->pOutFile, "\n");
+00397                 vPrintLevel(pDiag->pOutFile);
+00398         }
+00399 
+00400         if (szAttribute == NULL || szAttribute[0] == '\0') {
+00401                 fprintf(pDiag->pOutFile, "<%s>",
+00402                         atDocBookTags[(UINT)ucTag].szTagname);
+00403         } else {
+00404                 fprintf(pDiag->pOutFile, "<%s %s>",
+00405                         atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
+00406         }
+00407 
+00408         if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
+00409                 fprintf(pDiag->pOutFile, "\n");
+00410                 pDiag->lXleft = 0;
+00411         }
+00412 
+00413         vPushStack(ucTag);
+00414 
+00415         /* Set global variables */
+00416         switch (ucTag) {
+00417         case TAG_CHAPTER:
+00418                 usHeaderLevelCurrent = 1;
+00419                 bEmptyHeaderLevel = TRUE;
+00420                 break;
+00421         case TAG_SECT1:
+00422                 usHeaderLevelCurrent = 2;
+00423                 bEmptyHeaderLevel = TRUE;
+00424                 break;
+00425         case TAG_SECT2:
+00426                 usHeaderLevelCurrent = 3;
+00427                 bEmptyHeaderLevel = TRUE;
+00428                 break;
+00429         case TAG_SECT3:
+00430                 usHeaderLevelCurrent = 4;
+00431                 bEmptyHeaderLevel = TRUE;
+00432                 break;
+00433         case TAG_SECT4:
+00434                 usHeaderLevelCurrent = 5;
+00435                 bEmptyHeaderLevel = TRUE;
+00436                 break;
+00437         case TAG_SECT5:
+00438                 usHeaderLevelCurrent = 6;
+00439                 bEmptyHeaderLevel = TRUE;
+00440                 break;
+00441         case TAG_TITLE:
+00442                 fail(uiParagraphLevel != 0);
+00443                 bTitleOpen = TRUE;
+00444                 break;
+00445         case TAG_FOOTNOTE:
+00446                 bFootnoteOpen = TRUE;
+00447                 break;
+00448         case TAG_PARA:
+00449                 fail(bTitleOpen && !bFootnoteOpen);
+00450                 uiParagraphLevel++;
+00451                 bEmptyHeaderLevel = FALSE;
+00452                 break;
+00453         case TAG_EMPHASIS:
+00454                 bEmphasisOpen = TRUE;
+00455                 break;
+00456         case TAG_ITEMIZEDLIST:
+00457         case TAG_ORDEREDLIST:
+00458                 uiListLevel++;
+00459                 bEmptyListLevel = TRUE;
+00460                 bEmptyHeaderLevel = FALSE;
+00461                 break;
+00462         case TAG_LISTITEM:
+00463                 bEmptyListLevel = FALSE;
+00464                 break;
+00465         case TAG_SUPERSCRIPT:
+00466                 bSuperscriptOpen = TRUE;
+00467                 break;
+00468         case TAG_SUBSCRIPT:
+00469                 bSubscriptOpen = TRUE;
+00470                 break;
+00471         case TAG_INFORMALTABLE:
+00472                 bTableOpen = TRUE;
+00473                 bEmptyHeaderLevel = FALSE;
+00474                 break;
+00475         default:
+00476                 break;
+00477         }
+00478 } /* end of vAddStartTag */
+00479 
+00480 /*
+00481  * vAddEndTag - add the specified end tag to the file
+00482  */
+00483 static void
+00484 vAddEndTag(diagram_type *pDiag, UCHAR ucTag)
+00485 {
+00486         UCHAR   ucTopTag;
+00487 
+00488         fail(pDiag == NULL);
+00489         fail(pDiag->pOutFile == NULL);
+00490         fail((size_t)ucTag >= elementsof(atDocBookTags));
+00491 
+00492 #if defined(DEBUG)
+00493         ucTopTag = ucReadStack();
+00494         if (ucTag != ucTopTag) {
+00495                 DBG_DEC(ucTag);
+00496                 DBG_MSG(atDocBookTags[(UINT)ucTag].szTagname);
+00497                 vStackTrace();
+00498         }
+00499 #endif /* DEBUG */
+00500 
+00501         ucTopTag = ucPopStack();
+00502         fail((size_t)ucTopTag >= elementsof(atDocBookTags));
+00503         if (ucTag != ucTopTag) {
+00504                 DBG_DEC(ucTag);
+00505                 DBG_DEC(ucTopTag);
+00506                 DBG_FIXME();
+00507                 werr(1, "Impossible tag sequence, unable to continue");
+00508         }
+00509 
+00510         if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
+00511                 fprintf(pDiag->pOutFile, "\n");
+00512                 vPrintLevel(pDiag->pOutFile);
+00513         }
+00514 
+00515         fprintf(pDiag->pOutFile, "</%s>", atDocBookTags[(UINT)ucTag].szTagname);
+00516 
+00517         if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
+00518                 fprintf(pDiag->pOutFile, "\n");
+00519                 pDiag->lXleft = 0;
+00520         }
+00521 
+00522         /* Set global variables */
+00523         switch (ucTag) {
+00524         case TAG_CHAPTER:
+00525                 usHeaderLevelCurrent = 0;
+00526                 break;
+00527         case TAG_SECT1:
+00528                 usHeaderLevelCurrent = 1;
+00529                 break;
+00530         case TAG_SECT2:
+00531                 usHeaderLevelCurrent = 2;
+00532                 break;
+00533         case TAG_SECT3:
+00534                 usHeaderLevelCurrent = 3;
+00535                 break;
+00536         case TAG_SECT4:
+00537                 usHeaderLevelCurrent = 4;
+00538                 break;
+00539         case TAG_SECT5:
+00540                 usHeaderLevelCurrent = 5;
+00541                 break;
+00542         case TAG_TITLE:
+00543                 bTitleOpen = FALSE;
+00544                 break;
+00545         case TAG_FOOTNOTE:
+00546                 bFootnoteOpen = FALSE;
+00547                 break;
+00548         case TAG_PARA:
+00549                 uiParagraphLevel--;
+00550                 break;
+00551         case TAG_EMPHASIS:
+00552                 bEmphasisOpen = FALSE;
+00553                 break;
+00554         case TAG_SUPERSCRIPT:
+00555                 bSuperscriptOpen = FALSE;
+00556                 break;
+00557         case TAG_ITEMIZEDLIST:
+00558         case TAG_ORDEREDLIST:
+00559                 uiListLevel--;
+00560                 break;
+00561         case TAG_SUBSCRIPT:
+00562                 bSubscriptOpen = FALSE;
+00563                 break;
+00564         case TAG_INFORMALTABLE:
+00565                 bTableOpen = FALSE;
+00566                 iTableColumnsCurrent = 0;
+00567                 break;
+00568         default:
+00569                 break;
+00570         }
+00571 } /* end of vAddEndTag */
+00572 
+00573 /*
+00574  * vAddEndTagOptional - add the specified end tag to the file if needed
+00575  */
+00576 static void
+00577 vAddEndTagOptional(diagram_type *pDiag, UCHAR ucTag)
+00578 {
+00579         UCHAR   ucTopTag;
+00580 
+00581         ucTopTag = ucReadStack();
+00582         if (ucTag == ucTopTag) {
+00583                 vAddEndTag(pDiag, ucTag);
+00584         }
+00585 } /* end of vAddEndTagOptional */
+00586 
+00587 /*
+00588  * vAddCombinedTag - add the specified start and end tag to the file
+00589  */
+00590 static void
+00591 vAddCombinedTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
+00592 {
+00593         fail(pDiag == NULL);
+00594         fail(pDiag->pOutFile == NULL);
+00595         fail((size_t)ucTag >= elementsof(atDocBookTags));
+00596 
+00597         if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
+00598                 fprintf(pDiag->pOutFile, "\n");
+00599                 vPrintLevel(pDiag->pOutFile);
+00600         }
+00601 
+00602         if (szAttribute == NULL || szAttribute[0] == '\0') {
+00603                 fprintf(pDiag->pOutFile, "<%s/>",
+00604                         atDocBookTags[(UINT)ucTag].szTagname);
+00605         } else {
+00606                 fprintf(pDiag->pOutFile, "<%s %s/>",
+00607                         atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
+00608         }
+00609 
+00610         if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
+00611                 fprintf(pDiag->pOutFile, "\n");
+00612                 pDiag->lXleft = 0;
+00613         }
+00614 } /* end of vAddCombinedTag */
+00615 
+00616 /*
+00617  * vAddEndTagsUntil2 - add end tags until one the specified tags is seen
+00618  */
+00619 static void
+00620 vAddEndTagsUntil2(diagram_type *pDiag, UCHAR ucTag1, UCHAR ucTag2)
+00621 {
+00622         UCHAR   ucTopTag;
+00623 
+00624         do {
+00625                 ucTopTag = ucReadStack();
+00626                 switch (ucTopTag) {
+00627                 case TAG_CHAPTER:
+00628                 case TAG_SECT1:
+00629                 case TAG_SECT2:
+00630                 case TAG_SECT3:
+00631                 case TAG_SECT4:
+00632                 case TAG_SECT5:
+00633                         if (bEmptyHeaderLevel) {
+00634                                 /*
+00635                                  * An empty chapter is legal in Word,
+00636                                  * but not in DocBook.
+00637                                  */
+00638                                 vAddCombinedTag(pDiag, TAG_PARA, NULL);
+00639                                 bEmptyHeaderLevel = FALSE;
+00640                         }
+00641                         break;
+00642                 case TAG_ITEMIZEDLIST:
+00643                 case TAG_ORDEREDLIST:
+00644                         if (bEmptyListLevel) {
+00645                                 /*
+00646                                  * A list without items is legal in Word,
+00647                                  * but not in DocBook. (Nor are empty items)
+00648                                  */
+00649                                 vAddStartTag(pDiag, TAG_LISTITEM, NULL);
+00650                                 vAddCombinedTag(pDiag, TAG_PARA, NULL);
+00651                                 vAddEndTag(pDiag, TAG_LISTITEM);
+00652                                 bEmptyListLevel = FALSE;
+00653                         }
+00654                         break;
+00655                 default:
+00656                         break;
+00657                 }
+00658                 vAddEndTag(pDiag, ucTopTag);
+00659         } while (ucTopTag != ucTag1 && ucTopTag != ucTag2);
+00660 } /* end of vAddEndTagsUntil2 */
+00661 
+00662 /*
+00663  * vCreateBookIntro - create title and bookinfo
+00664  */
+00665 void
+00666 vCreateBookIntro(diagram_type *pDiag, int iVersion)
+00667 {
+00668         const char      *szTitle, *szSubject, *szAuthor;
+00669         const char      *szLastSaveDtm, *szCompany;
+00670         const char      *szLanguage;
+00671         char            szTmp[13];
+00672 
+00673         fail(pDiag == NULL);
+00674         fail(pDiag->pOutFile == NULL);
+00675         fail(iVersion < 0);
+00676         fail(eEncoding == encoding_neutral);
+00677 
+00678         iWordVersion = iVersion;
+00679         bOldMacFile = bIsOldMacFile();
+00680         szTitle = szGetTitle();
+00681         szSubject = szGetSubject();
+00682         szAuthor = szGetAuthor();
+00683         szLastSaveDtm = szGetLastSaveDtm();
+00684         szCompany = szGetCompany();
+00685 
+00686         /* Start Book */
+00687         szLanguage = szGetLanguage();
+00688         if (szLanguage != NULL) {
+00689                 DBG_MSG(szLanguage);
+00690                 sprintf(szTmp, "lang='%.5s'", szLanguage);
+00691                 szLanguage = szTmp;
+00692         }
+00693         vAddStartTag(pDiag, TAG_BOOK, szLanguage);
+00694 
+00695         /* Book title */
+00696         if (szTitle != NULL && szTitle[0] != '\0') {
+00697                 vAddStartTag(pDiag, TAG_TITLE, NULL);
+00698                 vPrintSpecialString(pDiag, szTitle);
+00699                 vAddEndTag(pDiag, TAG_TITLE);
+00700         }
+00701         /* Bookinfo */
+00702         if ((szTitle != NULL && szTitle[0] != '\0') ||
+00703             (szSubject != NULL && szSubject[0] != '\0') ||
+00704             (szAuthor != NULL && szAuthor[0] != '\0') ||
+00705             (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') ||
+00706             (szCompany != NULL && szCompany[0] != '\0')) {
+00707                 vAddStartTag(pDiag, TAG_BOOKINFO, NULL);
+00708                 if (szTitle != NULL && szTitle[0] != '\0') {
+00709                         vAddStartTag(pDiag, TAG_TITLE, NULL);
+00710                         vPrintSpecialString(pDiag, szTitle);
+00711                         vAddEndTag(pDiag, TAG_TITLE);
+00712                 }
+00713                 if (szSubject != NULL && szSubject[0] != '\0') {
+00714                         vAddStartTag(pDiag, TAG_SUBTITLE, NULL);
+00715                         vPrintSpecialString(pDiag, szSubject);
+00716                         vAddEndTag(pDiag, TAG_SUBTITLE);
+00717                 }
+00718                 if (szAuthor != NULL && szAuthor[0] != '\0') {
+00719                         vAddStartTag(pDiag, TAG_AUTHOR, NULL);
+00720                         vAddStartTag(pDiag, TAG_SURNAME, NULL);
+00721                         vPrintSpecialString(pDiag, szAuthor);
+00722                         vAddEndTag(pDiag, TAG_SURNAME);
+00723                         vAddEndTag(pDiag, TAG_AUTHOR);
+00724                 }
+00725                 if (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') {
+00726                         vAddStartTag(pDiag, TAG_DATE, NULL);
+00727                         vPrintSpecialString(pDiag, szLastSaveDtm);
+00728                         vAddEndTag(pDiag, TAG_DATE);
+00729                 }
+00730                 if (szCompany != NULL && szCompany[0] != '\0') {
+00731                         vAddStartTag(pDiag, TAG_CORPNAME, NULL);
+00732                         vPrintSpecialString(pDiag, szCompany);
+00733                         vAddEndTag(pDiag, TAG_CORPNAME);
+00734                 }
+00735                 vAddEndTag(pDiag, TAG_BOOKINFO);
+00736         }
+00737 } /* end of vCreateBookIntro */
+00738 
+00739 /*
+00740  * vPrologueXML - perform the XML initialization
+00741  */
+00742 void
+00743 vPrologueXML(diagram_type *pDiag, const options_type *pOptions)
+00744 {
+00745 
+00746         fail(pDiag == NULL);
+00747         fail(pDiag->pOutFile == NULL);
+00748         fail(pOptions == NULL);
+00749 
+00750 #if defined(DEBUG)
+00751         vCheckTagTable();
+00752 #endif /* DEBUG */
+00753 
+00754         /* Set global variables to their start values */
+00755         eEncoding = pOptions->eEncoding;
+00756         bEmphasisOpen = FALSE;
+00757         bSuperscriptOpen = FALSE;
+00758         bSubscriptOpen = FALSE;
+00759         bTitleOpen = FALSE;
+00760         bTableOpen = FALSE;
+00761         bFootnoteOpen = FALSE;
+00762         uiParagraphLevel = 0;
+00763         uiListLevel = 0;
+00764         bEmptyListLevel = TRUE;
+00765         usHeaderLevelCurrent = 0;
+00766         bEmptyHeaderLevel = TRUE;
+00767         iTableColumnsCurrent = 0;
+00768         uiFootnoteNumber = 0;
+00769 
+00770         pDiag->lXleft = 0;
+00771         pDiag->lYtop = 0;
+00772 
+00773         /* Create an empty stack */
+00774         tStacksize = INITIAL_STACK_SIZE;
+00775         aucStack = xcalloc(tStacksize, sizeof(UCHAR));
+00776         tStackNextFree = 0;
+00777 } /* end of vPrologueXML */
+00778 
+00779 /*
+00780  * vEpilogueXML - clean up after everything is done
+00781  */
+00782 void
+00783 vEpilogueXML(diagram_type *pDiag)
+00784 {
+00785         vStackTrace();
+00786 
+00787         vAddEndTagsUntil1(pDiag, TAG_BOOK);
+00788 
+00789         vStackTrace();
+00790 
+00791         /* Destroy the stack */
+00792         fail(tStackNextFree != 0);
+00793         tStacksize = 0;
+00794         aucStack = xfree(aucStack);
+00795         tStackNextFree = 0;
+00796 } /* end of vEpilogueXML */
+00797 
+00798 /*
+00799  * vPrintXML - print a XML string
+00800  */
+00801 static void
+00802 vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
+00803                 USHORT usFontstyle)
+00804 {
+00805         const char      *szAttr;
+00806         int     iCount;
+00807         size_t  tNextFree;
+00808         BOOL    bNotReady, bEmphasisNew, bSuperscriptNew, bSubscriptNew;
+00809         UCHAR   ucTopTag, aucStorage[3];
+00810 
+00811         fail(szString == NULL);
+00812 
+00813         if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
+00814                 return;
+00815         }
+00816 
+00817         if (tStringLength == 1 && szString[0] == FOOTNOTE_OR_ENDNOTE) {
+00818                 /* Don't do anything special for just a single footnote */
+00819                 bEmphasisNew = FALSE;
+00820                 bSuperscriptNew = FALSE;
+00821                 bSubscriptNew = FALSE;
+00822         } else {
+00823                 /* Situation normal */
+00824                 bEmphasisNew = bIsBold(usFontstyle) ||
+00825                                 bIsItalic(usFontstyle) ||
+00826                                 bIsUnderline(usFontstyle) ||
+00827                                 bIsStrike(usFontstyle);
+00828                 bSuperscriptNew = bIsSuperscript(usFontstyle);
+00829                 bSubscriptNew = bIsSubscript(usFontstyle);
+00830         }
+00831 
+00832         /* End what has to be ended (or more to keep the stack happy) */
+00833         tNextFree = 0;
+00834         bNotReady = TRUE;
+00835         do {
+00836                 ucTopTag = ucReadStack();
+00837                 switch (ucTopTag) {
+00838                 case TAG_EMPHASIS:
+00839                         fail(!bEmphasisOpen);
+00840                         if (bEmphasisNew) {
+00841                                 aucStorage[tNextFree++] = ucTopTag;
+00842                         }
+00843                         vAddEndTag(pDiag, ucTopTag);
+00844                         break;
+00845                 case TAG_SUPERSCRIPT:
+00846                         fail(!bSuperscriptOpen);
+00847                         if (bSuperscriptNew) {
+00848                                 aucStorage[tNextFree++] = ucTopTag;
+00849                         }
+00850                         vAddEndTag(pDiag, ucTopTag);
+00851                         break;
+00852                 case TAG_SUBSCRIPT:
+00853                         fail(!bSubscriptOpen);
+00854                         if (bSubscriptNew) {
+00855                                 aucStorage[tNextFree++] = ucTopTag;
+00856                         }
+00857                         vAddEndTag(pDiag, ucTopTag);
+00858                         break;
+00859                 default:
+00860                         bNotReady = FALSE;
+00861                         break;
+00862                 }
+00863                 fail(tNextFree > elementsof(aucStorage));
+00864                 fail(bNotReady && tNextFree == elementsof(aucStorage));
+00865         } while (bNotReady);
+00866 
+00867         /* Just te make sure */
+00868         vStartOfParagraphXML(pDiag, 1);
+00869 
+00870         /* Restart to keep the stack happy */
+00871         for (iCount = (int)tNextFree - 1; iCount > 0; iCount--) {
+00872                 vAddStartTag(pDiag, aucStorage[iCount], NULL);
+00873         }
+00874 
+00875         /* Start what has to be started */
+00876         if (bEmphasisNew && !bEmphasisOpen) {
+00877                 if (bIsBold(usFontstyle)) {
+00878                         szAttr = "role='bold'";
+00879                 } else if (bIsItalic(usFontstyle)) {
+00880                         szAttr = NULL;
+00881                 } else if (bIsUnderline(usFontstyle)) {
+00882                         szAttr = "role='underline'";
+00883                 } else if (bIsStrike(usFontstyle)) {
+00884                         szAttr = "role='strikethrough'";
+00885                 } else {
+00886                         szAttr = NULL;
+00887                 }
+00888                 vAddStartTag(pDiag, TAG_EMPHASIS, szAttr);
+00889         }
+00890         if (bSuperscriptNew && !bSuperscriptOpen) {
+00891                 vAddStartTag(pDiag, TAG_SUPERSCRIPT, NULL);
+00892         }
+00893         if (bSubscriptNew && !bSubscriptOpen) {
+00894                 vAddStartTag(pDiag, TAG_SUBSCRIPT, NULL);
+00895         }
+00896 
+00897         /* The print the string */
+00898         for (iCount = 0; iCount < (int)tStringLength; iCount++) {
+00899                 vPrintChar(pDiag, szString[iCount]);
+00900         }
+00901 } /* end of vPrintXML */
+00902 
+00903 /*
+00904  * vMove2NextLineXML - move to the next line
+00905  */
+00906 void
+00907 vMove2NextLineXML(diagram_type *pDiag)
+00908 {
+00909         fail(pDiag == NULL);
+00910 
+00911         /*
+00912         if (uiParagraphLevel != 0) {
+00913                 We need something like HTML's <BR> tag
+00914         }
+00915         */
+00916 } /* end of vMove2NextLineXML */
+00917 
+00918 /*
+00919  * vSubstringXML - put a sub string into a diagram
+00920  */
+00921 void
+00922 vSubstringXML(diagram_type *pDiag,
+00923         const char *szString, size_t tStringLength, long lStringWidth,
+00924         USHORT usFontstyle)
+00925 {
+00926         fail(pDiag == NULL || szString == NULL);
+00927         fail(pDiag->pOutFile == NULL);
+00928         fail(pDiag->lXleft < 0);
+00929         fail(tStringLength != strlen(szString));
+00930 
+00931         if (szString[0] == '\0' || tStringLength == 0) {
+00932                 return;
+00933         }
+00934 
+00935         vPrintXML(pDiag, szString, tStringLength, usFontstyle);
+00936         pDiag->lXleft += lStringWidth;
+00937 } /* end of vSubstringXML */
+00938 
+00939 /*
+00940  * Create an start of a paragraph
+00941  * Only works on paragraph level one, because Word doesn't allow paragraphs
+00942  * in paragraphs. Other paragraph levels result from DocBooks special needs.
+00943  */
+00944 void
+00945 vStartOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
+00946 {
+00947         fail(pDiag == NULL);
+00948 
+00949         if (uiParagraphLevel >= uiMaxLevel || bTitleOpen) {
+00950                 /* In Word a title is just a paragraph */
+00951                 return;
+00952         }
+00953         if (uiListLevel != 0 && bEmptyListLevel) {
+00954                 /* No paragraphs in a list before the first listitem */
+00955                 return;
+00956         }
+00957         if (usHeaderLevelCurrent == 0) {
+00958                 /* No paragraphs without an open header */
+00959                 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
+00960                 /* Dummy title */
+00961                 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
+00962         }
+00963         vAddStartTag(pDiag, TAG_PARA, NULL);
+00964 } /* end of vStartOfParagraphXML */
+00965 
+00966 /*
+00967  * Create an end of a paragraph
+00968  * Only for paragraph level one and for titles
+00969  */
+00970 void
+00971 vEndOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
+00972 {
+00973         UCHAR   ucTopTag;
+00974 
+00975         fail(pDiag == NULL);
+00976 
+00977         if (uiParagraphLevel > uiMaxLevel) {
+00978                 DBG_DEC(uiParagraphLevel);
+00979                 return;
+00980         }
+00981 
+00982         for(;;) {
+00983                 ucTopTag = ucReadStack();
+00984                 switch (ucTopTag) {
+00985                 case TAG_EMPHASIS:
+00986                         fail(!bEmphasisOpen);
+00987                         vAddEndTag(pDiag, TAG_EMPHASIS);
+00988                         break;
+00989                 case TAG_SUPERSCRIPT:
+00990                         fail(!bSuperscriptOpen);
+00991                         vAddEndTag(pDiag, TAG_SUPERSCRIPT);
+00992                         break;
+00993                 case TAG_SUBSCRIPT:
+00994                         fail(!bSubscriptOpen);
+00995                         vAddEndTag(pDiag, TAG_SUBSCRIPT);
+00996                         break;
+00997                 case TAG_TITLE:
+00998                         fail(!bTitleOpen);
+00999                         vAddEndTag(pDiag, TAG_TITLE);
+01000                         return;
+01001                 case TAG_PARA:
+01002                         fail(uiParagraphLevel == 0);
+01003                         vAddEndTag(pDiag, TAG_PARA);
+01004                         return;
+01005                 case TAG_TBODY:
+01006                 case TAG_TGROUP:
+01007                 case TAG_INFORMALTABLE:
+01008                         fail(!bTableOpen);
+01009                         vAddEndTag(pDiag, ucTopTag);
+01010                         break;
+01011                 case TAG_NOTAG:
+01012                         DBG_FIXME();
+01013                         werr(1, "Impossible tag sequence, unable to continue");
+01014                         break;
+01015                 default:
+01016                         DBG_DEC(ucTopTag);
+01017                         DBG_MSG_C((size_t)ucTopTag < elementsof(atDocBookTags),
+01018                                 atDocBookTags[(UINT)ucTopTag].szTagname);
+01019                         return;
+01020                 }
+01021         }
+01022 } /* end of vEndOfParagraphXML */
+01023 
+01024 /*
+01025  * Create an end of a page
+01026  */
+01027 void
+01028 vEndOfPageXML(diagram_type *pDiag)
+01029 {
+01030         if (bTableOpen || usHeaderLevelCurrent == 0) {
+01031                 /* No beginpage in a table or outside a chapter */
+01032                 return;
+01033         }
+01034         if (bTitleOpen) {
+01035                 /* A beginpage is not allowed when in a title */
+01036                 /* So start a new paragraph */
+01037                 vEndOfParagraphXML(pDiag, UINT_MAX);
+01038                 vStartOfParagraphXML(pDiag, UINT_MAX);
+01039                 return;
+01040         }
+01041         vAddCombinedTag(pDiag, TAG_BEGINPAGE, NULL);
+01042 } /* end of vEndOfPageXML */
+01043 
+01044 /*
+01045  * vCloseHeaderLevels - close the specified header levels
+01046  */
+01047 static void
+01048 vCloseHeaderLevels(diagram_type *pDiag, USHORT usIstd)
+01049 {
+01050         BOOL    bNotReady;
+01051         UCHAR   ucTopTag;
+01052 
+01053         DBG_MSG("vCloseHeaderLevels");
+01054         DBG_DEC(usIstd);
+01055         DBG_DEC(usHeaderLevelCurrent);
+01056 
+01057         vStackTrace();
+01058 
+01059         bNotReady = TRUE;
+01060         do {
+01061                 ucTopTag = ucReadStack();
+01062                 switch (ucTopTag) {
+01063                 case TAG_TITLE:
+01064                 case TAG_PARA:
+01065                         vAddEndTag(pDiag, ucTopTag);
+01066                         break;
+01067                 default:
+01068                         bNotReady = FALSE;
+01069                         break;
+01070                 }
+01071         } while (bNotReady);
+01072 
+01073         vStackTrace();
+01074 
+01075         while (usHeaderLevelCurrent >= usIstd) {
+01076                 if (bEmptyHeaderLevel) {
+01077                         vAddCombinedTag(pDiag, TAG_PARA, NULL);
+01078                         bEmptyHeaderLevel = FALSE;
+01079                 }
+01080                 switch (usHeaderLevelCurrent) {
+01081                 case 1: vAddEndTag(pDiag, TAG_CHAPTER); break;
+01082                 case 2: vAddEndTag(pDiag, TAG_SECT1); break;
+01083                 case 3: vAddEndTag(pDiag, TAG_SECT2); break;
+01084                 case 4: vAddEndTag(pDiag, TAG_SECT3); break;
+01085                 case 5: vAddEndTag(pDiag, TAG_SECT4); break;
+01086                 case 6: vAddEndTag(pDiag, TAG_SECT5); break;
+01087                 default:
+01088                         DBG_DEC(usHeaderLevelCurrent);
+01089                         DBG_FIXME();
+01090                         return;
+01091                 }
+01092         }
+01093 
+01094         DBG_DEC(usHeaderLevelCurrent);
+01095 
+01096         vStackTrace();
+01097 } /* end of vCloseHeaderLevels */
+01098 
+01099 /*
+01100  * vSetHeadersXML - set the headers
+01101  */
+01102 void
+01103 vSetHeadersXML(diagram_type *pDiag, USHORT usIstd)
+01104 {
+01105         fail(pDiag == NULL);
+01106 
+01107         if (usIstd == 0 || usIstd > 6) {
+01108                 DBG_DEC_C(usIstd != 0 && usIstd <= 9, usIstd);
+01109                 return;
+01110         }
+01111         DBG_DEC(usIstd);
+01112 
+01113         if (bTableOpen || uiListLevel != 0) {
+01114                 /* No headers when you're in a table or in a list */
+01115                 return;
+01116         }
+01117 
+01118         /* Close levels */
+01119         vCloseHeaderLevels(pDiag, usIstd);
+01120 
+01121         DBG_DEC(usHeaderLevelCurrent);
+01122 
+01123         /* Open levels */
+01124         while (usHeaderLevelCurrent < usIstd) {
+01125                 switch (usHeaderLevelCurrent) {
+01126                 case 0: vAddStartTag(pDiag, TAG_CHAPTER, NULL); break;
+01127                 case 1: vAddStartTag(pDiag, TAG_SECT1, NULL); break;
+01128                 case 2: vAddStartTag(pDiag, TAG_SECT2, NULL); break;
+01129                 case 3: vAddStartTag(pDiag, TAG_SECT3, NULL); break;
+01130                 case 4: vAddStartTag(pDiag, TAG_SECT4, NULL); break;
+01131                 case 5: vAddStartTag(pDiag, TAG_SECT5, NULL); break;
+01132                 default:
+01133                         DBG_DEC(usHeaderLevelCurrent);
+01134                         DBG_FIXME();
+01135                         return;
+01136                 }
+01137                 fail(usIstd == 0);
+01138                 /* The next paragraph should be a title */
+01139                 if (usHeaderLevelCurrent < usIstd) {
+01140                         /* This chapter level is not in the Word document */
+01141                         vAddCombinedTag(pDiag, TAG_TITLE, NULL);
+01142                 } else {
+01143                         vAddStartTag(pDiag, TAG_TITLE, NULL);
+01144                 }
+01145         }
+01146 } /* end of vSetHeadersXML */
+01147 
+01148 /*
+01149  * Create a start of a list
+01150  */
+01151 void
+01152 vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
+01153 {
+01154         const char      *szAttr;
+01155         UCHAR           ucTag;
+01156 
+01157         fail(pDiag == NULL);
+01158 
+01159         if (bIsEndOfTable) {
+01160                 /* FIXME: until a list in a table is allowed */
+01161                 vEndOfTableXML(pDiag);
+01162         }
+01163 
+01164         if (bTableOpen) {
+01165                 /* FIXME: a list in a table should be allowed */
+01166                 return;
+01167         }
+01168 
+01169         if (usHeaderLevelCurrent == 0) {
+01170                 /* No list without an open header */
+01171                 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
+01172                 /* Dummy title */
+01173                 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
+01174         }
+01175 
+01176         switch (ucNFC) {
+01177         case LIST_ARABIC_NUM:
+01178         case LIST_ORDINAL_NUM:
+01179         case LIST_NUMBER_TXT:
+01180         case LIST_ORDINAL_TXT:
+01181         case LIST_OUTLINE_NUM:
+01182                 ucTag = TAG_ORDEREDLIST;
+01183                 szAttr = "numeration='arabic'";
+01184                 break;
+01185         case LIST_UPPER_ROMAN:
+01186                 ucTag = TAG_ORDEREDLIST;
+01187                 szAttr = "numeration='upperroman'";
+01188                 break;
+01189         case LIST_LOWER_ROMAN:
+01190                 ucTag = TAG_ORDEREDLIST;
+01191                 szAttr = "numeration='lowerroman'";
+01192                 break;
+01193         case LIST_UPPER_ALPHA:
+01194                 ucTag = TAG_ORDEREDLIST;
+01195                 szAttr = "numeration='upperalpha'";
+01196                 break;
+01197         case LIST_LOWER_ALPHA:
+01198                 ucTag = TAG_ORDEREDLIST;
+01199                 szAttr = "numeration='loweralpha'";
+01200                 break;
+01201         case LIST_SPECIAL:
+01202         case LIST_SPECIAL2:
+01203         case LIST_BULLETS:
+01204                 ucTag = TAG_ITEMIZEDLIST;
+01205                 szAttr = "mark='bullet'";
+01206                 break;
+01207         default:
+01208                 ucTag = TAG_ORDEREDLIST;
+01209                 szAttr = "numeration='arabic'";
+01210                 DBG_HEX(ucNFC);
+01211                 DBG_FIXME();
+01212                 break;
+01213         }
+01214         vAddStartTag(pDiag, ucTag, szAttr);
+01215 } /* end of vStartOfListXML */
+01216 
+01217 /*
+01218  * Create an end of a list
+01219  */
+01220 void
+01221 vEndOfListXML(diagram_type *pDiag)
+01222 {
+01223         fail(pDiag == NULL);
+01224 
+01225         if (bTableOpen) {
+01226                 /* FIXME: a list in a table should be allowed */
+01227                 return;
+01228         }
+01229 
+01230         if (uiListLevel != 0) {
+01231                 vStackTrace();
+01232                 vAddEndTagsUntil2(pDiag, TAG_ITEMIZEDLIST, TAG_ORDEREDLIST);
+01233                 vStackTrace();
+01234         }
+01235 } /* end of vEndOfListXML */
+01236 
+01237 /*
+01238  * Create a start of a list item
+01239  */
+01240 void
+01241 vStartOfListItemXML(diagram_type *pDiag, BOOL bNoMarks)
+01242 {
+01243         const char      *szAttr;
+01244         UCHAR   ucTopTag;
+01245 
+01246         fail(pDiag == NULL);
+01247 
+01248         if (bTableOpen) {
+01249                 /* FIXME: a list in a table should be allowed */
+01250                 return;
+01251         }
+01252 
+01253         ucTopTag = ucReadStack();
+01254         if (ucTopTag != TAG_ITEMIZEDLIST && ucTopTag != TAG_ORDEREDLIST) {
+01255                 /* Must end a previous list item first */
+01256                 vAddEndTagsUntil1(pDiag, TAG_LISTITEM);
+01257         }
+01258 
+01259         DBG_DEC_C(ucReadStack() != TAG_ITEMIZEDLIST &&
+01260                 ucReadStack() != TAG_ORDEREDLIST, ucReadStack());
+01261 
+01262         /* Start a new list item */
+01263         szAttr = bNoMarks ? "override='none'" : NULL;
+01264         vAddStartTag(pDiag, TAG_LISTITEM, szAttr);
+01265         /* Start a new paragraph (independant of level) */
+01266         vAddStartTag(pDiag, TAG_PARA, NULL);
+01267 } /* end of vStartOfListItemXML */
+01268 
+01269 /*
+01270  * Create a start of a table
+01271  */
+01272 static void
+01273 vStartOfTable(diagram_type *pDiag, UCHAR ucBorderInfo)
+01274 {
+01275         const char      *szFrame;
+01276         BOOL    bNotReady;
+01277         UCHAR   ucTopTag;
+01278         char    cColSep, cRowSep;
+01279         char    szAttr[40];
+01280 
+01281         fail(pDiag == NULL);
+01282 
+01283         /* Close elements that cannot contain a table */
+01284         bNotReady = TRUE;
+01285         do {
+01286                 ucTopTag = ucReadStack();
+01287                 switch (ucTopTag) {
+01288                 case TAG_TITLE:
+01289                         fail(!bTitleOpen);
+01290                         vAddEndTag(pDiag, TAG_TITLE);
+01291                         break;
+01292                 case TAG_EMPHASIS:
+01293                         fail(!bEmphasisOpen);
+01294                         vAddEndTag(pDiag, TAG_EMPHASIS);
+01295                         break;
+01296                 case TAG_SUPERSCRIPT:
+01297                         fail(!bSuperscriptOpen);
+01298                         vAddEndTag(pDiag, TAG_SUPERSCRIPT);
+01299                         break;
+01300                 case TAG_SUBSCRIPT:
+01301                         fail(!bSubscriptOpen);
+01302                         vAddEndTag(pDiag, TAG_SUBSCRIPT);
+01303                         break;
+01304                 default:
+01305                         bNotReady = FALSE;
+01306                         break;
+01307                 }
+01308         } while (bNotReady);
+01309 
+01310         /* Create table attributes */
+01311         switch (ucBorderInfo) {
+01312         case TABLE_BORDER_TOP:
+01313                 szFrame = "top";
+01314                 break;
+01315         case TABLE_BORDER_LEFT|TABLE_BORDER_RIGHT:
+01316                 szFrame = "sides";
+01317                 break;
+01318         case TABLE_BORDER_TOP|TABLE_BORDER_BOTTOM:
+01319                 szFrame = "topbot";
+01320                 break;
+01321         case TABLE_BORDER_BOTTOM:
+01322                 szFrame = "bottom";
+01323                 break;
+01324         case TABLE_BORDER_TOP|TABLE_BORDER_LEFT|
+01325              TABLE_BORDER_BOTTOM|TABLE_BORDER_RIGHT:
+01326                 szFrame = "all";
+01327                 break;
+01328         default:
+01329                 szFrame = "none";
+01330                 break;
+01331         }
+01332         cColSep = bIsTableBorderLeft(ucBorderInfo) ||
+01333                   bIsTableBorderRight(ucBorderInfo) ? '1' : '0';
+01334         cRowSep = bIsTableBorderTop(ucBorderInfo) ||
+01335                   bIsTableBorderBottom(ucBorderInfo) ? '1' : '0';
+01336 
+01337         sprintf(szAttr, "frame='%.6s' colsep='%c' rowsep='%c'",
+01338                         szFrame, cColSep, cRowSep);
+01339 
+01340         if (usHeaderLevelCurrent == 0) {
+01341                 /* No table without an open header */
+01342                 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
+01343                 /* Dummy title */
+01344                 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
+01345         }
+01346         vAddStartTag(pDiag, TAG_INFORMALTABLE, szAttr);
+01347 } /* end of vStartOfTable */
+01348 
+01349 /*
+01350  * Create a start of a table group
+01351  */
+01352 static void
+01353 vStartOfTableGroup(diagram_type *pDiag,
+01354         int iNbrOfColumns, const short *asColumnWidth)
+01355 {
+01356         double  dWidth;
+01357         int     iIndex;
+01358         char    szCols[6 + 3 * sizeof(int) + 1 + 1];
+01359         char    szColWidth[10 + 3 * sizeof(short) + 3 + 3 + 1];
+01360 
+01361         fail(iNbrOfColumns < 1);
+01362         fail(asColumnWidth == NULL);
+01363 
+01364         sprintf(szCols, "cols='%d'", iNbrOfColumns);
+01365         vAddStartTag(pDiag, TAG_TGROUP, szCols);
+01366 
+01367         for (iIndex= 0; iIndex < iNbrOfColumns; iIndex++) {
+01368                 fail(asColumnWidth[iIndex] < 0);
+01369                 dWidth = dTwips2Points(asColumnWidth[iIndex]);
+01370                 if (dWidth <= 1.0) {
+01371                         strcpy(szColWidth, "colwidth='1.00pt'");
+01372                 } else {
+01373                         sprintf(szColWidth, "colwidth='%.2fpt'", dWidth);
+01374                 }
+01375                 vAddCombinedTag(pDiag, TAG_COLSPEC, szColWidth);
+01376         }
+01377 } /* end of vStartOfTableGroup */
+01378 
+01379 /*
+01380  * Create an end of a table
+01381  */
+01382 void
+01383 vEndOfTableXML(diagram_type *pDiag)
+01384 {
+01385         fail(pDiag == NULL);
+01386 
+01387         if (bTableOpen) {
+01388                 vAddEndTag(pDiag, TAG_TBODY);
+01389                 vAddEndTag(pDiag, TAG_TGROUP);
+01390                 vAddEndTag(pDiag, TAG_INFORMALTABLE);
+01391         }
+01392 } /* end of vEndOfTableXML */
+01393 
+01394 /*
+01395  * Add a table row
+01396  */
+01397 void
+01398 vAddTableRowXML(diagram_type *pDiag, char **aszColTxt,
+01399         int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo)
+01400 {
+01401         size_t  tCount, tStringLength;
+01402         int     iIndex;
+01403 
+01404         fail(pDiag == NULL);
+01405         fail(pDiag->pOutFile == NULL);
+01406         fail(aszColTxt == NULL);
+01407         fail(iNbrOfColumns < 1);
+01408         fail(asColumnWidth == NULL);
+01409 
+01410         if (iNbrOfColumns != iTableColumnsCurrent) {
+01411                 /* A new number of columns */
+01412                 /* End the old table body and table group (if they exist) */
+01413                 vAddEndTagOptional(pDiag, TAG_TBODY);
+01414                 vAddEndTagOptional(pDiag, TAG_TGROUP);
+01415                 if (!bTableOpen) {
+01416                         /* No table yet. Start a new table */
+01417                         vStartOfTable(pDiag, ucBorderInfo);
+01418                 }
+01419                 /* Start a new table group and a new table body */
+01420                 vStartOfTableGroup(pDiag, iNbrOfColumns, asColumnWidth);
+01421                 vAddStartTag(pDiag, TAG_TBODY, NULL);
+01422                 iTableColumnsCurrent = iNbrOfColumns;
+01423         }
+01424 
+01425         /* Add the table row */
+01426         vAddStartTag(pDiag, TAG_ROW, NULL);
+01427         for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
+01428                 /* Add a table cell */
+01429                 fail(aszColTxt[iIndex] == NULL);
+01430                 vAddStartTag(pDiag, TAG_ENTRY, NULL);
+01431                 tStringLength = strlen(aszColTxt[iIndex]);
+01432                 for (tCount = 0; tCount < tStringLength; tCount++) {
+01433                         vPrintChar(pDiag, aszColTxt[iIndex][tCount]);
+01434                 }
+01435                 vAddEndTag(pDiag, TAG_ENTRY);
+01436         }
+01437         vAddEndTag(pDiag, TAG_ROW);
+01438 } /* end of vAddTableRowXML */
+
+
Generated by  + +doxygen 1.6.2
+ +