diff --git a/source/distro/changelog.txt b/source/distro/changelog.txt index d538d71..83f451b 100644 --- a/source/distro/changelog.txt +++ b/source/distro/changelog.txt @@ -2,6 +2,21 @@ Changelog for Writer2LaTeX version 1.0 -> 1.2 ---------- version 1.1.9 ---------- +[w2x] *New option include_toc (default true) for EPUB export: If set to false, the table of content will not be exported + +[w2x] *New option split_after (default 0) for EPUB export: This sets the number of characters (in thousands) after + which an automatic split will occur (0 means no automatic split) + +[w2x] *New options use_default_font (default false) and default_font_name (default empty) for EPUB export. + If the former is true, font names are not exported, but the latter will be exported as default font (if non-empty) + +[w2x] *New options relative_font_size (default false) and font_scaling (default 100%) for EPUB export. + If the former is true, relative font sizes are used, scaled by the percentage given by the latter + +[w2x] *EPUB export now has its own export dialog + +[all] *API change: Added the method readResource to the Converter interface (only used by EPUB export currently) + [w2x] EPUB export now uses user-defined meta data to support meta data features that are not defined in ODF [w2x] The option use_dublin_core now also works for EPUB export @@ -23,8 +38,6 @@ Changelog for Writer2LaTeX version 1.0 -> 1.2 [w2l] Custom config ui: The four special styles for tables are now localized and can be selected from existing styles -[w2x] In EPUB export, convert_to_px=true now (despite the name) exports relative font sizes - [w2l] Custom config ui is now refactored to use ConfigurationDialogBase, fixing some minor bugs [w2l] String replace now also works with XeTeX as backend diff --git a/source/distro/doc/user-manual.odt b/source/distro/doc/user-manual.odt index 32d6a1a..ca0d8a8 100644 Binary files a/source/distro/doc/user-manual.odt and b/source/distro/doc/user-manual.odt differ diff --git a/source/java/org/openoffice/da/comp/w2lcommon/filter/ConfigurationDialogBase.java b/source/java/org/openoffice/da/comp/w2lcommon/filter/ConfigurationDialogBase.java index f7ae651..447aafd 100644 --- a/source/java/org/openoffice/da/comp/w2lcommon/filter/ConfigurationDialogBase.java +++ b/source/java/org/openoffice/da/comp/w2lcommon/filter/ConfigurationDialogBase.java @@ -32,8 +32,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.text.Collator; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -62,6 +60,7 @@ import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter; import writer2latex.api.ComplexOption; import writer2latex.api.Config; import writer2latex.api.ConverterFactory; +import writer2latex.util.Misc; import org.openoffice.da.comp.w2lcommon.helper.DialogAccess; import org.openoffice.da.comp.w2lcommon.helper.FilePicker; @@ -288,14 +287,6 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta config.setOption(sConfigName, sConfigValues[dlg.getListBoxSelectedItem(sListBoxName)]); } - // Utilities - protected String[] sortStringSet(Set theSet) { - String[] theArray = theSet.toArray(new String[theSet.size()]); - // TODO: Get locale from OOo rather than the system - Collator collator = Collator.getInstance(); - Arrays.sort(theArray, collator); - return theArray; - } } protected abstract class CustomFileHandler extends PageHandler { @@ -514,7 +505,7 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta private String newItem(Set suggestions) { XDialog xDialog=getDialog(getDialogLibraryName()+".NewDialog"); if (xDialog!=null) { - String[] sItems = sortStringSet(suggestions); + String[] sItems = Misc.sortStringSet(suggestions); DialogAccess ndlg = new DialogAccess(xDialog); ndlg.setListBoxStringItemList("Name", sItems); String sResult = null; @@ -658,7 +649,7 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta nCurrentFamily = nNewFamily; sCurrentStyleName = null; - String[] sStyleNames = sortStringSet(styleMap[nNewFamily].keySet()); + String[] sStyleNames = Misc.sortStringSet(styleMap[nNewFamily].keySet()); dlg.setListBoxStringItemList("StyleName", sStyleNames); if (sStyleNames.length>0) { dlg.setListBoxSelectedItem("StyleName", (short)0); diff --git a/source/java/org/openoffice/da/comp/writer2latex/ConfigurationDialog.java b/source/java/org/openoffice/da/comp/writer2latex/ConfigurationDialog.java index cadb262..ce4afae 100644 --- a/source/java/org/openoffice/da/comp/writer2latex/ConfigurationDialog.java +++ b/source/java/org/openoffice/da/comp/writer2latex/ConfigurationDialog.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-12-14) + * Version 1.2 (2010-12-21) * */ @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.Map; import writer2latex.api.ComplexOption; +import writer2latex.util.Misc; import org.openoffice.da.comp.w2lcommon.filter.ConfigurationDialogBase; import org.openoffice.da.comp.w2lcommon.helper.DialogAccess; @@ -677,7 +678,7 @@ public final class ConfigurationDialog extends ConfigurationDialogBase implement StyleNameProvider styleNameProvider = new StyleNameProvider(xContext); Map internalNames = styleNameProvider.getInternalNames("ParagraphStyles"); if (internalNames!=null) { - String[] styleNames = sortStringSet(internalNames.keySet()); + String[] styleNames = Misc.sortStringSet(internalNames.keySet()); dlg.setListBoxStringItemList("TableFirstHeadStyle",styleNames); dlg.setListBoxStringItemList("TableHeadStyle",styleNames); dlg.setListBoxStringItemList("TableFootStyle",styleNames); @@ -687,7 +688,7 @@ public final class ConfigurationDialog extends ConfigurationDialogBase implement // Fill the table sequence combo box with sequence names FieldMasterNameProvider fieldMasterNameProvider = new FieldMasterNameProvider(xContext); dlg.setListBoxStringItemList("TableSequenceName", - sortStringSet(fieldMasterNameProvider.getFieldMasterNames("com.sun.star.text.fieldmaster.SetExpression."))); + Misc.sortStringSet(fieldMasterNameProvider.getFieldMasterNames("com.sun.star.text.fieldmaster.SetExpression."))); dlg.setCheckBoxStateAsBoolean("NoTables", !"accept".equals(config.getOption("table_content"))); checkBoxFromConfig(dlg,"UseColortbl","use_colortbl"); @@ -766,7 +767,7 @@ public final class ConfigurationDialog extends ConfigurationDialogBase implement // Fill the figure sequence combo box with sequence names FieldMasterNameProvider fieldMasterNameProvider = new FieldMasterNameProvider(xContext); dlg.setListBoxStringItemList("FigureSequenceName", - sortStringSet(fieldMasterNameProvider.getFieldMasterNames("com.sun.star.text.fieldmaster.SetExpression."))); + Misc.sortStringSet(fieldMasterNameProvider.getFieldMasterNames("com.sun.star.text.fieldmaster.SetExpression."))); checkBoxFromConfig(dlg,"UseCaption","use_caption"); checkBoxFromConfig(dlg,"AlignFrames","align_frames"); @@ -825,7 +826,7 @@ public final class ConfigurationDialog extends ConfigurationDialogBase implement else { mathSymbols = new ComplexOption(); } mathSymbols.copyAll(config.getComplexOption("math-symbol-map")); sCurrentMathSymbol = null; - dlg.setListBoxStringItemList("MathSymbolName", sortStringSet(mathSymbols.keySet())); + dlg.setListBoxStringItemList("MathSymbolName", Misc.sortStringSet(mathSymbols.keySet())); // This triggers an onchange event dlg.setListBoxSelectedItem("MathSymbolName", (short)Math.min(0,mathSymbols.keySet().size()-1)); @@ -834,7 +835,7 @@ public final class ConfigurationDialog extends ConfigurationDialogBase implement else { stringReplace = new ComplexOption(); } stringReplace.copyAll(config.getComplexOption("string-replace")); sCurrentText = null; - dlg.setListBoxStringItemList("TextInput", sortStringSet(stringReplace.keySet())); + dlg.setListBoxStringItemList("TextInput", Misc.sortStringSet(stringReplace.keySet())); // This triggers an onchange event dlg.setListBoxSelectedItem("TextInput", (short)Math.min(0,stringReplace.keySet().size()-1)); diff --git a/source/java/org/openoffice/da/comp/writer2xhtml/EpubOptionsDialog.java b/source/java/org/openoffice/da/comp/writer2xhtml/EpubOptionsDialog.java new file mode 100644 index 0000000..b3dc0aa --- /dev/null +++ b/source/java/org/openoffice/da/comp/writer2xhtml/EpubOptionsDialog.java @@ -0,0 +1,319 @@ +/************************************************************************ + * + * EpubOptionsDialog.java + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Copyright: 2002-2010 by Henrik Just + * + * All Rights Reserved. + * + * Version 1.2 (2010-12-28) + * + */ + +// TODO: Add to doc: +// New options relative_font_size, font_scaling, use_default_font, default_font_name, split_after, page_break_split, include_toc +// Also add to list of possible locked options external_toc_depth + +package org.openoffice.da.comp.writer2xhtml; + +import java.awt.GraphicsEnvironment; + +import com.sun.star.awt.XDialog; +import com.sun.star.beans.XPropertySet; +import com.sun.star.uno.XComponentContext; + +import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper; +import org.openoffice.da.comp.w2lcommon.filter.OptionsDialogBase; + +/** This class provides a uno component which implements a filter ui for the + * EPUB export + */ +public class EpubOptionsDialog extends OptionsDialogBase { + + /** The component will be registered under this name. + */ + public static String __serviceName = "org.openoffice.da.writer2xhtml.EpubOptionsDialog"; + + /** The component should also have an implementation name. + */ + public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.EpubOptionsDialog"; + + @Override public String getDialogLibraryName() { return "W2XDialogs2"; } + + /** Return the name of the dialog within the library + */ + @Override public String getDialogName() { return "EpubOptions"; } + + /** Return the name of the registry path + */ + @Override public String getRegistryPath() { + return "/org.openoffice.da.Writer2xhtml.Options/EpubOptions"; + } + + /** Create a new EpubOptionsDialog */ + public EpubOptionsDialog(XComponentContext xContext) { + super(xContext); + xMSF = W2XRegistration.xMultiServiceFactory; + } + + /** Load settings from the registry to the dialog */ + @Override protected void loadSettings(XPropertySet xProps) { + // Style + loadConfig(xProps); + loadNumericOption(xProps, "Scaling"); + loadNumericOption(xProps, "ColumnScaling"); + loadCheckBoxOption(xProps, "RelativeFontSize"); + loadNumericOption(xProps, "FontScaling"); + loadCheckBoxOption(xProps, "RelativeFontSize"); + loadCheckBoxOption(xProps, "UseDefaultFont"); + loadComboBoxOption(xProps, "DefaultFontName"); + loadCheckBoxOption(xProps, "ConvertToPx"); + loadCheckBoxOption(xProps, "OriginalImageSize"); + + // Fill the font name list with all installed fonts + setListBoxStringItemList("DefaultFontName", + GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()); + + // Special content + loadCheckBoxOption(xProps, "DisplayHiddenText"); + loadCheckBoxOption(xProps, "Notes"); + loadCheckBoxOption(xProps, "UseDublinCore"); + + // AutoCorrect + loadCheckBoxOption(xProps, "IgnoreHardLineBreaks"); + loadCheckBoxOption(xProps, "IgnoreEmptyParagraphs"); + loadCheckBoxOption(xProps, "IgnoreDoubleSpaces"); + + // Files + loadCheckBoxOption(xProps, "Split"); + loadListBoxOption(xProps, "SplitLevel"); + loadCheckBoxOption(xProps, "UsePageBreakSplit"); + loadListBoxOption(xProps, "PageBreakSplit"); + loadCheckBoxOption(xProps, "UseSplitAfter"); + loadNumericOption(xProps, "SplitAfter"); + + // Table of contents + loadListBoxOption(xProps, "ExternalTocDepth"); + loadCheckBoxOption(xProps, "IncludeToc"); + + updateLockedOptions(); + enableControls(); + } + + /** Save settings from the dialog to the registry and create FilterData */ + @Override protected void saveSettings(XPropertySet xProps, PropertyHelper helper) { + // Style + short nConfig = saveConfig(xProps, helper); + switch (nConfig) { + case 0: helper.put("ConfigURL","*default.xml"); break; + case 1: helper.put("ConfigURL","$(user)/writer2xhtml.xml"); + helper.put("AutoCreate","true"); + helper.put("TemplateURL", "$(user)/writer2xhtml-template.xhtml"); + helper.put("StyleSheetURL", "$(user)/writer2xhtml-styles.css"); + } + + saveNumericOptionAsPercentage(xProps, helper, "Scaling", "scaling"); + saveNumericOptionAsPercentage(xProps, helper, "ColumnScaling", "column_scaling"); + saveCheckBoxOption(xProps, helper, "RelativeFontSize", "relative_font_size"); + saveNumericOptionAsPercentage(xProps, helper, "FontScaling", "font_scaling"); + saveCheckBoxOption(xProps, helper, "UseDefaultFont", "use_default_font"); + saveTextFieldOption(xProps, helper, "DefaultFontName", "default_font_name"); + saveCheckBoxOption(xProps, helper, "ConvertToPx", "convert_to_px"); + saveCheckBoxOption(xProps, helper, "OriginalImageSize", "original_image_size"); + + // Special content + saveCheckBoxOption(xProps, helper, "DisplayHiddenText", "display_hidden_text"); + saveCheckBoxOption(xProps, helper, "Notes", "notes"); + saveCheckBoxOption(xProps, helper, "UseDublinCore", "use_dublin_core"); + + // AutoCorrect + saveCheckBoxOption(xProps, helper, "IgnoreHardLineBreaks", "ignore_hard_line_breaks"); + saveCheckBoxOption(xProps, helper, "IgnoreEmptyParagraphs", "ignore_empty_paragraphs"); + saveCheckBoxOption(xProps, helper, "IgnoreDoubleSpaces", "ignore_double_spaces"); + + // Files + boolean bSplit = saveCheckBoxOption(xProps, "Split"); + short nSplitLevel = saveListBoxOption(xProps, "SplitLevel"); + if (!isLocked("split_level")) { + if (bSplit) { + helper.put("split_level",Integer.toString(nSplitLevel+1)); + } + else { + helper.put("split_level","0"); + } + } + + boolean bUsePageBreakSplit = saveCheckBoxOption(xProps, "UsePageBreakSplit"); + short nPageBreakSplit = saveListBoxOption(xProps, "PageBreakSplit"); + if (!isLocked("page_break_split")) { + if (bUsePageBreakSplit) { + switch (nPageBreakSplit) { + case 0: helper.put("page_break_split", "styles"); break; + case 1: helper.put("page_break_split", "explicit"); break; + case 2: helper.put("page_break_split", "all"); + } + } + else { + helper.put("page_break_split","none"); + } + } + + boolean bUseSplitAfter = saveCheckBoxOption(xProps, "UseSplitAfter"); + int nSplitAfter = saveNumericOption(xProps, "SplitAfter"); + if (!isLocked("split_after")) { + if (bUseSplitAfter) { + helper.put("split_after", nSplitAfter); + } + else { + helper.put("split_after", 0); + } + } + + // Table of contents + short nExternalTocDepth = saveListBoxOption(xProps, "ExternalTocDepth"); + helper.put("external_toc_depth", nExternalTocDepth+1); + saveCheckBoxOption(xProps, "IncludeToc"); + } + + + // Implement XDialogEventHandler + @Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) { + if (sMethod.equals("ConfigChange")) { + updateLockedOptions(); + enableControls(); + } + else if (sMethod.equals("RelativeFontSizeChange")) { + relativeFontSizeChange(); + } + else if (sMethod.equals("UseDefaultFontChange")) { + useDefaultFontChange(); + } + else if (sMethod.equals("SplitChange")) { + splitChange(); + } + else if (sMethod.equals("UsePageBreakSplitChange")) { + usePageBreakSplitChange(); + } + else if (sMethod.equals("UseSplitAfterChange")) { + useSplitAfterChange(); + } + return true; + } + + @Override public String[] getSupportedMethodNames() { + String[] sNames = { "ConfigChange", "RelativeFontSizeChange", "UseDefaultFontChange", + "SplitChange", "UsePageBreakSplitChange", "UseSplitAfterChange" }; + return sNames; + } + + private void enableControls() { + // Style + setControlEnabled("ScalingLabel",!isLocked("scaling")); + setControlEnabled("Scaling",!isLocked("scaling")); + setControlEnabled("ColumnScalingLabel",!isLocked("column_scaling")); + setControlEnabled("ColumnScaling",!isLocked("column_scaling")); + + boolean bRelativeFontSize = getCheckBoxStateAsBoolean("RelativeFontSize"); + setControlEnabled("RelativeFontSize",!isLocked("relative_font_size")); + setControlEnabled("FontScalingLabel", !isLocked("font_scaling") && bRelativeFontSize); + setControlEnabled("FontScaling",!isLocked("font_scaling") && bRelativeFontSize); + setControlEnabled("FontScalingPercentLabel", !isLocked("font_scaling") && bRelativeFontSize); + + boolean bUseDefaultFont = getCheckBoxStateAsBoolean("UseDefaultFont"); + setControlEnabled("UseDefaultFont",!isLocked("use_default_font")); + setControlEnabled("DefaultFontNameLabel",!isLocked("default_font_name") && bUseDefaultFont); + setControlEnabled("DefaultFontName",!isLocked("default_font_name") && bUseDefaultFont); + + setControlEnabled("DisplayHiddenText",!isLocked("display_hidden_text")); + setControlEnabled("ConvertToPx",!isLocked("convert_to_px")); + setControlEnabled("OriginalImageSize",!isLocked("original_image_size")); + + // Special content + setControlEnabled("Notes",!isLocked("notes")); + setControlEnabled("UseDublinCore",!isLocked("use_dublin_core")); + + // AutoCorrect + setControlEnabled("IgnoreHardLineBreaks",!isLocked("ignore_hard_line_breaks")); + setControlEnabled("IgnoreEmptyParagraphs",!isLocked("ignore_empty_paragraphs")); + setControlEnabled("IgnoreDoubleSpaces",!isLocked("ignore_double_spaces")); + + // Files + boolean bSplit = getCheckBoxStateAsBoolean("Split"); + setControlEnabled("Split",!isLocked("split_level")); + setControlEnabled("SplitLevelLabel",!isLocked("split_level") && bSplit); + setControlEnabled("SplitLevel",!isLocked("split_level") && bSplit); + + boolean bUsePageBreakSplit = getCheckBoxStateAsBoolean("UsePageBreakSplit"); + setControlEnabled("UsePageBreakSplit",!isLocked("page_break_split")); + setControlEnabled("PageBreakSplitLabel",!isLocked("page_break_split") && bUsePageBreakSplit); + setControlEnabled("PageBreakSplit",!isLocked("page_break_split") && bUsePageBreakSplit); + + boolean bUseSplitAfter = getCheckBoxStateAsBoolean("UseSplitAfter"); + setControlEnabled("UseSplitAfter",!isLocked("split_after")); + setControlEnabled("SplitAfterLabel",!isLocked("split_after") && bUseSplitAfter); + setControlEnabled("SplitAfter",!isLocked("split_after") && bUseSplitAfter); + + // Table of contents + setControlEnabled("ExternalTocDepthLabel", !isLocked("external_toc_depth")); + setControlEnabled("ExternalTocDepth", !isLocked("external_toc_depth")); + setControlEnabled("IncludeToc", !isLocked("include_toc")); + } + + private void relativeFontSizeChange() { + if (!isLocked("font_scaling")) { + boolean bState = getCheckBoxStateAsBoolean("RelativeFontSize"); + setControlEnabled("FontScalingLabel", bState); + setControlEnabled("FontScaling", bState); + setControlEnabled("FontScalingPercentLabel", bState); + } + } + + private void useDefaultFontChange() { + if (!isLocked("default_font_name")) { + boolean bState = getCheckBoxStateAsBoolean("UseDefaultFont"); + setControlEnabled("DefaultFontNameLabel", bState); + setControlEnabled("DefaultFontName", bState); + } + } + + private void splitChange() { + if (!isLocked("split_level")) { + boolean bState = getCheckBoxStateAsBoolean("Split"); + setControlEnabled("SplitLevelLabel",bState); + setControlEnabled("SplitLevel",bState); + } + } + + private void usePageBreakSplitChange() { + if (!isLocked("page_break_split")) { + boolean bState = getCheckBoxStateAsBoolean("UsePageBreakSplit"); + setControlEnabled("PageBreakSplitLabel",bState); + setControlEnabled("PageBreakSplit",bState); + } + } + + private void useSplitAfterChange() { + if (!isLocked("split_after")) { + boolean bState = getCheckBoxStateAsBoolean("UseSplitAfter"); + setControlEnabled("SplitAfterLabel",bState); + setControlEnabled("SplitAfter",bState); + } + } + + + +} diff --git a/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java b/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java index 2e639ab..447e33a 100644 --- a/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java +++ b/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-03-22) + * Version 1.2 (2010-12-28) * */ @@ -90,6 +90,12 @@ public class W2XRegistration { multiFactory, regKey); } + else if (implName.equals(EpubOptionsDialog.__implementationName)) { + xSingleServiceFactory = FactoryHelper.getServiceFactory(EpubOptionsDialog.class, + EpubOptionsDialog.__serviceName, + multiFactory, + regKey); + } else if (implName.equals(ConfigurationDialog.__implementationName)) { xSingleServiceFactory = FactoryHelper.getServiceFactory(ConfigurationDialog.class, ConfigurationDialog.__serviceName, @@ -120,7 +126,9 @@ public class W2XRegistration { XhtmlOptionsDialogXsl.__serviceName, regKey) & FactoryHelper.writeRegistryServiceInfo(XhtmlOptionsDialogCalc.__implementationName, XhtmlOptionsDialogCalc.__serviceName, regKey) & - FactoryHelper.writeRegistryServiceInfo(ConfigurationDialog.__implementationName, + FactoryHelper.writeRegistryServiceInfo(EpubOptionsDialog.__implementationName, + EpubOptionsDialog.__serviceName, regKey) & + FactoryHelper.writeRegistryServiceInfo(ConfigurationDialog.__implementationName, ConfigurationDialog.__serviceName, regKey); } } diff --git a/source/java/writer2latex/api/Converter.java b/source/java/writer2latex/api/Converter.java index 2457f9e..92f6c4a 100644 --- a/source/java/writer2latex/api/Converter.java +++ b/source/java/writer2latex/api/Converter.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-04-12) + * Version 1.2 (2010-12-21) * */ @@ -90,6 +90,29 @@ public interface Converter { */ public void readStyleSheet(File file) throws IOException; + /** Read a resource to include with the converted document. + * A resource can be any (binary) file and will be placed in the same directory as + * the style sheet + * + * @param is an InputStream from which to read the resource + * @param sFileName the file name to use for the resource + * @param sMediaType the media type of the resource + * @throws IOException if some exception occurs while reading the resource + */ + public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException; + + /** Read a style sheet to include with the converted document. + * A resource can be any (binary) file and will be placed in the same directory as + * the style sheet + * + * @param file a file from which to read the style sheet + * @param sFileName the file name to use for the resource + * @param sMediaType the media type of the resource + * @throws IOException if the file does not exist or some exception occurs + * while reading the resource + */ + public void readResource(File file, String sFileName, String sMediaType) throws IOException; + /** Convert a document * * @param is an InputStream from which to read the source document. diff --git a/source/java/writer2latex/base/ConverterBase.java b/source/java/writer2latex/base/ConverterBase.java index 08cac27..e1624b1 100644 --- a/source/java/writer2latex/base/ConverterBase.java +++ b/source/java/writer2latex/base/ConverterBase.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-04-12) + * Version 1.2 (2010-12-21) * */ @@ -81,6 +81,12 @@ public abstract class ConverterBase implements Converter { // Provide a do noting fallback method public void readStyleSheet(File file) throws IOException { } + // Provide a do noting fallback method + public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException { } + + // Provide a do noting fallback method + public void readResource(File file, String sFileName, String sMediaType) throws IOException { } + public ConverterResult convert(File source, String sTargetFileName) throws FileNotFoundException,IOException { return convert(new FileInputStream(source), sTargetFileName); } diff --git a/source/java/writer2latex/epub/EPUBWriter.java b/source/java/writer2latex/epub/EPUBWriter.java index 0f70b65..b3a8118 100644 --- a/source/java/writer2latex/epub/EPUBWriter.java +++ b/source/java/writer2latex/epub/EPUBWriter.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * version 1.2 (2010-12-15) + * version 1.2 (2010-12-20) * */ @@ -30,7 +30,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; -import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -70,10 +69,7 @@ public class EPUBWriter implements OutputFile { return true; } - public void write(OutputStream os) throws IOException { - // Create a universal unique ID - String sUUID = UUID.randomUUID().toString(); - + public void write(OutputStream os) throws IOException { ZipOutputStream zos = new ZipOutputStream(os); // Write uncompressed MIME type as first entry @@ -93,14 +89,14 @@ public class EPUBWriter implements OutputFile { zos.closeEntry(); // Then manifest - OutputFile manifest = new OPFWriter(xhtmlResult, sUUID, config.xhtmlUseDublinCore()); + OPFWriter manifest = new OPFWriter(xhtmlResult, config.xhtmlUseDublinCore()); ZipEntry manifestEntry = new ZipEntry("OEBPS/book.opf"); zos.putNextEntry(manifestEntry); writeZipEntry(manifest,zos); zos.closeEntry(); // And content table - OutputFile ncx = new NCXWriter(xhtmlResult, sUUID); + OutputFile ncx = new NCXWriter(xhtmlResult, manifest.getUid()); ZipEntry ncxEntry = new ZipEntry("OEBPS/book.ncx"); zos.putNextEntry(ncxEntry); writeZipEntry(ncx,zos); diff --git a/source/java/writer2latex/epub/OPFWriter.java b/source/java/writer2latex/epub/OPFWriter.java index 8e28b5f..928c55e 100644 --- a/source/java/writer2latex/epub/OPFWriter.java +++ b/source/java/writer2latex/epub/OPFWriter.java @@ -20,14 +20,16 @@ * * All Rights Reserved. * - * version 1.2 (2010-12-16) + * version 1.2 (2010-12-20) * */ package writer2latex.epub; +import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.UUID; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -47,8 +49,9 @@ import writer2latex.xmerge.NewDOMDocument; /** This class writes an OPF-file for an EPUB document (see http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html). */ public class OPFWriter extends NewDOMDocument { + private String sUID=null; - public OPFWriter(ConverterResult cr, String sUUID, boolean bUseDublinCore) { + public OPFWriter(ConverterResult cr, boolean bUseDublinCore) { super("book", "opf"); // create DOM @@ -76,123 +79,113 @@ public class OPFWriter extends NewDOMDocument { metadata.setAttribute("xmlns:opf", "http://www.idpf.org/2007/opf"); pack.appendChild(metadata); - Element title = contentDOM.createElement("dc:title"); - metadata.appendChild(title); - title.appendChild(contentDOM.createTextNode(cr.getMetaData().getTitle())); - - Element language = contentDOM.createElement("dc:language"); - metadata.appendChild(language); - language.appendChild(contentDOM.createTextNode(cr.getMetaData().getLanguage())); + appendElement(contentDOM, metadata, "dc:title", cr.getMetaData().getTitle()); + appendElement(contentDOM, metadata, "dc:language", cr.getMetaData().getLanguage()); // Additional meta data if (bUseDublinCore) { // Subject and keywords in ODF both map to Dublin core subjects if (cr.getMetaData().getSubject().length()>0) { - Element subject = contentDOM.createElement("dc:subject"); - metadata.appendChild(subject); - subject.appendChild(contentDOM.createTextNode(cr.getMetaData().getSubject())); + appendElement(contentDOM, metadata, "dc:subject", cr.getMetaData().getSubject()); } if (cr.getMetaData().getKeywords().length()>0) { String[] sKeywords = cr.getMetaData().getKeywords().split(","); for (String sKeyword : sKeywords) { - Element subject = contentDOM.createElement("dc:subject"); - metadata.appendChild(subject); - subject.appendChild(contentDOM.createTextNode(sKeyword.trim())); + appendElement(contentDOM, metadata, "dc:subject", sKeyword.trim()); } } if (cr.getMetaData().getDescription().length()>0) { - Element description = contentDOM.createElement("dc:description"); - metadata.appendChild(description); - description.appendChild(contentDOM.createTextNode(cr.getMetaData().getDescription())); + appendElement(contentDOM, metadata, "dc:description", cr.getMetaData().getDescription()); } } // User defined meta data // The identifier, creator, contributor and date has an optional attribute and there may be multiple instances of - // the first three. The key can be in any of the forms name, name.attribute, name.attribute.id, name..id + // the first three. The key must be in the form name[id][.attribute] // where the id is some unique id amongst the instances with the same name - // Thus you can have e.g. creator.aut.1="John Doe" and creator.aut.2="Jane Doe" + // Furthermore the instances will be sorted on the id + // Thus you can have e.g. creator1.aut="John Doe" and creator2.aut="Jane Doe", and "John Doe" will be the first author boolean bHasIdentifier = false; boolean bHasCreator = false; boolean bHasDate = false; - Map userDefined = cr.getMetaData().getUserDefinedMetaData(); - for (String sKey : userDefined.keySet()) { + // First rearrange the user-defined meta data + Map userDefinedMetaData = cr.getMetaData().getUserDefinedMetaData(); + Map dc = new HashMap(); + for (String sKey : userDefinedMetaData.keySet()) { if (sKey.length()>0) { - String[] sKeyElements = sKey.toLowerCase().split("\\."); - String sValue = userDefined.get(sKey); - if ("identifier".equals(sKeyElements[0])) { - Element identifier = contentDOM.createElement("dc:identifier"); - identifier.setAttribute("id", "BookId"); - if (sKeyElements.length>1 && sKeyElements[1].length()>0) { - identifier.setAttribute("opf:scheme", sKeyElements[1]); - } - metadata.appendChild(identifier); - identifier.appendChild(contentDOM.createTextNode(sValue)); - bHasIdentifier = true; + String[] sValue = new String[2]; + sValue[0] = userDefinedMetaData.get(sKey); + String sNewKey; + int nDot = sKey.indexOf("."); + if (nDot>0) { + sNewKey = sKey.substring(0, nDot).toLowerCase(); + sValue[1] = sKey.substring(nDot+1); } - else if ("creator".equals(sKeyElements[0])) { - Element creator = contentDOM.createElement("dc:creator"); - if (sKeyElements.length>1 && sKeyElements[1].length()>0) { - creator.setAttribute("opf:role", sKeyElements[1]); - } - metadata.appendChild(creator); - creator.appendChild(contentDOM.createTextNode(sValue)); - bHasCreator = true; + else { + sNewKey = sKey.toLowerCase(); + sValue[1] = null; } - else if ("contributor".equals(sKeyElements[0])) { - Element contributor = contentDOM.createElement("dc:contributor"); - if (sKeyElements.length>1 && sKeyElements[1].length()>0) { - contributor.setAttribute("opf:role", sKeyElements[1]); - } - metadata.appendChild(contributor); - contributor.appendChild(contentDOM.createTextNode(sValue)); + dc.put(sNewKey, sValue); + } + } + // Then export it + String[] sKeys = Misc.sortStringSet(dc.keySet()); + for (String sKey : sKeys) { + String sValue = dc.get(sKey)[0]; + String sAttributeValue = dc.get(sKey)[1]; + if (sKey.startsWith("identifier")) { + Element identifier = appendElement(contentDOM, metadata, "dc:identifier", sValue); + if (!bHasIdentifier) { // The first identifier is the unique ID + identifier.setAttribute("id", "BookId"); + sUID = sValue; } - else if ("date".equals(sKeyElements[0])) { - Element date = contentDOM.createElement("dc:date"); - if (sKeyElements.length>1 && sKeyElements[1].length()>0) { - date.setAttribute("opf:event", sKeyElements[1]); - } - metadata.appendChild(date); - date.appendChild(contentDOM.createTextNode(sValue)); - bHasDate = true; + if (sAttributeValue!=null) { + identifier.setAttribute("opf:scheme", sAttributeValue); } - else if (sKeyElements.length==1) { - // Remaining meta data elements must be unique - if ("publisher".equals(sKeyElements[0])) { - Element publisher = contentDOM.createElement("dc:publisher"); - metadata.appendChild(publisher); - publisher.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("type".equals(sKeyElements[0])) { - Element type = contentDOM.createElement("dc:type"); - metadata.appendChild(type); - type.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("format".equals(sKeyElements[0])) { - Element format = contentDOM.createElement("dc:format"); - metadata.appendChild(format); - format.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("source".equals(sKeyElements[0])) { - Element source = contentDOM.createElement("dc:source"); - metadata.appendChild(source); - source.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("relation".equals(sKeyElements[0])) { - Element relation = contentDOM.createElement("dc:relation"); - metadata.appendChild(relation); - relation.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("coverage".equals(sKeyElements[0])) { - Element coverage = contentDOM.createElement("dc:coverage"); - metadata.appendChild(coverage); - coverage.appendChild(contentDOM.createTextNode(sValue)); - } - else if ("rights".equals(sKeyElements[0])) { - Element rights = contentDOM.createElement("dc:rights"); - metadata.appendChild(rights); - rights.appendChild(contentDOM.createTextNode(sValue)); - } + bHasIdentifier = true; + } + else if (sKey.startsWith("creator")) { + Element creator = appendElement(contentDOM, metadata, "dc:creator", sValue); + if (sAttributeValue!=null) { + creator.setAttribute("opf:role", sAttributeValue); + } + bHasCreator = true; + } + else if (sKey.startsWith("contributor")) { + Element contributor = appendElement(contentDOM, metadata, "dc:contributor", sValue); + if (sAttributeValue!=null) { + contributor.setAttribute("opf:role", sAttributeValue); + } + } + else if (sKey.startsWith("date")) { + Element date = appendElement(contentDOM, metadata, "dc:date", sValue); + if (sAttributeValue!=null) { + date.setAttribute("opf:event", sAttributeValue); + } + bHasDate = true; + } + // Remaining properties must be unique and has not attributes, hence + else if (sAttributeValue==null) { + if ("publisher".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:publisher", sValue); + } + else if ("type".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:type", sValue); + } + else if ("format".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:format", sValue); + } + else if ("source".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:source", sValue); + } + else if ("relation".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:relation", sValue); + } + else if ("coverage".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:coverage", sValue); + } + else if ("rights".equals(sKey)) { + appendElement(contentDOM, metadata, "dc:rights", sValue); } } } @@ -200,21 +193,18 @@ public class OPFWriter extends NewDOMDocument { // Fall back values for creator and date if (bUseDublinCore) { if (!bHasIdentifier) { - Element identifier = contentDOM.createElement("dc:identifier"); + // Create a universal unique ID + sUID = UUID.randomUUID().toString(); + Element identifier = appendElement(contentDOM, metadata, "dc:identifier", sUID); identifier.setAttribute("id", "BookId"); identifier.setAttribute("opf:scheme", "UUID"); - metadata.appendChild(identifier); - identifier.appendChild(contentDOM.createTextNode(sUUID)); } if (!bHasCreator && cr.getMetaData().getCreator().length()>0) { - Element creator = contentDOM.createElement("dc:creator"); - metadata.appendChild(creator); - creator.appendChild(contentDOM.createTextNode(cr.getMetaData().getCreator())); + appendElement(contentDOM, metadata, "dc:creator", cr.getMetaData().getCreator()); } if (!bHasDate && cr.getMetaData().getDate().length()>0) { - Element date = contentDOM.createElement("dc:date"); - metadata.appendChild(date); - date.appendChild(contentDOM.createTextNode(cr.getMetaData().getDate())); + // TODO: Support meta:creation-date? + appendElement(contentDOM, metadata, "dc:date", cr.getMetaData().getDate()); } } @@ -269,6 +259,22 @@ public class OPFWriter extends NewDOMDocument { setContentDOM(contentDOM); } + /** Get the unique ID associated with this EPUB document (either collected from the user-defined + * meta data or a generated UUID) + * + * @return the ID + */ + public String getUid() { + return sUID; + } + + private Element appendElement(Document contentDOM, Element node, String sTagName, String sContent) { + Element child = contentDOM.createElement(sTagName); + node.appendChild(child); + child.appendChild(contentDOM.createTextNode(sContent)); + return child; + } + private void addGuideReference(Document contentDOM, Element guide, String sType, ContentEntry entry) { if (entry!=null) { Element reference = contentDOM.createElement("reference"); diff --git a/source/java/writer2latex/util/Misc.java b/source/java/writer2latex/util/Misc.java index 2941721..a4c5654 100644 --- a/source/java/writer2latex/util/Misc.java +++ b/source/java/writer2latex/util/Misc.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-12-08) + * Version 1.2 (2010-12-19) * */ @@ -34,12 +34,14 @@ import java.io.UnsupportedEncodingException; import java.lang.Math; import java.net.URLEncoder; import java.net.URLDecoder; +import java.text.Collator; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Set; //import java.util.Hashtable; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -357,6 +359,15 @@ public class Misc{ return buf.toString(); } + // Utility method to return a sorted string array based on a set + public static String[] sortStringSet(Set theSet) { + String[] theArray = theSet.toArray(new String[theSet.size()]); + Collator collator = Collator.getInstance(); + Arrays.sort(theArray, collator); + return theArray; + } + + /* Utility method that url encodes a string */ public static String urlEncode(String s) { try { diff --git a/source/java/writer2latex/xhtml/Converter.java b/source/java/writer2latex/xhtml/Converter.java index ee030a0..ad0fcf4 100644 --- a/source/java/writer2latex/xhtml/Converter.java +++ b/source/java/writer2latex/xhtml/Converter.java @@ -20,7 +20,7 @@ * * All Rights Reserved. * - * Version 1.2 (2010-11-22) + * Version 1.2 (2010-12-21) * */ @@ -28,8 +28,10 @@ package writer2latex.xhtml; import java.io.File; import java.io.FileInputStream; +import java.util.HashSet; import java.util.ListIterator; import java.util.LinkedList; +import java.util.Set; import java.util.Vector; import java.util.Hashtable; import java.util.Iterator; @@ -82,8 +84,9 @@ public class Converter extends ConverterBase { // The template private XhtmlDocument template = null; - // The included style sheet + // The included style sheet and associated resources private CssDocument styleSheet = null; + private Set resources = new HashSet(); // The xhtml output file(s) protected int nType = XhtmlDocument.XHTML10; // the doctype @@ -109,7 +112,7 @@ public class Converter extends ConverterBase { this.nType = nType; } - // override methods to read templates and style sheets + // override methods to read templates, style sheets and resources @Override public void readTemplate(InputStream is) throws IOException { template = new XhtmlDocument("Template",nType); template.read(is); @@ -129,6 +132,16 @@ public class Converter extends ConverterBase { @Override public void readStyleSheet(File file) throws IOException { readStyleSheet(new FileInputStream(file)); } + + @Override public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException { + ResourceDocument doc = new ResourceDocument(sFileName, sMediaType); + doc.read(is); + resources.add(doc); + } + + @Override public void readResource(File file, String sFileName, String sMediaType) throws IOException { + readResource(new FileInputStream(file), sFileName, sMediaType); + } protected StyleConverter getStyleCv() { return styleCv; } @@ -252,7 +265,11 @@ public class Converter extends ConverterBase { // Add included style sheet, if any - and we are creating OPS content if (bOPS && styleSheet!=null) { + // TODO: Move to subfolder converterResult.addDocument(styleSheet); + for (ResourceDocument doc : resources) { + converterResult.addDocument(doc); + } } // Export styles (temp.) diff --git a/source/java/writer2latex/xhtml/ResourceDocument.java b/source/java/writer2latex/xhtml/ResourceDocument.java new file mode 100644 index 0000000..251fd29 --- /dev/null +++ b/source/java/writer2latex/xhtml/ResourceDocument.java @@ -0,0 +1,79 @@ +/************************************************************************ + * + * ResourceDocument.java + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Copyright: 2002-2010 by Henrik Just + * + * All Rights Reserved. + * + * Version 1.2 (2010-12-21) + * + */ + +package writer2latex.xhtml; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import writer2latex.api.OutputFile; +import writer2latex.util.Misc; + +/** + * An implementation of OutputFile for resource documents. + * (A resource document is an arbitrary binary file to include in the converter result) + */ +public class ResourceDocument implements OutputFile { + + // Content + private String sFileName; + private String sMediaType; + private byte[] content; + + /** + * Constructor (creates an empty document) + * @param sFileName Document name. + * @param sMediaType the media type + */ + public ResourceDocument(String sFileName, String sMediaType) { + this.sFileName = sFileName; + this.sMediaType = sMediaType; + content = new byte[0]; + } + + public String getFileName() { + return sFileName; + } + + public String getMIMEType() { + return sMediaType; + } + + public boolean isMasterDocument() { + return false; + } + + public void write(OutputStream os) throws IOException { + os.write(content); + } + + public void read(InputStream is) throws IOException { + content = Misc.inputStreamToByteArray(is); + } + + +} \ No newline at end of file diff --git a/source/oxt/writer2xhtml/Options.xcs b/source/oxt/writer2xhtml/Options.xcs index 0736929..5124492 100644 --- a/source/oxt/writer2xhtml/Options.xcs +++ b/source/oxt/writer2xhtml/Options.xcs @@ -12,6 +12,11 @@ + + + + + @@ -44,6 +49,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/oxt/writer2xhtml/Options.xcu b/source/oxt/writer2xhtml/Options.xcu index ab5ed63..ef66302 100644 --- a/source/oxt/writer2xhtml/Options.xcu +++ b/source/oxt/writer2xhtml/Options.xcu @@ -54,6 +54,80 @@ + + + 0 + + + + + + true + + + 100 + + + 100 + + + false + + + false + + + 100 + + + true + + + + + + false + + + true + + + true + + + false + + + false + + + false + + + false + + + 1 + + + false + + + 0 + + + true + + + 150 + + + 0 + + + true + + 0 diff --git a/source/oxt/writer2xhtml/W2XDialogs2/EpubOptions.xdl b/source/oxt/writer2xhtml/W2XDialogs2/EpubOptions.xdl new file mode 100755 index 0000000..b967359 --- /dev/null +++ b/source/oxt/writer2xhtml/W2XDialogs2/EpubOptions.xdl @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/oxt/writer2xhtml/W2XDialogs2/dialog.xlb b/source/oxt/writer2xhtml/W2XDialogs2/dialog.xlb index b0d250e..7ca2e70 100644 --- a/source/oxt/writer2xhtml/W2XDialogs2/dialog.xlb +++ b/source/oxt/writer2xhtml/W2XDialogs2/dialog.xlb @@ -12,4 +12,5 @@ + \ No newline at end of file diff --git a/source/oxt/writer2xhtml/help/en/help.tree b/source/oxt/writer2xhtml/help/en/help.tree index 51ec2bd..bbb6cad 100644 --- a/source/oxt/writer2xhtml/help/en/help.tree +++ b/source/oxt/writer2xhtml/help/en/help.tree @@ -4,6 +4,7 @@ XHTML and EPUB Export (Writer) XHTML Export (Calc) + EPUB meta data (Writer) Introduction General diff --git a/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/epub.xhp b/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/epub.xhp new file mode 100644 index 0000000..0f1a298 --- /dev/null +++ b/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/epub.xhp @@ -0,0 +1,99 @@ + + + + + EPUB meta data + org.openoffice.da.writer2xhtml.oxt/epub.xhp + + + + + EPUB meta data + + The EPUB standard specifies a number of meta data elements not supported by ODF. + Writer2xhtml supports these elements using user-defined meta data. To add user-defined meta data choose + File-Properties, User-defined properties. The following properties are supported: + + + Identifier: Each EPUB document must have a unique ID. + Normally Writer2xhtml generates a Universal Unique ID (UUID) for this purpose, but you may override this with + your own ID. + To do this add a new property, enter Identifier + (case is not important) as name and the ID as value. + An identifier may follow a specific identification scheme, e.g. ISBN. + To specify an identification scheme, append this to the name separated by a period, e.g. Identifier.ISBN. + + It is possible to have several identifiers, in this case append a number + to the name, e.g. Identifier1.ISBN and Identifier2. The first identifier is used as the unique ID. + + + + Creator: A primary creator or author of the publication. + + Enter Creator as name and the creator's name as value. + + A creator may have a special role, you can specify this with a three + letter code after the word creator, e.g. creator.aut for the author or creator.ill + for the illustrator. For the complete list of three letter codes see the + EPUB specification. + You can define several creators, in this case add a number to the word creator, + e.g. creator1.aut and creator2. The creators will be sorted according to the numbers. + Note that some readers may only present the first creator. + + + + Contributor: A party whose contribution to the publication is secondary + to those named in creator elements. Otherwise it is handled like Creator, and the same rules apply. + + + + Date: Date of publication. The date must be in the format YYYY-MM-DD + (year-month-date) or more generally in the format specified in + http://www.w3.org/TR/NOTE-datetime. + + A date may be associated with a special event such as creation, + publication or modification. To define this, add the event after the word date, e.g. date.publication. + + You can give several dates, in this case add a number to the word date, + e.g. date1.creation, date2.modification. + + + + You can only have one instance of the remaining properties, + hence they cannot be numbered. Also no additional data can be appended to the name. + + + + Publisher: The publisher of the document. + + + + Type: Terms describing general categories, functions, genres, or aggregation levels for content. + + + + Format: The media type or dimensions of the resource. + + + + Source: Information regarding a prior resource from which the publication was derived. + + + + Relation: An identifier of an auxiliary resource and its relationship to the publication. + + + + Coverage: The extent or scope of the publication’s content. + + + + Rights: A statement about rights, or a reference to one. + + + + + + + + diff --git a/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/export.xhp b/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/export.xhp index 5366530..dd582eb 100644 --- a/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/export.xhp +++ b/source/oxt/writer2xhtml/help/en/org.openoffice.da.writer2xhtml.oxt/export.xhp @@ -114,6 +114,9 @@ are exported using the Dublin Core standard. + The EPUB format supports a number of additional meta data elements. + You can define these using user-defined properties. + AutoCorrect diff --git a/source/oxt/writer2xhtml/w2x_filters.xcu b/source/oxt/writer2xhtml/w2x_filters.xcu index e1ab97f..0fbda4a 100644 --- a/source/oxt/writer2xhtml/w2x_filters.xcu +++ b/source/oxt/writer2xhtml/w2x_filters.xcu @@ -91,7 +91,7 @@ 0 writer_epub_File com.sun.star.text.TextDocument - org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialog + org.openoffice.da.comp.writer2xhtml.EpubOptionsDialog org.openoffice.da.comp.writer2xhtml.W2XExportFilter unused com.sun.star.comp.Writer.XMLOasisImporter com.sun.star.comp.Writer.XMLOasisExporter staroffice/sxw application/epub+zip com.sun.star.comp.Writer.XmlFilterAdaptor