diff --git a/src/main/java/writer2latex/xhtml/XhtmlConfig.java b/src/main/java/writer2latex/xhtml/XhtmlConfig.java index a17d114..05bac20 100644 --- a/src/main/java/writer2latex/xhtml/XhtmlConfig.java +++ b/src/main/java/writer2latex/xhtml/XhtmlConfig.java @@ -40,7 +40,7 @@ import writer2latex.util.Misc; public class XhtmlConfig extends writer2latex.base.ConfigBase { // Implement configuration methods - protected int getOptionCount() { return 63; } + protected int getOptionCount() { return 64; } protected String getDefaultConfigPath() { return "/writer2latex/xhtml/config/"; } // Override setOption: To be backwards compatible, we must accept options @@ -162,6 +162,7 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase { private static final int PAGE_TAGS = 60; private static final int MIN_LETTER_SPACING = 61; private static final int PAGE_BREAK_STYLE = 62; + private static final int CSS_INLINE = 63; protected ComplexOption xheading = addComplexOption("heading-map"); protected ComplexOption xpar = addComplexOption("paragraph-map"); @@ -299,6 +300,8 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase { options[PAGE_TAGS] = new Option("page_tags","div"); options[MIN_LETTER_SPACING] = new Option("min_letter_spacing","0.15"); options[PAGE_BREAK_STYLE] = new Option("page_break_style",""); + options[CSS_INLINE] = new BooleanOption("css_inline","true"); + } @@ -457,6 +460,8 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase { public XhtmlStyleMap getXFrameStyleMap() { return getStyleMap(xframe); } public XhtmlStyleMap getXListStyleMap() { return getStyleMap(xlist); } public XhtmlStyleMap getXAttrStyleMap() { return getStyleMap(xattr); } + public boolean inlineCSS() { return ((BooleanOption) options[CSS_INLINE]).getValue(); } + private XhtmlStyleMap getStyleMap(ComplexOption co) { XhtmlStyleMap map = new XhtmlStyleMap(); diff --git a/src/main/java/writer2latex/xhtml/content/TextParser.java b/src/main/java/writer2latex/xhtml/content/TextParser.java index 5f8a735..34601f8 100644 --- a/src/main/java/writer2latex/xhtml/content/TextParser.java +++ b/src/main/java/writer2latex/xhtml/content/TextParser.java @@ -105,7 +105,7 @@ public class TextParser extends Parser { private boolean bInToc = false; // Display hidden text? - private boolean bDisplayHiddenText = false; + private boolean displayHiddenText = false; // Current page number int pageNum = 1; //Current master page name @@ -124,6 +124,7 @@ public class TextParser extends Parser { private boolean inFooter = false; private String endnotesContext = null; private String footnotesContext = null; + private boolean inlineCSS; PageContainer pageContainer = null; public TextParser(OfficeReader ofr, XhtmlConfig config, Converter converter) { @@ -142,9 +143,10 @@ public class TextParser extends Parser { nFloatMode = ofr.isText() && config.xhtmlFloatObjects() ? DrawParser.FLOATING : DrawParser.ABSOLUTE; outlineNumbering = new ListCounter(ofr.getOutlineStyle()); - bDisplayHiddenText = config.displayHiddenText(); + displayHiddenText = config.displayHiddenText(); pageContainer = converter.pageContainer; docSep = new Separator(config, converter); + inlineCSS = config.inlineCSS(); } /** Converts an office node as a complete text document @@ -541,7 +543,7 @@ public class TextParser extends Parser { boolean isLast = false; if (last != null && last.equals("true")) { isLast = true;} - if (!bDisplayHiddenText && "none".equals(Misc.getAttribute(onode,TEXT_DISPLAY))) { return hnode; } + if (!displayHiddenText && "none".equals(Misc.getAttribute(onode,TEXT_DISPLAY))) { return hnode; } if (pageWasOpened) {hnode = docSep.closePage(hnode);} boolean removeStyleAtExit = setSectionStyle(onode); @@ -600,134 +602,138 @@ public class TextParser extends Parser { /* * Process a text:h tag */ - private void handleHeading(Element onode, Element hnode, boolean bAfterSplit, - ListStyle listStyle, int nListLevel, boolean bUnNumbered, - boolean bRestart, int nStartValue) { - - // Note: nListLevel may in theory be different from the outline level, - // though the ui in OOo does not allow this - - // Numbering: It is possible to define outline numbering in CSS2 - // using counters; but this is not supported in all browsers - // TODO: Offer CSS2 solution as an alternative later. - - // Note: Conditional styles are not supported - int nLevel = getOutlineLevel(onode); - if (nLevel<=6) { // Export as heading - String sStyleName = onode.getAttribute(TEXT_STYLE_NAME); - StyleWithProperties style = ofr.getParStyle(sStyleName); - - // Check for hidden text - if (!bDisplayHiddenText && style!=null && "none".equals(style.getProperty(TEXT_DISPLAY))) { return; } - - // Numbering - if (!bUnNumbered) { - // If the heading uses a paragraph style which sets an explicit empty list style name, it's unnumbered - if (style!=null) { - String sListStyleName = style.getListStyleName(); - if (sListStyleName!=null && sListStyleName.length()==0) { - bUnNumbered = true; - } - } - } - ListCounter counter = null; - String sLabel=""; - if (!bUnNumbered) { - counter = getListCounter(listStyle); - if (bRestart) { counter.restart(nListLevel,nStartValue); } - sLabel = counter.step(nListLevel).getLabel(); - } - - // In EPUB export, a striked out heading will only appear in the external toc - boolean bTocOnly = false; - if (converter.isOPS() && style!=null) { - String sStrikeOut = style.getProperty(STYLE_TEXT_LINE_THROUGH_STYLE, true); - if (sStrikeOut!=null && !"none".equals(sStrikeOut)) { - bTocOnly = true; - } - } - - // Export the heading - if (!bTocOnly) { - // If split output, add headings of higher levels - if (bAfterSplit && nSplit>0) { - int nFirst = nLevel-nRepeatLevels; - if (nFirst<0) { nFirst=0; } - for (int i=nFirst; i0) { - content = converter.createElement(innerInfo.sTagName); - heading.appendChild(content); - applyStyle(innerInfo, content); - } - traverseInlineText(onode,content); - - // Add before/after text if required - addBeforeAfter(heading,ofr.getParStyle(getParSc().getRealParStyleName(sStyleName)),config.getXHeadingStyleMap()); - - // Keep track of current headings for split output - currentHeading[nLevel] = heading; - for (int i=nLevel+1; i<=6; i++) { - currentHeading[i] = null; - } - } - else { - if (!bInToc) { - tocCv.handleHeadingExternal(onode, hnode, sLabel); - } - // Keep track of current headings for split output - currentHeading[nLevel] = null; - for (int i=nLevel+1; i<=6; i++) { - currentHeading[i] = null; - } - - } - } - else { // beyond h6 - export as ordinary paragraph - handleParagraph(onode,hnode); - } - } + private void handleHeading(Element onode, Element hnode, boolean bAfterSplit, ListStyle listStyle, int nListLevel, boolean bUnNumbered, boolean bRestart, int nStartValue) { + + // Note: nListLevel may in theory be different from the outline level, + // though the ui in OOo does not allow this + + // Numbering: It is possible to define outline numbering in CSS2 + // using counters; but this is not supported in all browsers + // TODO: Offer CSS2 solution as an alternative later. + + // Note: Conditional styles are not supported + int nLevel = getOutlineLevel(onode); + if (nLevel <= 6) { // Export as heading + String sStyleName = onode.getAttribute(TEXT_STYLE_NAME); + StyleWithProperties style = ofr.getParStyle(sStyleName); + + // Check for hidden text + if (!displayHiddenText && style != null && "none".equals(style.getProperty(TEXT_DISPLAY))) { + return; + } + + // Numbering + if (!bUnNumbered) { + // If the heading uses a paragraph style which sets an explicit empty + // list style name, it's unnumbered + if (style != null) { + String sListStyleName = style.getListStyleName(); + if (sListStyleName != null && sListStyleName.length() == 0) { + bUnNumbered = true; + } + } + } + ListCounter counter = null; + String sLabel = ""; + if (!bUnNumbered) { + counter = getListCounter(listStyle); + if (bRestart) { + counter.restart(nListLevel, nStartValue); + } + sLabel = counter.step(nListLevel).getLabel(); + } + + // In EPUB export, a striked out heading will only appear in the external + // toc + boolean bTocOnly = false; + if (converter.isOPS() && style != null) { + String sStrikeOut = style.getProperty(STYLE_TEXT_LINE_THROUGH_STYLE, true); + if (sStrikeOut != null && !"none".equals(sStrikeOut)) { + bTocOnly = true; + } + } + + // Export the heading + if (!bTocOnly) { + // If split output, add headings of higher levels + if (bAfterSplit && nSplit > 0) { + int nFirst = nLevel - nRepeatLevels; + if (nFirst < 0) { + nFirst = 0; + } + for (int i = nFirst; i < nLevel; i++) { + if (currentHeading[i] != null) { + hnode.appendChild(converter.importNode(currentHeading[i], true)); + } + } + } + + // Apply style + StyleInfo info = new StyleInfo(); + info.sTagName = "h" + nLevel; + getHeadingSc().applyStyle(nLevel, sStyleName, info); + + // add root element + Element heading = converter.createElement(info.sTagName); + hnode.appendChild(heading); + applyStyle(info, heading); + traverseFloats(onode, hnode, heading); + // Apply writing direction + /* + * String sStyleName = Misc.getAttribute(onode,TEXT_STYLE_NAME); + * StyleWithProperties style = ofr.getParStyle(sStyleName); if + * (style!=null) { StyleInfo headInfo = new StyleInfo(); + * StyleConverterHelper.applyDirection(style,headInfo); + * getParSc().applyStyle(headInfo,heading); } + */ + + // Prepend asapNode + prependAsapNode(heading); + + // Prepend numbering + if (!bUnNumbered) { + insertListLabel(listStyle, nListLevel, "SectionNumber", null, sLabel, heading); + } + + // Add to toc + if (!bInToc) { + tocCv.handleHeading(onode, heading, sLabel); + } + + // Convert content + StyleInfo innerInfo = new StyleInfo(); + getHeadingSc().applyInnerStyle(nLevel, sStyleName, innerInfo); + Element content = heading; + if (innerInfo.sTagName != null && innerInfo.sTagName.length() > 0) { + content = converter.createElement(innerInfo.sTagName); + heading.appendChild(content); + applyStyle(innerInfo, content); + } + traverseInlineText(onode, content); + + // Add before/after text if required + addBeforeAfter(heading, ofr.getParStyle(getParSc().getRealParStyleName(sStyleName)), config.getXHeadingStyleMap()); + + // Keep track of current headings for split output + currentHeading[nLevel] = heading; + for (int i = nLevel + 1; i <= 6; i++) { + currentHeading[i] = null; + } + } else { + if (!bInToc) { + tocCv.handleHeadingExternal(onode, hnode, sLabel); + } + // Keep track of current headings for split output + currentHeading[nLevel] = null; + for (int i = nLevel + 1; i <= 6; i++) { + currentHeading[i] = null; + } + + } + } else { // beyond h6 - export as ordinary paragraph + handleParagraph(onode, hnode); + } + } /* * Process a text:p tag @@ -737,7 +743,7 @@ public class TextParser extends Parser { if (config.ignoreEmptyParagraphs() && bIsEmpty) { return; } String styleName = Misc.getAttribute(onode,TEXT_STYLE_NAME); StyleWithProperties style = ofr.getParStyle(styleName); - if (!bDisplayHiddenText && style!=null && "none".equals(style.getProperty(TEXT_DISPLAY))) { return; } + if (!displayHiddenText && style!=null && "none".equals(style.getProperty(TEXT_DISPLAY))) { return; } Element par; if (ofr.isSpreadsheet()) { // attach inline text directly to parent (always a table cell) @@ -1378,19 +1384,20 @@ public class TextParser extends Parser { } } - private void handleSpan(Node onode, Node hnode) { - StyleWithProperties style = ofr.getTextStyle(Misc.getAttribute(onode, TEXT_STYLE_NAME)); - if (!bDisplayHiddenText && style!=null && "none".equals(style.getProperty(TEXT_DISPLAY))) { return; } - - if (!bInToc) { - String sStyleName = Misc.getAttribute(onode,TEXT_STYLE_NAME); - Element span = createInline((Element) hnode,sStyleName); - traverseInlineText(onode,span); - } - else { - traverseInlineText(onode,hnode); - } - } + private void handleSpan(Node onode, Node hnode) { + StyleWithProperties style = ofr.getTextStyle(Misc.getAttribute(onode, TEXT_STYLE_NAME)); + if (!displayHiddenText && style != null && "none".equals(style.getProperty(TEXT_DISPLAY))) { + return; + } + + if (!bInToc) { + String sStyleName = Misc.getAttribute(onode, TEXT_STYLE_NAME); + Element span = createInline((Element) hnode, sStyleName); + traverseInlineText(onode, span); + } else { + traverseInlineText(onode, hnode); + } + } protected void traversePCDATA(Node onode, Node hnode) { if (onode.hasChildNodes()) { @@ -1814,8 +1821,10 @@ public class TextParser extends Parser { private void setPageContainerStyle() { MasterPage mp = ofr.getFullMasterPage(currentMasterPage); PageLayout layout = ofr.getPageLayout(mp.getPageLayoutName()); - String containerStyle = "column-count: " + layout.getColCount() + ";"; - pageContainer.setRootStyle(containerStyle); + if (layout.getColCount() != 1) { + String containerStyle = "column-count: " + layout.getColCount() + ";"; + pageContainer.setRootStyle(containerStyle); + } } private void fitPageNumberToMasterPageStyle() { diff --git a/src/main/java/writer2latex/xhtml/style/StyleParser.java b/src/main/java/writer2latex/xhtml/style/StyleParser.java index 05b99c8..0fa5fde 100644 --- a/src/main/java/writer2latex/xhtml/style/StyleParser.java +++ b/src/main/java/writer2latex/xhtml/style/StyleParser.java @@ -61,6 +61,7 @@ public abstract class StyleParser extends Parser { private String sScale; private String sColScale; private boolean bConvertToPx; + private boolean inlineCSS; /** Create a new StyleConverterHelper * @param ofr an OfficeReader to read style information from @@ -76,6 +77,7 @@ public abstract class StyleParser extends Parser { sScale = config.getXhtmlScaling(); sColScale = config.getXhtmlColumnScaling(); bConvertToPx = config.xhtmlConvertToPx(); + inlineCSS = config.inlineCSS(); } public String scale(String s) {