1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * xml.c
3*25b329d5SDavid du Colombier * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6f5736e95SDavid du Colombier * Functions to deal with the XML/DocBook format
7f5736e95SDavid du Colombier *
8f5736e95SDavid du Colombier */
9f5736e95SDavid du Colombier
10f5736e95SDavid du Colombier #include <string.h>
11f5736e95SDavid du Colombier #include "antiword.h"
12f5736e95SDavid du Colombier
13f5736e95SDavid du Colombier
14f5736e95SDavid du Colombier #define vAddEndTagsUntil1(p,t) vAddEndTagsUntil2(p,t,TAG_NOTAG)
15f5736e95SDavid du Colombier
16f5736e95SDavid du Colombier #if defined(DEBUG)
17f5736e95SDavid du Colombier #define vStackTrace() __vStackTrace(__LINE__)
18f5736e95SDavid du Colombier #else
19f5736e95SDavid du Colombier #define vStackTrace() /* EMPTY */
20f5736e95SDavid du Colombier #endif /* DEBUG */
21f5736e95SDavid du Colombier
22*25b329d5SDavid du Colombier /* The character set */
23*25b329d5SDavid du Colombier static encoding_type eEncoding = encoding_neutral;
24*25b329d5SDavid du Colombier /* Word version */
25*25b329d5SDavid du Colombier static int iWordVersion = -1;
26*25b329d5SDavid du Colombier /* Special treatment for files from Word 4/5/6 on an Apple Macintosh */
27*25b329d5SDavid du Colombier static BOOL bOldMacFile = FALSE;
28f5736e95SDavid du Colombier /* Text is emphasised */
29f5736e95SDavid du Colombier static BOOL bEmphasisOpen = FALSE;
30f5736e95SDavid du Colombier /* Text is superscript */
31f5736e95SDavid du Colombier static BOOL bSuperscriptOpen = FALSE;
32f5736e95SDavid du Colombier /* Text is subscript */
33f5736e95SDavid du Colombier static BOOL bSubscriptOpen = FALSE;
34f5736e95SDavid du Colombier /* Title is open */
35f5736e95SDavid du Colombier static BOOL bTitleOpen = FALSE;
36f5736e95SDavid du Colombier /* Table is open */
37f5736e95SDavid du Colombier static BOOL bTableOpen = FALSE;
38*25b329d5SDavid du Colombier /* Footnote is open */
39*25b329d5SDavid du Colombier static BOOL bFootnoteOpen = FALSE;
40f5736e95SDavid du Colombier /* Current paragraph level */
41f5736e95SDavid du Colombier static UINT uiParagraphLevel = 0;
42f5736e95SDavid du Colombier /* Current list level */
43f5736e95SDavid du Colombier static UINT uiListLevel = 0;
44f5736e95SDavid du Colombier /* Current list level is still empty */
45f5736e95SDavid du Colombier static BOOL bEmptyListLevel = TRUE;
46f5736e95SDavid du Colombier /* Current header level */
47f5736e95SDavid du Colombier static USHORT usHeaderLevelCurrent = 0;
48f5736e95SDavid du Colombier /* Current header level is still empty */
49f5736e95SDavid du Colombier static BOOL bEmptyHeaderLevel = TRUE;
50f5736e95SDavid du Colombier /* Number of columns in the current table */
51f5736e95SDavid du Colombier static int iTableColumnsCurrent = 0;
52*25b329d5SDavid du Colombier /* Footnote number */
53*25b329d5SDavid du Colombier static UINT uiFootnoteNumber = 0;
54f5736e95SDavid du Colombier
55f5736e95SDavid du Colombier /* Constants for the stack */
56f5736e95SDavid du Colombier #define INITIAL_STACK_SIZE 10
57f5736e95SDavid du Colombier #if defined(DEBUG)
58f5736e95SDavid du Colombier #define EXTENSION_STACK_SIZE 2
59f5736e95SDavid du Colombier #else
60f5736e95SDavid du Colombier #define EXTENSION_STACK_SIZE 10
61f5736e95SDavid du Colombier #endif /* DEBUG */
62f5736e95SDavid du Colombier
63f5736e95SDavid du Colombier /* Variables for the stack */
64f5736e95SDavid du Colombier static UCHAR *aucStack = NULL;
65f5736e95SDavid du Colombier static size_t tStacksize = 0;
66f5736e95SDavid du Colombier static size_t tStackNextFree = 0;
67f5736e95SDavid du Colombier
68f5736e95SDavid du Colombier /* Constants for the tags */
69f5736e95SDavid du Colombier #define TAG_NOTAG (UCHAR)0
70f5736e95SDavid du Colombier #define TAG_AUTHOR (UCHAR)1
71f5736e95SDavid du Colombier #define TAG_BEGINPAGE (UCHAR)2
72f5736e95SDavid du Colombier #define TAG_BOOK (UCHAR)3
73f5736e95SDavid du Colombier #define TAG_BOOKINFO (UCHAR)4
74f5736e95SDavid du Colombier #define TAG_CHAPTER (UCHAR)5
75f5736e95SDavid du Colombier #define TAG_COLSPEC (UCHAR)6
76f5736e95SDavid du Colombier #define TAG_CORPNAME (UCHAR)7
77f5736e95SDavid du Colombier #define TAG_DATE (UCHAR)8
78f5736e95SDavid du Colombier #define TAG_EMPHASIS (UCHAR)9
79f5736e95SDavid du Colombier #define TAG_ENTRY (UCHAR)10
80f5736e95SDavid du Colombier #define TAG_FILENAME (UCHAR)11
81*25b329d5SDavid du Colombier #define TAG_FOOTNOTE (UCHAR)12
82*25b329d5SDavid du Colombier #define TAG_INFORMALTABLE (UCHAR)13
83*25b329d5SDavid du Colombier #define TAG_ITEMIZEDLIST (UCHAR)14
84*25b329d5SDavid du Colombier #define TAG_LISTITEM (UCHAR)15
85*25b329d5SDavid du Colombier #define TAG_ORDEREDLIST (UCHAR)16
86*25b329d5SDavid du Colombier #define TAG_PARA (UCHAR)17
87*25b329d5SDavid du Colombier #define TAG_ROW (UCHAR)18
88*25b329d5SDavid du Colombier #define TAG_SECT1 (UCHAR)19
89*25b329d5SDavid du Colombier #define TAG_SECT2 (UCHAR)20
90*25b329d5SDavid du Colombier #define TAG_SECT3 (UCHAR)21
91*25b329d5SDavid du Colombier #define TAG_SECT4 (UCHAR)22
92*25b329d5SDavid du Colombier #define TAG_SECT5 (UCHAR)23
93*25b329d5SDavid du Colombier #define TAG_SUBSCRIPT (UCHAR)24
94*25b329d5SDavid du Colombier #define TAG_SUBTITLE (UCHAR)25
95*25b329d5SDavid du Colombier #define TAG_SUPERSCRIPT (UCHAR)26
96*25b329d5SDavid du Colombier #define TAG_SURNAME (UCHAR)27
97*25b329d5SDavid du Colombier #define TAG_TBODY (UCHAR)28
98*25b329d5SDavid du Colombier #define TAG_TGROUP (UCHAR)29
99*25b329d5SDavid du Colombier #define TAG_TITLE (UCHAR)30
100f5736e95SDavid du Colombier
101f5736e95SDavid du Colombier typedef struct docbooktags_tag {
102f5736e95SDavid du Colombier UCHAR ucTagnumber;
103f5736e95SDavid du Colombier char szTagname[15];
104*25b329d5SDavid du Colombier BOOL bAddNewlineStart;
105*25b329d5SDavid du Colombier BOOL bAddNewlineEnd;
106f5736e95SDavid du Colombier } docbooktags_type;
107f5736e95SDavid du Colombier
108f5736e95SDavid du Colombier static const docbooktags_type atDocBookTags[] = {
109*25b329d5SDavid du Colombier { TAG_NOTAG, "!ERROR!", TRUE, TRUE },
110*25b329d5SDavid du Colombier { TAG_AUTHOR, "author", TRUE, TRUE },
111*25b329d5SDavid du Colombier { TAG_BEGINPAGE, "beginpage", TRUE, TRUE },
112*25b329d5SDavid du Colombier { TAG_BOOK, "book", TRUE, TRUE },
113*25b329d5SDavid du Colombier { TAG_BOOKINFO, "bookinfo", TRUE, TRUE },
114*25b329d5SDavid du Colombier { TAG_CHAPTER, "chapter", TRUE, TRUE },
115*25b329d5SDavid du Colombier { TAG_COLSPEC, "colspec", TRUE, TRUE },
116*25b329d5SDavid du Colombier { TAG_CORPNAME, "corpname", FALSE, FALSE },
117*25b329d5SDavid du Colombier { TAG_DATE, "date", FALSE, FALSE },
118*25b329d5SDavid du Colombier { TAG_EMPHASIS, "emphasis", FALSE, FALSE },
119*25b329d5SDavid du Colombier { TAG_ENTRY, "entry", TRUE, TRUE },
120*25b329d5SDavid du Colombier { TAG_FILENAME, "filename", FALSE, FALSE },
121*25b329d5SDavid du Colombier { TAG_FOOTNOTE, "footnote", FALSE, FALSE },
122*25b329d5SDavid du Colombier { TAG_INFORMALTABLE, "informaltable",TRUE, TRUE },
123*25b329d5SDavid du Colombier { TAG_ITEMIZEDLIST, "itemizedlist", TRUE, TRUE },
124*25b329d5SDavid du Colombier { TAG_LISTITEM, "listitem", TRUE, TRUE },
125*25b329d5SDavid du Colombier { TAG_ORDEREDLIST, "orderedlist", TRUE, TRUE },
126*25b329d5SDavid du Colombier { TAG_PARA, "para", TRUE, TRUE },
127*25b329d5SDavid du Colombier { TAG_ROW, "row", TRUE, TRUE },
128*25b329d5SDavid du Colombier { TAG_SECT1, "sect1", TRUE, TRUE },
129*25b329d5SDavid du Colombier { TAG_SECT2, "sect2", TRUE, TRUE },
130*25b329d5SDavid du Colombier { TAG_SECT3, "sect3", TRUE, TRUE },
131*25b329d5SDavid du Colombier { TAG_SECT4, "sect4", TRUE, TRUE },
132*25b329d5SDavid du Colombier { TAG_SECT5, "sect5", TRUE, TRUE },
133*25b329d5SDavid du Colombier { TAG_SUBSCRIPT, "subscript", FALSE, FALSE },
134*25b329d5SDavid du Colombier { TAG_SUBTITLE, "subtitle", FALSE, FALSE },
135*25b329d5SDavid du Colombier { TAG_SUPERSCRIPT, "superscript", FALSE, FALSE },
136*25b329d5SDavid du Colombier { TAG_SURNAME, "surname", FALSE, FALSE },
137*25b329d5SDavid du Colombier { TAG_TBODY, "tbody", TRUE, TRUE },
138*25b329d5SDavid du Colombier { TAG_TGROUP, "tgroup", TRUE, TRUE },
139*25b329d5SDavid du Colombier { TAG_TITLE, "title", FALSE, FALSE },
140f5736e95SDavid du Colombier };
141f5736e95SDavid du Colombier
142*25b329d5SDavid du Colombier static void vAddStartTag(diagram_type *, UCHAR, const char *);
143*25b329d5SDavid du Colombier static void vAddEndTag(diagram_type *, UCHAR);
144*25b329d5SDavid du Colombier static void vAddCombinedTag(diagram_type *, UCHAR, const char *);
145*25b329d5SDavid du Colombier static void vPrintChar(diagram_type *, char);
146*25b329d5SDavid du Colombier
147f5736e95SDavid du Colombier
148f5736e95SDavid du Colombier #if defined(DEBUG)
149f5736e95SDavid du Colombier /*
150f5736e95SDavid du Colombier * vCheckTagTable - check the tag table
151f5736e95SDavid du Colombier */
152f5736e95SDavid du Colombier static void
vCheckTagTable(void)153f5736e95SDavid du Colombier vCheckTagTable(void)
154f5736e95SDavid du Colombier {
155f5736e95SDavid du Colombier size_t tIndex;
156f5736e95SDavid du Colombier
157f5736e95SDavid du Colombier for (tIndex = 0; tIndex < elementsof(atDocBookTags); tIndex++) {
158f5736e95SDavid du Colombier if (tIndex != (size_t)atDocBookTags[tIndex].ucTagnumber) {
159f5736e95SDavid du Colombier DBG_DEC(tIndex);
160f5736e95SDavid du Colombier werr(1, "Array atDocBookTags is broken");
161f5736e95SDavid du Colombier }
162f5736e95SDavid du Colombier }
163f5736e95SDavid du Colombier } /* end of vCheckTagTable */
164f5736e95SDavid du Colombier
165f5736e95SDavid du Colombier /*
166f5736e95SDavid du Colombier * __vStackTrace - show a stack trace
167f5736e95SDavid du Colombier */
168f5736e95SDavid du Colombier static void
__vStackTrace(int iLine)169f5736e95SDavid du Colombier __vStackTrace(int iLine)
170f5736e95SDavid du Colombier {
171f5736e95SDavid du Colombier int iIndex;
172f5736e95SDavid du Colombier
173f5736e95SDavid du Colombier fprintf(stderr, "%s[%3d]:\n", __FILE__, iLine);
174f5736e95SDavid du Colombier
175f5736e95SDavid du Colombier if (tStackNextFree == 0) {
176f5736e95SDavid du Colombier fprintf(stderr, "The stack is empty\n");
177f5736e95SDavid du Colombier return;
178f5736e95SDavid du Colombier }
179f5736e95SDavid du Colombier for (iIndex = (int)tStackNextFree - 1; iIndex >= 0; iIndex--) {
180f5736e95SDavid du Colombier fprintf(stderr, "%2d: %2d: '%s'\n",
181f5736e95SDavid du Colombier iIndex,
182f5736e95SDavid du Colombier (int)atDocBookTags[(UINT)aucStack[iIndex]].ucTagnumber,
183f5736e95SDavid du Colombier atDocBookTags[(UINT)aucStack[iIndex]].szTagname);
184f5736e95SDavid du Colombier }
185f5736e95SDavid du Colombier } /* end of __vStackTrace */
186f5736e95SDavid du Colombier #endif /* DEBUG */
187f5736e95SDavid du Colombier
188f5736e95SDavid du Colombier /*
189f5736e95SDavid du Colombier * vPushStack - push a tag onto the stack
190f5736e95SDavid du Colombier */
191f5736e95SDavid du Colombier static void
vPushStack(UCHAR ucTag)192f5736e95SDavid du Colombier vPushStack(UCHAR ucTag)
193f5736e95SDavid du Colombier {
194f5736e95SDavid du Colombier fail(tStackNextFree > tStacksize);
195f5736e95SDavid du Colombier
196f5736e95SDavid du Colombier if (tStackNextFree == tStacksize) {
197f5736e95SDavid du Colombier /* The stack is full; enlarge the stack */
198f5736e95SDavid du Colombier tStacksize += EXTENSION_STACK_SIZE;
199f5736e95SDavid du Colombier aucStack = xrealloc(aucStack, tStacksize * sizeof(UCHAR));
200f5736e95SDavid du Colombier DBG_DEC(tStacksize);
201f5736e95SDavid du Colombier }
202f5736e95SDavid du Colombier
203f5736e95SDavid du Colombier fail(tStackNextFree >= tStacksize);
204f5736e95SDavid du Colombier
205f5736e95SDavid du Colombier aucStack[tStackNextFree++] = ucTag;
206f5736e95SDavid du Colombier } /* end of vPushStack */
207f5736e95SDavid du Colombier
208f5736e95SDavid du Colombier /*
209f5736e95SDavid du Colombier * vPopStack - pop a tag from the stack
210f5736e95SDavid du Colombier */
211f5736e95SDavid du Colombier static UCHAR
ucPopStack(void)212f5736e95SDavid du Colombier ucPopStack(void)
213f5736e95SDavid du Colombier {
214f5736e95SDavid du Colombier DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree);
215f5736e95SDavid du Colombier DBG_DEC_C(tStackNextFree > tStacksize, tStacksize);
216f5736e95SDavid du Colombier fail(tStackNextFree > tStacksize);
217f5736e95SDavid du Colombier fail(tStackNextFree == 0);
218f5736e95SDavid du Colombier
219f5736e95SDavid du Colombier if (tStackNextFree == 0) {
220f5736e95SDavid du Colombier werr(1, "The stack is empty, unable to continue");
221f5736e95SDavid du Colombier return TAG_NOTAG;
222f5736e95SDavid du Colombier }
223f5736e95SDavid du Colombier return aucStack[--tStackNextFree];
224f5736e95SDavid du Colombier } /* end of ucPopStack */
225f5736e95SDavid du Colombier
226f5736e95SDavid du Colombier /*
227f5736e95SDavid du Colombier * vReadStack - read a tag from the top of the stack
228f5736e95SDavid du Colombier */
229f5736e95SDavid du Colombier static UCHAR
ucReadStack(void)230f5736e95SDavid du Colombier ucReadStack(void)
231f5736e95SDavid du Colombier {
232f5736e95SDavid du Colombier DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree);
233f5736e95SDavid du Colombier DBG_DEC_C(tStackNextFree > tStacksize, tStacksize);
234f5736e95SDavid du Colombier fail(tStackNextFree > tStacksize);
235f5736e95SDavid du Colombier
236f5736e95SDavid du Colombier if (tStackNextFree == 0) {
237f5736e95SDavid du Colombier /* The stack is empty */
238f5736e95SDavid du Colombier return TAG_NOTAG;
239f5736e95SDavid du Colombier }
240f5736e95SDavid du Colombier return aucStack[tStackNextFree - 1];
241f5736e95SDavid du Colombier } /* end of ucReadStack */
242f5736e95SDavid du Colombier
243f5736e95SDavid du Colombier /*
244f5736e95SDavid du Colombier * vPrintLevel - print the tag level
245f5736e95SDavid du Colombier */
246f5736e95SDavid du Colombier static void
vPrintLevel(FILE * pOutFile)247f5736e95SDavid du Colombier vPrintLevel(FILE *pOutFile)
248f5736e95SDavid du Colombier {
249f5736e95SDavid du Colombier size_t tIndex;
250f5736e95SDavid du Colombier
251f5736e95SDavid du Colombier fail(pOutFile == NULL);
252f5736e95SDavid du Colombier
253f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tStackNextFree; tIndex++) {
254f5736e95SDavid du Colombier (void)putc(' ', pOutFile);
255f5736e95SDavid du Colombier }
256f5736e95SDavid du Colombier } /* end of vPrintLevel */
257f5736e95SDavid du Colombier
258f5736e95SDavid du Colombier /*
259*25b329d5SDavid du Colombier * vPrintFootnote - print a footnote
260*25b329d5SDavid du Colombier */
261*25b329d5SDavid du Colombier static void
vPrintFootnote(diagram_type * pDiag,UINT uiFootnoteIndex)262*25b329d5SDavid du Colombier vPrintFootnote(diagram_type *pDiag, UINT uiFootnoteIndex)
263*25b329d5SDavid du Colombier {
264*25b329d5SDavid du Colombier const char *szText, *pcTmp;
265*25b329d5SDavid du Colombier BOOL bSuScript;
266*25b329d5SDavid du Colombier UCHAR ucTopTag;
267*25b329d5SDavid du Colombier
268*25b329d5SDavid du Colombier TRACE_MSG("vPrintFootnote");
269*25b329d5SDavid du Colombier
270*25b329d5SDavid du Colombier szText = szGetFootnootText(uiFootnoteIndex);
271*25b329d5SDavid du Colombier
272*25b329d5SDavid du Colombier if (szText == NULL) {
273*25b329d5SDavid du Colombier szText = "";
274*25b329d5SDavid du Colombier }
275*25b329d5SDavid du Colombier
276*25b329d5SDavid du Colombier /* Remove the subscript/superscript (if any) */
277*25b329d5SDavid du Colombier ucTopTag = ucReadStack();
278*25b329d5SDavid du Colombier bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT;
279*25b329d5SDavid du Colombier if (bSuScript) {
280*25b329d5SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
281*25b329d5SDavid du Colombier }
282*25b329d5SDavid du Colombier
283*25b329d5SDavid du Colombier /* Start a footnote */
284*25b329d5SDavid du Colombier vAddStartTag(pDiag, TAG_FOOTNOTE, NULL);
285*25b329d5SDavid du Colombier vAddStartTag(pDiag, TAG_PARA, NULL);
286*25b329d5SDavid du Colombier
287*25b329d5SDavid du Colombier /* Print a footnote */
288*25b329d5SDavid du Colombier for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) {
289*25b329d5SDavid du Colombier if (*pcTmp == PAR_END) {
290*25b329d5SDavid du Colombier if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') {
291*25b329d5SDavid du Colombier /* PAR_END is not empty and not last */
292*25b329d5SDavid du Colombier vAddEndTag(pDiag, TAG_PARA);
293*25b329d5SDavid du Colombier vAddStartTag(pDiag, TAG_PARA, NULL);
294*25b329d5SDavid du Colombier }
295*25b329d5SDavid du Colombier } else {
296*25b329d5SDavid du Colombier vPrintChar(pDiag, *pcTmp);
297*25b329d5SDavid du Colombier }
298*25b329d5SDavid du Colombier }
299*25b329d5SDavid du Colombier
300*25b329d5SDavid du Colombier /* End a footnote */
301*25b329d5SDavid du Colombier vAddEndTag(pDiag, TAG_PARA);
302*25b329d5SDavid du Colombier vAddEndTag(pDiag, TAG_FOOTNOTE);
303*25b329d5SDavid du Colombier
304*25b329d5SDavid du Colombier /* Repair the subscript/superscript (if any) */
305*25b329d5SDavid du Colombier if (bSuScript) {
306*25b329d5SDavid du Colombier vAddStartTag(pDiag, ucTopTag, NULL);
307*25b329d5SDavid du Colombier }
308*25b329d5SDavid du Colombier } /* end of vPrintFootnote */
309*25b329d5SDavid du Colombier
310*25b329d5SDavid du Colombier /*
311f5736e95SDavid du Colombier * vPrintChar - print a character with XML encoding
312f5736e95SDavid du Colombier */
313f5736e95SDavid du Colombier static void
vPrintChar(diagram_type * pDiag,char cChar)314*25b329d5SDavid du Colombier vPrintChar(diagram_type *pDiag, char cChar)
315f5736e95SDavid du Colombier {
316*25b329d5SDavid du Colombier fail(pDiag == NULL);
317*25b329d5SDavid du Colombier fail(pDiag->pOutFile == NULL);
318*25b329d5SDavid du Colombier
319f5736e95SDavid du Colombier switch (cChar) {
320*25b329d5SDavid du Colombier case FOOTNOTE_OR_ENDNOTE:
321*25b329d5SDavid du Colombier uiFootnoteNumber++;
322*25b329d5SDavid du Colombier vPrintFootnote(pDiag, uiFootnoteNumber - 1);
323*25b329d5SDavid du Colombier break;
324f5736e95SDavid du Colombier case '<':
325*25b329d5SDavid du Colombier fprintf(pDiag->pOutFile, "%s", "<");
326f5736e95SDavid du Colombier break;
327f5736e95SDavid du Colombier case '>':
328*25b329d5SDavid du Colombier fprintf(pDiag->pOutFile, "%s", ">");
329f5736e95SDavid du Colombier break;
330f5736e95SDavid du Colombier case '&':
331*25b329d5SDavid du Colombier fprintf(pDiag->pOutFile, "%s", "&");
332f5736e95SDavid du Colombier break;
333f5736e95SDavid du Colombier default:
334*25b329d5SDavid du Colombier (void)putc(cChar, pDiag->pOutFile);
335f5736e95SDavid du Colombier break;
336f5736e95SDavid du Colombier }
337f5736e95SDavid du Colombier } /* end of vPrintChar */
338f5736e95SDavid du Colombier
339f5736e95SDavid du Colombier /*
340*25b329d5SDavid du Colombier * vPrintSpecialChar - convert and print a character
341f5736e95SDavid du Colombier */
342f5736e95SDavid du Colombier static void
vPrintSpecialChar(diagram_type * pDiag,USHORT usChar)343*25b329d5SDavid du Colombier vPrintSpecialChar(diagram_type *pDiag, USHORT usChar)
344f5736e95SDavid du Colombier {
345f5736e95SDavid du Colombier ULONG ulChar;
346f5736e95SDavid du Colombier size_t tLen, tIndex;
347f5736e95SDavid du Colombier char szResult[4];
348f5736e95SDavid du Colombier
349*25b329d5SDavid du Colombier fail(pDiag == NULL);
350*25b329d5SDavid du Colombier fail(pDiag->pOutFile == NULL);
351*25b329d5SDavid du Colombier fail(iWordVersion < 0);
352*25b329d5SDavid du Colombier fail(eEncoding == encoding_neutral);
353f5736e95SDavid du Colombier
354f5736e95SDavid du Colombier ulChar = ulTranslateCharacters(usChar, 0, iWordVersion,
355f5736e95SDavid du Colombier conversion_xml, eEncoding, bOldMacFile);
356f5736e95SDavid du Colombier tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
357f5736e95SDavid du Colombier if (tLen == 1) {
358*25b329d5SDavid du Colombier vPrintChar(pDiag, szResult[0]);
359f5736e95SDavid du Colombier } else {
360f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tLen; tIndex++) {
361*25b329d5SDavid du Colombier (void)putc(szResult[tIndex], pDiag->pOutFile);
362f5736e95SDavid du Colombier }
363f5736e95SDavid du Colombier }
364*25b329d5SDavid du Colombier } /* end of vPrintSpecialChar */
365*25b329d5SDavid du Colombier
366*25b329d5SDavid du Colombier /*
367*25b329d5SDavid du Colombier * vPrintSpecialString - convert and print a string
368*25b329d5SDavid du Colombier */
369*25b329d5SDavid du Colombier static void
vPrintSpecialString(diagram_type * pDiag,const char * szString)370*25b329d5SDavid du Colombier vPrintSpecialString(diagram_type *pDiag, const char *szString)
371*25b329d5SDavid du Colombier {
372*25b329d5SDavid du Colombier int iIndex;
373*25b329d5SDavid du Colombier USHORT usChar;
374*25b329d5SDavid du Colombier
375*25b329d5SDavid du Colombier fail(pDiag == NULL);
376*25b329d5SDavid du Colombier fail(pDiag->pOutFile == NULL);
377*25b329d5SDavid du Colombier fail(szString == NULL);
378*25b329d5SDavid du Colombier
379*25b329d5SDavid du Colombier for (iIndex = 0; szString[iIndex] != '\0'; iIndex++) {
380*25b329d5SDavid du Colombier usChar = (USHORT)(UCHAR)szString[iIndex];
381*25b329d5SDavid du Colombier vPrintSpecialChar(pDiag, usChar);
382f5736e95SDavid du Colombier }
383*25b329d5SDavid du Colombier } /* end of vPrintSpecialString */
384f5736e95SDavid du Colombier
385f5736e95SDavid du Colombier /*
386f5736e95SDavid du Colombier * vAddStartTag - add the specified start tag to the file
387f5736e95SDavid du Colombier */
388f5736e95SDavid du Colombier static void
vAddStartTag(diagram_type * pDiag,UCHAR ucTag,const char * szAttribute)389f5736e95SDavid du Colombier vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
390f5736e95SDavid du Colombier {
391f5736e95SDavid du Colombier fail(pDiag == NULL);
392f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
393f5736e95SDavid du Colombier fail((size_t)ucTag >= elementsof(atDocBookTags));
394f5736e95SDavid du Colombier
395*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
396f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
397f5736e95SDavid du Colombier vPrintLevel(pDiag->pOutFile);
398f5736e95SDavid du Colombier }
399f5736e95SDavid du Colombier
400f5736e95SDavid du Colombier if (szAttribute == NULL || szAttribute[0] == '\0') {
401f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "<%s>",
402f5736e95SDavid du Colombier atDocBookTags[(UINT)ucTag].szTagname);
403f5736e95SDavid du Colombier } else {
404f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "<%s %s>",
405f5736e95SDavid du Colombier atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
406f5736e95SDavid du Colombier }
407f5736e95SDavid du Colombier
408*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
409f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
410f5736e95SDavid du Colombier pDiag->lXleft = 0;
411f5736e95SDavid du Colombier }
412f5736e95SDavid du Colombier
413f5736e95SDavid du Colombier vPushStack(ucTag);
414f5736e95SDavid du Colombier
415f5736e95SDavid du Colombier /* Set global variables */
416f5736e95SDavid du Colombier switch (ucTag) {
417f5736e95SDavid du Colombier case TAG_CHAPTER:
418f5736e95SDavid du Colombier usHeaderLevelCurrent = 1;
419f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
420f5736e95SDavid du Colombier break;
421f5736e95SDavid du Colombier case TAG_SECT1:
422f5736e95SDavid du Colombier usHeaderLevelCurrent = 2;
423f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
424f5736e95SDavid du Colombier break;
425f5736e95SDavid du Colombier case TAG_SECT2:
426f5736e95SDavid du Colombier usHeaderLevelCurrent = 3;
427f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
428f5736e95SDavid du Colombier break;
429f5736e95SDavid du Colombier case TAG_SECT3:
430f5736e95SDavid du Colombier usHeaderLevelCurrent = 4;
431f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
432f5736e95SDavid du Colombier break;
433f5736e95SDavid du Colombier case TAG_SECT4:
434f5736e95SDavid du Colombier usHeaderLevelCurrent = 5;
435f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
436f5736e95SDavid du Colombier break;
437f5736e95SDavid du Colombier case TAG_SECT5:
438f5736e95SDavid du Colombier usHeaderLevelCurrent = 6;
439f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
440f5736e95SDavid du Colombier break;
441f5736e95SDavid du Colombier case TAG_TITLE:
442f5736e95SDavid du Colombier fail(uiParagraphLevel != 0);
443f5736e95SDavid du Colombier bTitleOpen = TRUE;
444f5736e95SDavid du Colombier break;
445*25b329d5SDavid du Colombier case TAG_FOOTNOTE:
446*25b329d5SDavid du Colombier bFootnoteOpen = TRUE;
447*25b329d5SDavid du Colombier break;
448f5736e95SDavid du Colombier case TAG_PARA:
449*25b329d5SDavid du Colombier fail(bTitleOpen && !bFootnoteOpen);
450f5736e95SDavid du Colombier uiParagraphLevel++;
451f5736e95SDavid du Colombier bEmptyHeaderLevel = FALSE;
452f5736e95SDavid du Colombier break;
453f5736e95SDavid du Colombier case TAG_EMPHASIS:
454f5736e95SDavid du Colombier bEmphasisOpen = TRUE;
455f5736e95SDavid du Colombier break;
456f5736e95SDavid du Colombier case TAG_ITEMIZEDLIST:
457f5736e95SDavid du Colombier case TAG_ORDEREDLIST:
458f5736e95SDavid du Colombier uiListLevel++;
459f5736e95SDavid du Colombier bEmptyListLevel = TRUE;
460f5736e95SDavid du Colombier bEmptyHeaderLevel = FALSE;
461f5736e95SDavid du Colombier break;
462f5736e95SDavid du Colombier case TAG_LISTITEM:
463f5736e95SDavid du Colombier bEmptyListLevel = FALSE;
464f5736e95SDavid du Colombier break;
465f5736e95SDavid du Colombier case TAG_SUPERSCRIPT:
466f5736e95SDavid du Colombier bSuperscriptOpen = TRUE;
467f5736e95SDavid du Colombier break;
468f5736e95SDavid du Colombier case TAG_SUBSCRIPT:
469f5736e95SDavid du Colombier bSubscriptOpen = TRUE;
470f5736e95SDavid du Colombier break;
471f5736e95SDavid du Colombier case TAG_INFORMALTABLE:
472f5736e95SDavid du Colombier bTableOpen = TRUE;
473f5736e95SDavid du Colombier bEmptyHeaderLevel = FALSE;
474f5736e95SDavid du Colombier break;
475f5736e95SDavid du Colombier default:
476f5736e95SDavid du Colombier break;
477f5736e95SDavid du Colombier }
478f5736e95SDavid du Colombier } /* end of vAddStartTag */
479f5736e95SDavid du Colombier
480f5736e95SDavid du Colombier /*
481f5736e95SDavid du Colombier * vAddEndTag - add the specified end tag to the file
482f5736e95SDavid du Colombier */
483f5736e95SDavid du Colombier static void
vAddEndTag(diagram_type * pDiag,UCHAR ucTag)484f5736e95SDavid du Colombier vAddEndTag(diagram_type *pDiag, UCHAR ucTag)
485f5736e95SDavid du Colombier {
486f5736e95SDavid du Colombier UCHAR ucTopTag;
487f5736e95SDavid du Colombier
488f5736e95SDavid du Colombier fail(pDiag == NULL);
489f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
490f5736e95SDavid du Colombier fail((size_t)ucTag >= elementsof(atDocBookTags));
491f5736e95SDavid du Colombier
492f5736e95SDavid du Colombier #if defined(DEBUG)
493f5736e95SDavid du Colombier ucTopTag = ucReadStack();
494f5736e95SDavid du Colombier if (ucTag != ucTopTag) {
495f5736e95SDavid du Colombier DBG_DEC(ucTag);
496f5736e95SDavid du Colombier DBG_MSG(atDocBookTags[(UINT)ucTag].szTagname);
497f5736e95SDavid du Colombier vStackTrace();
498f5736e95SDavid du Colombier }
499f5736e95SDavid du Colombier #endif /* DEBUG */
500f5736e95SDavid du Colombier
501f5736e95SDavid du Colombier ucTopTag = ucPopStack();
502f5736e95SDavid du Colombier fail((size_t)ucTopTag >= elementsof(atDocBookTags));
503f5736e95SDavid du Colombier if (ucTag != ucTopTag) {
504f5736e95SDavid du Colombier DBG_DEC(ucTag);
505f5736e95SDavid du Colombier DBG_DEC(ucTopTag);
506f5736e95SDavid du Colombier DBG_FIXME();
507f5736e95SDavid du Colombier werr(1, "Impossible tag sequence, unable to continue");
508f5736e95SDavid du Colombier }
509f5736e95SDavid du Colombier
510*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
511f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
512f5736e95SDavid du Colombier vPrintLevel(pDiag->pOutFile);
513f5736e95SDavid du Colombier }
514f5736e95SDavid du Colombier
515f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "</%s>", atDocBookTags[(UINT)ucTag].szTagname);
516f5736e95SDavid du Colombier
517*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
518f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
519f5736e95SDavid du Colombier pDiag->lXleft = 0;
520f5736e95SDavid du Colombier }
521f5736e95SDavid du Colombier
522f5736e95SDavid du Colombier /* Set global variables */
523f5736e95SDavid du Colombier switch (ucTag) {
524f5736e95SDavid du Colombier case TAG_CHAPTER:
525f5736e95SDavid du Colombier usHeaderLevelCurrent = 0;
526f5736e95SDavid du Colombier break;
527f5736e95SDavid du Colombier case TAG_SECT1:
528f5736e95SDavid du Colombier usHeaderLevelCurrent = 1;
529f5736e95SDavid du Colombier break;
530f5736e95SDavid du Colombier case TAG_SECT2:
531f5736e95SDavid du Colombier usHeaderLevelCurrent = 2;
532f5736e95SDavid du Colombier break;
533f5736e95SDavid du Colombier case TAG_SECT3:
534f5736e95SDavid du Colombier usHeaderLevelCurrent = 3;
535f5736e95SDavid du Colombier break;
536f5736e95SDavid du Colombier case TAG_SECT4:
537f5736e95SDavid du Colombier usHeaderLevelCurrent = 4;
538f5736e95SDavid du Colombier break;
539f5736e95SDavid du Colombier case TAG_SECT5:
540f5736e95SDavid du Colombier usHeaderLevelCurrent = 5;
541f5736e95SDavid du Colombier break;
542f5736e95SDavid du Colombier case TAG_TITLE:
543f5736e95SDavid du Colombier bTitleOpen = FALSE;
544f5736e95SDavid du Colombier break;
545*25b329d5SDavid du Colombier case TAG_FOOTNOTE:
546*25b329d5SDavid du Colombier bFootnoteOpen = FALSE;
547*25b329d5SDavid du Colombier break;
548f5736e95SDavid du Colombier case TAG_PARA:
549f5736e95SDavid du Colombier uiParagraphLevel--;
550f5736e95SDavid du Colombier break;
551f5736e95SDavid du Colombier case TAG_EMPHASIS:
552f5736e95SDavid du Colombier bEmphasisOpen = FALSE;
553f5736e95SDavid du Colombier break;
554f5736e95SDavid du Colombier case TAG_SUPERSCRIPT:
555f5736e95SDavid du Colombier bSuperscriptOpen = FALSE;
556f5736e95SDavid du Colombier break;
557f5736e95SDavid du Colombier case TAG_ITEMIZEDLIST:
558f5736e95SDavid du Colombier case TAG_ORDEREDLIST:
559f5736e95SDavid du Colombier uiListLevel--;
560f5736e95SDavid du Colombier break;
561f5736e95SDavid du Colombier case TAG_SUBSCRIPT:
562f5736e95SDavid du Colombier bSubscriptOpen = FALSE;
563f5736e95SDavid du Colombier break;
564f5736e95SDavid du Colombier case TAG_INFORMALTABLE:
565f5736e95SDavid du Colombier bTableOpen = FALSE;
566f5736e95SDavid du Colombier iTableColumnsCurrent = 0;
567f5736e95SDavid du Colombier break;
568f5736e95SDavid du Colombier default:
569f5736e95SDavid du Colombier break;
570f5736e95SDavid du Colombier }
571f5736e95SDavid du Colombier } /* end of vAddEndTag */
572f5736e95SDavid du Colombier
573f5736e95SDavid du Colombier /*
574f5736e95SDavid du Colombier * vAddEndTagOptional - add the specified end tag to the file if needed
575f5736e95SDavid du Colombier */
576f5736e95SDavid du Colombier static void
vAddEndTagOptional(diagram_type * pDiag,UCHAR ucTag)577f5736e95SDavid du Colombier vAddEndTagOptional(diagram_type *pDiag, UCHAR ucTag)
578f5736e95SDavid du Colombier {
579f5736e95SDavid du Colombier UCHAR ucTopTag;
580f5736e95SDavid du Colombier
581f5736e95SDavid du Colombier ucTopTag = ucReadStack();
582f5736e95SDavid du Colombier if (ucTag == ucTopTag) {
583f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTag);
584f5736e95SDavid du Colombier }
585f5736e95SDavid du Colombier } /* end of vAddEndTagOptional */
586f5736e95SDavid du Colombier
587f5736e95SDavid du Colombier /*
588f5736e95SDavid du Colombier * vAddCombinedTag - add the specified start and end tag to the file
589f5736e95SDavid du Colombier */
590f5736e95SDavid du Colombier static void
vAddCombinedTag(diagram_type * pDiag,UCHAR ucTag,const char * szAttribute)591f5736e95SDavid du Colombier vAddCombinedTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
592f5736e95SDavid du Colombier {
593f5736e95SDavid du Colombier fail(pDiag == NULL);
594f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
595f5736e95SDavid du Colombier fail((size_t)ucTag >= elementsof(atDocBookTags));
596f5736e95SDavid du Colombier
597*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
598f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
599f5736e95SDavid du Colombier vPrintLevel(pDiag->pOutFile);
600f5736e95SDavid du Colombier }
601f5736e95SDavid du Colombier
602f5736e95SDavid du Colombier if (szAttribute == NULL || szAttribute[0] == '\0') {
603f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "<%s/>",
604f5736e95SDavid du Colombier atDocBookTags[(UINT)ucTag].szTagname);
605f5736e95SDavid du Colombier } else {
606f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "<%s %s/>",
607f5736e95SDavid du Colombier atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
608f5736e95SDavid du Colombier }
609f5736e95SDavid du Colombier
610*25b329d5SDavid du Colombier if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
611f5736e95SDavid du Colombier fprintf(pDiag->pOutFile, "\n");
612f5736e95SDavid du Colombier pDiag->lXleft = 0;
613f5736e95SDavid du Colombier }
614f5736e95SDavid du Colombier } /* end of vAddCombinedTag */
615f5736e95SDavid du Colombier
616f5736e95SDavid du Colombier /*
617f5736e95SDavid du Colombier * vAddEndTagsUntil2 - add end tags until one the specified tags is seen
618f5736e95SDavid du Colombier */
619f5736e95SDavid du Colombier static void
vAddEndTagsUntil2(diagram_type * pDiag,UCHAR ucTag1,UCHAR ucTag2)620f5736e95SDavid du Colombier vAddEndTagsUntil2(diagram_type *pDiag, UCHAR ucTag1, UCHAR ucTag2)
621f5736e95SDavid du Colombier {
622f5736e95SDavid du Colombier UCHAR ucTopTag;
623f5736e95SDavid du Colombier
624f5736e95SDavid du Colombier do {
625f5736e95SDavid du Colombier ucTopTag = ucReadStack();
626f5736e95SDavid du Colombier switch (ucTopTag) {
627f5736e95SDavid du Colombier case TAG_CHAPTER:
628f5736e95SDavid du Colombier case TAG_SECT1:
629f5736e95SDavid du Colombier case TAG_SECT2:
630f5736e95SDavid du Colombier case TAG_SECT3:
631f5736e95SDavid du Colombier case TAG_SECT4:
632f5736e95SDavid du Colombier case TAG_SECT5:
633f5736e95SDavid du Colombier if (bEmptyHeaderLevel) {
634f5736e95SDavid du Colombier /*
635f5736e95SDavid du Colombier * An empty chapter is legal in Word,
636f5736e95SDavid du Colombier * but not in DocBook.
637f5736e95SDavid du Colombier */
638f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_PARA, NULL);
639f5736e95SDavid du Colombier bEmptyHeaderLevel = FALSE;
640f5736e95SDavid du Colombier }
641f5736e95SDavid du Colombier break;
642f5736e95SDavid du Colombier case TAG_ITEMIZEDLIST:
643f5736e95SDavid du Colombier case TAG_ORDEREDLIST:
644f5736e95SDavid du Colombier if (bEmptyListLevel) {
645f5736e95SDavid du Colombier /*
646f5736e95SDavid du Colombier * A list without items is legal in Word,
647f5736e95SDavid du Colombier * but not in DocBook. (Nor are empty items)
648f5736e95SDavid du Colombier */
649f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_LISTITEM, NULL);
650f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_PARA, NULL);
651f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_LISTITEM);
652f5736e95SDavid du Colombier bEmptyListLevel = FALSE;
653f5736e95SDavid du Colombier }
654f5736e95SDavid du Colombier break;
655f5736e95SDavid du Colombier default:
656f5736e95SDavid du Colombier break;
657f5736e95SDavid du Colombier }
658f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
659f5736e95SDavid du Colombier } while (ucTopTag != ucTag1 && ucTopTag != ucTag2);
660f5736e95SDavid du Colombier } /* end of vAddEndTagsUntil2 */
661f5736e95SDavid du Colombier
662f5736e95SDavid du Colombier /*
663f5736e95SDavid du Colombier * vCreateBookIntro - create title and bookinfo
664f5736e95SDavid du Colombier */
665f5736e95SDavid du Colombier void
vCreateBookIntro(diagram_type * pDiag,int iVersion)666*25b329d5SDavid du Colombier vCreateBookIntro(diagram_type *pDiag, int iVersion)
667f5736e95SDavid du Colombier {
668f5736e95SDavid du Colombier const char *szTitle, *szSubject, *szAuthor;
669f5736e95SDavid du Colombier const char *szLastSaveDtm, *szCompany;
670f5736e95SDavid du Colombier const char *szLanguage;
671f5736e95SDavid du Colombier char szTmp[13];
672f5736e95SDavid du Colombier
673f5736e95SDavid du Colombier fail(pDiag == NULL);
674f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
675*25b329d5SDavid du Colombier fail(iVersion < 0);
676f5736e95SDavid du Colombier fail(eEncoding == encoding_neutral);
677f5736e95SDavid du Colombier
678*25b329d5SDavid du Colombier iWordVersion = iVersion;
679*25b329d5SDavid du Colombier bOldMacFile = bIsOldMacFile();
680f5736e95SDavid du Colombier szTitle = szGetTitle();
681f5736e95SDavid du Colombier szSubject = szGetSubject();
682f5736e95SDavid du Colombier szAuthor = szGetAuthor();
683f5736e95SDavid du Colombier szLastSaveDtm = szGetLastSaveDtm();
684f5736e95SDavid du Colombier szCompany = szGetCompany();
685f5736e95SDavid du Colombier
686f5736e95SDavid du Colombier /* Start Book */
687f5736e95SDavid du Colombier szLanguage = szGetLanguage();
688f5736e95SDavid du Colombier if (szLanguage != NULL) {
689f5736e95SDavid du Colombier DBG_MSG(szLanguage);
690f5736e95SDavid du Colombier sprintf(szTmp, "lang='%.5s'", szLanguage);
691f5736e95SDavid du Colombier szLanguage = szTmp;
692f5736e95SDavid du Colombier }
693f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_BOOK, szLanguage);
694f5736e95SDavid du Colombier
695f5736e95SDavid du Colombier /* Book title */
696f5736e95SDavid du Colombier if (szTitle != NULL && szTitle[0] != '\0') {
697f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_TITLE, NULL);
698*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szTitle);
699f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TITLE);
700f5736e95SDavid du Colombier }
701f5736e95SDavid du Colombier /* Bookinfo */
702f5736e95SDavid du Colombier if ((szTitle != NULL && szTitle[0] != '\0') ||
703f5736e95SDavid du Colombier (szSubject != NULL && szSubject[0] != '\0') ||
704f5736e95SDavid du Colombier (szAuthor != NULL && szAuthor[0] != '\0') ||
705f5736e95SDavid du Colombier (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') ||
706f5736e95SDavid du Colombier (szCompany != NULL && szCompany[0] != '\0')) {
707f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_BOOKINFO, NULL);
708f5736e95SDavid du Colombier if (szTitle != NULL && szTitle[0] != '\0') {
709f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_TITLE, NULL);
710*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szTitle);
711f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TITLE);
712f5736e95SDavid du Colombier }
713f5736e95SDavid du Colombier if (szSubject != NULL && szSubject[0] != '\0') {
714f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_SUBTITLE, NULL);
715*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szSubject);
716f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SUBTITLE);
717f5736e95SDavid du Colombier }
718f5736e95SDavid du Colombier if (szAuthor != NULL && szAuthor[0] != '\0') {
719f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_AUTHOR, NULL);
720f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_SURNAME, NULL);
721*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szAuthor);
722f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SURNAME);
723f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_AUTHOR);
724f5736e95SDavid du Colombier }
725f5736e95SDavid du Colombier if (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') {
726f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_DATE, NULL);
727*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szLastSaveDtm);
728f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_DATE);
729f5736e95SDavid du Colombier }
730f5736e95SDavid du Colombier if (szCompany != NULL && szCompany[0] != '\0') {
731f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_CORPNAME, NULL);
732*25b329d5SDavid du Colombier vPrintSpecialString(pDiag, szCompany);
733f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_CORPNAME);
734f5736e95SDavid du Colombier }
735f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_BOOKINFO);
736f5736e95SDavid du Colombier }
737f5736e95SDavid du Colombier } /* end of vCreateBookIntro */
738f5736e95SDavid du Colombier
739f5736e95SDavid du Colombier /*
740f5736e95SDavid du Colombier * vPrologueXML - perform the XML initialization
741f5736e95SDavid du Colombier */
742f5736e95SDavid du Colombier void
vPrologueXML(diagram_type * pDiag,const options_type * pOptions)743*25b329d5SDavid du Colombier vPrologueXML(diagram_type *pDiag, const options_type *pOptions)
744f5736e95SDavid du Colombier {
745f5736e95SDavid du Colombier
746f5736e95SDavid du Colombier fail(pDiag == NULL);
747f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
748*25b329d5SDavid du Colombier fail(pOptions == NULL);
749f5736e95SDavid du Colombier
750f5736e95SDavid du Colombier #if defined(DEBUG)
751f5736e95SDavid du Colombier vCheckTagTable();
752f5736e95SDavid du Colombier #endif /* DEBUG */
753f5736e95SDavid du Colombier
754f5736e95SDavid du Colombier /* Set global variables to their start values */
755*25b329d5SDavid du Colombier eEncoding = pOptions->eEncoding;
756f5736e95SDavid du Colombier bEmphasisOpen = FALSE;
757f5736e95SDavid du Colombier bSuperscriptOpen = FALSE;
758f5736e95SDavid du Colombier bSubscriptOpen = FALSE;
759f5736e95SDavid du Colombier bTitleOpen = FALSE;
760f5736e95SDavid du Colombier bTableOpen = FALSE;
761*25b329d5SDavid du Colombier bFootnoteOpen = FALSE;
762f5736e95SDavid du Colombier uiParagraphLevel = 0;
763f5736e95SDavid du Colombier uiListLevel = 0;
764f5736e95SDavid du Colombier bEmptyListLevel = TRUE;
765f5736e95SDavid du Colombier usHeaderLevelCurrent = 0;
766f5736e95SDavid du Colombier bEmptyHeaderLevel = TRUE;
767f5736e95SDavid du Colombier iTableColumnsCurrent = 0;
768*25b329d5SDavid du Colombier uiFootnoteNumber = 0;
769f5736e95SDavid du Colombier
770f5736e95SDavid du Colombier pDiag->lXleft = 0;
771f5736e95SDavid du Colombier pDiag->lYtop = 0;
772f5736e95SDavid du Colombier
773f5736e95SDavid du Colombier /* Create an empty stack */
774f5736e95SDavid du Colombier tStacksize = INITIAL_STACK_SIZE;
775f5736e95SDavid du Colombier aucStack = xcalloc(tStacksize, sizeof(UCHAR));
776f5736e95SDavid du Colombier tStackNextFree = 0;
777f5736e95SDavid du Colombier } /* end of vPrologueXML */
778f5736e95SDavid du Colombier
779f5736e95SDavid du Colombier /*
780f5736e95SDavid du Colombier * vEpilogueXML - clean up after everything is done
781f5736e95SDavid du Colombier */
782f5736e95SDavid du Colombier void
vEpilogueXML(diagram_type * pDiag)783f5736e95SDavid du Colombier vEpilogueXML(diagram_type *pDiag)
784f5736e95SDavid du Colombier {
785f5736e95SDavid du Colombier vStackTrace();
786f5736e95SDavid du Colombier
787f5736e95SDavid du Colombier vAddEndTagsUntil1(pDiag, TAG_BOOK);
788f5736e95SDavid du Colombier
789f5736e95SDavid du Colombier vStackTrace();
790f5736e95SDavid du Colombier
791f5736e95SDavid du Colombier /* Destroy the stack */
792f5736e95SDavid du Colombier fail(tStackNextFree != 0);
793f5736e95SDavid du Colombier tStacksize = 0;
794f5736e95SDavid du Colombier aucStack = xfree(aucStack);
795f5736e95SDavid du Colombier tStackNextFree = 0;
796f5736e95SDavid du Colombier } /* end of vEpilogueXML */
797f5736e95SDavid du Colombier
798f5736e95SDavid du Colombier /*
799f5736e95SDavid du Colombier * vPrintXML - print a XML string
800f5736e95SDavid du Colombier */
801f5736e95SDavid du Colombier static void
vPrintXML(diagram_type * pDiag,const char * szString,size_t tStringLength,USHORT usFontstyle)802f5736e95SDavid du Colombier vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
803f5736e95SDavid du Colombier USHORT usFontstyle)
804f5736e95SDavid du Colombier {
805*25b329d5SDavid du Colombier const char *szAttr;
806f5736e95SDavid du Colombier int iCount;
807f5736e95SDavid du Colombier size_t tNextFree;
808f5736e95SDavid du Colombier BOOL bNotReady, bEmphasisNew, bSuperscriptNew, bSubscriptNew;
809f5736e95SDavid du Colombier UCHAR ucTopTag, aucStorage[3];
810f5736e95SDavid du Colombier
811f5736e95SDavid du Colombier fail(szString == NULL);
812f5736e95SDavid du Colombier
813f5736e95SDavid du Colombier if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
814f5736e95SDavid du Colombier return;
815f5736e95SDavid du Colombier }
816f5736e95SDavid du Colombier
817*25b329d5SDavid du Colombier if (tStringLength == 1 && szString[0] == FOOTNOTE_OR_ENDNOTE) {
818*25b329d5SDavid du Colombier /* Don't do anything special for just a single footnote */
819*25b329d5SDavid du Colombier bEmphasisNew = FALSE;
820*25b329d5SDavid du Colombier bSuperscriptNew = FALSE;
821*25b329d5SDavid du Colombier bSubscriptNew = FALSE;
822*25b329d5SDavid du Colombier } else {
823*25b329d5SDavid du Colombier /* Situation normal */
824f5736e95SDavid du Colombier bEmphasisNew = bIsBold(usFontstyle) ||
825f5736e95SDavid du Colombier bIsItalic(usFontstyle) ||
826f5736e95SDavid du Colombier bIsUnderline(usFontstyle) ||
827f5736e95SDavid du Colombier bIsStrike(usFontstyle);
828f5736e95SDavid du Colombier bSuperscriptNew = bIsSuperscript(usFontstyle);
829f5736e95SDavid du Colombier bSubscriptNew = bIsSubscript(usFontstyle);
830*25b329d5SDavid du Colombier }
831f5736e95SDavid du Colombier
832f5736e95SDavid du Colombier /* End what has to be ended (or more to keep the stack happy) */
833f5736e95SDavid du Colombier tNextFree = 0;
834f5736e95SDavid du Colombier bNotReady = TRUE;
835f5736e95SDavid du Colombier do {
836f5736e95SDavid du Colombier ucTopTag = ucReadStack();
837f5736e95SDavid du Colombier switch (ucTopTag) {
838f5736e95SDavid du Colombier case TAG_EMPHASIS:
839f5736e95SDavid du Colombier fail(!bEmphasisOpen);
840f5736e95SDavid du Colombier if (bEmphasisNew) {
841f5736e95SDavid du Colombier aucStorage[tNextFree++] = ucTopTag;
842f5736e95SDavid du Colombier }
843f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
844f5736e95SDavid du Colombier break;
845f5736e95SDavid du Colombier case TAG_SUPERSCRIPT:
846f5736e95SDavid du Colombier fail(!bSuperscriptOpen);
847f5736e95SDavid du Colombier if (bSuperscriptNew) {
848f5736e95SDavid du Colombier aucStorage[tNextFree++] = ucTopTag;
849f5736e95SDavid du Colombier }
850f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
851f5736e95SDavid du Colombier break;
852f5736e95SDavid du Colombier case TAG_SUBSCRIPT:
853f5736e95SDavid du Colombier fail(!bSubscriptOpen);
854f5736e95SDavid du Colombier if (bSubscriptNew) {
855f5736e95SDavid du Colombier aucStorage[tNextFree++] = ucTopTag;
856f5736e95SDavid du Colombier }
857f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
858f5736e95SDavid du Colombier break;
859f5736e95SDavid du Colombier default:
860f5736e95SDavid du Colombier bNotReady = FALSE;
861f5736e95SDavid du Colombier break;
862f5736e95SDavid du Colombier }
863f5736e95SDavid du Colombier fail(tNextFree > elementsof(aucStorage));
864f5736e95SDavid du Colombier fail(bNotReady && tNextFree == elementsof(aucStorage));
865f5736e95SDavid du Colombier } while (bNotReady);
866f5736e95SDavid du Colombier
867f5736e95SDavid du Colombier /* Just te make sure */
868f5736e95SDavid du Colombier vStartOfParagraphXML(pDiag, 1);
869f5736e95SDavid du Colombier
870f5736e95SDavid du Colombier /* Restart to keep the stack happy */
871f5736e95SDavid du Colombier for (iCount = (int)tNextFree - 1; iCount > 0; iCount--) {
872f5736e95SDavid du Colombier vAddStartTag(pDiag, aucStorage[iCount], NULL);
873f5736e95SDavid du Colombier }
874f5736e95SDavid du Colombier
875f5736e95SDavid du Colombier /* Start what has to be started */
876f5736e95SDavid du Colombier if (bEmphasisNew && !bEmphasisOpen) {
877*25b329d5SDavid du Colombier if (bIsBold(usFontstyle)) {
878*25b329d5SDavid du Colombier szAttr = "role='bold'";
879*25b329d5SDavid du Colombier } else if (bIsItalic(usFontstyle)) {
880*25b329d5SDavid du Colombier szAttr = NULL;
881*25b329d5SDavid du Colombier } else if (bIsUnderline(usFontstyle)) {
882*25b329d5SDavid du Colombier szAttr = "role='underline'";
883*25b329d5SDavid du Colombier } else if (bIsStrike(usFontstyle)) {
884*25b329d5SDavid du Colombier szAttr = "role='strikethrough'";
885*25b329d5SDavid du Colombier } else {
886*25b329d5SDavid du Colombier szAttr = NULL;
887*25b329d5SDavid du Colombier }
888*25b329d5SDavid du Colombier vAddStartTag(pDiag, TAG_EMPHASIS, szAttr);
889f5736e95SDavid du Colombier }
890f5736e95SDavid du Colombier if (bSuperscriptNew && !bSuperscriptOpen) {
891f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_SUPERSCRIPT, NULL);
892f5736e95SDavid du Colombier }
893f5736e95SDavid du Colombier if (bSubscriptNew && !bSubscriptOpen) {
894f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_SUBSCRIPT, NULL);
895f5736e95SDavid du Colombier }
896f5736e95SDavid du Colombier
897f5736e95SDavid du Colombier /* The print the string */
898f5736e95SDavid du Colombier for (iCount = 0; iCount < (int)tStringLength; iCount++) {
899*25b329d5SDavid du Colombier vPrintChar(pDiag, szString[iCount]);
900f5736e95SDavid du Colombier }
901f5736e95SDavid du Colombier } /* end of vPrintXML */
902f5736e95SDavid du Colombier
903f5736e95SDavid du Colombier /*
904f5736e95SDavid du Colombier * vMove2NextLineXML - move to the next line
905f5736e95SDavid du Colombier */
906f5736e95SDavid du Colombier void
vMove2NextLineXML(diagram_type * pDiag)907f5736e95SDavid du Colombier vMove2NextLineXML(diagram_type *pDiag)
908f5736e95SDavid du Colombier {
909f5736e95SDavid du Colombier fail(pDiag == NULL);
910f5736e95SDavid du Colombier
911*25b329d5SDavid du Colombier /*
912f5736e95SDavid du Colombier if (uiParagraphLevel != 0) {
913*25b329d5SDavid du Colombier We need something like HTML's <BR> tag
914f5736e95SDavid du Colombier }
915*25b329d5SDavid du Colombier */
916f5736e95SDavid du Colombier } /* end of vMove2NextLineXML */
917f5736e95SDavid du Colombier
918f5736e95SDavid du Colombier /*
919f5736e95SDavid du Colombier * vSubstringXML - put a sub string into a diagram
920f5736e95SDavid du Colombier */
921f5736e95SDavid du Colombier void
vSubstringXML(diagram_type * pDiag,const char * szString,size_t tStringLength,long lStringWidth,USHORT usFontstyle)922f5736e95SDavid du Colombier vSubstringXML(diagram_type *pDiag,
923f5736e95SDavid du Colombier const char *szString, size_t tStringLength, long lStringWidth,
924f5736e95SDavid du Colombier USHORT usFontstyle)
925f5736e95SDavid du Colombier {
926f5736e95SDavid du Colombier fail(pDiag == NULL || szString == NULL);
927f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
928f5736e95SDavid du Colombier fail(pDiag->lXleft < 0);
929f5736e95SDavid du Colombier fail(tStringLength != strlen(szString));
930f5736e95SDavid du Colombier
931f5736e95SDavid du Colombier if (szString[0] == '\0' || tStringLength == 0) {
932f5736e95SDavid du Colombier return;
933f5736e95SDavid du Colombier }
934f5736e95SDavid du Colombier
935f5736e95SDavid du Colombier vPrintXML(pDiag, szString, tStringLength, usFontstyle);
936f5736e95SDavid du Colombier pDiag->lXleft += lStringWidth;
937f5736e95SDavid du Colombier } /* end of vSubstringXML */
938f5736e95SDavid du Colombier
939f5736e95SDavid du Colombier /*
940f5736e95SDavid du Colombier * Create an start of a paragraph
941f5736e95SDavid du Colombier * Only works on paragraph level one, because Word doesn't allow paragraphs
942f5736e95SDavid du Colombier * in paragraphs. Other paragraph levels result from DocBooks special needs.
943f5736e95SDavid du Colombier */
944f5736e95SDavid du Colombier void
vStartOfParagraphXML(diagram_type * pDiag,UINT uiMaxLevel)945*25b329d5SDavid du Colombier vStartOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
946f5736e95SDavid du Colombier {
947f5736e95SDavid du Colombier fail(pDiag == NULL);
948f5736e95SDavid du Colombier
949*25b329d5SDavid du Colombier if (uiParagraphLevel >= uiMaxLevel || bTitleOpen) {
950*25b329d5SDavid du Colombier /* In Word a title is just a paragraph */
951f5736e95SDavid du Colombier return;
952f5736e95SDavid du Colombier }
953f5736e95SDavid du Colombier if (uiListLevel != 0 && bEmptyListLevel) {
954f5736e95SDavid du Colombier /* No paragraphs in a list before the first listitem */
955f5736e95SDavid du Colombier return;
956f5736e95SDavid du Colombier }
957f5736e95SDavid du Colombier if (usHeaderLevelCurrent == 0) {
958f5736e95SDavid du Colombier /* No paragraphs without an open header */
959f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_CHAPTER, NULL);
960f5736e95SDavid du Colombier /* Dummy title */
961f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_TITLE, NULL);
962f5736e95SDavid du Colombier }
963f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_PARA, NULL);
964f5736e95SDavid du Colombier } /* end of vStartOfParagraphXML */
965f5736e95SDavid du Colombier
966f5736e95SDavid du Colombier /*
967f5736e95SDavid du Colombier * Create an end of a paragraph
968f5736e95SDavid du Colombier * Only for paragraph level one and for titles
969f5736e95SDavid du Colombier */
970f5736e95SDavid du Colombier void
vEndOfParagraphXML(diagram_type * pDiag,UINT uiMaxLevel)971*25b329d5SDavid du Colombier vEndOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
972f5736e95SDavid du Colombier {
973f5736e95SDavid du Colombier UCHAR ucTopTag;
974f5736e95SDavid du Colombier
975f5736e95SDavid du Colombier fail(pDiag == NULL);
976f5736e95SDavid du Colombier
977*25b329d5SDavid du Colombier if (uiParagraphLevel > uiMaxLevel) {
978f5736e95SDavid du Colombier DBG_DEC(uiParagraphLevel);
979f5736e95SDavid du Colombier return;
980f5736e95SDavid du Colombier }
981f5736e95SDavid du Colombier
982f5736e95SDavid du Colombier for(;;) {
983f5736e95SDavid du Colombier ucTopTag = ucReadStack();
984f5736e95SDavid du Colombier switch (ucTopTag) {
985f5736e95SDavid du Colombier case TAG_EMPHASIS:
986f5736e95SDavid du Colombier fail(!bEmphasisOpen);
987f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_EMPHASIS);
988f5736e95SDavid du Colombier break;
989f5736e95SDavid du Colombier case TAG_SUPERSCRIPT:
990f5736e95SDavid du Colombier fail(!bSuperscriptOpen);
991f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SUPERSCRIPT);
992f5736e95SDavid du Colombier break;
993f5736e95SDavid du Colombier case TAG_SUBSCRIPT:
994f5736e95SDavid du Colombier fail(!bSubscriptOpen);
995f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SUBSCRIPT);
996f5736e95SDavid du Colombier break;
997f5736e95SDavid du Colombier case TAG_TITLE:
998f5736e95SDavid du Colombier fail(!bTitleOpen);
999f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TITLE);
1000f5736e95SDavid du Colombier return;
1001f5736e95SDavid du Colombier case TAG_PARA:
1002f5736e95SDavid du Colombier fail(uiParagraphLevel == 0);
1003f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_PARA);
1004f5736e95SDavid du Colombier return;
1005f5736e95SDavid du Colombier case TAG_TBODY:
1006f5736e95SDavid du Colombier case TAG_TGROUP:
1007f5736e95SDavid du Colombier case TAG_INFORMALTABLE:
1008f5736e95SDavid du Colombier fail(!bTableOpen);
1009f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
1010f5736e95SDavid du Colombier break;
1011f5736e95SDavid du Colombier case TAG_NOTAG:
1012f5736e95SDavid du Colombier DBG_FIXME();
1013f5736e95SDavid du Colombier werr(1, "Impossible tag sequence, unable to continue");
1014f5736e95SDavid du Colombier break;
1015f5736e95SDavid du Colombier default:
1016f5736e95SDavid du Colombier DBG_DEC(ucTopTag);
1017f5736e95SDavid du Colombier DBG_MSG_C((size_t)ucTopTag < elementsof(atDocBookTags),
1018f5736e95SDavid du Colombier atDocBookTags[(UINT)ucTopTag].szTagname);
1019f5736e95SDavid du Colombier return;
1020f5736e95SDavid du Colombier }
1021f5736e95SDavid du Colombier }
1022f5736e95SDavid du Colombier } /* end of vEndOfParagraphXML */
1023f5736e95SDavid du Colombier
1024f5736e95SDavid du Colombier /*
1025f5736e95SDavid du Colombier * Create an end of a page
1026f5736e95SDavid du Colombier */
1027f5736e95SDavid du Colombier void
vEndOfPageXML(diagram_type * pDiag)1028f5736e95SDavid du Colombier vEndOfPageXML(diagram_type *pDiag)
1029f5736e95SDavid du Colombier {
1030f5736e95SDavid du Colombier if (bTableOpen || usHeaderLevelCurrent == 0) {
1031f5736e95SDavid du Colombier /* No beginpage in a table or outside a chapter */
1032f5736e95SDavid du Colombier return;
1033f5736e95SDavid du Colombier }
1034f5736e95SDavid du Colombier if (bTitleOpen) {
1035f5736e95SDavid du Colombier /* A beginpage is not allowed when in a title */
1036f5736e95SDavid du Colombier /* So start a new paragraph */
1037*25b329d5SDavid du Colombier vEndOfParagraphXML(pDiag, UINT_MAX);
1038*25b329d5SDavid du Colombier vStartOfParagraphXML(pDiag, UINT_MAX);
1039f5736e95SDavid du Colombier return;
1040f5736e95SDavid du Colombier }
1041f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_BEGINPAGE, NULL);
1042f5736e95SDavid du Colombier } /* end of vEndOfPageXML */
1043f5736e95SDavid du Colombier
1044f5736e95SDavid du Colombier /*
1045f5736e95SDavid du Colombier * vCloseHeaderLevels - close the specified header levels
1046f5736e95SDavid du Colombier */
1047f5736e95SDavid du Colombier static void
vCloseHeaderLevels(diagram_type * pDiag,USHORT usIstd)1048f5736e95SDavid du Colombier vCloseHeaderLevels(diagram_type *pDiag, USHORT usIstd)
1049f5736e95SDavid du Colombier {
1050f5736e95SDavid du Colombier BOOL bNotReady;
1051f5736e95SDavid du Colombier UCHAR ucTopTag;
1052f5736e95SDavid du Colombier
1053f5736e95SDavid du Colombier DBG_MSG("vCloseHeaderLevels");
1054f5736e95SDavid du Colombier DBG_DEC(usIstd);
1055f5736e95SDavid du Colombier DBG_DEC(usHeaderLevelCurrent);
1056f5736e95SDavid du Colombier
1057f5736e95SDavid du Colombier vStackTrace();
1058f5736e95SDavid du Colombier
1059f5736e95SDavid du Colombier bNotReady = TRUE;
1060f5736e95SDavid du Colombier do {
1061f5736e95SDavid du Colombier ucTopTag = ucReadStack();
1062f5736e95SDavid du Colombier switch (ucTopTag) {
1063f5736e95SDavid du Colombier case TAG_TITLE:
1064f5736e95SDavid du Colombier case TAG_PARA:
1065f5736e95SDavid du Colombier vAddEndTag(pDiag, ucTopTag);
1066f5736e95SDavid du Colombier break;
1067f5736e95SDavid du Colombier default:
1068f5736e95SDavid du Colombier bNotReady = FALSE;
1069f5736e95SDavid du Colombier break;
1070f5736e95SDavid du Colombier }
1071f5736e95SDavid du Colombier } while (bNotReady);
1072f5736e95SDavid du Colombier
1073f5736e95SDavid du Colombier vStackTrace();
1074f5736e95SDavid du Colombier
1075f5736e95SDavid du Colombier while (usHeaderLevelCurrent >= usIstd) {
1076f5736e95SDavid du Colombier if (bEmptyHeaderLevel) {
1077f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_PARA, NULL);
1078f5736e95SDavid du Colombier bEmptyHeaderLevel = FALSE;
1079f5736e95SDavid du Colombier }
1080f5736e95SDavid du Colombier switch (usHeaderLevelCurrent) {
1081f5736e95SDavid du Colombier case 1: vAddEndTag(pDiag, TAG_CHAPTER); break;
1082f5736e95SDavid du Colombier case 2: vAddEndTag(pDiag, TAG_SECT1); break;
1083f5736e95SDavid du Colombier case 3: vAddEndTag(pDiag, TAG_SECT2); break;
1084f5736e95SDavid du Colombier case 4: vAddEndTag(pDiag, TAG_SECT3); break;
1085f5736e95SDavid du Colombier case 5: vAddEndTag(pDiag, TAG_SECT4); break;
1086f5736e95SDavid du Colombier case 6: vAddEndTag(pDiag, TAG_SECT5); break;
1087f5736e95SDavid du Colombier default:
1088f5736e95SDavid du Colombier DBG_DEC(usHeaderLevelCurrent);
1089f5736e95SDavid du Colombier DBG_FIXME();
1090f5736e95SDavid du Colombier return;
1091f5736e95SDavid du Colombier }
1092f5736e95SDavid du Colombier }
1093f5736e95SDavid du Colombier
1094f5736e95SDavid du Colombier DBG_DEC(usHeaderLevelCurrent);
1095f5736e95SDavid du Colombier
1096f5736e95SDavid du Colombier vStackTrace();
1097f5736e95SDavid du Colombier } /* end of vCloseHeaderLevels */
1098f5736e95SDavid du Colombier
1099f5736e95SDavid du Colombier /*
1100f5736e95SDavid du Colombier * vSetHeadersXML - set the headers
1101f5736e95SDavid du Colombier */
1102f5736e95SDavid du Colombier void
vSetHeadersXML(diagram_type * pDiag,USHORT usIstd)1103f5736e95SDavid du Colombier vSetHeadersXML(diagram_type *pDiag, USHORT usIstd)
1104f5736e95SDavid du Colombier {
1105f5736e95SDavid du Colombier fail(pDiag == NULL);
1106f5736e95SDavid du Colombier
1107f5736e95SDavid du Colombier if (usIstd == 0 || usIstd > 6) {
1108f5736e95SDavid du Colombier DBG_DEC_C(usIstd != 0 && usIstd <= 9, usIstd);
1109f5736e95SDavid du Colombier return;
1110f5736e95SDavid du Colombier }
1111f5736e95SDavid du Colombier DBG_DEC(usIstd);
1112f5736e95SDavid du Colombier
1113f5736e95SDavid du Colombier if (bTableOpen || uiListLevel != 0) {
1114f5736e95SDavid du Colombier /* No headers when you're in a table or in a list */
1115f5736e95SDavid du Colombier return;
1116f5736e95SDavid du Colombier }
1117f5736e95SDavid du Colombier
1118f5736e95SDavid du Colombier /* Close levels */
1119f5736e95SDavid du Colombier vCloseHeaderLevels(pDiag, usIstd);
1120f5736e95SDavid du Colombier
1121f5736e95SDavid du Colombier DBG_DEC(usHeaderLevelCurrent);
1122f5736e95SDavid du Colombier
1123f5736e95SDavid du Colombier /* Open levels */
1124f5736e95SDavid du Colombier while (usHeaderLevelCurrent < usIstd) {
1125f5736e95SDavid du Colombier switch (usHeaderLevelCurrent) {
1126f5736e95SDavid du Colombier case 0: vAddStartTag(pDiag, TAG_CHAPTER, NULL); break;
1127f5736e95SDavid du Colombier case 1: vAddStartTag(pDiag, TAG_SECT1, NULL); break;
1128f5736e95SDavid du Colombier case 2: vAddStartTag(pDiag, TAG_SECT2, NULL); break;
1129f5736e95SDavid du Colombier case 3: vAddStartTag(pDiag, TAG_SECT3, NULL); break;
1130f5736e95SDavid du Colombier case 4: vAddStartTag(pDiag, TAG_SECT4, NULL); break;
1131f5736e95SDavid du Colombier case 5: vAddStartTag(pDiag, TAG_SECT5, NULL); break;
1132f5736e95SDavid du Colombier default:
1133f5736e95SDavid du Colombier DBG_DEC(usHeaderLevelCurrent);
1134f5736e95SDavid du Colombier DBG_FIXME();
1135f5736e95SDavid du Colombier return;
1136f5736e95SDavid du Colombier }
1137f5736e95SDavid du Colombier fail(usIstd == 0);
1138f5736e95SDavid du Colombier /* The next paragraph should be a title */
1139f5736e95SDavid du Colombier if (usHeaderLevelCurrent < usIstd) {
1140f5736e95SDavid du Colombier /* This chapter level is not in the Word document */
1141f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_TITLE, NULL);
1142f5736e95SDavid du Colombier } else {
1143f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_TITLE, NULL);
1144f5736e95SDavid du Colombier }
1145f5736e95SDavid du Colombier }
1146f5736e95SDavid du Colombier } /* end of vSetHeadersXML */
1147f5736e95SDavid du Colombier
1148f5736e95SDavid du Colombier /*
1149f5736e95SDavid du Colombier * Create a start of a list
1150f5736e95SDavid du Colombier */
1151f5736e95SDavid du Colombier void
vStartOfListXML(diagram_type * pDiag,UCHAR ucNFC,BOOL bIsEndOfTable)1152f5736e95SDavid du Colombier vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
1153f5736e95SDavid du Colombier {
1154f5736e95SDavid du Colombier const char *szAttr;
1155f5736e95SDavid du Colombier UCHAR ucTag;
1156f5736e95SDavid du Colombier
1157f5736e95SDavid du Colombier fail(pDiag == NULL);
1158f5736e95SDavid du Colombier
1159f5736e95SDavid du Colombier if (bIsEndOfTable) {
1160f5736e95SDavid du Colombier /* FIXME: until a list in a table is allowed */
1161f5736e95SDavid du Colombier vEndOfTableXML(pDiag);
1162f5736e95SDavid du Colombier }
1163f5736e95SDavid du Colombier
1164f5736e95SDavid du Colombier if (bTableOpen) {
1165f5736e95SDavid du Colombier /* FIXME: a list in a table should be allowed */
1166f5736e95SDavid du Colombier return;
1167f5736e95SDavid du Colombier }
1168f5736e95SDavid du Colombier
1169f5736e95SDavid du Colombier if (usHeaderLevelCurrent == 0) {
1170f5736e95SDavid du Colombier /* No list without an open header */
1171f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_CHAPTER, NULL);
1172f5736e95SDavid du Colombier /* Dummy title */
1173f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_TITLE, NULL);
1174f5736e95SDavid du Colombier }
1175f5736e95SDavid du Colombier
1176f5736e95SDavid du Colombier switch (ucNFC) {
1177f5736e95SDavid du Colombier case LIST_ARABIC_NUM:
1178f5736e95SDavid du Colombier case LIST_ORDINAL_NUM:
1179*25b329d5SDavid du Colombier case LIST_NUMBER_TXT:
1180*25b329d5SDavid du Colombier case LIST_ORDINAL_TXT:
1181*25b329d5SDavid du Colombier case LIST_OUTLINE_NUM:
1182f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1183f5736e95SDavid du Colombier szAttr = "numeration='arabic'";
1184f5736e95SDavid du Colombier break;
1185f5736e95SDavid du Colombier case LIST_UPPER_ROMAN:
1186f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1187f5736e95SDavid du Colombier szAttr = "numeration='upperroman'";
1188f5736e95SDavid du Colombier break;
1189f5736e95SDavid du Colombier case LIST_LOWER_ROMAN:
1190f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1191f5736e95SDavid du Colombier szAttr = "numeration='lowerroman'";
1192f5736e95SDavid du Colombier break;
1193f5736e95SDavid du Colombier case LIST_UPPER_ALPHA:
1194f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1195f5736e95SDavid du Colombier szAttr = "numeration='upperalpha'";
1196f5736e95SDavid du Colombier break;
1197f5736e95SDavid du Colombier case LIST_LOWER_ALPHA:
1198f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1199f5736e95SDavid du Colombier szAttr = "numeration='loweralpha'";
1200f5736e95SDavid du Colombier break;
1201f5736e95SDavid du Colombier case LIST_SPECIAL:
1202*25b329d5SDavid du Colombier case LIST_SPECIAL2:
1203f5736e95SDavid du Colombier case LIST_BULLETS:
1204f5736e95SDavid du Colombier ucTag = TAG_ITEMIZEDLIST;
1205f5736e95SDavid du Colombier szAttr = "mark='bullet'";
1206f5736e95SDavid du Colombier break;
1207f5736e95SDavid du Colombier default:
1208f5736e95SDavid du Colombier ucTag = TAG_ORDEREDLIST;
1209f5736e95SDavid du Colombier szAttr = "numeration='arabic'";
1210*25b329d5SDavid du Colombier DBG_HEX(ucNFC);
1211f5736e95SDavid du Colombier DBG_FIXME();
1212f5736e95SDavid du Colombier break;
1213f5736e95SDavid du Colombier }
1214f5736e95SDavid du Colombier vAddStartTag(pDiag, ucTag, szAttr);
1215f5736e95SDavid du Colombier } /* end of vStartOfListXML */
1216f5736e95SDavid du Colombier
1217f5736e95SDavid du Colombier /*
1218f5736e95SDavid du Colombier * Create an end of a list
1219f5736e95SDavid du Colombier */
1220f5736e95SDavid du Colombier void
vEndOfListXML(diagram_type * pDiag)1221f5736e95SDavid du Colombier vEndOfListXML(diagram_type *pDiag)
1222f5736e95SDavid du Colombier {
1223f5736e95SDavid du Colombier fail(pDiag == NULL);
1224f5736e95SDavid du Colombier
1225f5736e95SDavid du Colombier if (bTableOpen) {
1226f5736e95SDavid du Colombier /* FIXME: a list in a table should be allowed */
1227f5736e95SDavid du Colombier return;
1228f5736e95SDavid du Colombier }
1229f5736e95SDavid du Colombier
1230f5736e95SDavid du Colombier if (uiListLevel != 0) {
1231f5736e95SDavid du Colombier vStackTrace();
1232f5736e95SDavid du Colombier vAddEndTagsUntil2(pDiag, TAG_ITEMIZEDLIST, TAG_ORDEREDLIST);
1233f5736e95SDavid du Colombier vStackTrace();
1234f5736e95SDavid du Colombier }
1235f5736e95SDavid du Colombier } /* end of vEndOfListXML */
1236f5736e95SDavid du Colombier
1237f5736e95SDavid du Colombier /*
1238f5736e95SDavid du Colombier * Create a start of a list item
1239f5736e95SDavid du Colombier */
1240f5736e95SDavid du Colombier void
vStartOfListItemXML(diagram_type * pDiag,BOOL bNoMarks)1241f5736e95SDavid du Colombier vStartOfListItemXML(diagram_type *pDiag, BOOL bNoMarks)
1242f5736e95SDavid du Colombier {
1243f5736e95SDavid du Colombier const char *szAttr;
1244f5736e95SDavid du Colombier UCHAR ucTopTag;
1245f5736e95SDavid du Colombier
1246f5736e95SDavid du Colombier fail(pDiag == NULL);
1247f5736e95SDavid du Colombier
1248f5736e95SDavid du Colombier if (bTableOpen) {
1249f5736e95SDavid du Colombier /* FIXME: a list in a table should be allowed */
1250f5736e95SDavid du Colombier return;
1251f5736e95SDavid du Colombier }
1252f5736e95SDavid du Colombier
1253f5736e95SDavid du Colombier ucTopTag = ucReadStack();
1254f5736e95SDavid du Colombier if (ucTopTag != TAG_ITEMIZEDLIST && ucTopTag != TAG_ORDEREDLIST) {
1255f5736e95SDavid du Colombier /* Must end a previous list item first */
1256f5736e95SDavid du Colombier vAddEndTagsUntil1(pDiag, TAG_LISTITEM);
1257f5736e95SDavid du Colombier }
1258f5736e95SDavid du Colombier
1259f5736e95SDavid du Colombier DBG_DEC_C(ucReadStack() != TAG_ITEMIZEDLIST &&
1260f5736e95SDavid du Colombier ucReadStack() != TAG_ORDEREDLIST, ucReadStack());
1261f5736e95SDavid du Colombier
1262f5736e95SDavid du Colombier /* Start a new list item */
1263f5736e95SDavid du Colombier szAttr = bNoMarks ? "override='none'" : NULL;
1264f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_LISTITEM, szAttr);
1265f5736e95SDavid du Colombier /* Start a new paragraph (independant of level) */
1266f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_PARA, NULL);
1267f5736e95SDavid du Colombier } /* end of vStartOfListItemXML */
1268f5736e95SDavid du Colombier
1269f5736e95SDavid du Colombier /*
1270f5736e95SDavid du Colombier * Create a start of a table
1271f5736e95SDavid du Colombier */
1272f5736e95SDavid du Colombier static void
vStartOfTable(diagram_type * pDiag,UCHAR ucBorderInfo)1273f5736e95SDavid du Colombier vStartOfTable(diagram_type *pDiag, UCHAR ucBorderInfo)
1274f5736e95SDavid du Colombier {
1275f5736e95SDavid du Colombier const char *szFrame;
1276f5736e95SDavid du Colombier BOOL bNotReady;
1277f5736e95SDavid du Colombier UCHAR ucTopTag;
1278f5736e95SDavid du Colombier char cColSep, cRowSep;
1279f5736e95SDavid du Colombier char szAttr[40];
1280f5736e95SDavid du Colombier
1281f5736e95SDavid du Colombier fail(pDiag == NULL);
1282f5736e95SDavid du Colombier
1283f5736e95SDavid du Colombier /* Close elements that cannot contain a table */
1284f5736e95SDavid du Colombier bNotReady = TRUE;
1285f5736e95SDavid du Colombier do {
1286f5736e95SDavid du Colombier ucTopTag = ucReadStack();
1287f5736e95SDavid du Colombier switch (ucTopTag) {
1288f5736e95SDavid du Colombier case TAG_TITLE:
1289f5736e95SDavid du Colombier fail(!bTitleOpen);
1290f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TITLE);
1291f5736e95SDavid du Colombier break;
1292f5736e95SDavid du Colombier case TAG_EMPHASIS:
1293f5736e95SDavid du Colombier fail(!bEmphasisOpen);
1294f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_EMPHASIS);
1295f5736e95SDavid du Colombier break;
1296f5736e95SDavid du Colombier case TAG_SUPERSCRIPT:
1297f5736e95SDavid du Colombier fail(!bSuperscriptOpen);
1298f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SUPERSCRIPT);
1299f5736e95SDavid du Colombier break;
1300f5736e95SDavid du Colombier case TAG_SUBSCRIPT:
1301f5736e95SDavid du Colombier fail(!bSubscriptOpen);
1302f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_SUBSCRIPT);
1303f5736e95SDavid du Colombier break;
1304f5736e95SDavid du Colombier default:
1305f5736e95SDavid du Colombier bNotReady = FALSE;
1306f5736e95SDavid du Colombier break;
1307f5736e95SDavid du Colombier }
1308f5736e95SDavid du Colombier } while (bNotReady);
1309f5736e95SDavid du Colombier
1310f5736e95SDavid du Colombier /* Create table attributes */
1311f5736e95SDavid du Colombier switch (ucBorderInfo) {
1312f5736e95SDavid du Colombier case TABLE_BORDER_TOP:
1313f5736e95SDavid du Colombier szFrame = "top";
1314f5736e95SDavid du Colombier break;
1315f5736e95SDavid du Colombier case TABLE_BORDER_LEFT|TABLE_BORDER_RIGHT:
1316f5736e95SDavid du Colombier szFrame = "sides";
1317f5736e95SDavid du Colombier break;
1318f5736e95SDavid du Colombier case TABLE_BORDER_TOP|TABLE_BORDER_BOTTOM:
1319f5736e95SDavid du Colombier szFrame = "topbot";
1320f5736e95SDavid du Colombier break;
1321f5736e95SDavid du Colombier case TABLE_BORDER_BOTTOM:
1322f5736e95SDavid du Colombier szFrame = "bottom";
1323f5736e95SDavid du Colombier break;
1324f5736e95SDavid du Colombier case TABLE_BORDER_TOP|TABLE_BORDER_LEFT|
1325f5736e95SDavid du Colombier TABLE_BORDER_BOTTOM|TABLE_BORDER_RIGHT:
1326f5736e95SDavid du Colombier szFrame = "all";
1327f5736e95SDavid du Colombier break;
1328f5736e95SDavid du Colombier default:
1329f5736e95SDavid du Colombier szFrame = "none";
1330f5736e95SDavid du Colombier break;
1331f5736e95SDavid du Colombier }
1332f5736e95SDavid du Colombier cColSep = bIsTableBorderLeft(ucBorderInfo) ||
1333f5736e95SDavid du Colombier bIsTableBorderRight(ucBorderInfo) ? '1' : '0';
1334f5736e95SDavid du Colombier cRowSep = bIsTableBorderTop(ucBorderInfo) ||
1335f5736e95SDavid du Colombier bIsTableBorderBottom(ucBorderInfo) ? '1' : '0';
1336f5736e95SDavid du Colombier
1337f5736e95SDavid du Colombier sprintf(szAttr, "frame='%.6s' colsep='%c' rowsep='%c'",
1338f5736e95SDavid du Colombier szFrame, cColSep, cRowSep);
1339f5736e95SDavid du Colombier
1340f5736e95SDavid du Colombier if (usHeaderLevelCurrent == 0) {
1341f5736e95SDavid du Colombier /* No table without an open header */
1342f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_CHAPTER, NULL);
1343f5736e95SDavid du Colombier /* Dummy title */
1344f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_TITLE, NULL);
1345f5736e95SDavid du Colombier }
1346f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_INFORMALTABLE, szAttr);
1347f5736e95SDavid du Colombier } /* end of vStartOfTable */
1348f5736e95SDavid du Colombier
1349f5736e95SDavid du Colombier /*
1350f5736e95SDavid du Colombier * Create a start of a table group
1351f5736e95SDavid du Colombier */
1352f5736e95SDavid du Colombier static void
vStartOfTableGroup(diagram_type * pDiag,int iNbrOfColumns,const short * asColumnWidth)1353f5736e95SDavid du Colombier vStartOfTableGroup(diagram_type *pDiag,
1354f5736e95SDavid du Colombier int iNbrOfColumns, const short *asColumnWidth)
1355f5736e95SDavid du Colombier {
1356f5736e95SDavid du Colombier double dWidth;
1357f5736e95SDavid du Colombier int iIndex;
1358f5736e95SDavid du Colombier char szCols[6 + 3 * sizeof(int) + 1 + 1];
1359f5736e95SDavid du Colombier char szColWidth[10 + 3 * sizeof(short) + 3 + 3 + 1];
1360f5736e95SDavid du Colombier
1361f5736e95SDavid du Colombier fail(iNbrOfColumns < 1);
1362f5736e95SDavid du Colombier fail(asColumnWidth == NULL);
1363f5736e95SDavid du Colombier
1364f5736e95SDavid du Colombier sprintf(szCols, "cols='%d'", iNbrOfColumns);
1365f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_TGROUP, szCols);
1366f5736e95SDavid du Colombier
1367f5736e95SDavid du Colombier for (iIndex= 0; iIndex < iNbrOfColumns; iIndex++) {
1368f5736e95SDavid du Colombier fail(asColumnWidth[iIndex] < 0);
1369f5736e95SDavid du Colombier dWidth = dTwips2Points(asColumnWidth[iIndex]);
1370f5736e95SDavid du Colombier if (dWidth <= 1.0) {
1371f5736e95SDavid du Colombier strcpy(szColWidth, "colwidth='1.00pt'");
1372f5736e95SDavid du Colombier } else {
1373f5736e95SDavid du Colombier sprintf(szColWidth, "colwidth='%.2fpt'", dWidth);
1374f5736e95SDavid du Colombier }
1375f5736e95SDavid du Colombier vAddCombinedTag(pDiag, TAG_COLSPEC, szColWidth);
1376f5736e95SDavid du Colombier }
1377f5736e95SDavid du Colombier } /* end of vStartOfTableGroup */
1378f5736e95SDavid du Colombier
1379f5736e95SDavid du Colombier /*
1380f5736e95SDavid du Colombier * Create an end of a table
1381f5736e95SDavid du Colombier */
1382f5736e95SDavid du Colombier void
vEndOfTableXML(diagram_type * pDiag)1383f5736e95SDavid du Colombier vEndOfTableXML(diagram_type *pDiag)
1384f5736e95SDavid du Colombier {
1385f5736e95SDavid du Colombier fail(pDiag == NULL);
1386f5736e95SDavid du Colombier
1387f5736e95SDavid du Colombier if (bTableOpen) {
1388f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TBODY);
1389f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_TGROUP);
1390f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_INFORMALTABLE);
1391f5736e95SDavid du Colombier }
1392f5736e95SDavid du Colombier } /* end of vEndOfTableXML */
1393f5736e95SDavid du Colombier
1394f5736e95SDavid du Colombier /*
1395f5736e95SDavid du Colombier * Add a table row
1396f5736e95SDavid du Colombier */
1397f5736e95SDavid du Colombier void
vAddTableRowXML(diagram_type * pDiag,char ** aszColTxt,int iNbrOfColumns,const short * asColumnWidth,UCHAR ucBorderInfo)1398f5736e95SDavid du Colombier vAddTableRowXML(diagram_type *pDiag, char **aszColTxt,
1399f5736e95SDavid du Colombier int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo)
1400f5736e95SDavid du Colombier {
1401f5736e95SDavid du Colombier size_t tCount, tStringLength;
1402f5736e95SDavid du Colombier int iIndex;
1403f5736e95SDavid du Colombier
1404f5736e95SDavid du Colombier fail(pDiag == NULL);
1405f5736e95SDavid du Colombier fail(pDiag->pOutFile == NULL);
1406f5736e95SDavid du Colombier fail(aszColTxt == NULL);
1407f5736e95SDavid du Colombier fail(iNbrOfColumns < 1);
1408f5736e95SDavid du Colombier fail(asColumnWidth == NULL);
1409f5736e95SDavid du Colombier
1410f5736e95SDavid du Colombier if (iNbrOfColumns != iTableColumnsCurrent) {
1411f5736e95SDavid du Colombier /* A new number of columns */
1412f5736e95SDavid du Colombier /* End the old table body and table group (if they exist) */
1413f5736e95SDavid du Colombier vAddEndTagOptional(pDiag, TAG_TBODY);
1414f5736e95SDavid du Colombier vAddEndTagOptional(pDiag, TAG_TGROUP);
1415f5736e95SDavid du Colombier if (!bTableOpen) {
1416f5736e95SDavid du Colombier /* No table yet. Start a new table */
1417f5736e95SDavid du Colombier vStartOfTable(pDiag, ucBorderInfo);
1418f5736e95SDavid du Colombier }
1419f5736e95SDavid du Colombier /* Start a new table group and a new table body */
1420f5736e95SDavid du Colombier vStartOfTableGroup(pDiag, iNbrOfColumns, asColumnWidth);
1421f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_TBODY, NULL);
1422f5736e95SDavid du Colombier iTableColumnsCurrent = iNbrOfColumns;
1423f5736e95SDavid du Colombier }
1424f5736e95SDavid du Colombier
1425f5736e95SDavid du Colombier /* Add the table row */
1426f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_ROW, NULL);
1427f5736e95SDavid du Colombier for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
1428f5736e95SDavid du Colombier /* Add a table cell */
1429f5736e95SDavid du Colombier fail(aszColTxt[iIndex] == NULL);
1430f5736e95SDavid du Colombier vAddStartTag(pDiag, TAG_ENTRY, NULL);
1431f5736e95SDavid du Colombier tStringLength = strlen(aszColTxt[iIndex]);
1432f5736e95SDavid du Colombier for (tCount = 0; tCount < tStringLength; tCount++) {
1433*25b329d5SDavid du Colombier vPrintChar(pDiag, aszColTxt[iIndex][tCount]);
1434f5736e95SDavid du Colombier }
1435f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_ENTRY);
1436f5736e95SDavid du Colombier }
1437f5736e95SDavid du Colombier vAddEndTag(pDiag, TAG_ROW);
1438f5736e95SDavid du Colombier } /* end of vAddTableRowXML */
1439