00001
00002
00003
00004
00005
00006
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()
00020 #endif
00021
00022
00023 static encoding_type eEncoding = encoding_neutral;
00024
00025 static int iWordVersion = -1;
00026
00027 static BOOL bOldMacFile = FALSE;
00028
00029 static BOOL bEmphasisOpen = FALSE;
00030
00031 static BOOL bSuperscriptOpen = FALSE;
00032
00033 static BOOL bSubscriptOpen = FALSE;
00034
00035 static BOOL bTitleOpen = FALSE;
00036
00037 static BOOL bTableOpen = FALSE;
00038
00039 static BOOL bFootnoteOpen = FALSE;
00040
00041 static UINT uiParagraphLevel = 0;
00042
00043 static UINT uiListLevel = 0;
00044
00045 static BOOL bEmptyListLevel = TRUE;
00046
00047 static USHORT usHeaderLevelCurrent = 0;
00048
00049 static BOOL bEmptyHeaderLevel = TRUE;
00050
00051 static int iTableColumnsCurrent = 0;
00052
00053 static UINT uiFootnoteNumber = 0;
00054
00055
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
00062
00063
00064 static UCHAR *aucStack = NULL;
00065 static size_t tStacksize = 0;
00066 static size_t tStackNextFree = 0;
00067
00068
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
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 }
00164
00165
00166
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 }
00186 #endif
00187
00188
00189
00190
00191 static void
00192 vPushStack(UCHAR ucTag)
00193 {
00194 fail(tStackNextFree > tStacksize);
00195
00196 if (tStackNextFree == tStacksize) {
00197
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 }
00207
00208
00209
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 }
00225
00226
00227
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
00238 return TAG_NOTAG;
00239 }
00240 return aucStack[tStackNextFree - 1];
00241 }
00242
00243
00244
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 }
00257
00258
00259
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
00277 ucTopTag = ucReadStack();
00278 bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT;
00279 if (bSuScript) {
00280 vAddEndTag(pDiag, ucTopTag);
00281 }
00282
00283
00284 vAddStartTag(pDiag, TAG_FOOTNOTE, NULL);
00285 vAddStartTag(pDiag, TAG_PARA, NULL);
00286
00287
00288 for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) {
00289 if (*pcTmp == PAR_END) {
00290 if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') {
00291
00292 vAddEndTag(pDiag, TAG_PARA);
00293 vAddStartTag(pDiag, TAG_PARA, NULL);
00294 }
00295 } else {
00296 vPrintChar(pDiag, *pcTmp);
00297 }
00298 }
00299
00300
00301 vAddEndTag(pDiag, TAG_PARA);
00302 vAddEndTag(pDiag, TAG_FOOTNOTE);
00303
00304
00305 if (bSuScript) {
00306 vAddStartTag(pDiag, ucTopTag, NULL);
00307 }
00308 }
00309
00310
00311
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 }
00338
00339
00340
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 }
00365
00366
00367
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 }
00384
00385
00386
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
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 }
00479
00480
00481
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
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
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 }
00572
00573
00574
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 }
00586
00587
00588
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 }
00615
00616
00617
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
00636
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
00647
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 }
00661
00662
00663
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
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
00696 if (szTitle != NULL && szTitle[0] != '\0') {
00697 vAddStartTag(pDiag, TAG_TITLE, NULL);
00698 vPrintSpecialString(pDiag, szTitle);
00699 vAddEndTag(pDiag, TAG_TITLE);
00700 }
00701
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 }
00738
00739
00740
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
00753
00754
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
00774 tStacksize = INITIAL_STACK_SIZE;
00775 aucStack = xcalloc(tStacksize, sizeof(UCHAR));
00776 tStackNextFree = 0;
00777 }
00778
00779
00780
00781
00782 void
00783 vEpilogueXML(diagram_type *pDiag)
00784 {
00785 vStackTrace();
00786
00787 vAddEndTagsUntil1(pDiag, TAG_BOOK);
00788
00789 vStackTrace();
00790
00791
00792 fail(tStackNextFree != 0);
00793 tStacksize = 0;
00794 aucStack = xfree(aucStack);
00795 tStackNextFree = 0;
00796 }
00797
00798
00799
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
00819 bEmphasisNew = FALSE;
00820 bSuperscriptNew = FALSE;
00821 bSubscriptNew = FALSE;
00822 } else {
00823
00824 bEmphasisNew = bIsBold(usFontstyle) ||
00825 bIsItalic(usFontstyle) ||
00826 bIsUnderline(usFontstyle) ||
00827 bIsStrike(usFontstyle);
00828 bSuperscriptNew = bIsSuperscript(usFontstyle);
00829 bSubscriptNew = bIsSubscript(usFontstyle);
00830 }
00831
00832
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
00868 vStartOfParagraphXML(pDiag, 1);
00869
00870
00871 for (iCount = (int)tNextFree - 1; iCount > 0; iCount--) {
00872 vAddStartTag(pDiag, aucStorage[iCount], NULL);
00873 }
00874
00875
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
00898 for (iCount = 0; iCount < (int)tStringLength; iCount++) {
00899 vPrintChar(pDiag, szString[iCount]);
00900 }
00901 }
00902
00903
00904
00905
00906 void
00907 vMove2NextLineXML(diagram_type *pDiag)
00908 {
00909 fail(pDiag == NULL);
00910
00911
00912
00913
00914
00915
00916 }
00917
00918
00919
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 }
00938
00939
00940
00941
00942
00943
00944 void
00945 vStartOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
00946 {
00947 fail(pDiag == NULL);
00948
00949 if (uiParagraphLevel >= uiMaxLevel || bTitleOpen) {
00950
00951 return;
00952 }
00953 if (uiListLevel != 0 && bEmptyListLevel) {
00954
00955 return;
00956 }
00957 if (usHeaderLevelCurrent == 0) {
00958
00959 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
00960
00961 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
00962 }
00963 vAddStartTag(pDiag, TAG_PARA, NULL);
00964 }
00965
00966
00967
00968
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 }
01023
01024
01025
01026
01027 void
01028 vEndOfPageXML(diagram_type *pDiag)
01029 {
01030 if (bTableOpen || usHeaderLevelCurrent == 0) {
01031
01032 return;
01033 }
01034 if (bTitleOpen) {
01035
01036
01037 vEndOfParagraphXML(pDiag, UINT_MAX);
01038 vStartOfParagraphXML(pDiag, UINT_MAX);
01039 return;
01040 }
01041 vAddCombinedTag(pDiag, TAG_BEGINPAGE, NULL);
01042 }
01043
01044
01045
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 }
01098
01099
01100
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
01115 return;
01116 }
01117
01118
01119 vCloseHeaderLevels(pDiag, usIstd);
01120
01121 DBG_DEC(usHeaderLevelCurrent);
01122
01123
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
01139 if (usHeaderLevelCurrent < usIstd) {
01140
01141 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
01142 } else {
01143 vAddStartTag(pDiag, TAG_TITLE, NULL);
01144 }
01145 }
01146 }
01147
01148
01149
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
01161 vEndOfTableXML(pDiag);
01162 }
01163
01164 if (bTableOpen) {
01165
01166 return;
01167 }
01168
01169 if (usHeaderLevelCurrent == 0) {
01170
01171 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
01172
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 }
01216
01217
01218
01219
01220 void
01221 vEndOfListXML(diagram_type *pDiag)
01222 {
01223 fail(pDiag == NULL);
01224
01225 if (bTableOpen) {
01226
01227 return;
01228 }
01229
01230 if (uiListLevel != 0) {
01231 vStackTrace();
01232 vAddEndTagsUntil2(pDiag, TAG_ITEMIZEDLIST, TAG_ORDEREDLIST);
01233 vStackTrace();
01234 }
01235 }
01236
01237
01238
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
01250 return;
01251 }
01252
01253 ucTopTag = ucReadStack();
01254 if (ucTopTag != TAG_ITEMIZEDLIST && ucTopTag != TAG_ORDEREDLIST) {
01255
01256 vAddEndTagsUntil1(pDiag, TAG_LISTITEM);
01257 }
01258
01259 DBG_DEC_C(ucReadStack() != TAG_ITEMIZEDLIST &&
01260 ucReadStack() != TAG_ORDEREDLIST, ucReadStack());
01261
01262
01263 szAttr = bNoMarks ? "override='none'" : NULL;
01264 vAddStartTag(pDiag, TAG_LISTITEM, szAttr);
01265
01266 vAddStartTag(pDiag, TAG_PARA, NULL);
01267 }
01268
01269
01270
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
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
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
01342 vAddStartTag(pDiag, TAG_CHAPTER, NULL);
01343
01344 vAddCombinedTag(pDiag, TAG_TITLE, NULL);
01345 }
01346 vAddStartTag(pDiag, TAG_INFORMALTABLE, szAttr);
01347 }
01348
01349
01350
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 }
01378
01379
01380
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 }
01393
01394
01395
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
01412
01413 vAddEndTagOptional(pDiag, TAG_TBODY);
01414 vAddEndTagOptional(pDiag, TAG_TGROUP);
01415 if (!bTableOpen) {
01416
01417 vStartOfTable(pDiag, ucBorderInfo);
01418 }
01419
01420 vStartOfTableGroup(pDiag, iNbrOfColumns, asColumnWidth);
01421 vAddStartTag(pDiag, TAG_TBODY, NULL);
01422 iTableColumnsCurrent = iNbrOfColumns;
01423 }
01424
01425
01426 vAddStartTag(pDiag, TAG_ROW, NULL);
01427 for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
01428
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 }