📄 xml.c
字号:
/* * xml.c * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL * * Description: * Functions to deal with the XML/DocBook format * */#include <string.h>#include "antiword.h"#define vAddEndTagsUntil1(p,t) vAddEndTagsUntil2(p,t,TAG_NOTAG) #if defined(DEBUG)#define vStackTrace() __vStackTrace(__LINE__)#else#define vStackTrace() /* EMPTY */#endif /* DEBUG *//* The character set */static encoding_type eEncoding = encoding_neutral;/* Word version */static int iWordVersion = -1;/* Special treatment for files from Word 4/5/6 on an Apple Macintosh */static BOOL bOldMacFile = FALSE;/* Text is emphasised */static BOOL bEmphasisOpen = FALSE;/* Text is superscript */static BOOL bSuperscriptOpen = FALSE;/* Text is subscript */static BOOL bSubscriptOpen = FALSE;/* Title is open */static BOOL bTitleOpen = FALSE;/* Table is open */static BOOL bTableOpen = FALSE;/* Footnote is open */static BOOL bFootnoteOpen = FALSE;/* Current paragraph level */static UINT uiParagraphLevel = 0;/* Current list level */static UINT uiListLevel = 0;/* Current list level is still empty */static BOOL bEmptyListLevel = TRUE;/* Current header level */static USHORT usHeaderLevelCurrent = 0;/* Current header level is still empty */static BOOL bEmptyHeaderLevel = TRUE;/* Number of columns in the current table */static int iTableColumnsCurrent = 0;/* Footnote number */static UINT uiFootnoteNumber = 0;/* Constants for the stack */#define INITIAL_STACK_SIZE 10#if defined(DEBUG)#define EXTENSION_STACK_SIZE 2#else#define EXTENSION_STACK_SIZE 10#endif /* DEBUG *//* Variables for the stack */static UCHAR *aucStack = NULL;static size_t tStacksize = 0;static size_t tStackNextFree = 0;/* Constants for the tags */#define TAG_NOTAG (UCHAR)0#define TAG_AUTHOR (UCHAR)1#define TAG_BEGINPAGE (UCHAR)2#define TAG_BOOK (UCHAR)3#define TAG_BOOKINFO (UCHAR)4#define TAG_CHAPTER (UCHAR)5#define TAG_COLSPEC (UCHAR)6#define TAG_CORPNAME (UCHAR)7#define TAG_DATE (UCHAR)8#define TAG_EMPHASIS (UCHAR)9#define TAG_ENTRY (UCHAR)10#define TAG_FILENAME (UCHAR)11#define TAG_FOOTNOTE (UCHAR)12#define TAG_INFORMALTABLE (UCHAR)13#define TAG_ITEMIZEDLIST (UCHAR)14#define TAG_LISTITEM (UCHAR)15#define TAG_ORDEREDLIST (UCHAR)16#define TAG_PARA (UCHAR)17#define TAG_ROW (UCHAR)18#define TAG_SECT1 (UCHAR)19#define TAG_SECT2 (UCHAR)20#define TAG_SECT3 (UCHAR)21#define TAG_SECT4 (UCHAR)22#define TAG_SECT5 (UCHAR)23#define TAG_SUBSCRIPT (UCHAR)24#define TAG_SUBTITLE (UCHAR)25#define TAG_SUPERSCRIPT (UCHAR)26#define TAG_SURNAME (UCHAR)27#define TAG_TBODY (UCHAR)28#define TAG_TGROUP (UCHAR)29#define TAG_TITLE (UCHAR)30typedef struct docbooktags_tag { UCHAR ucTagnumber; char szTagname[15]; BOOL bAddNewlineStart; BOOL bAddNewlineEnd;} docbooktags_type;static const docbooktags_type atDocBookTags[] = { { TAG_NOTAG, "!ERROR!", TRUE, TRUE }, { TAG_AUTHOR, "author", TRUE, TRUE }, { TAG_BEGINPAGE, "beginpage", TRUE, TRUE }, { TAG_BOOK, "book", TRUE, TRUE }, { TAG_BOOKINFO, "bookinfo", TRUE, TRUE }, { TAG_CHAPTER, "chapter", TRUE, TRUE }, { TAG_COLSPEC, "colspec", TRUE, TRUE }, { TAG_CORPNAME, "corpname", FALSE, FALSE }, { TAG_DATE, "date", FALSE, FALSE }, { TAG_EMPHASIS, "emphasis", FALSE, FALSE }, { TAG_ENTRY, "entry", TRUE, TRUE }, { TAG_FILENAME, "filename", FALSE, FALSE }, { TAG_FOOTNOTE, "footnote", FALSE, FALSE }, { TAG_INFORMALTABLE, "informaltable",TRUE, TRUE }, { TAG_ITEMIZEDLIST, "itemizedlist", TRUE, TRUE }, { TAG_LISTITEM, "listitem", TRUE, TRUE }, { TAG_ORDEREDLIST, "orderedlist", TRUE, TRUE }, { TAG_PARA, "para", TRUE, TRUE }, { TAG_ROW, "row", TRUE, TRUE }, { TAG_SECT1, "sect1", TRUE, TRUE }, { TAG_SECT2, "sect2", TRUE, TRUE }, { TAG_SECT3, "sect3", TRUE, TRUE }, { TAG_SECT4, "sect4", TRUE, TRUE }, { TAG_SECT5, "sect5", TRUE, TRUE }, { TAG_SUBSCRIPT, "subscript", FALSE, FALSE }, { TAG_SUBTITLE, "subtitle", FALSE, FALSE }, { TAG_SUPERSCRIPT, "superscript", FALSE, FALSE }, { TAG_SURNAME, "surname", FALSE, FALSE }, { TAG_TBODY, "tbody", TRUE, TRUE }, { TAG_TGROUP, "tgroup", TRUE, TRUE }, { TAG_TITLE, "title", FALSE, FALSE },};static void vAddStartTag(diagram_type *, UCHAR, const char *);static void vAddEndTag(diagram_type *, UCHAR);static void vAddCombinedTag(diagram_type *, UCHAR, const char *);static void vPrintChar(diagram_type *, char);#if defined(DEBUG)/* * vCheckTagTable - check the tag table */static voidvCheckTagTable(void){ size_t tIndex; for (tIndex = 0; tIndex < elementsof(atDocBookTags); tIndex++) { if (tIndex != (size_t)atDocBookTags[tIndex].ucTagnumber) { DBG_DEC(tIndex); werr(1, "Array atDocBookTags is broken"); } }} /* end of vCheckTagTable *//* * __vStackTrace - show a stack trace */static void__vStackTrace(int iLine){ int iIndex; fprintf(stderr, "%s[%3d]:\n", __FILE__, iLine); if (tStackNextFree == 0) { fprintf(stderr, "The stack is empty\n"); return; } for (iIndex = (int)tStackNextFree - 1; iIndex >= 0; iIndex--) { fprintf(stderr, "%2d: %2d: '%s'\n", iIndex, (int)atDocBookTags[(UINT)aucStack[iIndex]].ucTagnumber, atDocBookTags[(UINT)aucStack[iIndex]].szTagname); }} /* end of __vStackTrace */#endif /* DEBUG *//* * vPushStack - push a tag onto the stack */static voidvPushStack(UCHAR ucTag){ fail(tStackNextFree > tStacksize); if (tStackNextFree == tStacksize) { /* The stack is full; enlarge the stack */ tStacksize += EXTENSION_STACK_SIZE; aucStack = xrealloc(aucStack, tStacksize * sizeof(UCHAR)); DBG_DEC(tStacksize); } fail(tStackNextFree >= tStacksize); aucStack[tStackNextFree++] = ucTag;} /* end of vPushStack *//* * vPopStack - pop a tag from the stack */static UCHARucPopStack(void){ DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree); DBG_DEC_C(tStackNextFree > tStacksize, tStacksize); fail(tStackNextFree > tStacksize); fail(tStackNextFree == 0); if (tStackNextFree == 0) { werr(1, "The stack is empty, unable to continue"); return TAG_NOTAG; } return aucStack[--tStackNextFree];} /* end of ucPopStack *//* * vReadStack - read a tag from the top of the stack */static UCHARucReadStack(void){ DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree); DBG_DEC_C(tStackNextFree > tStacksize, tStacksize); fail(tStackNextFree > tStacksize); if (tStackNextFree == 0) { /* The stack is empty */ return TAG_NOTAG; } return aucStack[tStackNextFree - 1];} /* end of ucReadStack *//* * vPrintLevel - print the tag level */static voidvPrintLevel(FILE *pOutFile){ size_t tIndex; fail(pOutFile == NULL); for (tIndex = 0; tIndex < tStackNextFree; tIndex++) { (void)putc(' ', pOutFile); }} /* end of vPrintLevel *//* * vPrintFootnote - print a footnote */static voidvPrintFootnote(diagram_type *pDiag, UINT uiFootnoteIndex){ const char *szText, *pcTmp; BOOL bSuScript; UCHAR ucTopTag; TRACE_MSG("vPrintFootnote"); szText = szGetFootnootText(uiFootnoteIndex); if (szText == NULL) { szText = ""; } /* Remove the subscript/superscript (if any) */ ucTopTag = ucReadStack(); bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT; if (bSuScript) { vAddEndTag(pDiag, ucTopTag); } /* Start a footnote */ vAddStartTag(pDiag, TAG_FOOTNOTE, NULL); vAddStartTag(pDiag, TAG_PARA, NULL); /* Print a footnote */ for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) { if (*pcTmp == PAR_END) { if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') { /* PAR_END is not empty and not last */ vAddEndTag(pDiag, TAG_PARA); vAddStartTag(pDiag, TAG_PARA, NULL); } } else { vPrintChar(pDiag, *pcTmp); } } /* End a footnote */ vAddEndTag(pDiag, TAG_PARA); vAddEndTag(pDiag, TAG_FOOTNOTE); /* Repair the subscript/superscript (if any) */ if (bSuScript) { vAddStartTag(pDiag, ucTopTag, NULL); }} /* end of vPrintFootnote *//* * vPrintChar - print a character with XML encoding */static voidvPrintChar(diagram_type *pDiag, char cChar){ fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); switch (cChar) { case FOOTNOTE_OR_ENDNOTE: uiFootnoteNumber++; vPrintFootnote(pDiag, uiFootnoteNumber - 1); break; case '<': fprintf(pDiag->pOutFile, "%s", "<"); break; case '>': fprintf(pDiag->pOutFile, "%s", ">"); break; case '&': fprintf(pDiag->pOutFile, "%s", "&"); break; default: (void)putc(cChar, pDiag->pOutFile); break; }} /* end of vPrintChar *//* * vPrintSpecialChar - convert and print a character */static voidvPrintSpecialChar(diagram_type *pDiag, USHORT usChar){ ULONG ulChar; size_t tLen, tIndex; char szResult[4]; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); fail(iWordVersion < 0); fail(eEncoding == encoding_neutral); ulChar = ulTranslateCharacters(usChar, 0, iWordVersion, conversion_xml, eEncoding, bOldMacFile); tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); if (tLen == 1) { vPrintChar(pDiag, szResult[0]); } else { for (tIndex = 0; tIndex < tLen; tIndex++) { (void)putc(szResult[tIndex], pDiag->pOutFile); } }} /* end of vPrintSpecialChar *//* * vPrintSpecialString - convert and print a string */static voidvPrintSpecialString(diagram_type *pDiag, const char *szString){ int iIndex; USHORT usChar; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); fail(szString == NULL); for (iIndex = 0; szString[iIndex] != '\0'; iIndex++) { usChar = (USHORT)(UCHAR)szString[iIndex]; vPrintSpecialChar(pDiag, usChar); }} /* end of vPrintSpecialString *//* * vAddStartTag - add the specified start tag to the file */static voidvAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute){ fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); fail((size_t)ucTag >= elementsof(atDocBookTags)); if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) { fprintf(pDiag->pOutFile, "\n"); vPrintLevel(pDiag->pOutFile); } if (szAttribute == NULL || szAttribute[0] == '\0') { fprintf(pDiag->pOutFile, "<%s>", atDocBookTags[(UINT)ucTag].szTagname); } else { fprintf(pDiag->pOutFile, "<%s %s>", atDocBookTags[(UINT)ucTag].szTagname, szAttribute); } if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) { fprintf(pDiag->pOutFile, "\n"); pDiag->lXleft = 0; } vPushStack(ucTag); /* Set global variables */ switch (ucTag) { case TAG_CHAPTER: usHeaderLevelCurrent = 1; bEmptyHeaderLevel = TRUE; break; case TAG_SECT1: usHeaderLevelCurrent = 2; bEmptyHeaderLevel = TRUE; break; case TAG_SECT2: usHeaderLevelCurrent = 3; bEmptyHeaderLevel = TRUE; break; case TAG_SECT3: usHeaderLevelCurrent = 4; bEmptyHeaderLevel = TRUE; break; case TAG_SECT4: usHeaderLevelCurrent = 5; bEmptyHeaderLevel = TRUE; break; case TAG_SECT5: usHeaderLevelCurrent = 6; bEmptyHeaderLevel = TRUE; break; case TAG_TITLE: fail(uiParagraphLevel != 0); bTitleOpen = TRUE; break; case TAG_FOOTNOTE: bFootnoteOpen = TRUE; break; case TAG_PARA: fail(bTitleOpen && !bFootnoteOpen); uiParagraphLevel++; bEmptyHeaderLevel = FALSE; break; case TAG_EMPHASIS: bEmphasisOpen = TRUE; break; case TAG_ITEMIZEDLIST: case TAG_ORDEREDLIST: uiListLevel++; bEmptyListLevel = TRUE; bEmptyHeaderLevel = FALSE; break; case TAG_LISTITEM: bEmptyListLevel = FALSE; break; case TAG_SUPERSCRIPT: bSuperscriptOpen = TRUE; break; case TAG_SUBSCRIPT: bSubscriptOpen = TRUE; break; case TAG_INFORMALTABLE: bTableOpen = TRUE; bEmptyHeaderLevel = FALSE; break; default: break; }} /* end of vAddStartTag *//*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -