Support EPUB style resources (embed images and fonts used in custom CSS file)

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@108 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2011-06-07 09:01:15 +00:00
parent 2ad8f3b7a2
commit ef05312e21
14 changed files with 342 additions and 97 deletions
source

View file

@ -2,6 +2,14 @@ Changelog for Writer2LaTeX version 1.0 -> 1.2
---------- version 1.1.8 ----------
[w2x] The EPUB export now supports additional resource files (e.g. images, fonts) to the custom style sheet
- using the readResource method of the converter API
- using the -resource method of the command line application
- using the ResourceURL or Resources property of the filter API
- by specifying the resource files in a custom configuration
[all] API change: Added the method readResource to the Converter interface (only used by EPUB export currently)
[w2x] Crossed out headings are ignored in EPUB export, but retained in the external toc
[all] Added Farsi translation from Mostafa Barmshory

Binary file not shown.

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2010 by Henrik Just
* Copyright: 2002-2011 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.2 (2010-12-09)
* Version 1.2 (2011-06-06)
*
*/
@ -79,13 +79,13 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta
protected XComponentContext xContext;
// File picker wrapper
private FilePicker filePicker = null;
protected FilePicker filePicker = null;
// UNO simple file access service
protected XSimpleFileAccess2 sfa2 = null;
// UNO path substitution
private XStringSubstitution xPathSub = null;
protected XStringSubstitution xPathSub = null;
// The configuration implementation
protected Config config;
@ -287,6 +287,38 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta
config.setOption(sConfigName, sConfigValues[dlg.getListBoxSelectedItem(sListBoxName)]);
}
// Method to get a named dialog
protected XDialog getDialog(String sDialogName) {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext(
"com.sun.star.awt.DialogProvider2", xContext);
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+sDialogName+"?location=application";
return xDialogProvider.createDialog(sDialogUrl);
}
catch (Exception e) {
return null;
}
}
// Method to display delete dialog
protected boolean deleteItem(String sName) {
XDialog xDialog=getDialog(getDialogLibraryName()+".DeleteDialog");
if (xDialog!=null) {
DialogAccess ddlg = new DialogAccess(xDialog);
String sLabel = ddlg.getLabelText("DeleteLabel");
sLabel = sLabel.replaceAll("%s", sName);
ddlg.setLabelText("DeleteLabel", sLabel);
boolean bDelete = xDialog.execute()==ExecutableDialogResults.OK;
xDialog.endExecute();
return bDelete;
}
return false;
}
}
protected abstract class CustomFileHandler extends PageHandler {
@ -373,7 +405,7 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta
// Helpers for sfa2
// Checks that the file exists
private boolean fileExists(String sFileName) {
protected boolean fileExists(String sFileName) {
try {
return sfa2!=null && sfa2.exists(sFileName);
}
@ -385,7 +417,7 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta
}
// Delete a file if it exists, return true on success
private boolean killFile(String sFileName) {
protected boolean killFile(String sFileName) {
try {
if (sfa2!=null && sfa2.exists(sFileName)) {
sfa2.kill(sFileName);
@ -453,35 +485,6 @@ public abstract class ConfigurationDialogBase extends WeakBase implements XConta
protected abstract class UserListPageHandler extends PageHandler {
// Methods to handle user controlled lists
protected XDialog getDialog(String sDialogName) {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext(
"com.sun.star.awt.DialogProvider2", xContext);
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+sDialogName+"?location=application";
return xDialogProvider.createDialog(sDialogUrl);
}
catch (Exception e) {
return null;
}
}
private boolean deleteItem(String sName) {
XDialog xDialog=getDialog(getDialogLibraryName()+".DeleteDialog");
if (xDialog!=null) {
DialogAccess ddlg = new DialogAccess(xDialog);
String sLabel = ddlg.getLabelText("DeleteLabel");
sLabel = sLabel.replaceAll("%s", sName);
ddlg.setLabelText("DeleteLabel", sLabel);
boolean bDelete = xDialog.execute()==ExecutableDialogResults.OK;
xDialog.endExecute();
return bDelete;
}
return false;
}
protected boolean deleteCurrentItem(DialogAccess dlg, String sListName) {
String[] sItems = dlg.getListBoxStringItemList(sListName);
short nSelected = dlg.getListBoxSelectedItem(sListName);

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-01-15)
* Version 1.2 (2011-06-07)
*
*/
@ -38,6 +38,7 @@ import com.sun.star.io.XOutputStream;
import com.sun.star.ucb.CommandAbortedException;
import com.sun.star.ucb.XSimpleFileAccess2;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XStringSubstitution;
@ -109,7 +110,7 @@ public class FilterDataParser {
PropertyHelper props = new PropertyHelper(filterData);
// Get the special properties TemplateURL, StyleSheetURL, Resources, ConfigURL and AutoCreate
// Get the special properties TemplateURL, StyleSheetURL, ResourceURL, Resources, ConfigURL and AutoCreate
Object tpl = props.get("TemplateURL");
String sTemplate = null;
if (tpl!=null && AnyConverter.isString(tpl)) {
@ -132,7 +133,19 @@ public class FilterDataParser {
}
}
// This property accepts a semicolon separated list of <mime type>!<file name>!<URL> (not very elegant)
// This property accepts an URL pointing to a folder containing the resources to include
Object resourcedir = props.get("ResourceURL");
String sResourceURL = null;
if (resourcedir!=null && AnyConverter.isString(resourcedir)) {
try {
sResourceURL = substituteVariables(AnyConverter.toString(resourcedir));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
// This property accepts a semicolon separated list of <URL>[[::<file name>]::<mime type>]
Object resources = props.get("Resources");
String[] sResources = null;
if (resources!=null && AnyConverter.isString(resources)) {
@ -218,33 +231,70 @@ public class FilterDataParser {
}
}
// Load the resource from the specified folder URL, if any
if (sfa2!=null && sResourceURL!=null && sResourceURL.length()>0) {
String[] sURLs;
try {
sURLs = sfa2.getFolderContents(sResourceURL, false); // do not include folders
for (String sURL : sURLs) {
XInputStream xIs = sfa2.openFileRead(sURL);
if (xIs!=null) {
String sFileName = sURL.substring(sURL.lastIndexOf('/')+1);
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readResource(is,sFileName,null);
is.close();
xIs.closeInput();
}
}
} catch (IOException e) {
// ignore
} catch (CommandAbortedException e1) {
// ignore
} catch (Exception e1) {
// ignore
}
}
// Load the resources from the specified URLs, if any
if (sfa2!=null && sResources!=null) {
for (String sResource : sResources) {
try {
String[] sParts = sResource.split("!");
// Format is <URL>[[::<file name>]::<mime type>]
String[] sParts = sResource.split("::");
if (sParts.length>0) {
String sURL=sParts[0];
String sFileName;
String sMediaType=null;
if (sParts.length==3) {
// Format is <mime type>!<file name>!<URL>
XInputStream xIs = sfa2.openFileRead(sParts[2]);
sFileName = sParts[1];
sMediaType = sParts[2];
}
else {
sFileName = sURL.substring(sURL.lastIndexOf('/')+1);
if (sParts.length==2) {
sMediaType = sParts[1];
}
}
try {
XInputStream xIs = sfa2.openFileRead(sURL);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readResource(is, sParts[1], sParts[0]);
converter.readResource(is, sFileName, sMediaType);
is.close();
xIs.closeInput();
}
} // otherwise wrong format, ignore
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
} // otherwise wrong format, ignore
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
}
}

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-02-23)
* Version 1.2 (2011-06-07)
*
*/
@ -393,21 +393,39 @@ public abstract class OptionsDialogBase extends DialogBase implements
short nConfig = getListBoxSelectedItem("Config");
int nStdConfigs = getListBoxStringItemList("Config").length - sConfigNames.length;
if (nConfig>=nStdConfigs) { // only handle registry configurations
int i = nConfig-nStdConfigs;
try {
Object config = xNameAccess.getByName(sConfigNames[i]);
XPropertySet xCfgProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
MacroExpander expander = new MacroExpander(xContext);
filterData.put("ConfigURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"ConfigURL")));
filterData.put("TemplateURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"TargetTemplateURL")));
filterData.put("StyleSheetURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"StyleSheetURL")));
// TODO: Resources...
XPropertySetHelper.setPropertyValue(xProps,"ConfigName",sConfigNames[i]);
bFound = true;
}
catch (Exception e) {
}
int i = nConfig-nStdConfigs;
try {
Object config = xNameAccess.getByName(sConfigNames[i]);
XPropertySet xCfgProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
MacroExpander expander = new MacroExpander(xContext);
filterData.put("ConfigURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"ConfigURL")));
filterData.put("TemplateURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"TargetTemplateURL")));
filterData.put("StyleSheetURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"StyleSheetURL")));
// The resources are provided as a set
Object resources = XPropertySetHelper.getPropertyValue(xCfgProps,"Resources");
XNameAccess xResourceNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,resources);
if (xResourceNameAccess!=null) {
StringBuffer buf = new StringBuffer();
String[] sResourceNames = xResourceNameAccess.getElementNames();
for (String sName : sResourceNames) {
Object resource = xResourceNameAccess.getByName(sName);
XPropertySet xResourceProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,resource);
String sURL = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"URL"));
String sFileName = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"FileName"));
String sMediaType = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"MediaType"));
if (buf.length()>0) { buf.append(';'); }
buf.append(sURL).append("::").append(sFileName).append("::").append(sMediaType);
}
filterData.put("Resources",buf.toString());
XPropertySetHelper.setPropertyValue(xProps,"ConfigName",sConfigNames[i]);
bFound = true;
}
}
catch (Exception e) {
}
}
XPropertySetHelper.setPropertyValue(xProps,"Config",nConfig);
if (!bFound) { XPropertySetHelper.setPropertyValue(xProps,"ConfigName",""); }

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-03-08)
* Version 1.2 (2011-06-06)
*
*/
@ -30,11 +30,16 @@ import java.util.Map;
import org.openoffice.da.comp.w2lcommon.filter.ConfigurationDialogBase;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.FilePicker;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.ucb.CommandAbortedException;
import com.sun.star.uno.Exception;
import com.sun.star.uno.XComponentContext;
public class ConfigurationDialog extends ConfigurationDialogBase implements XServiceInfo {
private String sResourceDirName;
// Implement the interface XServiceInfo
@ -70,6 +75,14 @@ public class ConfigurationDialog extends ConfigurationDialogBase implements XSer
public ConfigurationDialog(XComponentContext xContext) {
super(xContext);
// Create the resource dir name
try {
sResourceDirName = xPathSub.substituteVariables("$(user)/writer2xhtml-resources", false);
}
catch (NoSuchElementException e) {
sResourceDirName = "writer2xhtml-resources";
}
pageHandlers.put("General", new GeneralHandler());
pageHandlers.put("Template", new TemplateHandler());
pageHandlers.put("Stylesheets", new StylesheetsHandler());
@ -84,7 +97,8 @@ public class ConfigurationDialog extends ConfigurationDialogBase implements XSer
public String[] getSupportedMethodNames() {
String[] sNames = { "EncodingChange", // General
"CustomTemplateChange", "LoadTemplateClick", // Template
"UseCustomStylesheetChange", "IncludeCustomStylesheetClick", "LoadStylesheetClick", // Stylesheet
"UseCustomStylesheetChange", "IncludeCustomStylesheetClick", "LoadStylesheetClick",
"NewResourceClick", "DeleteResourceClick", // Stylesheet
"StyleFamilyChange", "StyleNameChange", "NewStyleClick", "DeleteStyleClick", "LoadDefaultsClick" // Styles1
};
return sNames;
@ -198,6 +212,11 @@ public class ConfigurationDialog extends ConfigurationDialogBase implements XSer
}
protected void useCustomInner(DialogAccess dlg, boolean bEnable) {
dlg.setControlEnabled("ResourceLabel", bEnable);
dlg.setControlEnabled("Resources", bEnable);
dlg.setControlEnabled("NewResourceButton", bEnable);
dlg.setControlEnabled("DeleteResourceButton", bEnable);
updateResources(dlg);
}
@ -207,6 +226,8 @@ public class ConfigurationDialog extends ConfigurationDialogBase implements XSer
textFieldFromConfig(dlg, "CustomStylesheetURL", "custom_stylesheet");
linkCustomStylesheetChange(dlg);
updateResources(dlg);
}
@Override protected void getControls(DialogAccess dlg) {
@ -227,15 +248,80 @@ public class ConfigurationDialog extends ConfigurationDialogBase implements XSer
linkCustomStylesheetChange(dlg);
return true;
}
else if (sMethod.equals("NewResourceClick")) {
newResourceClick(dlg);
return true;
}
else if (sMethod.equals("DeleteResourceClick")) {
deleteResourceClick(dlg);
return true;
}
return false;
}
private void linkCustomStylesheetChange(DialogAccess dlg) {
private void linkCustomStylesheetChange(DialogAccess dlg) {
boolean bLinkCustomStylesheet = dlg.getCheckBoxStateAsBoolean("LinkCustomStylesheet");
dlg.setControlEnabled("CustomStylesheetURLLabel", bLinkCustomStylesheet);
dlg.setControlEnabled("CustomStylesheetURL", bLinkCustomStylesheet);
}
private void newResourceClick(DialogAccess dlg) {
FilePicker filePicker = new FilePicker(xContext);
String sFileName=filePicker.getPath();
if (sFileName!=null) {
createResourceDir();
String sBaseFileName = sFileName.substring(sFileName.lastIndexOf('/'));
try {
String sTargetFileName = sResourceDirName+"/"+sBaseFileName;
if (fileExists(sTargetFileName)) { killFile(sTargetFileName); }
sfa2.copy(sFileName, sTargetFileName);
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
updateResources(dlg);
}
}
private void deleteResourceClick(DialogAccess dlg) {
int nItem = dlg.getListBoxSelectedItem("Resources");
if (nItem>=0) {
String sFileName = dlg.getListBoxStringItemList("Resources")[nItem];
if (deleteItem(sFileName)) {
killFile(sResourceDirName+"/"+sFileName);
updateResources(dlg);
}
}
}
private void createResourceDir() {
try {
if (!sfa2.isFolder(sResourceDirName)) {
sfa2.createFolder(sResourceDirName);
}
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateResources(DialogAccess dlg) {
try {
String[] sFiles = sfa2.getFolderContents(sResourceDirName, false); // do not include folders
int nCount = sFiles.length;
for (int i=0; i<nCount; i++) {
sFiles[i] = sFiles[i].substring(sFiles[i].lastIndexOf('/')+1);
}
dlg.setListBoxStringItemList("Resources", sFiles);
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class Styles1Handler extends StylesPageHandler {

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-03-21)
* Version 1.2 (2011-06-06)
*
*/
@ -123,6 +123,7 @@ public class EpubOptionsDialog extends OptionsDialogBase {
helper.put("AutoCreate","true");
helper.put("TemplateURL", "$(user)/writer2xhtml-template.xhtml");
helper.put("StyleSheetURL", "$(user)/writer2xhtml-styles.css");
helper.put("ResourceURL", "$(user)/writer2xhtml-resources");
}
saveNumericOptionAsPercentage(xProps, helper, "Scaling", "scaling");

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2010 by Henrik Just
* Copyright: 2002-2011 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.2 (2010-04-12)
* Version 1.2 (2011-06-05)
*
*/
@ -33,7 +33,9 @@ import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.Vector;
import writer2latex.api.BatchConverter;
@ -59,6 +61,7 @@ import writer2latex.util.Misc;
* <li><code>-config[=]filename</code>
* <li><code>-template[=]filename</code>
* <li><code>-stylesheet[=]filename</code>
* <li><code>-resource[=]filename[::media type]</code>
* <li><code>-option[=]value</code>
* </ul>
* <p>where <code>option</code> can be any simple option known to Writer2LaTeX
@ -72,6 +75,7 @@ public final class Application {
private Vector<String> configFileNames = new Vector<String>();
private String sTemplateFileName = null;
private String sStyleSheetFileName = null;
private Set<String> resources = new HashSet<String>();
private Hashtable<String,String> options = new Hashtable<String,String>();
private String sSource = null;
private String sTarget = null;
@ -194,6 +198,30 @@ public final class Application {
System.out.println(" "+e.getMessage());
}
}
// Step 5c: Read style resources
for (String sResource : resources) {
String sMediaType;
String sFileName;
int nSeparator = sResource.indexOf("::");
if (nSeparator>-1) {
sFileName = sResource.substring(0,nSeparator);
sMediaType = sResource.substring(nSeparator+2);
}
else {
sFileName = sResource;
sMediaType = null;
}
System.out.println("Reading resource file "+sFileName);
try {
byte [] resourceBytes = Misc.inputStreamToByteArray(new FileInputStream(sFileName));
converter.readResource(new ByteArrayInputStream(resourceBytes),sFileName,sMediaType);
} catch (IOException e) {
System.out.println("--> Failed to read the resource file!");
System.out.println(" "+e.getMessage());
}
}
// Step 6: Read config
for (int i=0; i<configFileNames.size(); i++) {
@ -302,6 +330,7 @@ public final class Application {
System.out.println(" -recurse");
System.out.println(" -template[=]<template file>");
System.out.println(" -stylesheet[=]<style sheet file>");
System.out.println(" -resource[=]<resource file>[::<media type>]");
System.out.println(" -ultraclean");
System.out.println(" -clean");
System.out.println(" -pdfprint");
@ -353,6 +382,7 @@ public final class Application {
if ("-config".equals(sArg)) { configFileNames.add(sArg2); }
else if ("-template".equals(sArg)) { sTemplateFileName = sArg2; }
else if ("-stylesheet".equals(sArg)) { sStyleSheetFileName = sArg2; }
else if ("-resource".equals(sArg)) { resources.add(sArg2); }
else { // configuration option
options.put(sArg.substring(1),sArg2);
}

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2010 by Henrik Just
* Copyright: 2002-2011 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.2 (2010-12-21)
* Version 1.2 (2011-06-05)
*
*/
@ -96,7 +96,7 @@ public interface Converter {
*
* @param is an <code>InputStream</code> from which to read the resource
* @param sFileName the file name to use for the resource
* @param sMediaType the media type of the resource
* @param sMediaType the media type of the resource, if null the media type will be guessed from the file name
* @throws IOException if some exception occurs while reading the resource
*/
public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException;
@ -107,7 +107,7 @@ public interface Converter {
*
* @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
* @param sMediaType the media type of the resource, if null the media type will be guessed from the file name
* @throws IOException if the file does not exist or some exception occurs
* while reading the resource
*/

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-06-05)
* Version 1.2 (2011-06-07)
*
*/
@ -33,7 +33,7 @@ public class ConverterFactory {
// Version information
private static final String VERSION = "1.1.8";
private static final String DATE = "2011-06-05";
private static final String DATE = "2011-06-07";
/** Return the Writer2LaTeX version in the form
* (major version).(minor version).(patch level)<br/>

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2011-05-09)
* Version 1.2 (2011-06-07)
*
*/
@ -65,6 +65,7 @@ import writer2latex.util.Misc;
*
*/
public class Converter extends ConverterBase {
private static final String EPUB_STYLES_FOLDER = "styles/";
private static final String EPUB_STYLESHEET = "styles/styles1.css";
private static final String EPUB_CUSTOM_STYLESHEET = "styles/styles.css";
@ -142,7 +143,21 @@ public class Converter extends ConverterBase {
}
@Override public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException {
ResourceDocument doc = new ResourceDocument(sFileName, sMediaType);
if (sMediaType==null) {
// Guess the media type from the file extension
sMediaType="";
String sfilename = sFileName.toLowerCase();
// PNG, JPEG and GIF are the basic raster image formats that must be supported by EPUB readers
if (sfilename.endsWith(MIMETypes.PNG_EXT)) { sMediaType = MIMETypes.PNG; }
else if (sfilename.endsWith(MIMETypes.JPEG_EXT)) { sMediaType = MIMETypes.JPEG; }
else if (sfilename.endsWith(".jpeg")) { sMediaType = MIMETypes.JPEG; }
else if (sfilename.endsWith(MIMETypes.GIF_EXT)) { sMediaType = MIMETypes.GIF; }
// The OPS 2.0.1 specification recommends (and only mentions) OpenType with this media type
else if (sfilename.endsWith(".otf")) { sMediaType = "application/vnd.ms-opentype"; }
// For convenience we also include a media type for true type fonts (the most common, it seems)
else if (sfilename.endsWith(".ttf")) { sMediaType = "application/x-font-ttf"; }
}
ResourceDocument doc = new ResourceDocument(EPUB_STYLES_FOLDER+sFileName, sMediaType);
doc.read(is);
resources.add(doc);
}

View file

@ -15,9 +15,9 @@
<set oor:name="Resources" oor:node-type="Resource" />
</group>
<group oor:name="Resource">
<prop oor:name="MediaType" oor:type="xs:string" />
<prop oor:name="FileName" oor:type="xs:string" />
<prop oor:name="URL" oor:type="xs:string" />
<prop oor:name="FileName" oor:type="xs:string" />
<prop oor:name="MediaType" oor:type="xs:string" />
</group>
<group oor:name="Template">
<prop oor:name="TemplateName" oor:type="xs:string" />

View file

@ -3,19 +3,25 @@
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="Stylesheets" dlg:left="139" dlg:top="84" dlg:width="260" dlg:height="185" dlg:closeable="true" dlg:moveable="true" dlg:title="Stylesheets" dlg:withtitlebar="false">
<dlg:bulletinboard>
<dlg:text dlg:id="IncludedCustomStylesheetLabel" dlg:tab-index="0" dlg:left="5" dlg:top="8" dlg:width="245" dlg:height="12" dlg:value="Custom style sheets"/>
<dlg:checkbox dlg:id="LinkCustomStylesheet" dlg:tab-index="1" dlg:left="10" dlg:top="22" dlg:width="240" dlg:height="12" dlg:value="Insert link to custom style sheet (XHTML export)" dlg:checked="false" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:LinkCustomStylesheet">
<dlg:checkbox dlg:id="LinkCustomStylesheet" dlg:tab-index="1" dlg:left="10" dlg:top="22" dlg:width="240" dlg:height="12" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:LinkCustomStylesheet" dlg:value="Insert link to custom style sheet (XHTML export)" dlg:checked="false">
<script:event script:event-name="on-itemstatechange" script:macro-name="vnd.sun.star.UNO:LinkCustomStylesheetChange" script:language="UNO"/>
</dlg:checkbox>
<dlg:text dlg:id="CustomStylesheetURLLabel" dlg:tab-index="2" dlg:left="19" dlg:top="36" dlg:width="55" dlg:height="12" dlg:value="URL"/>
<dlg:textfield dlg:id="CustomStylesheetURL" dlg:tab-index="3" dlg:left="80" dlg:top="34" dlg:width="170" dlg:height="12" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:CustomStylesheetURL"/>
<dlg:checkbox dlg:id="UseCustomStylesheet" dlg:tab-index="4" dlg:left="10" dlg:top="50" dlg:width="240" dlg:height="12" dlg:value="Include custom style sheet (EPUB export)" dlg:checked="false" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:UseCustomStylesheet">
<dlg:checkbox dlg:id="UseCustomStylesheet" dlg:tab-index="4" dlg:left="10" dlg:top="50" dlg:width="140" dlg:height="12" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:UseCustomStylesheet" dlg:value="Include custom style sheet (EPUB export)" dlg:checked="false">
<script:event script:event-name="on-itemstatechange" script:macro-name="vnd.sun.star.UNO:UseCustomStylesheetChange" script:language="UNO"/>
</dlg:checkbox>
<dlg:textfield dlg:id="CustomStylesheet" dlg:tab-index="5" dlg:left="18" dlg:top="64" dlg:width="232" dlg:height="84" dlg:hscroll="true" dlg:vscroll="true" dlg:multiline="true" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:UseCustomStylesheet"/>
<dlg:button dlg:id="LoadStylesheetButton" dlg:tab-index="6" dlg:left="18" dlg:top="156" dlg:width="60" dlg:height="12" dlg:value="Load..." dlg:help-url="org.openoffice.da.writer2xhtml.oxt:LoadStylesheet">
<dlg:textfield dlg:id="CustomStylesheet" dlg:tab-index="5" dlg:left="18" dlg:top="64" dlg:width="135" dlg:height="84" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:CustomStylesheet" dlg:hscroll="true" dlg:vscroll="true" dlg:multiline="true"/>
<dlg:button dlg:id="LoadStylesheetButton" dlg:tab-index="6" dlg:left="18" dlg:top="156" dlg:width="60" dlg:height="12" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:LoadStylesheet" dlg:value="Load...">
<script:event script:event-name="on-mouseup" script:macro-name="vnd.sun.star.UNO:LoadStylesheetClick" script:language="UNO"/>
</dlg:button>
<dlg:text dlg:id="ResourceLabel" dlg:tab-index="8" dlg:left="160" dlg:top="50" dlg:width="90" dlg:height="12" dlg:value="Style resources"/>
<dlg:menulist dlg:id="Resources" dlg:tab-index="7" dlg:left="160" dlg:top="64" dlg:width="90" dlg:height="84" dlg:help-url="org.openoffice.da.writer2xhtml.oxt:Resources"/>
<dlg:button dlg:id="NewResourceButton" dlg:tab-index="9" dlg:left="160" dlg:top="156" dlg:width="40" dlg:height="12" dlg:value="New..." dlg:help-url="org.openoffice.da.writer2xhtml.oxt:NewResource">
<script:event script:event-name="on-mouseup" script:macro-name="vnd.sun.star.UNO:NewResourceClick" script:language="UNO"/>
</dlg:button>
<dlg:button dlg:id="DeleteResourceButton" dlg:tab-index="10" dlg:left="209" dlg:top="156" dlg:width="40" dlg:height="12" dlg:value="Delete..." dlg:help-url="org.openoffice.da.writer2xhtml.oxt:DeleteResource">
<script:event script:event-name="on-mouseup" script:macro-name="vnd.sun.star.UNO:DeleteResourceClick" script:language="UNO"/>
</dlg:button>
</dlg:bulletinboard>
</dlg:window>

View file

@ -7,7 +7,7 @@
</topic>
</meta>
<body>
<paragraph role="heading" level="1" xml-lang="en-US">Stylesheets</paragraph>
<paragraph role="heading" level="1" xml-lang="en-US">Style sheets</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Use this page to provide your own style sheets for the exported documents.</paragraph>
<section id="howtoget" xml-lang="en-US">
@ -33,9 +33,37 @@
<paragraph role="heading" level="3" xml-lang="en-US">Include custom style sheet (EPUB export)</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Check this to include a custom style sheet in the EPUB document.</paragraph>
<bookmark xml-lang="en-US" branch="hid/org.openoffice.da.writer2xhtml.oxt:CustomStylesheet" id="bm_configcustomstylesheet"/>
<paragraph role="heading" level="3" xml-lang="en-US">Custom style sheet</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Enter the CSS code for your custom style sheet here.</paragraph>
<bookmark xml-lang="en-US" branch="hid/org.openoffice.da.writer2xhtml.oxt:LoadStylesheet" id="bm_configloadstylesheet"/>
<paragraph role="heading" level="3" xml-lang="en-US">Load...</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Click to load the style sheet from a file.</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Click to load the style sheet from a file.
This will create a copy of the original file. If you change, move or delete the original file, nothing
will happen to the style sheet. If you want to update the style sheet with a new version of the original file, click
this button again.</paragraph>
<bookmark xml-lang="en-US" branch="hid/org.openoffice.da.writer2xhtml.oxt:Resources" id="bm_configresources"/>
<paragraph role="heading" level="3" xml-lang="en-US">Style resources</paragraph>
<paragraph role="paragraph" xml-lang="en-US">This is a list of resource files to include with the custom style sheet.
You can refer to these files from your style sheet. The reference should be by file name only, as the resource files
are placed in the same directory as the style sheet. For example:</paragraph>
<paragraph role="code" xml-lang="en-US">body { background-image:url('myimage.jpg'); }</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Note that changes to this list will <emph>not</emph> be undone if
you click <emph>Cancel</emph>.</paragraph>
<bookmark xml-lang="en-US" branch="hid/org.openoffice.da.writer2xhtml.oxt:NewResource" id="bm_newresource"/>
<paragraph role="heading" level="3" xml-lang="en-US">New...</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Click this to add a new resource file to the list. Select the file and press
<emph>Open</emph>. This will create a copy of the original file. If you change, move or delete the original file, nothing
will happen to the resource file. If you want to update the resource file with a new version of the original file, click
this button again.</paragraph>
<bookmark xml-lang="en-US" branch="hid/org.openoffice.da.writer2xhtml.oxt:DeleteResource" id="bm_deleteresource"/>
<paragraph role="heading" level="3" xml-lang="en-US">Delete...</paragraph>
<paragraph role="paragraph" xml-lang="en-US">Click this to delete the currently selected resource file from the list.
This will not affect the original file.</paragraph>
</body>
</helpdocument>