diff --git a/source/distro/changelog.txt b/source/distro/changelog.txt index 7598198..bff1a61 100644 --- a/source/distro/changelog.txt +++ b/source/distro/changelog.txt @@ -2,10 +2,12 @@ Changelog for Writer2LaTeX version 1.0 -> 1.2 ---------- version 1.1.1 ---------- +[w2l] Partial support for the new list formatting of ODT 1.2 (implemented in OOo 3.0) + [all] Filter: Filters out characters that are illegal in xml (this fixes a problem with rtf documents imported in OOo) -[w2x] Introduced hack to set link attributes using the link name +[w2x] Introduced hack to set link attributes using the link name: accepts a semicolon separated list of name=value, for example title=link to next page;rel=next diff --git a/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java b/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java index 4d8335b..5af207f 100644 --- a/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java +++ b/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2009-04-23) + * Version 1.2 (2009-04-25) * */ @@ -137,16 +137,16 @@ public abstract class ExportFilterBase implements int nLen = origString.length(); for (int i=0; i'){ + else if (c=='>'){ buf.append(">"); } else if (c=='\u0009' || c=='\n' || c=='\r' || (c>='\u0020' && c<='\uD7FF') || (c>='\uE000' && c<'\uFFFD')) { diff --git a/source/java/org/openoffice/da/comp/writer4latex/ConfigurationDialog.java b/source/java/org/openoffice/da/comp/writer4latex/ConfigurationDialog.java index 115ba3b..342d883 100644 --- a/source/java/org/openoffice/da/comp/writer4latex/ConfigurationDialog.java +++ b/source/java/org/openoffice/da/comp/writer4latex/ConfigurationDialog.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2009-04-23) + * Version 1.2 (2009-04-25) * */ @@ -259,24 +259,8 @@ public final class ConfigurationDialog // Configure the applications automatically (OS dependent) private boolean autoConfigure(XWindow xWindow) { String sOsName = System.getProperty("os.name"); - if ("Linux".equals(sOsName)) { - configureApp(ExternalApps.LATEX, "latex", "--interaction=batchmode %s"); - configureApp(ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s"); - configureApp(ExternalApps.XELATEX, "xelatex", "--interaction=batchmode %s"); - configureApp(ExternalApps.DVIPS, "dvips", "%s"); - configureApp(ExternalApps.BIBTEX, "bibtex", "%s"); - configureApp(ExternalApps.MAKEINDEX, "makeindex", "%s"); - configureApp(ExternalApps.OOLATEX, "oolatex", "%s"); - // We have several possible viewers - String[] sDviViewers = {"evince", "okular", "xdvi"}; - configureApp(ExternalApps.DVIVIEWER, sDviViewers, "%s"); - String[] sPdfViewers = {"evince", "okular", "xpdf"}; - configureApp(ExternalApps.PDFVIEWER, sPdfViewers, "%s"); - String[] sPsViewers = {"evince", "okular", "ghostview"}; - configureApp(ExternalApps.POSTSCRIPTVIEWER, sPsViewers, "%s"); - } - else if ("Windows".equals(sOsName)) { - // TODO: Get information from the windows registry + if (sOsName.startsWith("Windows")) { + // TODO: Get information from the windows registry using unowinreg.dll from the SDK // Assume MikTeX externalApps.setApplication(ExternalApps.LATEX, "latex", "--interaction=batchmode %s"); externalApps.setApplication(ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s"); @@ -291,8 +275,21 @@ public final class ConfigurationDialog externalApps.setApplication(ExternalApps.PDFVIEWER, "gsview32.exe", "-e \"%s\""); externalApps.setApplication(ExternalApps.POSTSCRIPTVIEWER, "gsview32.exe", "-e \"%s\""); } - else { - // Unsupported OS + else { // Assume a unix-like system supporting the "which" command + configureApp(ExternalApps.LATEX, "latex", "--interaction=batchmode %s"); + configureApp(ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s"); + configureApp(ExternalApps.XELATEX, "xelatex", "--interaction=batchmode %s"); + configureApp(ExternalApps.DVIPS, "dvips", "%s"); + configureApp(ExternalApps.BIBTEX, "bibtex", "%s"); + configureApp(ExternalApps.MAKEINDEX, "makeindex", "%s"); + configureApp(ExternalApps.OOLATEX, "oolatex", "%s"); + // We have several possible viewers + String[] sDviViewers = {"evince", "okular", "xdvi"}; + configureApp(ExternalApps.DVIVIEWER, sDviViewers, "%s"); + String[] sPdfViewers = {"evince", "okular", "xpdf"}; + configureApp(ExternalApps.PDFVIEWER, sPdfViewers, "%s"); + String[] sPsViewers = {"evince", "okular", "ghostview"}; + configureApp(ExternalApps.POSTSCRIPTVIEWER, sPsViewers, "%s"); } changeApplication(xWindow); return true; diff --git a/source/java/org/openoffice/da/comp/writer4latex/Writer4LaTeX.java b/source/java/org/openoffice/da/comp/writer4latex/Writer4LaTeX.java index 8e23a3e..b36c638 100644 --- a/source/java/org/openoffice/da/comp/writer4latex/Writer4LaTeX.java +++ b/source/java/org/openoffice/da/comp/writer4latex/Writer4LaTeX.java @@ -158,10 +158,6 @@ public final class Writer4LaTeX extends WeakBase if (updateMediaProperties()) { process(); } - else { - MessageBox msgBox = new MessageBox(m_xContext, m_xFrame); - msgBox.showMessage("Writer4LaTeX Error","Please install Writer2LaTeX version 1.0 or later"); - } } else { warnNotSaved(); @@ -173,10 +169,6 @@ public final class Writer4LaTeX extends WeakBase if (mediaProps!=null || updateMediaProperties()) { process(); } - else { - MessageBox msgBox = new MessageBox(m_xContext, m_xFrame); - msgBox.showMessage("Writer4LaTeX Error","Please install Writer2LaTeX version 1.0 or later"); - } } else { warnNotSaved(); @@ -318,6 +310,8 @@ public final class Writer4LaTeX extends WeakBase // If Writer2LaTeX is not installed, this will return null if (dialog==null) { mediaProps = null; + MessageBox msgBox = new MessageBox(m_xContext, m_xFrame); + msgBox.showMessage("Writer4LaTeX Error","Please install Writer2LaTeX version 1.0 or later"); return false; } diff --git a/source/java/writer2latex/api/ConverterFactory.java b/source/java/writer2latex/api/ConverterFactory.java index 33d65d4..eff0de2 100644 --- a/source/java/writer2latex/api/ConverterFactory.java +++ b/source/java/writer2latex/api/ConverterFactory.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2009-03-30) + * Version 1.2 (2009-04-25) * */ @@ -33,7 +33,7 @@ public class ConverterFactory { // Version information private static final String VERSION = "1.1.1"; - private static final String DATE = "2008-04-23"; + private static final String DATE = "2008-04-25"; /** Return version information * @return the Writer2LaTeX version in the form diff --git a/source/java/writer2latex/latex/HeadingConverter.java b/source/java/writer2latex/latex/HeadingConverter.java index ef2f7bd..67772b1 100644 --- a/source/java/writer2latex/latex/HeadingConverter.java +++ b/source/java/writer2latex/latex/HeadingConverter.java @@ -16,11 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Copyright: 2002-2008 by Henrik Just + * Copyright: 2002-2009 by Henrik Just * * All Rights Reserved. * - * Version 1.0 (2008-11-22) + * Version 1.2 (2009-04-28) * */ @@ -205,6 +205,12 @@ public class HeadingConverter extends ConverterHelper { String sMarginTop = style.getAbsoluteLength(XMLString.FO_MARGIN_TOP); String sMarginBottom = style.getAbsoluteLength(XMLString.FO_MARGIN_BOTTOM); String sMarginLeft = style.getAbsoluteLength(XMLString.FO_MARGIN_LEFT); + + ListStyle outline = ofr.getOutlineStyle(); + if (outline.isNewType(i)) { + // Override left margin with the value from the outline + sMarginLeft = outline.getLevelStyleProperty(i, XMLString.FO_MARGIN_LEFT); + } String sSecName = hm.getName(i); if (!comm.isEmpty()) { // have to create a cs for this heading @@ -264,15 +270,34 @@ public class HeadingConverter extends ConverterHelper { else { if (!bOnlyNum) { // Distance between label and text: - String sDistance = outline.getLevelStyleProperty(i,XMLString.TEXT_MIN_LABEL_DISTANCE); + String sSpaceChar=""; + String sDistance=null; + if (outline.isNewType(i)) { + String sFormat = outline.getLevelStyleProperty(i, XMLString.TEXT_LABEL_FOLLOWED_BY); + if ("listtab".equals(sFormat)) { + String sMarginLeft = outline.getLevelStyleProperty(i, XMLString.FO_MARGIN_LEFT); + if (sMarginLeft==null) { sMarginLeft = "0cm"; } + String sTextIndent = outline.getLevelStyleProperty(i, XMLString.FO_TEXT_INDENT); + if (sTextIndent==null) { sTextIndent = "0cm"; } + String sTabPos = outline.getLevelStyleProperty(i, XMLString.TEXT_LIST_TAB_STOP_POSITION); + if (sTabPos==null) { sTabPos = "0cm"; } + sDistance = Misc.sub(sTabPos, Misc.add(sMarginLeft, sTextIndent)); + } + else if ("space".equals(sFormat)) { + sSpaceChar="\\ "; + } + } + else { + sDistance = outline.getLevelStyleProperty(i,XMLString.TEXT_MIN_LABEL_DISTANCE); + } ldp.append("\\newcommand\\@distance") .append(hm.getName(i)).append("{"); if (sDistance!=null) { ldp.append("\\hspace{").append(sDistance).append("}"); } ldp.append("}").nl(); + // Label width and alignment - String sLabelWidth = outline.getLevelStyleProperty(i,XMLString.TEXT_MIN_LABEL_WIDTH); String sTextAlign = outline.getLevelStyleProperty(i,XMLString.FO_TEXT_ALIGN); String sAlignmentChar = "l"; // start (or left) is default if (sTextAlign!=null) { @@ -280,6 +305,16 @@ public class HeadingConverter extends ConverterHelper { else if ("right".equals(sTextAlign)) { sAlignmentChar="r"; } else if ("center".equals(sTextAlign)) { sAlignmentChar="c"; } } + String sLabelWidth = null; + if (outline.isNewType(i)) { + String sFormat = outline.getLevelStyleProperty(i, XMLString.TEXT_LABEL_FOLLOWED_BY); + if ("listtab".equals(sFormat) || sAlignmentChar=="r") { + sLabelWidth="0cm"; + } + } + else { + sLabelWidth = outline.getLevelStyleProperty(i,XMLString.TEXT_MIN_LABEL_WIDTH); + } // Textstyle to use for label: String sStyleName = outline.getLevelProperty(i,XMLString.TEXT_STYLE_NAME); // Prefix and suffix text to decorate the label @@ -291,7 +326,7 @@ public class HeadingConverter extends ConverterHelper { ldp.append("\\newcommand\\@textstyle") .append(hm.getName(i)).append("[1]{"); if (!bOnlyNum && sLabelWidth!=null) { - ldp.append("\\makebox[").append(sLabelWidth).append("][").append(sAlignmentChar).append("]{"); + ldp.append("\\protect\\makebox[").append(sLabelWidth).append("][").append(sAlignmentChar).append("]{"); } ldp.append(baText.getBefore()) .append(sPrefix!=null ? sPrefix : "") diff --git a/source/java/writer2latex/latex/ListStyleConverter.java b/source/java/writer2latex/latex/ListStyleConverter.java index 5c19c47..601ca64 100644 --- a/source/java/writer2latex/latex/ListStyleConverter.java +++ b/source/java/writer2latex/latex/ListStyleConverter.java @@ -16,11 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Copyright: 2002-2008 by Henrik Just + * Copyright: 2002-2009 by Henrik Just * * All Rights Reserved. * - * Version 1.0 (2008-09-08) + * Version 1.2 (2009-04-28) * */ @@ -36,349 +36,402 @@ import writer2latex.latex.util.Context; /* This class creates LaTeX code from OOo list styles */ public class ListStyleConverter extends StyleConverter { - boolean bNeedSaveEnumCounter = false; - private Hashtable listStyleLevelNames = new Hashtable(); + boolean bNeedSaveEnumCounter = false; + private Hashtable listStyleLevelNames = new Hashtable(); - /**

Constructs a new ListStyleConverter.

- */ - public ListStyleConverter(OfficeReader ofr, LaTeXConfig config, - ConverterPalette palette) { - super(ofr,config,palette); - } - - public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) { - if (config.formatting()>=LaTeXConfig.CONVERT_MOST || !styleNames.isEmpty()) { - decl.append("% List styles").nl(); - // May need an extra counter to handle continued numbering in lists - if (bNeedSaveEnumCounter) { - decl.append("\\newcounter{saveenum}").nl(); - } - // If we export formatting, we need some hooks from lists to paragraphs: - if (config.formatting()>=LaTeXConfig.CONVERT_MOST) { - decl.append("\\newcommand\\writerlistleftskip{}").nl() - .append("\\newcommand\\writerlistparindent{}").nl() - .append("\\newcommand\\writerlistlabel{}").nl() - .append("\\newcommand\\writerlistremovelabel{") - .append("\\aftergroup\\let\\aftergroup\\writerlistparindent\\aftergroup\\relax") - .append("\\aftergroup\\let\\aftergroup\\writerlistlabel\\aftergroup\\relax}").nl(); - } - super.appendDeclarations(pack,decl); - } - } + /**

Constructs a new ListStyleConverter.

+ */ + public ListStyleConverter(OfficeReader ofr, LaTeXConfig config, + ConverterPalette palette) { + super(ofr,config,palette); + } - /**

Apply a list style to an ordered or unordered list.

*/ - public void applyListStyle(String sStyleName, int nLevel, boolean bOrdered, - boolean bContinue, BeforeAfter ba) { - // Step 1. We may have a style map, this always takes precedence - String sDisplayName = ofr.getListStyles().getDisplayName(sStyleName); - if (config.getListStyleMap().contains(sDisplayName)) { - ba.add(config.getListStyleMap().getBefore(sDisplayName), - config.getListStyleMap().getAfter(sDisplayName)); - return; - } - // Step 2: The list style may not exist, or the user wants to ignore it. - // In this case we create default lists - ListStyle style = ofr.getListStyle(sStyleName); - if (style==null || config.formatting()<=LaTeXConfig.IGNORE_MOST) { - if (nLevel<=4) { - if (bOrdered) { - ba.add("\\begin{enumerate}","\\end{enumerate}"); - } - else { - ba.add("\\begin{itemize}","\\end{itemize}"); - } - } - return; - } - // Step 3: Export as default lists, but redefine labels - if (config.formatting()==LaTeXConfig.CONVERT_BASIC) { - if (nLevel==1) { - if (!styleNames.containsName(getDisplayName(sStyleName))) { - createListStyleLabels(sStyleName); - } - ba.add("\\liststyle"+styleNames.getExportName(getDisplayName(sStyleName))+"\n",""); - } - if (nLevel<=4) { - String sCounterName = listStyleLevelNames.get(sStyleName)[nLevel]; - if (bContinue && style.isNumber(nLevel)) { - bNeedSaveEnumCounter = true; - ba.add("\\setcounter{saveenum}{\\value{"+sCounterName+"}}\n",""); - } - if (bOrdered) { - ba.add("\\begin{enumerate}","\\end{enumerate}"); - } - else { - ba.add("\\begin{itemize}","\\end{itemize}"); - } - if (bContinue && style.isNumber(nLevel)) { - ba.add("\n\\setcounter{"+sCounterName+"}{\\value{saveenum}}",""); - } - } - return; - } - // Step 4: Export with formatting, as "Writer style" custom lists - if (nLevel<=4) { // TODO: Max level should not be fixed - if (!styleNames.containsName(getDisplayName(sStyleName))) { - createListStyle(sStyleName); - } - String sTeXName="list"+styleNames.getExportName(getDisplayName(sStyleName)) - +"level"+Misc.int2roman(nLevel); - if (!bContinue && style.isNumber(nLevel)) { - int nStartValue = Misc.getPosInteger(style.getLevelProperty(nLevel,XMLString.TEXT_START_VALUE),1)-1; - ba.add("\\setcounter{"+sTeXName+"}{"+Integer.toString(nStartValue)+"}\n",""); - } - ba.add("\\begin{"+sTeXName+"}","\\end{"+sTeXName+"}"); - } - } - - /**

Apply a list style to a list item.

*/ - public void applyListItemStyle(String sStyleName, int nLevel, boolean bHeader, - boolean bRestart, int nStartValue, BeforeAfter ba) { - // Step 1. We may have a style map, this always takes precedence - String sDisplayName = ofr.getListStyles().getDisplayName(sStyleName); - if (config.getListItemStyleMap().contains(sDisplayName)) { - ba.add(config.getListItemStyleMap().getBefore(sDisplayName), - config.getListItemStyleMap().getAfter(sDisplayName)); - return; - } - // Step 2: The list style may not exist, or the user wants to ignore it. - // In this case we create default lists - ListStyle style = ofr.getListStyle(sStyleName); - if (style==null || config.formatting()<=LaTeXConfig.IGNORE_MOST) { - if (nLevel<=4) { - if (bHeader) { ba.add("\\item[] ",""); } - else { ba.add("\\item ",""); } - } - return; - } - // Step 3: Export as default lists (with redefined labels) - if (config.formatting()==LaTeXConfig.CONVERT_BASIC) { - if (nLevel<=4) { - if (bHeader) { - ba.add("\\item[] ",""); - } - else if (bRestart && style.isNumber(nLevel)) { - ba.add("\n\\setcounter{enum"+Misc.int2roman(nLevel) - +"}{"+(nStartValue-1)+"}\n\\item ",""); - } - else { - ba.add("\\item ",""); - } - } - return; - } - // Step 4: Export with formatting, as "Writer style" custom lists - if (nLevel<=4 && !bHeader) { // TODO: Max level should not be fixed - String sTeXName="list"+styleNames.getExportName(getDisplayName(sStyleName)) - +"level"+Misc.int2roman(nLevel); - if (bRestart && style.isNumber(nLevel)) { - ba.add("\\setcounter{"+sTeXName+"}{"+(nStartValue-1)+"}\n",""); - } - ba.add("\\item ",""); - } - } + public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) { + if (config.formatting()>=LaTeXConfig.CONVERT_MOST || !styleNames.isEmpty()) { + decl.append("% List styles").nl(); + // May need an extra counter to handle continued numbering in lists + if (bNeedSaveEnumCounter) { + decl.append("\\newcounter{saveenum}").nl(); + } + // If we export formatting, we need some hooks from lists to paragraphs: + if (config.formatting()>=LaTeXConfig.CONVERT_MOST) { + decl.append("\\newcommand\\writerlistleftskip{}").nl() + .append("\\newcommand\\writerlistparindent{}").nl() + .append("\\newcommand\\writerlistlabel{}").nl() + .append("\\newcommand\\writerlistremovelabel{") + .append("\\aftergroup\\let\\aftergroup\\writerlistparindent\\aftergroup\\relax") + .append("\\aftergroup\\let\\aftergroup\\writerlistlabel\\aftergroup\\relax}").nl(); + } + super.appendDeclarations(pack,decl); + } + } + + /**

Apply a list style to an ordered or unordered list.

*/ + public void applyListStyle(String sStyleName, int nLevel, boolean bOrdered, + boolean bContinue, BeforeAfter ba) { + // Step 1. We may have a style map, this always takes precedence + String sDisplayName = ofr.getListStyles().getDisplayName(sStyleName); + if (config.getListStyleMap().contains(sDisplayName)) { + ba.add(config.getListStyleMap().getBefore(sDisplayName), + config.getListStyleMap().getAfter(sDisplayName)); + return; + } + // Step 2: The list style may not exist, or the user wants to ignore it. + // In this case we create default lists + ListStyle style = ofr.getListStyle(sStyleName); + if (style==null || config.formatting()<=LaTeXConfig.IGNORE_MOST) { + if (nLevel<=4) { + if (bOrdered) { + ba.add("\\begin{enumerate}","\\end{enumerate}"); + } + else { + ba.add("\\begin{itemize}","\\end{itemize}"); + } + } + return; + } + // Step 3: Export as default lists, but redefine labels + if (config.formatting()==LaTeXConfig.CONVERT_BASIC) { + if (nLevel==1) { + if (!styleNames.containsName(getDisplayName(sStyleName))) { + createListStyleLabels(sStyleName); + } + ba.add("\\liststyle"+styleNames.getExportName(getDisplayName(sStyleName))+"\n",""); + } + if (nLevel<=4) { + String sCounterName = listStyleLevelNames.get(sStyleName)[nLevel]; + if (bContinue && style.isNumber(nLevel)) { + bNeedSaveEnumCounter = true; + ba.add("\\setcounter{saveenum}{\\value{"+sCounterName+"}}\n",""); + } + if (bOrdered) { + ba.add("\\begin{enumerate}","\\end{enumerate}"); + } + else { + ba.add("\\begin{itemize}","\\end{itemize}"); + } + if (bContinue && style.isNumber(nLevel)) { + ba.add("\n\\setcounter{"+sCounterName+"}{\\value{saveenum}}",""); + } + } + return; + } + // Step 4: Export with formatting, as "Writer style" custom lists + if (nLevel<=4) { // TODO: Max level should not be fixed + if (!styleNames.containsName(getDisplayName(sStyleName))) { + createListStyle(sStyleName); + } + String sTeXName="list"+styleNames.getExportName(getDisplayName(sStyleName)) + +"level"+Misc.int2roman(nLevel); + if (!bContinue && style.isNumber(nLevel)) { + int nStartValue = Misc.getPosInteger(style.getLevelProperty(nLevel,XMLString.TEXT_START_VALUE),1)-1; + ba.add("\\setcounter{"+sTeXName+"}{"+Integer.toString(nStartValue)+"}\n",""); + } + ba.add("\\begin{"+sTeXName+"}","\\end{"+sTeXName+"}"); + } + } + + /**

Apply a list style to a list item.

*/ + public void applyListItemStyle(String sStyleName, int nLevel, boolean bHeader, + boolean bRestart, int nStartValue, BeforeAfter ba) { + // Step 1. We may have a style map, this always takes precedence + String sDisplayName = ofr.getListStyles().getDisplayName(sStyleName); + if (config.getListItemStyleMap().contains(sDisplayName)) { + ba.add(config.getListItemStyleMap().getBefore(sDisplayName), + config.getListItemStyleMap().getAfter(sDisplayName)); + return; + } + // Step 2: The list style may not exist, or the user wants to ignore it. + // In this case we create default lists + ListStyle style = ofr.getListStyle(sStyleName); + if (style==null || config.formatting()<=LaTeXConfig.IGNORE_MOST) { + if (nLevel<=4) { + if (bHeader) { ba.add("\\item[] ",""); } + else { ba.add("\\item ",""); } + } + return; + } + // Step 3: Export as default lists (with redefined labels) + if (config.formatting()==LaTeXConfig.CONVERT_BASIC) { + if (nLevel<=4) { + if (bHeader) { + ba.add("\\item[] ",""); + } + else if (bRestart && style.isNumber(nLevel)) { + ba.add("\n\\setcounter{enum"+Misc.int2roman(nLevel) + +"}{"+(nStartValue-1)+"}\n\\item ",""); + } + else { + ba.add("\\item ",""); + } + } + return; + } + // Step 4: Export with formatting, as "Writer style" custom lists + if (nLevel<=4 && !bHeader) { // TODO: Max level should not be fixed + String sTeXName="list"+styleNames.getExportName(getDisplayName(sStyleName)) + +"level"+Misc.int2roman(nLevel); + if (bRestart && style.isNumber(nLevel)) { + ba.add("\\setcounter{"+sTeXName+"}{"+(nStartValue-1)+"}\n",""); + } + ba.add("\\item ",""); + } + } - /**

Create labels for default lists (enumerate/itemize) based on - * a List Style - */ - private void createListStyleLabels(String sStyleName) { - String sTeXName = styleNames.getExportName(getDisplayName(sStyleName)); - declarations.append("\\newcommand\\liststyle") - .append(sTeXName).append("{%").nl(); - ListStyle style = ofr.getListStyle(sStyleName); - int nEnum = 0; - int nItem = 0; - String sName[] = new String[5]; - for (int i=1; i<=4; i++) { - if (style.isNumber(i)) { sName[i]="enum"+Misc.int2roman(++nEnum); } - else { sName[i]="item"+Misc.int2roman(++nItem); } - } - listStyleLevelNames.put(sStyleName, sName); - createLabels(style, sName, 4, false, true, false, declarations); - declarations.append("}").nl(); - } + /**

Create labels for default lists (enumerate/itemize) based on + * a List Style + */ + private void createListStyleLabels(String sStyleName) { + String sTeXName = styleNames.getExportName(getDisplayName(sStyleName)); + declarations.append("\\newcommand\\liststyle") + .append(sTeXName).append("{%").nl(); + ListStyle style = ofr.getListStyle(sStyleName); + int nEnum = 0; + int nItem = 0; + String sName[] = new String[5]; + for (int i=1; i<=4; i++) { + if (style.isNumber(i)) { sName[i]="enum"+Misc.int2roman(++nEnum); } + else { sName[i]="item"+Misc.int2roman(++nItem); } + } + listStyleLevelNames.put(sStyleName, sName); + createLabels(style, sName, 4, false, true, false, declarations); + declarations.append("}").nl(); + } - /**

Create "Writer style" lists based on a List Style. + /**

Create "Writer style" lists based on a List Style.

A list in writer is really a sequence of numbered paragraphs, so this is also how we implement it in LaTeX. The enivronment + redefined \item defines three hooks: \writerlistleftskip, \writerlistparindent, \writerlistlabel which are used by exported paragraph styles to apply numbering. - */ - private void createListStyle(String sStyleName) { - ListStyle style = ofr.getListStyle(sStyleName); + */ + private void createListStyle(String sStyleName) { + ListStyle style = ofr.getListStyle(sStyleName); - // Create labels - String sTeXName = styleNames.getExportName(getDisplayName(sStyleName)); - String[] sLevelName = new String[5]; - for (int i=1; i<=4; i++) { - sLevelName[i]="list"+sTeXName+"level"+Misc.int2roman(i); - } - createLabels(style,sLevelName,4,true,false,true,declarations); + // Create labels + String sTeXName = styleNames.getExportName(getDisplayName(sStyleName)); + String[] sLevelName = new String[5]; + for (int i=1; i<=4; i++) { + sLevelName[i]="list"+sTeXName+"level"+Misc.int2roman(i); + } + createLabels(style,sLevelName,4,true,false,true,declarations); - // Create environments - for (int i=1; i<=4; i++) { - String sSpaceBefore = getLength(style,i,XMLString.TEXT_SPACE_BEFORE); - String sLabelWidth = getLength(style,i,XMLString.TEXT_MIN_LABEL_WIDTH); - String sLabelDistance = getLength(style,i,XMLString.TEXT_MIN_LABEL_DISTANCE); - String sTextAlign = style.getLevelStyleProperty(i,XMLString.FO_TEXT_ALIGN); - String sAlignmentChar = "l"; // start (or left) is default - if (sTextAlign!=null) { - if ("end".equals(sTextAlign)) { sAlignmentChar="r"; } - else if ("right".equals(sTextAlign)) { sAlignmentChar="r"; } - else if ("center".equals(sTextAlign)) { sAlignmentChar="c"; } - } - declarations - .append("\\newenvironment{") - .append(sLevelName[i]).append("}{") - .append("\\def\\writerlistleftskip{\\addtolength\\leftskip{") - .append(Misc.add(sSpaceBefore,sLabelWidth)).append("}}") - .append("\\def\\writerlistparindent{}") - .append("\\def\\writerlistlabel{}"); - // Redefine \item - declarations - .append("\\def\\item{") - .append("\\def\\writerlistparindent{\\setlength\\parindent{") - .append("-").append(sLabelWidth).append("}}") - .append("\\def\\writerlistlabel{"); - if (style.isNumber(i)) { - declarations.append("\\stepcounter{") - .append(sLevelName[i]).append("}"); - } - declarations - .append("\\makebox[").append(sLabelWidth).append("][") - .append(sAlignmentChar).append("]{") - .append("\\label").append(sLevelName[i]).append("}") - .append("\\hspace{").append(sLabelDistance).append("}") - .append("\\writerlistremovelabel}}}{}").nl(); - } - } - - /**

Create LaTeX list labels from an OOo list style. Examples:

- *

Bullets:

- *
\newcommand\labelliststylei{\textbullet}
-     *  \newcommand\labelliststyleii{*}
-     *  \newcommand\labelliststyleiii{\textstylebullet{>}}
- *

Numbering:

- *
\newcounter{liststylei}
-     *  \newcounter{liststyleii}[liststylei]
-     *  \newcounter{liststyleiii}[liststyleii]
-     *  \renewcommand\theliststylei{\Roman{liststylei}}
-     *  \renewcommand\theliststyleii{\Roman{liststylei}.\arabic{liststyleii}}
-     *  \renewcommand\theliststyleiii{\alph{liststyleiii}}
-     *  \newcommand\labelliststylei{\textstylelabel{\theliststylei .}}
-     *  \newcommand\labelliststyleii{\textstylelabel{\theliststyleii .}}
-     *  \newcommand\labelliststyleiii{\textstylelabel{\theliststyleiii )}}
- * - * @param style the OOo list style to use - * @param sName an array of label basenames to use - * @param nMaxLevel the highest level in this numbering - * @param bDeclareCounters true if counters should be declared (they may - * exist already, eg. "section", "subsection"... or "enumi", "enumii"... - * @param bRenewLabels true if labels should be defined with \renewcommand - * @param bUseTextStyle true if labels should be formatted with the associated text style - * (rather than \newcommand). - * @param ldp the LaTeXDocumentPortion to add LaTeX code to. - */ - private void createLabels(ListStyle style, String[] sName, int nMaxLevel, - boolean bDeclareCounters, boolean bRenewLabels, - boolean bUseTextStyle, LaTeXDocumentPortion ldp) { - // Declare counters if required (eg. "\newcounter{countername1}[countername2]") - if (bDeclareCounters) { - int j = 0; - for (int i=1; i<=nMaxLevel; i++) { - if (style.isNumber(i)) { - ldp.append("\\newcounter{").append(sName[i]).append("}"); - if (j>0) { ldp.append("[").append(sName[j]).append("]"); } - ldp.nl(); - j = i; - } - } - } - // Create numbering for each level (eg. "\arabic{countername}") - String[] sNumFormat = new String[nMaxLevel+1]; - for (int i=1; i<=nMaxLevel; i++) { - String s = numFormat(style.getLevelProperty(i,XMLString.STYLE_NUM_FORMAT)); - if (s==null) { sNumFormat[i]=""; } - else { sNumFormat[i] = s + "{" + sName[i] + "}"; } - } - // Create numberings (ie. define "\thecountername"): - for (int i=1; i<=nMaxLevel; i++) { - if (style.isNumber(i)) { - ldp.append("\\renewcommand\\the").append(sName[i]).append("{"); - int nLevels = Misc.getPosInteger(style.getLevelProperty(i,XMLString.TEXT_DISPLAY_LEVELS),1); - for (int j=i-nLevels+1; jCreate LaTeX list labels from an OOo list style. Examples:

+ *

Bullets:

+ *
\newcommand\labelliststylei{\textbullet}
+	 *  \newcommand\labelliststyleii{*}
+	 *  \newcommand\labelliststyleiii{\textstylebullet{>}}
+ *

Numbering:

+ *
\newcounter{liststylei}
+	 *  \newcounter{liststyleii}[liststylei]
+	 *  \newcounter{liststyleiii}[liststyleii]
+	 *  \renewcommand\theliststylei{\Roman{liststylei}}
+	 *  \renewcommand\theliststyleii{\Roman{liststylei}.\arabic{liststyleii}}
+	 *  \renewcommand\theliststyleiii{\alph{liststyleiii}}
+	 *  \newcommand\labelliststylei{\textstylelabel{\theliststylei .}}
+	 *  \newcommand\labelliststyleii{\textstylelabel{\theliststyleii .}}
+	 *  \newcommand\labelliststyleiii{\textstylelabel{\theliststyleiii )}}
+ * + * @param style the OOo list style to use + * @param sName an array of label basenames to use + * @param nMaxLevel the highest level in this numbering + * @param bDeclareCounters true if counters should be declared (they may + * exist already, eg. "section", "subsection"... or "enumi", "enumii"... + * @param bRenewLabels true if labels should be defined with \renewcommand + * @param bUseTextStyle true if labels should be formatted with the associated text style + * (rather than \newcommand). + * @param ldp the LaTeXDocumentPortion to add LaTeX code to. + */ + private void createLabels(ListStyle style, String[] sName, int nMaxLevel, + boolean bDeclareCounters, boolean bRenewLabels, + boolean bUseTextStyle, LaTeXDocumentPortion ldp) { +// Declare counters if required (eg. "\newcounter{countername1}[countername2]") + if (bDeclareCounters) { + int j = 0; + for (int i=1; i<=nMaxLevel; i++) { + if (style.isNumber(i)) { + ldp.append("\\newcounter{").append(sName[i]).append("}"); + if (j>0) { ldp.append("[").append(sName[j]).append("]"); } + ldp.nl(); + j = i; + } + } + } +// Create numbering for each level (eg. "\arabic{countername}") + String[] sNumFormat = new String[nMaxLevel+1]; + for (int i=1; i<=nMaxLevel; i++) { + String s = numFormat(style.getLevelProperty(i,XMLString.STYLE_NUM_FORMAT)); + if (s==null) { sNumFormat[i]=""; } + else { sNumFormat[i] = s + "{" + sName[i] + "}"; } + } +// Create numberings (ie. define "\thecountername"): + for (int i=1; i<=nMaxLevel; i++) { + if (style.isNumber(i)) { + ldp.append("\\renewcommand\\the").append(sName[i]).append("{"); + int nLevels = Misc.getPosInteger(style.getLevelProperty(i,XMLString.TEXT_DISPLAY_LEVELS),1); + for (int j=i-nLevels+1; j=1 && i<=MAX_LEVEL) { @@ -90,39 +94,53 @@ public class ListStyle extends OfficeStyle { public void loadStyleFromDOM(Node node) { super.loadStyleFromDOM(node); - // Collect level information from child elements: - if (node.hasChildNodes()){ - NodeList nl = node.getChildNodes(); - int nLen = nl.getLength(); - for (int i = 0; i < nLen; i++ ) { - Node child=nl.item(i); - if (child.getNodeType()==Node.ELEMENT_NODE){ - String sLevel = Misc.getAttribute(child,XMLString.TEXT_LEVEL); - if (sLevel!=null) { - int nLevel = Misc.getPosInteger(sLevel,1); - if (nLevel>=1 && nLevel<=MAX_LEVEL) { - level[nLevel].loadFromDOM(child); - // Also include style:properties - if (child.hasChildNodes()){ - NodeList nl2 = child.getChildNodes(); - int nLen2 = nl2.getLength(); - for (int i2 = 0; i2 < nLen2; i2++ ) { - Node child2=nl2.item(i2); - if (child2.getNodeType()==Node.ELEMENT_NODE){ - if (child2.getNodeName().equals(XMLString.STYLE_PROPERTIES)) { - levelStyle[nLevel].loadFromDOM(child2); - } - if (child2.getNodeName().equals(XMLString.STYLE_LIST_LEVEL_PROPERTIES)) { // oasis - levelStyle[nLevel].loadFromDOM(child2); - } - } - } - } - } + // Collect level information from child elements (text:list-level-style-*): + Node child = node.getFirstChild(); + while (child!=null) { + if (child.getNodeType()==Node.ELEMENT_NODE){ + String sLevel = Misc.getAttribute(child,XMLString.TEXT_LEVEL); + if (sLevel!=null) { + int nLevel = Misc.getPosInteger(sLevel,1); + if (nLevel>=1 && nLevel<=MAX_LEVEL) { + loadLevelPropertiesFromDOM(nLevel,child); } } } + child = child.getNextSibling(); } } + + private void loadLevelPropertiesFromDOM(int nLevel, Node node) { + // Load the attributes + level[nLevel].loadFromDOM(node); + // Also include style:properties + Node child = node.getFirstChild(); + while (child!=null) { + if (child.getNodeType()==Node.ELEMENT_NODE){ + if (child.getNodeName().equals(XMLString.STYLE_PROPERTIES)) { + levelStyle[nLevel].loadFromDOM(child); + loadLevelLabelPropertiesFromDOM(nLevel,node); + } + if (child.getNodeName().equals(XMLString.STYLE_LIST_LEVEL_PROPERTIES)) { // oasis + levelStyle[nLevel].loadFromDOM(child); + loadLevelLabelPropertiesFromDOM(nLevel,child); + } + } + child = child.getNextSibling(); + } + } + + private void loadLevelLabelPropertiesFromDOM(int nLevel, Node node) { + // Merge the properties from style:list-level-label-alignment + Node child = node.getFirstChild(); + while (child!=null) { + if (child.getNodeType()==Node.ELEMENT_NODE){ + if (child.getNodeName().equals(XMLString.STYLE_LIST_LEVEL_LABEL_ALIGNMENT)) { + levelStyle[nLevel].loadFromDOM(child); + } + } + child = child.getNextSibling(); + } + } } \ No newline at end of file diff --git a/source/java/writer2latex/office/XMLString.java b/source/java/writer2latex/office/XMLString.java index bd68b4f..0b259d9 100644 --- a/source/java/writer2latex/office/XMLString.java +++ b/source/java/writer2latex/office/XMLString.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2009-03-26) + * Version 1.2 (2009-03-27) * */ @@ -146,6 +146,7 @@ public class XMLString { public static final String STYLE_PAGE_LAYOUT_PROPERTIES="style:page-layout-properties"; // oasis public static final String STYLE_DRAWING_PAGE_PROPERTIES="style:drawing-page-properties"; // oasis public static final String STYLE_HEADER_FOOTER_PROPERTIES="style:header-footer-properties"; // oasis + public static final String STYLE_LIST_LEVEL_LABEL_ALIGNMENT="style:list-level-label-alignment"; // oasis 1.2 public static final String STYLE_BACKGROUND_IMAGE="style:background-image"; public static final String STYLE_COLUMNS="style:columns"; public static final String STYLE_HEADER="style:header"; @@ -359,7 +360,11 @@ public class XMLString { public static final String TEXT_DISPLAY="text:display"; public static final String TEXT_DISPLAY_OUTLINE_LEVEL="text:display-outline-level"; public static final String TEXT_SEPARATION_CHARACTER="text:separation-character"; - + + public static final String TEXT_LIST_LEVEL_POSITION_AND_SPACE_MODE="text:list-level-position-and-space-mode"; // oasis 1.2 + public static final String TEXT_LABEL_FOLLOWED_BY="text:label-followed-by"; // oasis 1.2 + public static final String TEXT_LIST_TAB_STOP_POSITION="text:list-tab-stop-position"; // oasis 1.2 + public static final String TEXT_IDENTIFIER="text:identifier"; public static final String TEXT_BIBLIOGRAPHY_TYPE="text:bibliography-type"; public static final String TEXT_BIBILIOGRAPHIC_TYPE="text:bibiliographic-type"; // bug in OOo 1.0 diff --git a/source/java/writer2latex/xhtml/Converter.java b/source/java/writer2latex/xhtml/Converter.java index a8903a8..1ee18b6 100644 --- a/source/java/writer2latex/xhtml/Converter.java +++ b/source/java/writer2latex/xhtml/Converter.java @@ -610,7 +610,7 @@ public class Converter extends ConverterBase { for (String sElement : sElements) { String[] sNameVal = sElement.split("="); if (sNameVal.length>=2) { - anchor.setAttribute(sNameVal[0],sNameVal[1]); + anchor.setAttribute(sNameVal[0].trim(),sNameVal[1].trim()); } } } diff --git a/source/oxt/writer4latex/Addons.xcu b/source/oxt/writer4latex/Addons.xcu index c676b65..1b4a6a0 100644 --- a/source/oxt/writer4latex/Addons.xcu +++ b/source/oxt/writer4latex/Addons.xcu @@ -35,6 +35,7 @@ + com.sun.star.text.TextDocument