WordConverter *WordConverterNew(DFDocument *html, const char *abstractPath, const char *idPrefix, WordPackage *package, DFBuffer *warnings) { WordConverter *converter = (WordConverter *)calloc(1,sizeof(WordConverter)); if ((abstractPath == NULL) || (strlen(abstractPath) == 0)) abstractPath = "."; converter->html = DFDocumentRetain(html); converter->abstractPath = strdup(abstractPath); converter->concretePath = strdup(package->tempPath); converter->idPrefix = DFStrDup(idPrefix); converter->package = WordPackageRetain(package); converter->styles = WordSheetNew(converter->package->styles); converter->numbering = WordNumberingNew(converter->package); converter->theme = WordThemeNew(converter->package); converter->mainSection = WordSectionNew(); converter->objects = WordObjectsNew(converter->package); converter->footnotes = WordNoteGroupNewFootnotes(converter->package->footnotes); converter->endnotes = WordNoteGroupNewEndnotes(converter->package->endnotes); converter->supportedContentTypes = DFHashTableNew((DFCopyFunction)strdup,free); DFHashTableAdd(converter->supportedContentTypes,"jpg","image/jpeg"); DFHashTableAdd(converter->supportedContentTypes,"jpeg","image/jpeg"); DFHashTableAdd(converter->supportedContentTypes,"tif","image/tiff"); DFHashTableAdd(converter->supportedContentTypes,"tiff","image/tiff"); DFHashTableAdd(converter->supportedContentTypes,"gif","image/gif"); DFHashTableAdd(converter->supportedContentTypes,"bmp","image/bmp"); DFHashTableAdd(converter->supportedContentTypes,"png","image/png"); converter->warnings = DFBufferRetain(warnings); return converter; }
static ImageInfo *ImageInfoNew(const char *rId, double widthPts, double heightPts) { ImageInfo *info = (ImageInfo *)calloc(1,sizeof(ImageInfo)); info->rId = DFStrDup(rId); info->widthPts = widthPts; info->heightPts = heightPts; return info; }
static void fixWordLists(DFNode *node, WordConverter *conv) { for (DFNode *child = node->first; child != NULL; child = child->next) fixWordLists(child,conv); int haveParagraphs = 0; for (DFNode *child = node->first; child != NULL; child = child->next) { if (child->tag == WORD_P) { haveParagraphs = 1; break; } } if (!haveParagraphs) return; int createdHashTables = 0; DFHashTable *replacementNumIds = NULL; DFHashTable *itemNoByListKey = NULL; DFHashTable *lastNumIdByIlvl = NULL; DFHashTable *itemNoByIlvl = NULL; int maxIlvl = -1; for (DFNode *child = node->first; child != NULL; child = child->next) { if (child->tag != WORD_P) continue; DFNode *pPrElem = DFChildWithTag(child,WORD_PPR); DFNode *numPrElem = DFChildWithTag(pPrElem,WORD_NUMPR); DFNode *numIdElem = DFChildWithTag(numPrElem,WORD_NUMID); DFNode *ilvlElem = DFChildWithTag(numPrElem,WORD_ILVL); const char *numId = DFGetAttribute(numIdElem,WORD_VAL); const char *ilvl = DFGetAttribute(ilvlElem,WORD_VAL); if ((numId == NULL) || (atoi(numId) == 0)) continue; if (!createdHashTables) { replacementNumIds = DFHashTableNew((DFCopyFunction)xstrdup,free); itemNoByListKey = DFHashTableNew((DFCopyFunction)xstrdup,free); lastNumIdByIlvl = DFHashTableNew((DFCopyFunction)xstrdup,free); itemNoByIlvl = DFHashTableNew((DFCopyFunction)xstrdup,free); createdHashTables = 1; } if (ilvl == NULL) ilvl = "0";; WordConcreteNum *concreteNum = WordNumberingConcreteWithId(conv->numbering,numId); // may be NULL WordNumLevel *numLevel = WordConcreteNumGetLevel(concreteNum,atoi(ilvl)); // may be NULL const char *levelStart = NULL; if (numLevel != NULL) { for (DFNode *lvlChild = numLevel->element->first; lvlChild != NULL; lvlChild = lvlChild->next) { switch (lvlChild->tag) { case WORD_START: levelStart = DFGetAttribute(lvlChild,WORD_VAL); break; } } } char *listKey = DFFormatString("%s:%s",numId,ilvl); char *itemNo = DFStrDup(DFHashTableLookup(itemNoByListKey,listKey)); if (itemNo == NULL) { itemNo = xstrdup("1"); if ((levelStart != NULL) && (atoi(levelStart) > 1) && (atoi(ilvl) <= maxIlvl)) { const char *prevNumId = DFHashTableLookup(lastNumIdByIlvl,ilvl); const char *prevItemNo = DFHashTableLookup(itemNoByIlvl,ilvl); if ((prevNumId != NULL) && (prevItemNo != NULL)) { DFHashTableAdd(replacementNumIds,numId,prevNumId); free(itemNo); itemNo = DFFormatString("%d",atoi(prevItemNo)+1); } } } else { int intValue = atoi(itemNo); free(itemNo); itemNo = DFFormatString("%d",intValue+1); } DFHashTableAdd(itemNoByListKey,listKey,itemNo); const char *replNumId = DFHashTableLookup(replacementNumIds,numId); if (replNumId != NULL) { numId = replNumId; DFSetAttribute(numIdElem,WORD_VAL,numId); } DFHashTableAdd(lastNumIdByIlvl,ilvl,numId); DFHashTableAdd(itemNoByIlvl,ilvl,itemNo); maxIlvl = atoi(ilvl); free(listKey); free(itemNo); } DFHashTableRelease(replacementNumIds); DFHashTableRelease(itemNoByListKey); DFHashTableRelease(lastNumIdByIlvl); DFHashTableRelease(itemNoByIlvl); }
char *WordStyleIdForStyle(CSSStyle *style) { const char *selector = style->selector; char *resStyleId = NULL; if (!strcmp(selector,"table.Normal_Table")) return strdup("TableNormal"); if (!strcmp(selector,"table.Table_Grid")) return strdup("TableGrid"); if (!strcmp(selector,"span.Default_Paragraph_Font")) return strdup("DefaultParagraphFont"); if (!strcmp(selector,"p.List_Paragraph")) return strdup("ListParagraph"); int headingLevel = CSSSelectorHeadingLevel(selector); if (headingLevel != 0) { char *prefix = DFFormatString("heading_%d",headingLevel); if ((style->className != NULL) && DFStringHasPrefix(style->className,prefix)) { char *rest = DFSubstring(style->className,strlen(prefix),strlen(style->className)); char *result = DFFormatString("Heading%d%s",headingLevel,rest); free(rest); free(prefix); return result; } free(prefix); } if (!strcmp(selector,"span.Heading1Char")) return strdup("Heading1Char"); if (!strcmp(selector,"span.Heading2Char")) return strdup("Heading2Char"); if (!strcmp(selector,"span.Heading3Char")) return strdup("Heading3Char"); if (!strcmp(selector,"span.Heading4Char")) return strdup("Heading4Char"); if (!strcmp(selector,"span.Heading5Char")) return strdup("Heading5Char"); if (!strcmp(selector,"span.Heading6Char")) return strdup("Heading6Char"); if (!strcmp(selector,"span.Heading7Char")) return strdup("Heading7Char"); if (!strcmp(selector,"span.Heading8Char")) return strdup("Heading8Char"); if (!strcmp(selector,"span.Heading9Char")) return strdup("Heading9Char"); char *className = CSSSelectorCopyClassName(selector); switch (CSSSelectorGetTag(selector)) { case HTML_FIGURE: { resStyleId = DFStrDup("Figure"); break; } case HTML_CAPTION: { resStyleId = DFStrDup("Caption"); break; } case HTML_H1: case HTML_H2: case HTML_H3: case HTML_H4: case HTML_H5: case HTML_H6: { if ((className == NULL) || (strlen(className) == 0)) { int level = CSSSelectorHeadingLevel(selector); if ((level >= 1) && (level <= 6)) { // FIXME: we shouldn't rely on the specific word "Heading" here - instead using the localised name // FIXME: not covered by tests resStyleId = DFFormatString("Heading%d",level); } } else { resStyleId = DFStrDup(className); } break; } case HTML_P: resStyleId = DFStrDup(className); break; case HTML_SPAN: resStyleId = DFStrDup(className); break; case HTML_TABLE: resStyleId = DFStrDup(className); break; } free(className); if (resStyleId == NULL) { // Note: selector here may start with . (i.e. applies to all elements) // FIXME: not covered by tests resStyleId = strdup(selector); } return resStyleId; }