Exemplo n.º 1
0
static DFNode *createAbstractPlaceholder(WordGetData *get, const char *placeholderText, DFNode *concrete)
{
    DFNode *span = WordConverterCreateAbstract(get,HTML_SPAN,concrete);
    DFSetAttribute(span,HTML_CLASS,DFPlaceholderClass);
    DFNode *text = DFCreateTextNode(get->conv->html,placeholderText);
    DFAppendChild(span,text);
    return span;
}
Exemplo n.º 2
0
static DFNode *WordBookmarkGet(WordGetData *get, DFNode *concrete)
{
    if (!WordBookmarkIsVisible2(concrete))
        return NULL;
    DFNode *abstract = WordConverterCreateAbstract(get,HTML_SPAN,concrete);
    DFSetAttribute(abstract,HTML_CLASS,DFBookmarkClass);
    WordContainerGet(get,&WordParagraphContentLens,abstract,concrete);
    return abstract;
}
Exemplo n.º 3
0
static DFNode *WordDocumentGet(WordGetData *get, DFNode *concrete)
{
    if (concrete->tag != WORD_DOCUMENT)
        return NULL;

    DFNode *html = WordConverterCreateAbstract(get,HTML_HTML,concrete);
    DFNode *head = WordConverterCreateAbstract(get,HTML_HEAD,NULL);
    DFAppendChild(html,head);
    DFNode *meta = WordConverterCreateAbstract(get,HTML_META,NULL);
    DFAppendChild(head,meta);
    DFSetAttribute(meta,HTML_CHARSET,"utf-8");

    DFNode *wordBody = DFChildWithTag(concrete,WORD_BODY);
    if (wordBody != NULL) {
        DFNode *htmlBody = WordBodyLens.get(get,wordBody);
        DFAppendChild(html,htmlBody);
    }
    return html;
}
Exemplo n.º 4
0
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;
    }
}
Exemplo n.º 5
0
static DFNode *imageWithFilename(WordGetData *get, const char *filename, double widthPts, DFNode *concrete)
{
    const char *concretePath = get->conv->concretePath;
    const char *abstractPath = get->conv->abstractPath;

    char *abstractImagesPath = DFAppendPathComponent(abstractPath,"images");
    char *lastComponent = DFPathBaseName(filename);
    char *srcImagePath = DFAppendPathComponent(concretePath,filename);
    char *dstImagePath = DFAppendPathComponent(abstractImagesPath,lastComponent);

    if (DFFileExists(dstImagePath))
        DFDeleteFile(dstImagePath,NULL);

    DFError *error = NULL;
    DFNode *imageNode = NULL;

    if (!DFFileExists(abstractImagesPath) &&
        !DFCreateDirectory(abstractImagesPath,1,&error)) {
        WordConverterWarning(get->conv,"Create %s: %s",abstractImagesPath,DFErrorMessage(&error));
        DFErrorRelease(error);
        imageNode = createAbstractPlaceholder(get,"[Error reading image]",concrete);
    }
    else if (!DFCopyFile(srcImagePath,dstImagePath,&error)) {
        WordConverterWarning(get->conv,"Copy %s to %s: %s",srcImagePath,dstImagePath,DFErrorMessage(&error));
        DFErrorRelease(error);
        imageNode = createAbstractPlaceholder(get,"[Error reading image]",concrete);
    }
    else {
        imageNode = WordConverterCreateAbstract(get,HTML_IMG,concrete);
        DFFormatAttribute(imageNode,HTML_SRC,"images/%s",lastComponent);

        double contentWidthPts = WordSectionContentWidthPts(get->conv->mainSection);
        if (contentWidthPts > 0) {
            double widthPct = widthPts/contentWidthPts*100.0;
            CSSProperties *properties = CSSPropertiesNew();
            char buf[100];
            CSSPut(properties,"width",DFFormatDoublePct(buf,100,widthPct));
            char *propertiesText = CSSPropertiesCopyDescription(properties);
            DFSetAttribute(imageNode,HTML_STYLE,propertiesText);
            free(propertiesText);
            CSSPropertiesRelease(properties);
        }
    }

    free(abstractImagesPath);
    free(lastComponent);
    free(srcImagePath);
    free(dstImagePath);
    return imageNode;
}
Exemplo n.º 6
0
static DFNode *WordTcCreateAbstractNode(WordGetData *get, DFNode *concrete)
{
    DFNode *td = WordConverterCreateAbstract(get,HTML_TD,concrete);

    CSSProperties *properties = CSSPropertiesNew();
    DFNode *tcPr = DFChildWithTag(concrete,WORD_TCPR);
    if (tcPr != NULL)
        WordGetTcPr(tcPr,properties);;
    DFHashTable *collapsed = CSSCollapseProperties(properties);
    char *styleValue = CSSSerializeProperties(collapsed);
    DFHashTableRelease(collapsed);
    if (strlen(styleValue) > 0)
        DFSetAttribute(td,HTML_STYLE,styleValue);
    free(styleValue);

    CSSPropertiesRelease(properties);
    return td;
}
Exemplo n.º 7
0
static DFNode *WordRunGet(WordGetData *get, DFNode *concrete)
{
    assert(concrete->tag == WORD_R);

    // First check the run to see if it's a footnote or endnote reference. These need to be handled specially,
    // as we place the actual content of the footnote or endnote in-line in the HTML output.
    DFNode *note = WordRunGetNote(get,concrete);
    if (note != NULL)
        return note;

    // If we didn't find a footnote or endnote reference, treat it as a normal content run
    assert(concrete->tag == WORD_R);
    DFNode *rPr = DFChildWithTag(concrete,WORD_RPR);
    CSSProperties *properties = CSSPropertiesNew();
    const char *styleId = NULL;
    if (rPr != NULL)
        WordGetRPr(rPr,properties,&styleId,get->conv->theme);;

    const char *selector = WordSheetSelectorForStyleId(get->conv->styles,"character",styleId);
    Tag elementName = (selector == NULL) ? HTML_SPAN : CSSSelectorGetTag(selector);
    char *className = (selector == NULL) ? NULL : CSSSelectorCopyClassName(selector);
    DFNode *abstract = WordConverterCreateAbstract(get,elementName,concrete);
    DFSetAttribute(abstract,HTML_CLASS,className);
    free(className);

    DFHashTable *collapsed = CSSCollapseProperties(properties);
    char *styleValue = CSSSerializeProperties(collapsed);
    DFHashTableRelease(collapsed);
    if (strlen(styleValue) > 0)
        DFSetAttribute(abstract,HTML_STYLE,styleValue);
    free(styleValue);

    CSSPropertiesRelease(properties);

    WordContainerGet(get,&WordRunContentLens,abstract,concrete);
    return abstract;
}
Exemplo n.º 8
0
static DFNode *WordFieldGet(WordGetData *get, DFNode *concrete)
{
    if (concrete->tag != WORD_FLDSIMPLE)
        return NULL;;

    const char *instr = DFGetAttribute(concrete,WORD_INSTR);
    if (instr != NULL) {
        const char **args = Word_parseField(instr);
        size_t argCount = DFStringArrayCount(args);

        if ((argCount >= 2) && !strcmp(args[0],"REF")) {
            WordBookmark *bookmark = WordObjectsBookmarkWithName(get->conv->objects,args[1]);
            if ((bookmark != NULL) && (bookmark->target != NULL)) {

                WordRefType type = WordRefTypeGet(args,bookmark);

                DFNode *a = WordConverterCreateAbstract(get,HTML_A,concrete);
                DFFormatAttribute(a,HTML_HREF,"#%s%u",get->conv->idPrefix,bookmark->target->seqNo);
                DFSetAttribute(a,HTML_CLASS,WordRefTypeClassName(type));

                free(args);
                return a;
            }
        }
        else if ((argCount >= 1) && !strcmp(args[0],"TOC")) {

            if ((argCount >= 2) && !strcmp(args[1],"\\o")) {
                DFNode *nav = WordConverterCreateAbstract(get,HTML_NAV,concrete);
                DFSetAttribute(nav,HTML_CLASS,DFTableOfContentsClass);
                free(args);
                return nav;
            }
            else if ((argCount >= 3) && !strcmp(args[1],"\\c")) {
                // FIXME: The names "Figure" and "Table" here will be different if the document
                // was created in a language other than English. We need to look through the
                // document to figure out which counter names are used in captions adjacent to
                // figures and tables to know what the counter names used in the document
                // actually are.

                // Another option might be just to collect a static list of names used in all the
                // major languages and base the detection on that. These would need to be checked
                // with multiple versions of word, as the names used could in theory change
                // between releases.

                // We should keep track of a set of "document parameters", which record the names
                // used for figure and table counters, as well as the prefixes used on numbered
                // figures and tables. The latter would correspond to the content property of the
                // caption::before and figcaption::before CSS rules.

                if (!strcmp(args[2],"Figure")) {
                    DFNode *nav = WordConverterCreateAbstract(get,HTML_NAV,concrete);
                    DFSetAttribute(nav,HTML_CLASS,DFListOfFiguresClass);
                    free(args);
                    return nav;
                }
                else if (!strcmp(args[2],"Table")) {
                    DFNode *nav = WordConverterCreateAbstract(get,HTML_NAV,concrete);
                    DFSetAttribute(nav,HTML_CLASS,DFListOfTablesClass);
                    free(args);
                    return nav;
                }
            }
        }

        DFNode *span = WordConverterCreateAbstract(get,HTML_SPAN,concrete);
        DFSetAttribute(span,HTML_CLASS,DFFieldClass);
        DFNode *text = DFCreateTextNode(get->conv->html,instr);
        DFAppendChild(span,text);
        free(args);
        return span;
    }
    return NULL;
}
Exemplo n.º 9
0
static DFNode *WordTblGet(WordGetData *get, DFNode *concrete)
{
    if (concrete->tag != WORD_TBL)
        return NULL;;

    DFNode *table = WordConverterCreateAbstract(get,HTML_TABLE,concrete);
    ConcreteInfo *cinfo = getConcreteInfo(get->conv,concrete);
    calcTotals(get,cinfo);
    const char *cellWidthType = cellWidthTypeForTable(concrete);
    int autoWidth = DFStringEquals(cellWidthType,"auto");

    if ((CSSGet(cinfo->tableProperties,"width") == NULL) && autoWidth) {
        CSSPut(cinfo->tableProperties,"width",NULL);
    }
    else {
        // Determine column widths and table width

        if (cinfo->totalWidthPts > 0) {
            DFNode *colgroup = HTML_createColgroup(get->conv->html,cinfo->structure);
            DFAppendChild(table,colgroup);

            double tableWidthPct = 100.0;
            if (WordSectionContentWidth(get->conv->mainSection) > 0) {
                double contentWidthPts = WordSectionContentWidth(get->conv->mainSection)/20.0;
                tableWidthPct = 100.0*cinfo->totalWidthPts/contentWidthPts;
                if (CSSGet(cinfo->tableProperties,"width") == NULL) {
                    char buf[100];
                    CSSPut(cinfo->tableProperties,"width",DFFormatDoublePct(buf,100,tableWidthPct));
                }
            }
        }

        if (CSSGet(cinfo->tableProperties,"width") == NULL)
            CSSPut(cinfo->tableProperties,"width","100%");
    }

    DFHashTable *collapsed = CSSCollapseProperties(cinfo->tableProperties);
    char *styleValue = CSSSerializeProperties(collapsed);
    DFHashTableRelease(collapsed);
    if (strlen(styleValue) > 0)
        DFSetAttribute(table,HTML_STYLE,styleValue);
    free(styleValue);
    if ((cinfo->style != NULL) && (cinfo->style->selector != NULL)) {
        char *className = CSSSelectorCopyClassName(cinfo->style->selector);
        DFSetAttribute(table,HTML_CLASS,className);
        free(className);
    }
    else {
        CSSStyle *defaultStyle = CSSSheetDefaultStyleForFamily(get->conv->styleSheet,StyleFamilyTable);
        if (defaultStyle != NULL)
            DFSetAttribute(table,HTML_CLASS,defaultStyle->className);
    }

    // Create rows and cells
    int row = 0;
    for (DFNode *tblChild = concrete->first; tblChild != NULL; tblChild = tblChild->next) {
        if (tblChild->tag != WORD_TR)
            continue;
        DFNode *tr = WordConverterCreateAbstract(get,HTML_TR,tblChild);
        DFAppendChild(table,tr);
        unsigned int col = 0;
        while (col < cinfo->structure->cols) {
            DFCell *cell = DFTableGetCell(cinfo->structure,row,col);
            if (cell == NULL) {
                DFNode *td = DFCreateElement(get->conv->html,HTML_TD);
                DFAppendChild(tr,td);
                col++;
                continue;
            }

            if (row == cell->row) {
                DFNode *td = WordTcGet(get,cell->element);
                DFAppendChild(tr,td);
                if (cell->colSpan != 1)
                    DFFormatAttribute(td,HTML_COLSPAN,"%d",cell->colSpan);
                if (cell->rowSpan != 1)
                    DFFormatAttribute(td,HTML_ROWSPAN,"%d",cell->rowSpan);
            }
            col += cell->colSpan;
        }
        row++;
    }

    ConcreteInfoFree(cinfo);
    return table;
}