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 @@ + + +
+ +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", "<"); +00326 break; +00327 case '>': +00328 fprintf(pDiag->pOutFile, "%s", ">"); +00329 break; +00330 case '&': +00331 fprintf(pDiag->pOutFile, "%s", "&"); +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 */ +