Polyglossia + EPUB meta data

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@80 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2010-12-16 09:22:24 +00:00
parent ea5d8679c9
commit e02f738e85
20 changed files with 727 additions and 520 deletions

View file

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

View file

@ -20,12 +20,14 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-03-15)
* Version 1.2 (2010-12-15)
*
*/
package writer2latex.api;
import java.util.Map;
/** This interface provides access to the predefined meta data of the
* source document (currently incomplete)
*/
@ -36,10 +38,45 @@ public interface MetaData {
*/
public String getTitle();
/** Get the subject of the source document
*
* @return the subject (may return an empty string)
*/
public String getSubject();
/** Get the keywords of the source document
*
* @return the keywords as a comma separated list (may return an empty string)
*/
public String getKeywords();
/** Get the description of the source document
*
* @return the description (may return an empty string)
*/
public String getDescription();
/** Get the creator of the source document (or the initial creator if none is specified)
*
* @return the creator (may return an empty string)
*/
public String getCreator();
/** Get the (main) language of the document
*
* @return the language
*/
public String getLanguage();
/** Get the date of the source document
*
* @return the date (may return an empty string)
*/
public String getDate();
/** Get the user-defined meta data
*
* @return the user-defined meta data as a name-value map
*/
public Map<String,String> getUserDefinedMetaData();
}

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* version 1.2 (2010-03-28)
* version 1.2 (2010-12-15)
*
*/
@ -48,7 +48,7 @@ public final class EPUBConverter extends Xhtml11Converter {
ConverterResult xhtmlResult = super.convert(is, sTargetFileName);
ConverterResultImpl epubResult = new ConverterResultImpl();
epubResult.addDocument(new EPUBWriter(xhtmlResult,sTargetFileName));
epubResult.addDocument(new EPUBWriter(xhtmlResult,sTargetFileName,getXhtmlConfig()));
epubResult.setMetaData(xhtmlResult.getMetaData());
return epubResult;
}

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* version 1.2 (2010-03-31)
* version 1.2 (2010-12-15)
*
*/
@ -37,6 +37,7 @@ import java.util.zip.ZipOutputStream;
import writer2latex.api.ConverterResult;
import writer2latex.api.OutputFile;
import writer2latex.util.Misc;
import writer2latex.xhtml.XhtmlConfig;
/** This class repackages an XHTML document into EPUB format.
* Some filenames are hard wired in this implementation: The main directory is OEBPS and
@ -49,10 +50,12 @@ public class EPUBWriter implements OutputFile {
private ConverterResult xhtmlResult;
private String sFileName;
private XhtmlConfig config;
public EPUBWriter(ConverterResult xhtmlResult, String sFileName) {
public EPUBWriter(ConverterResult xhtmlResult, String sFileName, XhtmlConfig config) {
this.xhtmlResult = xhtmlResult;
this.sFileName = Misc.removeExtension(sFileName);
this.config = config;
}
public String getFileName() {
@ -90,7 +93,7 @@ public class EPUBWriter implements OutputFile {
zos.closeEntry();
// Then manifest
OutputFile manifest = new OPFWriter(xhtmlResult, sUUID);
OutputFile manifest = new OPFWriter(xhtmlResult, sUUID, config.xhtmlUseDublinCore());
ZipEntry manifestEntry = new ZipEntry("OEBPS/book.opf");
zos.putNextEntry(manifestEntry);
writeZipEntry(manifest,zos);

View file

@ -20,13 +20,14 @@
*
* All Rights Reserved.
*
* version 1.2 (2010-07-02)
* version 1.2 (2010-12-16)
*
*/
package writer2latex.epub;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@ -47,7 +48,7 @@ import writer2latex.xmerge.NewDOMDocument;
*/
public class OPFWriter extends NewDOMDocument {
public OPFWriter(ConverterResult cr, String sUUID) {
public OPFWriter(ConverterResult cr, String sUUID, boolean bUseDublinCore) {
super("book", "opf");
// create DOM
@ -83,11 +84,139 @@ public class OPFWriter extends NewDOMDocument {
metadata.appendChild(language);
language.appendChild(contentDOM.createTextNode(cr.getMetaData().getLanguage()));
Element identifier = contentDOM.createElement("dc:identifier");
identifier.setAttribute("id", "BookId");
identifier.setAttribute("opf:scheme", "UUID");
metadata.appendChild(identifier);
identifier.appendChild(contentDOM.createTextNode(sUUID));
// 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()));
}
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()));
}
}
if (cr.getMetaData().getDescription().length()>0) {
Element description = contentDOM.createElement("dc:description");
metadata.appendChild(description);
description.appendChild(contentDOM.createTextNode(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
// 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"
boolean bHasIdentifier = false;
boolean bHasCreator = false;
boolean bHasDate = false;
Map<String,String> userDefined = cr.getMetaData().getUserDefinedMetaData();
for (String sKey : userDefined.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;
}
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 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));
}
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;
}
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));
}
}
}
}
// Fall back values for creator and date
if (bUseDublinCore) {
if (!bHasIdentifier) {
Element identifier = contentDOM.createElement("dc:identifier");
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()));
}
if (!bHasDate && cr.getMetaData().getDate().length()>0) {
Element date = contentDOM.createElement("dc:date");
metadata.appendChild(date);
date.appendChild(contentDOM.createTextNode(cr.getMetaData().getDate()));
}
}
// Manifest must contain references to all the files in the XHTML converter result
// Spine should contain references to all the master documents within the converter result

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-10-09)
* Version 1.2 (2010-12-15)
*
*/
@ -308,7 +308,7 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
};
options[METADATA] = new BooleanOption("metadata","true");
options[TABSTOP] = new Option("tabstop","");
options[WRAP_LINES_AFTER] = new IntegerOption("wrap_lines_after","72") {
options[WRAP_LINES_AFTER] = new IntegerOption("wrap_lines_after","120") {
public void setString(String sValue) {
super.setString(sValue);
nValue = Misc.getPosInteger(sValue,0);

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-05-11)
* Version 1.2 (2010-12-15)
*
*/
@ -359,7 +359,7 @@ public class ClassicI18n extends I18n {
}
/** Apply a language language
* @param style the OOo style to read attributesfrom
* @param style the OOo style to read attributes from
* @param bDecl true if declaration form is required
* @param bInherit true if inherited properties should be used
* @param ba the <code>BeforeAfter</code> to add LaTeX code to.
@ -662,7 +662,8 @@ public class ClassicI18n extends I18n {
babelLanguages.put("is", "icelandic"); // latin1
babelLanguages.put("it", "italian"); // latin1
babelLanguages.put("nl", "dutch"); // latin1
babelLanguages.put("no", "norsk"); // latin1
babelLanguages.put("nb", "norsk"); // latin1
babelLanguages.put("nn", "nynorsk"); // latin1
babelLanguages.put("pl", "polish"); // latin2
babelLanguages.put("pt", "portuges"); // latin1
babelLanguages.put("ro", "romanian"); // latin2

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-10-30)
* Version 1.2 (2010-12-14)
*
*/
@ -118,7 +118,7 @@ public abstract class I18n {
/** Get the default language (either the document language or the most used language)
*
* @param the default language
* @return the default language
*/
public String getDefaultLanguage() {
return sDefaultLanguage;

View file

@ -0,0 +1,217 @@
/************************************************************************
*
* XeTeXI18n.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-15)
*
*/
package writer2latex.latex.i18n;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Polyglossia {
private static Map<String,String> languageMap;
private static Map<String,String> variantMap;
static {
languageMap = new HashMap<String,String>();
languageMap.put("am", "amharic");
languageMap.put("ar", "arabic");
languageMap.put("ast", "asturian");
languageMap.put("bg", "bulgarian");
languageMap.put("bn", "bengali");
languageMap.put("br", "breton");
languageMap.put("ca", "catalan");
languageMap.put("cop", "coptic");
languageMap.put("cs", "czech");
languageMap.put("cy", "welsh");
languageMap.put("da", "danish");
languageMap.put("de", "german");
languageMap.put("dsb", "lsorbian");
languageMap.put("dv", "divehi");
languageMap.put("el", "greek");
languageMap.put("en", "english");
languageMap.put("eo", "esperanto");
languageMap.put("es", "spanish");
languageMap.put("et", "estonian");
languageMap.put("eu", "basque");
languageMap.put("fa", "farsi");
languageMap.put("fi", "finnish");
languageMap.put("fr", "french");
languageMap.put("ga", "irish");
languageMap.put("gd", "scottish");
languageMap.put("gl", "galician");
languageMap.put("grc", "greek");
languageMap.put("he", "hebrew");
languageMap.put("hi", "hindi");
languageMap.put("hr", "croatian");
languageMap.put("hsb", "usorbian");
languageMap.put("hu", "magyar");
languageMap.put("hy", "armenian");
languageMap.put("id", "bahasai"); // Bahasa Indonesia
languageMap.put("ie", "interlingua");
languageMap.put("is", "icelandic");
languageMap.put("it", "italian");
languageMap.put("la", "latin");
languageMap.put("lo", "lao");
languageMap.put("lt", "lithuanian");
languageMap.put("lv", "latvian");
languageMap.put("ml", "malayalam");
languageMap.put("mr", "marathi");
languageMap.put("ms", "bahasam"); // Bahasa Melayu
languageMap.put("nb", "norsk");
languageMap.put("nl", "dutch");
languageMap.put("nn", "nynorsk");
languageMap.put("oc", "occitan");
languageMap.put("pl", "polish");
languageMap.put("pt", "portuges");
languageMap.put("pt-BR", "brazilian");
languageMap.put("ro", "romanian");
languageMap.put("ru", "russian");
languageMap.put("sa", "sanskrit");
languageMap.put("sk", "slovak");
languageMap.put("sl", "slovenian");
languageMap.put("sq", "albanian");
languageMap.put("sr", "serbian");
languageMap.put("sv", "swedish");
languageMap.put("syr", "syriac");
languageMap.put("ta", "tamil");
languageMap.put("te", "telugu");
languageMap.put("th", "thai");
languageMap.put("tk", "turkmen");
languageMap.put("tr", "turkish");
languageMap.put("uk", "ukrainian");
languageMap.put("ur", "urdu");
languageMap.put("vi", "vietnamese");
// TODO: Which language is samin?? One guess could be sami with the n for north?
//languageMap.put("??", "samin");
variantMap = new HashMap<String,String>();
// English variants
variantMap.put("en-US", "american");
variantMap.put("en-GB", "british");
variantMap.put("en-AU", "australian");
variantMap.put("en-NZ", "newzealand");
// Greek variants
variantMap.put("el", "monotonic");
variantMap.put("grc", "ancient"); // Supported in OOo since 3.2
}
private static String getEntry(Map<String,String> map, String sLocale, String sLang) {
if (map.containsKey(sLocale)) {
return map.get(sLocale);
}
else if (map.containsKey(sLang)) {
return map.get(sLang);
}
return null;
}
// This ended the static part of Polyglossia
private Set<String> languages = new HashSet<String>();
private List<String> declarations = new ArrayList<String>();
private Map<String,String[]> commands = new HashMap<String,String[]>();
/** <p>Get the declarations for the applied languages, in the form</p>
* <p><code>\\usepackage{polyglossia}</code></p>
* <p><code>\\setdefaultlanguage{language1}</code></p>
* <p><code>\\setotherlanguage{language2}</code></p>
* <p><code>\\setotherlanguage{language3}</code></p>
* <p><code>...</code></p>
*
* @return the declarations as a string array
*/
public String[] getDeclarations() {
return declarations.toArray(new String[declarations.size()]);
}
/** <p>Add the given locale to the list of applied locales and return definitions for applying the
* language to a text portion:</p>
* <ul>
* <li>A command of the forn <code>\textlanguage[variant=languagevariant]</code></li>
* <li>An environment in the form
* <code>\begin{language}[variant=languagevariant]</code>...<code>\end{language}</code></li>
* </ul>
* <p>The first applied language is the default language</p>
*
* @param sLang The language
* @param sCountry The country (may be null)
* @return a string array containing definitions to apply the language: Entry 0 contains a command
* and Entry 1 and 2 contains an environment
*/
public String[] applyLanguage(String sLang, String sCountry) {
String sLocale = sCountry!=null ? sLang+"-"+sCountry : sLang;
if (commands.containsKey(sLocale)) {
return commands.get(sLocale);
}
else {
// Get the Polyglossia language and variant
String sPolyLang = getEntry(languageMap,sLocale,sLang);
if (sPolyLang!=null) {
String sVariant = getEntry(variantMap,sLocale,sLang);
if (sVariant!=null) {
sVariant = "[variant="+sVariant+"]";
}
else {
sVariant = "";
}
if (languages.size()==0) {
// First language, load Polyglossia and make the language default
declarations.add("\\usepackage{polyglossia}");
declarations.add("\\setdefaultlanguage"+sVariant+"{"+sPolyLang+"}");
languages.add(sPolyLang);
sVariant = ""; // Do not apply variant directly
}
else if (!languages.contains(sPolyLang)) {
// New language, add to declarations
declarations.add("\\setotherlanguage"+sVariant+"{"+sPolyLang+"}");
languages.add(sPolyLang);
sVariant = ""; // Do not apply variant directly
}
String[] sCommand = new String[3];
sCommand[0] = "\\text"+sPolyLang+sVariant;
if ("arabic".equals(sPolyLang)) { sPolyLang="Arabic"; }
sCommand[1] = "\\begin{"+sPolyLang+"}"+sVariant;
sCommand[2] = "\\end{"+sPolyLang+"}";
commands.put(sLocale, sCommand);
return sCommand;
}
else {
// Unknown language
String[] sCommand = new String[3];
sCommand[0] = "";
sCommand[1] = "";
sCommand[2] = "";
commands.put(sLocale, sCommand);
return sCommand;
}
}
}
}

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-11-30)
* Version 1.2 (2010-12-15)
*
*/
@ -36,7 +36,7 @@ import writer2latex.latex.util.BeforeAfter;
*/
public class XeTeXI18n extends I18n {
// **** Constructors ****
private Polyglossia polyglossia;
/** Construct a new XeTeXI18n as ConverterHelper
* @param ofr the OfficeReader to get language information from
@ -45,6 +45,7 @@ public class XeTeXI18n extends I18n {
*/
public XeTeXI18n(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette) {
super(ofr,config,palette);
polyglossia = new Polyglossia();
}
/** Add declarations to the preamble to load the required packages
@ -56,17 +57,33 @@ public class XeTeXI18n extends I18n {
.append("\\usepackage{fontspec}").nl()
.append("\\usepackage{xunicode}").nl()
.append("\\usepackage{xltxtra}").nl();
String[] polyglossiaDeclarations = polyglossia.getDeclarations();
for (String s: polyglossiaDeclarations) {
pack.append(s).nl();
}
}
/** Apply a language language
* @param style the OOo style to read attributesfrom
* @param style the OOo style to read attributes from
* @param bDecl true if declaration form is required
* @param bInherit true if inherited properties should be used
* @param ba the <code>BeforeAfter</code> to add LaTeX code to.
*/
public void applyLanguage(StyleWithProperties style, boolean bDecl, boolean bInherit, BeforeAfter ba) {
// TODO (polyglossia)
if (!bAlwaysUseDefaultLang && style!=null) {
// TODO: Support CTL and CJK
String sISOLang = style.getProperty(XMLString.FO_LANGUAGE,bInherit);
String sISOCountry = style.getProperty(XMLString.FO_COUNTRY, bInherit);
if (sISOLang!=null) {
String[] sCommand = polyglossia.applyLanguage(sISOLang, sISOCountry);
if (bDecl) {
ba.add(sCommand[1],sCommand[2]);
}
else {
ba.add(sCommand[0]+"{","}");
}
}
}
}
/** Push a font to the font stack

View file

@ -26,6 +26,9 @@
package writer2latex.office;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -49,6 +52,8 @@ public class MetaData implements writer2latex.api.MetaData {
private String sSubject = "";
// Keywords
private String sKeywords = "";
// User-defined
private Map<String,String> userdefined = new HashMap<String,String>();
/** <p>Construct a new instance from an OOo Writer document.</p>
* @param oooDoc is the OOo document
@ -74,28 +79,28 @@ public class MetaData implements writer2latex.api.MetaData {
if (XMLString.DC_TITLE.equals(sName)) {
sTitle = getContent(child);
}
if (XMLString.DC_CREATOR.equals(sName)) {
else if (XMLString.DC_CREATOR.equals(sName)) {
sCreator = getContent(child);
}
if (XMLString.DC_DATE.equals(sName)) {
else if (XMLString.DC_DATE.equals(sName)) {
sDate = getContent(child);
}
if (XMLString.DC_DESCRIPTION.equals(sName)) {
else if (XMLString.DC_DESCRIPTION.equals(sName)) {
sDescription = getContent(child);
}
if (XMLString.DC_LANGUAGE.equals(sName)) {
else if (XMLString.DC_LANGUAGE.equals(sName)) {
sLanguage = getContent(child);
}
if (XMLString.DC_SUBJECT.equals(sName)) {
else if (XMLString.DC_SUBJECT.equals(sName)) {
sSubject = getContent(child);
}
if (XMLString.META_INITIAL_CREATOR.equals(sName)) {
else if (XMLString.META_INITIAL_CREATOR.equals(sName)) {
sInitialCreator = getContent(child);
}
if (XMLString.META_KEYWORD.equals(sName)) { // oasis
else if (XMLString.META_KEYWORD.equals(sName)) { // oasis
keywords.addValue(getContent(child));
}
if (XMLString.META_KEYWORDS.equals(sName)) {
else if (XMLString.META_KEYWORDS.equals(sName)) {
// Old format: Keywords are contained within meta:keywords
if (child.hasChildNodes()) {
// traverse the keywords
@ -109,36 +114,42 @@ public class MetaData implements writer2latex.api.MetaData {
}
}
}
else if (XMLString.META_USER_DEFINED.equals(sName)) {
String sPropertyName = Misc.getAttribute(child, XMLString.META_NAME);
if (sPropertyName!=null) {
userdefined.put(sPropertyName,getContent(child));
}
}
}
sKeywords = keywords.toString();
}
/** <p> Get the title of this document (may be null)</p>
/** <p> Get the title of this document (may be empty)</p>
* @return the title of the document
*/
public String getTitle() { return sTitle; }
/** <p> Get the creator of this document (may be null)</p>
/** <p> Get the creator of this document (may be empty)</p>
* @return the creator of the document (or the initial creator if none is specified)
*/
public String getCreator() { return sCreator==null ? sInitialCreator : sCreator; }
/** <p> Get the initial creator of this document (may be null)</p>
/** <p> Get the initial creator of this document (may be empty)</p>
* @return the initial creator of the document
*/
public String getInitialCreator() { return sInitialCreator; }
/** <p> Get the date of this document (may be null)</p>
/** <p> Get the date of this document (may be empty)</p>
* @return the date of the document
*/
public String getDate() { return sDate; }
/** <p> Get the description of this document (may be null)</p>
/** <p> Get the description of this document (may be empty)</p>
* @return the description of the document
*/
public String getDescription() { return sDescription; }
/** <p> Get the language of this document (may be null)</p>
/** <p> Get the language of this document (may be empty)</p>
* @return the language of the document
*/
public String getLanguage() { return sLanguage; }
@ -147,27 +158,32 @@ public class MetaData implements writer2latex.api.MetaData {
this.sLanguage = sLanguage;
}
/** <p> Get the subject of this document (may be null)</p>
/** <p> Get the subject of this document (may be empty)</p>
* @return the subject of the document
*/
public String getSubject() { return sSubject; }
/** <p> Get the keywords of this document as a comma separated list (may be null)</p>
/** <p> Get the keywords of this document as a comma separated list (may be epmty)</p>
* @return the keywords of the document
*/
public String getKeywords() { return sKeywords; }
/** Get the user-defined meta data
*
* @return the user-defined meta data as a name-value map
*/
public Map<String,String> getUserDefinedMetaData() { return userdefined; }
private String getContent(Node node) {
if (!node.hasChildNodes()) { return null; }
String s="";
NodeList list = node.getChildNodes();
int nLen = list.getLength();
for (int i=0; i<nLen; i++) {
if (list.item(i).getNodeType()==Node.TEXT_NODE) {
s+= list.item(i).getNodeValue();
}
StringBuffer buf = new StringBuffer();
Node child = node.getFirstChild();
while (child!=null) {
if (child.getNodeType()==Node.TEXT_NODE) {
buf.append(child.getNodeValue());
}
child = child.getNextSibling();
}
return s;
return buf.toString();
}
}

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.2 (2010-10-04)
* Version 1.2 (2010-12-15)
*
*/
@ -61,6 +61,9 @@ public class XMLString {
public static final String META_INITIAL_CREATOR="meta:initial-creator";
public static final String META_KEYWORDS="meta:keywords";
public static final String META_KEYWORD="meta:keyword";
public static final String META_USER_DEFINED="meta:user-defined";
// meta namespace - attributes
public static final String META_NAME="meta:name";
// manifest namespace
public static final String MANIFEST_FILE_ENTRY="manifest:file-entry";

View file

@ -66,6 +66,8 @@ public class Converter extends ConverterBase {
private XhtmlConfig config;
public Config getConfig() { return config; }
protected XhtmlConfig getXhtmlConfig() { return config; }
// The locale
private L10n l10n;

View file

@ -47,7 +47,7 @@ public class CssDocument implements OutputFile {
/**
* Constructor (creates an empty document)
* @param name <code>Document</code> name.
* @param sName <code>Document</code> name.
*/
public CssDocument(String sName) {
this.sName = sName;