diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/xml_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/xml_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1454 +0,0 @@ - - -
- -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 */ -