static void WordGetTblStylePr(DFNode *concrete, CSSStyle *style, WordSection *section, WordTheme *theme) { const char *tableComponent = DFGetAttribute(concrete,WORD_TYPE); if (tableComponent == NULL) return;; CSSProperties *rule = CSSStyleRuleForTableComponent(style,tableComponent); if (rule == NULL) return; for (DFNode *child = concrete->first; child != NULL; child = child->next) { const char *styleId = NULL; switch (child->tag) { case WORD_RPR: WordGetRPr(child,rule,&styleId,theme); break; case WORD_PPR: WordGetPPr(child,rule,&styleId,section); break; case WORD_TBLPR: WordGetTblPr(child,rule,NULL,section,&styleId); break; case WORD_TRPR: // FIXME break; case WORD_TCPR: WordGetTcPr(child,rule); break; } } }
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; }
static void WordGetStyle(DFNode *concrete, CSSStyle *style, WordConverter *converter) { WordSection *section = converter->mainSection; for (DFNode *child = concrete->first; child != NULL; child = child->next) { const char *styleId = NULL; switch (child->tag) { case WORD_NAME: CSSStyleSetDisplayName(style,DFGetAttribute(child,WORD_VAL)); break; case WORD_NEXT: { // FIXME: do he need to handle style types other than paragraph here? const char *nextName = DFGetAttribute(child,WORD_VAL); if (nextName == NULL) continue; WordStyle *nextStyle = WordSheetStyleForTypeId(converter->styles,"paragraph",nextName); if (nextStyle == NULL) continue; CSSStyleSetNext(style,nextStyle->selector); break; } case WORD_RPR: WordGetRPr(child,CSSStyleRule(style),&styleId,converter->theme); break; case WORD_PPR: { WordGetPPr(child,CSSStyleRule(style),&styleId,section); if (style->headingLevel > 0) { DFNode *numPr = DFChildWithTag(child,WORD_NUMPR); if (numPr != NULL) WordGetNumPrStyle(numPr,style,converter); } break; } case WORD_TBLPR: WordGetTblPr(child,CSSStyleRule(style),CSSStyleCell(style),section,&styleId); break; case WORD_TRPR: // FIXME break; case WORD_TCPR: WordGetTcPr(child,CSSStyleRule(style)); break; case WORD_TBLSTYLEPR: WordGetTblStylePr(child,style,section,converter->theme); break; } } // Special case: The ListParagraph style that word automatically adds specifies an indentation // of 36pt. We don't actually want this, because HTML automatically indents lists anyway. If // we see this, clear it, but keep the old value around for when we update the word document. StyleFamily family = WordStyleFamilyForSelector(style->selector); const char *name = WordSheetStyleIdForSelector(converter->styles,style->selector); if ((family == StyleFamilyParagraph) && DFStringEquals(name,"ListParagraph")) { CSSProperties *properties = CSSStyleRule(style); const char *wordMarginLeft = CSSGet(properties,"margin-left"); CSSPut(properties,"-word-margin-left",wordMarginLeft); CSSPut(properties,"margin-left",NULL); } DFNode *pPr = DFChildWithTag(concrete,WORD_PPR); DFNode *numPr = DFChildWithTag(pPr,WORD_NUMPR); const char *numId = DFGetChildAttribute(numPr,WORD_NUMID,WORD_VAL); if ((numId != NULL) && (atoi(numId) == 0)) { switch (style->tag) { case HTML_H1: case HTML_H2: case HTML_H3: case HTML_H4: case HTML_H5: case HTML_H6: case HTML_FIGURE: case HTML_TABLE: { char *counterIncrement = DFFormatString("%s 0",style->elementName); CSSPut(CSSStyleRule(style),"counter-reset","null"); CSSPut(CSSStyleRule(style),"counter-increment",counterIncrement); CSSPut(CSSStyleBefore(style),"content","none"); free(counterIncrement); } } } }