static void enableNumberingForStyle(CSSStyle *style) { int level = style->headingLevel; DFBuffer *reset = DFBufferNew(); for (int after = level+1; after <= 6; after++) { if (reset->len == 0) DFBufferFormat(reset,"h%d",after); else DFBufferFormat(reset," h%d",after); } DFBuffer *content = DFBufferNew(); for (int upto = 1; upto <= level; upto++) { if (content->len == 0) DFBufferFormat(content,"counter(h%d)",upto); else DFBufferFormat(content," \".\" counter(h%d)",upto); } DFBufferFormat(content," \" \""); CSSProperties *rule = CSSStyleRule(style); CSSPut(rule,"counter-increment",style->elementName); if (reset->len > 0) CSSPut(rule,"counter-reset",reset->data); CSSPut(CSSStyleBefore(style),"content",content->data); style->latent = 0; DFBufferRelease(reset); DFBufferRelease(content); }
int DFUnzip(const char *zipFilename, DFStorage *storage, DFError **error) { unsigned char *buf; DFextZipHandleP zipHandle; int i; zipHandle = DFextZipOpen(zipFilename); if (!zipHandle) return zipError(error,"Cannot open file"); for (i = 0; i < zipHandle->zipFileCount; i++) { if ( (buf = DFextZipReadFile(zipHandle, &zipHandle->zipFileEntries[i])) == NULL) return zipError(error, "Cannot read file in zip"); DFBuffer *content = DFBufferNew(); DFBufferAppendData(content, (void *)buf, zipHandle->zipFileEntries[i].uncompressedSize); free(buf); if (!DFBufferWriteToStorage(content, storage, zipHandle->zipFileEntries[i].fileName, error)) { DFBufferRelease(content); return zipError(error, "%s: %s", zipHandle->zipFileEntries[i].fileName, DFErrorMessage(error)); } DFBufferRelease(content); } DFextZipClose(zipHandle); return 1; }
void DFSAXParserFree(DFSAXParser *parser) { DFDocumentRelease(parser->document); DFBufferRelease(parser->warnings); DFBufferRelease(parser->errors); DFBufferRelease(parser->fatalErrors); DFMarkupCompatibilityFree(parser->compatibility); free(parser); }
static int parsePackage(TextPackage *package, const char *string, const char *path, DFError **error) { DFBuffer *replaced = DFBufferNew(); if (!strcmp(path,"")) path = "."; if (!processIncludes(package,string,replaced,path,error)) { DFBufferRelease(replaced); return 0; } char *currentKey = strdup(""); DFBuffer *currentValue = DFBufferNew(); const char **lines = DFStringSplit(replaced->data,"\n",0); for (int lineno = 0; lines[lineno]; lineno++) { const char *line = lines[lineno]; if (!DFStringHasPrefix(line,"#")) { DFBufferFormat(currentValue,"%s\n",line); } else if (DFStringHasPrefix(line,"#item ")) { package->keys = (char **)realloc(package->keys,(package->nkeys+2)*sizeof(char *)); package->keys[package->nkeys++] = strdup(currentKey); package->keys[package->nkeys] = NULL; DFHashTableAdd(package->items,currentKey,currentValue->data); free(currentKey); DFBufferRelease(currentValue); currentKey = DFSubstring(line,6,strlen(line)); currentValue = DFBufferNew(); } else if (DFStringHasPrefix(line,"##")) { DFBufferFormat(currentValue,"%s\n",&line[1]); } else { DFErrorFormat(error,"Unknown command: %s on line %d",line,(lineno+1)); return 0; } } package->keys = (char **)realloc(package->keys,(package->nkeys+2)*sizeof(char *)); package->keys[package->nkeys++] = strdup(currentKey); package->keys[package->nkeys] = NULL; DFHashTableAdd(package->items,currentKey,currentValue->data); free(lines); free(currentKey); DFBufferRelease(currentValue); DFBufferRelease(replaced); return 1; }
char *CSSSheetCopyText(CSSSheet *sheet) { DFBuffer *result = DFBufferNew(); const char **allSelectors = CSSSheetCopySelectors(sheet); DFSortStringsCaseInsensitive(allSelectors); for (int selIndex = 0; allSelectors[selIndex]; selIndex++) { CSSStyle *style = CSSSheetLookupSelector(sheet,allSelectors[selIndex],0,0); DFBufferFormat(result,"%s\n",style->selector); const char **sortedSuffixes = CSSStyleCopySuffixes(style); DFSortStringsCaseInsensitive(sortedSuffixes); for (int suffixIndex = 0; sortedSuffixes[suffixIndex]; suffixIndex++) { const char *suffix = sortedSuffixes[suffixIndex]; char *quotedSuffix = DFQuote(suffix); DFBufferFormat(result," %s\n",quotedSuffix); free(quotedSuffix); CSSProperties *properties = CSSStyleRuleForSuffix(style,suffix); const char **sortedNames = CSSPropertiesCopyNames(properties); DFSortStringsCaseInsensitive(sortedNames); for (int nameIndex = 0; sortedNames[nameIndex]; nameIndex++) { const char *name = sortedNames[nameIndex]; const char *value = CSSGet(properties,name); DFBufferFormat(result," %s = %s\n",name,value); } free(sortedNames); } free(sortedSuffixes); } free(allSelectors); char *str = xstrdup(result->data); DFBufferRelease(result); return str; }
char *DFNodeTextToString(DFNode *node) { DFBuffer *buf = DFBufferNew(); DFNodeTextToBuffer(node,buf); char *result = xstrdup(buf->data); DFBufferRelease(buf); return result; }
char *DFSerializeXMLString(DFDocument *doc, NamespaceID defaultNS, int indent) { DFBuffer *buf = DFBufferNew(); DFSerializeXMLBuffer(doc,defaultNS,indent,buf); char *result = xstrdup(buf->data); DFBufferRelease(buf); return result; }
int Word_simplifyFields(WordPackage *package) { WordSimplification simp; bzero(&simp,sizeof(WordSimplification)); simplifyRecursive(&simp,package->document->docNode); DFBufferRelease(simp.instrText); return simp.haveFields; }
int DFSerializeXMLFile(DFDocument *doc, NamespaceID defaultNS, int indent, const char *filename, DFError **error) { DFBuffer *buf = DFBufferNew(); DFSerializeXMLBuffer(doc,defaultNS,indent,buf); int r = DFBufferWriteToFile(buf,filename,error); DFBufferRelease(buf); return r; }
static int writeString(const char *str, const char *filename, DFError **error) { DFBuffer *buf = DFBufferNew(); DFBufferAppendString(buf,str); int ok = writeData(buf,filename,error); DFBufferRelease(buf); return ok; }
DFDocument *DFParseXMLFile(const char *filename, DFError **error) { DFBuffer *buf = DFBufferReadFromFile(filename,error); if (buf == NULL) return NULL;; DFDocument *doc = DFParseXMLString(buf->data,error); DFBufferRelease(buf); return doc; }
DFDocument *DFParseXMLStorage(DFStorage *storage, const char *filename, DFError **error) { DFBuffer *content = DFBufferReadFromStorage(storage,filename,error); if (content == NULL) return NULL;; DFDocument *doc = DFParseXMLString(content->data,error); DFBufferRelease(content); return doc; }
static char *readString(const char *filename, DFError **error) { DFBuffer *buffer = readData(filename,error); if (buffer == NULL) return NULL; char *result = xstrdup(buffer->data); DFBufferRelease(buffer); return result; }
static char *Word_toPlainFromDir(DFStorage *storage, DFHashTable *parts, DFError **error) { char *documentPath = NULL; DFHashTable *rels = DFHashTableNew((DFCopyFunction)xstrdup,(DFFreeFunction)free); DFBuffer *output = DFBufferNew(); char *relsPathRel = NULL; DFDocument *relsDoc = NULL; int ok = 0; documentPath = findDocumentPath(storage,error); if (documentPath == NULL) { DFErrorFormat(error,"findDocumentPath: %s",DFErrorMessage(error)); goto end; } relsPathRel = computeDocumentRelsPath(documentPath); if (DFStorageExists(storage,relsPathRel) && ((relsDoc = DFParseXMLStorage(storage,relsPathRel,error)) == NULL)) { DFErrorFormat(error,"%s: %s",relsPathRel,DFErrorMessage(error)); goto end; } parseDocumentRels(documentPath,relsDoc,rels,error); if (!processParts(parts,documentPath,relsDoc,rels,output,storage,error)) goto end; ok = 1; end: free(relsPathRel); free(documentPath); DFHashTableRelease(rels); DFDocumentRelease(relsDoc); if (!ok) { DFBufferRelease(output); return NULL; } else { char *result = xstrdup(output->data); DFBufferRelease(output); return result; } }
int btosFile(const char *inFilename, const char *outFilename, DFError **error) { DFBuffer *data = readData(inFilename,error); if (data == NULL) return 0; char *str = binaryToString(data); int ok = writeString(str,outFilename,error); free(str); DFBufferRelease(data); return ok; }
int stobFile(const char *inFilename, const char *outFilename, DFError **error) { char *str = readString(inFilename,error); if (str == NULL) return 0;; DFBuffer *bin = stringToBinary(str); int ok = writeData(bin,outFilename,error); DFBufferRelease(bin); free(str); return ok; }
int DFSerializeXMLStorage(DFDocument *doc, NamespaceID defaultNS, int indent, DFStorage *storage, const char *filename, DFError **error) { char *str = DFSerializeXMLString(doc,defaultNS,indent); DFBuffer *content = DFBufferNew(); DFBufferAppendString(content,str); int r = DFBufferWriteToStorage(content,storage,filename,error); DFBufferRelease(content); free(str); return r; }
static char *extractPrefix(DFNode *node, const char *counterName) { if (findSeqChild(node) == NULL) return NULL; DFBuffer *result = DFBufferNew(); int foundSeq = 0; int foundContent = 0; extractPrefixRecursive(node,counterName,result,&foundSeq,&foundContent); char *str = strdup(result->data); DFBufferRelease(result); return str; }
void findLabel(WordBookmark *bookmark) { // FIXME: Not covered by tests DFBuffer *buffer = DFBufferNew(); for (DFNode *child = bookmark->element->first; child != NULL; child = child->next) { // FIXME: handle inserted and deleted text if (child->tag == WORD_R) DFNodeTextToBuffer(child,buffer); } free(bookmark->label); bookmark->label = strdup(buffer->data); DFBufferRelease(buffer); }
int DFZip(const char *zipFilename, DFStorage *storage, DFError **error) { const char **allPaths = NULL; DFBuffer *content = NULL; int ok = 0; DFextZipHandleP zipHandle = NULL; allPaths = DFStorageList(storage,error); if (allPaths == NULL || !(zipHandle = DFextZipCreate(zipFilename))) { DFErrorFormat(error,"Cannot create file"); } else { for (int i = 0; allPaths[i]; i++) { const char *path = allPaths[i]; DFBufferRelease(content); content = DFBufferReadFromStorage(storage,path,error); if (content == NULL) { DFErrorFormat(error,"%s: %s",path,DFErrorMessage(error)); goto end; } if (!zipAddFile(zipHandle, path, content, error)) goto end; } ok = 1; } end: DFBufferRelease(content); free(allPaths); if (zipHandle != NULL) DFextZipClose(zipHandle); return ok; }
static void simplifyRecursive(WordSimplification *simp, DFNode *node) { switch (node->tag) { case WORD_FLDCHAR: { const char *type = DFGetAttribute(node,WORD_FLDCHARTYPE); if (DFStringEquals(type,"begin")) { if (simp->depth == 0) { DFBufferRelease(simp->instrText); simp->instrText = DFBufferNew(); simp->beginNode = node; simp->endNode = NULL; simp->inSeparate = 0; } simp->depth++; } else if (DFStringEquals(type,"end") && (simp->depth > 0)) { simp->depth--; if (simp->depth == 0) { simp->endNode = node; replaceField(simp); } } else if (DFStringEquals(type,"separate")) { if (simp->depth == 1) simp->inSeparate = 1; } break; } case WORD_INSTRTEXT: { if ((simp->depth == 1) && !simp->inSeparate) { char *value = DFNodeTextToString(node); DFBufferFormat(simp->instrText,"%s",value); free(value); } break; } } DFNode *next; for (DFNode *child = node->first; child != NULL; child = next) { next = child->next; simplifyRecursive(simp,child); } }
void WordConverterFree(WordConverter *converter) { DFDocumentRelease(converter->html); free(converter->abstractPath); free(converter->concretePath); free(converter->idPrefix); WordSheetFree(converter->styles); WordNumberingFree(converter->numbering); WordThemeFree(converter->theme); WordSectionFree(converter->mainSection); WordObjectsFree(converter->objects); WordNoteGroupRelease(converter->footnotes); WordNoteGroupRelease(converter->endnotes); DFHashTableRelease(converter->supportedContentTypes); DFBufferRelease(converter->warnings); CSSSheetRelease(converter->styleSheet); WordPackageRelease(converter->package); free(converter); }
static DFNode *WordRunContentGet(WordGetData *get, DFNode *concrete) { switch (concrete->tag) { case WORD_T: case WORD_DELTEXT: { DFBuffer *buf = DFBufferNew(); DFNodeTextToBuffer(concrete,buf); DFNode *abstract = DFCreateTextNode(get->conv->html,buf->data); DFBufferRelease(buf); return abstract; } case WORD_DRAWING: case WORD_OBJECT: case WORD_PICT: return WordDrawingGet(get,concrete); case WORD_TAB: { DFNode *span = WordConverterCreateAbstract(get,HTML_SPAN,concrete); DFSetAttribute(span,HTML_CLASS,DFTabClass); return span; } case WORD_BR: { const char *type = DFGetAttribute(concrete,WORD_TYPE); if (DFStringEquals(type,"column")) { DFNode *span = WordConverterCreateAbstract(get,HTML_SPAN,concrete); DFSetAttribute(span,HTML_CLASS,DFPlaceholderClass); DFCreateChildTextNode(span,"[Column break]"); return span; } else if (DFStringEquals(type,"page")) { DFNode *span = WordConverterCreateAbstract(get,HTML_SPAN,concrete); DFSetAttribute(span,HTML_CLASS,DFPlaceholderClass); DFCreateChildTextNode(span,"[Page break]"); return span; } else { return WordConverterCreateAbstract(get,HTML_BR,concrete); } } default: return NULL; } }
static void replaceField(WordSimplification *simp) { assert(simp->instrText != NULL); assert(simp->beginNode != NULL); assert(simp->endNode != NULL); if ((simp->beginNode->parent->tag == WORD_R) && (simp->endNode->parent->tag == WORD_R)) { DFNode *beginRun = simp->beginNode->parent; DFNode *simple = DFCreateElement(simp->beginNode->doc,WORD_FLDSIMPLE); DFSetAttribute(simple,WORD_INSTR,simp->instrText->data); DFInsertBefore(beginRun->parent,simple,beginRun); removeNodes(simp->beginNode,simp->endNode); } DFBufferRelease(simp->instrText); simp->instrText = NULL; simp->beginNode = NULL; simp->endNode = NULL; simp->haveFields = 1; }
static int processParts(DFHashTable *parts, const char *documentPath, DFDocument *relsDoc, DFHashTable *documentRels, DFBuffer *output, DFStorage *storage, DFError **error) { int ok = 0; DFHashTable *includeTypes = DFHashTableNew((DFCopyFunction)xstrdup,free); DFHashTableAdd(includeTypes,WORDREL_HYPERLINK,""); DFHashTableAdd(includeTypes,WORDREL_IMAGE,""); if ((parts == NULL) || (DFHashTableLookup(parts,"document") != NULL)) { DFDocument *doc = DFParseXMLStorage(storage,documentPath,error); if (doc == NULL) goto end; addStrippedSerializedDoc(output,doc,"document.xml"); DFDocumentRelease(doc); } if ((parts == NULL) || (DFHashTableLookup(parts,"styles") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_STYLES,"styles.xml",output,includeTypes,storage,error)) goto end; } if ((parts == NULL) || (DFHashTableLookup(parts,"numbering") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_NUMBERING,"numbering.xml",output,includeTypes,storage,error)) goto end; } if ((parts == NULL) || (DFHashTableLookup(parts,"footnotes") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_FOOTNOTES,"footnotes.xml",output,includeTypes,storage,error)) goto end; } if ((parts == NULL) || (DFHashTableLookup(parts,"endnotes") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_ENDNOTES,"endnotes.xml",output,includeTypes,storage,error)) goto end; } if ((parts != NULL) && (DFHashTableLookup(parts,"settings") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_SETTINGS,"settings.xml",output,includeTypes,storage,error)) goto end; } if ((parts != NULL) && (DFHashTableLookup(parts,"theme") != NULL)) { if (!addRelatedDoc(parts,documentRels,WORDREL_THEME,"theme.xml",output,includeTypes,storage,error)) goto end; } if ((DFHashTableLookup(documentRels,WORDREL_HYPERLINK) != NULL) || (DFHashTableLookup(documentRels,WORDREL_IMAGE) != NULL) || ((parts != NULL) && (DFHashTableLookup(parts,"documentRels") != NULL))) { if (relsDoc == NULL) { DFErrorFormat(error,"document.xml.rels does not exist"); goto end; } DFNode *next; for (DFNode *child = relsDoc->root->first; child != NULL; child = next) { next = child->next; if (child->tag != REL_RELATIONSHIP) continue; const char *type = DFGetAttribute(child,NULL_Type); if ((type != NULL) && (DFHashTableLookup(includeTypes,type) == NULL)) { DFRemoveNode(child); } } addSerializedDoc(output,relsDoc,"document.xml.rels"); } const char **entries = DFStorageList(storage,NULL); if (entries != NULL) { // FIXME: Should really report an error if this is not the case for (int i = 0; entries[i]; i++) { const char *filename = entries[i]; char *extension = DFPathExtension(filename); if (DFStringEqualsCI(extension,"png") || DFStringEqualsCI(extension,"jpg")) { char *absFilename; if (!DFStringHasSuffix(filename,"/")) absFilename = DFFormatString("/%s",filename); else absFilename = xstrdup(filename); DFBuffer *data = DFBufferReadFromStorage(storage,absFilename,NULL); addSerializedBinary(output,data,absFilename); DFBufferRelease(data); free(absFilename); } free(extension); } } free(entries); DFHashTableRelease(includeTypes); ok = 1; end: return ok; }