w2x: Regenerate bibliography
git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@255 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
parent
a475b5fd42
commit
67ceaae08a
12 changed files with 508 additions and 97 deletions
|
@ -2,13 +2,16 @@ Changelog for Writer2LaTeX version 1.4 -> 1.6
|
|||
|
||||
---------- version 1.5.3 ----------
|
||||
|
||||
[w2x] The bibliography is now regenerated from the template. This implies that bibliographic citations now link
|
||||
directly to the cited work rather than to the bibliography as a whole.
|
||||
|
||||
[w2x] The option separate_stylesheet can now be set in the configuration UI, on the Formatting page.
|
||||
|
||||
[w2x] New option max_width (default value 800px) used to define the max-width on the body element (XHTML and text
|
||||
documents only). In the custom configuration UI, this setting is found on the Formatting page.
|
||||
|
||||
[w2x] Added support for semantic inflection in EPUB 3 export for the types footnote(s), endnote(s), toc, index
|
||||
and bibliography
|
||||
[w2x] Added support for semantic inflection in EPUB 3 export for the types footnote(s), endnote(s), toc, index,
|
||||
bibliography and biblioentry
|
||||
(http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#sec-xhtml-semantic-inflection).
|
||||
|
||||
[w2x] Improved the semantic markup of footnotes, endnotes, table of contents and alphabetical index in HTML export
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-16)
|
||||
* Version 1.6 (2015-06-19)
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class ConverterFactory {
|
|||
|
||||
// Version information
|
||||
private static final String VERSION = "1.5.3";
|
||||
private static final String DATE = "2015-06-16";
|
||||
private static final String DATE = "2015-06-19";
|
||||
|
||||
/** Return the Writer2LaTeX version in the form
|
||||
* (major version).(minor version).(patch level)<br/>
|
||||
|
|
257
source/java/writer2latex/base/BibliographyGenerator.java
Normal file
257
source/java/writer2latex/base/BibliographyGenerator.java
Normal file
|
@ -0,0 +1,257 @@
|
|||
/************************************************************************
|
||||
*
|
||||
* BibliographyGenerator.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-2015 by Henrik Just
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-19)
|
||||
*
|
||||
*/
|
||||
|
||||
package writer2latex.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import writer2latex.office.OfficeReader;
|
||||
import writer2latex.office.XMLString;
|
||||
import writer2latex.util.Misc;
|
||||
import writer2latex.util.StringComparator;
|
||||
|
||||
/** This class is used to generate bibliographic references and a bibliography.
|
||||
* Bibliographies are generated from a list of items (text:bibliograpy-mark), a global configuration
|
||||
* (text:bibliography-configuration) and a formatting template (text:bibliography-source)
|
||||
*/
|
||||
public abstract class BibliographyGenerator {
|
||||
|
||||
// Bibliography configuration data
|
||||
private String sPrefix = "[";
|
||||
private String sSuffix = "]";
|
||||
|
||||
// The sorted list of bibliography marks
|
||||
private List<Element> bibMarkList = new ArrayList<Element>();
|
||||
|
||||
// Map from key to label
|
||||
private Map<String,String> bibMarkCitation = new HashMap<String,String>();
|
||||
|
||||
/** Create a new bibliography generator based on a bibliography configuration and a list of bibliography marks
|
||||
*
|
||||
* @param ofr the office reader used to access the source document
|
||||
*/
|
||||
protected BibliographyGenerator(OfficeReader ofr) {
|
||||
Element bibConfig = ofr.getBibliographyConfiguration();
|
||||
if (bibConfig!=null) {
|
||||
if (bibConfig.hasAttribute(XMLString.TEXT_PREFIX)) {
|
||||
sPrefix = bibConfig.getAttribute(XMLString.TEXT_PREFIX);
|
||||
}
|
||||
if (bibConfig.hasAttribute(XMLString.TEXT_SUFFIX)) {
|
||||
sSuffix = bibConfig.getAttribute(XMLString.TEXT_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
collectBibMarks(ofr.getBibliographyMarks());
|
||||
sortBibMarks(bibConfig);
|
||||
createLabels(bibConfig);
|
||||
}
|
||||
|
||||
// Collect the bibliography marks from the raw list, removing any duplicates
|
||||
private void collectBibMarks(List<Element> bibMarks) {
|
||||
Set<String> keys = new HashSet<String>();
|
||||
for (Element bibMark : bibMarks) {
|
||||
String sKey = bibMark.getAttribute(XMLString.TEXT_IDENTIFIER);
|
||||
if (!keys.contains(sKey)) {
|
||||
bibMarkList.add(bibMark);
|
||||
keys.add(sKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the bibliography marks based on the settings in the bibliography configuration
|
||||
private void sortBibMarks(Element bibConfig) {
|
||||
if (bibConfig!=null && "false".equals(bibConfig.getAttribute(XMLString.TEXT_SORT_BY_POSITION))) {
|
||||
// Get the sort algorithm
|
||||
//String sSortAlgorithm = "alphanumeric";
|
||||
//if (bibConfig.hasAttribute(XMLString.TEXT_SORT_ALGORITHM)) {
|
||||
// sSortAlgorithm = bibConfig.getAttribute(XMLString.TEXT_SORT_ALGORITHM);
|
||||
//}
|
||||
|
||||
// Get the sort keys
|
||||
List<String> sortKeys = new ArrayList<String>();
|
||||
List<Boolean> sortAscending = new ArrayList<Boolean>();
|
||||
Node child = bibConfig.getFirstChild();
|
||||
while (child!=null) {
|
||||
if (child.getNodeType()==Node.ELEMENT_NODE && child.getNodeName().equals(XMLString.TEXT_SORT_KEY)) {
|
||||
String sKey = Misc.getAttribute(child, XMLString.TEXT_KEY);
|
||||
if (sKey!=null) {
|
||||
sortKeys.add(sKey);
|
||||
sortAscending.add(!"false".equals(Misc.getAttribute(child, XMLString.TEXT_SORT_ASCENDING)));
|
||||
}
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
|
||||
// Sort the list
|
||||
Comparator<Element> comparator = new StringComparator<Element>(
|
||||
Misc.getAttribute(bibConfig,XMLString.FO_LANGUAGE),
|
||||
Misc.getAttribute(bibConfig, XMLString.FO_COUNTRY)) {
|
||||
private List<String> sortKeys = null;
|
||||
private List<Boolean> sortAscending = null;
|
||||
|
||||
public Comparator<Element> setSortKeys(List<String> sortKeys, List<Boolean> sortAscending) {
|
||||
this.sortKeys = sortKeys;
|
||||
this.sortAscending = sortAscending;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public int compare(Element a, Element b) {
|
||||
int nCount = sortKeys.size();
|
||||
for (int i=0; i<nCount; i++) {
|
||||
String sWorda = a.getAttribute("text:"+sortKeys.get(i));
|
||||
String sWordb = b.getAttribute("text:"+sortKeys.get(i));
|
||||
int nCompare = getCollator().compare(sWorda, sWordb)*(sortAscending.get(i) ? 1 : -1);
|
||||
if (nCompare!=0) { return nCompare; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}.setSortKeys(sortKeys, sortAscending);
|
||||
|
||||
Collections.sort(bibMarkList, comparator);
|
||||
}
|
||||
}
|
||||
|
||||
private void createLabels(Element bibConfig) {
|
||||
boolean bNumberedEntries = bibConfig!=null && "true".equals(bibConfig.getAttribute(XMLString.TEXT_NUMBERED_ENTRIES));
|
||||
int nCount = bibMarkList.size();
|
||||
for (int i=0; i<nCount; i++) {
|
||||
Element item = bibMarkList.get(i);
|
||||
String sKey = item.getAttribute(XMLString.TEXT_IDENTIFIER);
|
||||
if (bNumberedEntries) {
|
||||
bibMarkCitation.put(sKey, Integer.toString(i+1));
|
||||
}
|
||||
else {
|
||||
bibMarkCitation.put(sKey, sKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get citation text for a reference to the bibliography
|
||||
*
|
||||
* @param sKey the key of the bibliography item
|
||||
* @return the citation text to be shown in the document
|
||||
*/
|
||||
public String generateCitation(String sKey) {
|
||||
return sPrefix+bibMarkCitation.get(sKey)+sSuffix;
|
||||
}
|
||||
|
||||
/** Generate a bibliography
|
||||
*
|
||||
* @param bibliography a text:bibliography-source element
|
||||
*/
|
||||
public void generateBibliography(Element bibSource) {
|
||||
Map<String,Element> bibEntryTemplate = collectTemplates(bibSource);
|
||||
for (Element bibMark : bibMarkList) {
|
||||
String sKey = bibMark.getAttribute(XMLString.TEXT_IDENTIFIER);
|
||||
String sType = bibMark.getAttribute(XMLString.TEXT_BIBLIOGRAPHY_TYPE);
|
||||
if (bibEntryTemplate.containsKey(sType)) {
|
||||
Element template = bibEntryTemplate.get(sType);
|
||||
String sStyleName = template.getAttribute(XMLString.TEXT_STYLE_NAME);
|
||||
insertBibliographyItem(sStyleName,sKey);
|
||||
applyTemplate(template,bibMark);
|
||||
}
|
||||
else { // Use a default template (identical with the default template in LO)
|
||||
String sAuthor = bibMark.getAttribute(XMLString.TEXT_AUTHOR);
|
||||
String sTitle = bibMark.getAttribute(XMLString.TEXT_TITLE);
|
||||
String sYear = bibMark.getAttribute(XMLString.TEXT_YEAR);
|
||||
insertBibliographyItem(null,sKey);
|
||||
insertBibliographyItemElement(null,bibMarkCitation.get(sKey));
|
||||
insertBibliographyItemElement(null,": ");
|
||||
insertBibliographyItemElement(null,sAuthor);
|
||||
insertBibliographyItemElement(null,", ");
|
||||
insertBibliographyItemElement(null,sTitle);
|
||||
insertBibliographyItemElement(null,", ");
|
||||
insertBibliographyItemElement(null,sYear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String,Element> collectTemplates(Element bibSource) {
|
||||
Map<String,Element> bibEntryTemplate = new HashMap<String,Element>();
|
||||
Node child = bibSource.getFirstChild();
|
||||
while (child!=null) {
|
||||
if (child.getNodeType()==Node.ELEMENT_NODE
|
||||
&& child.getNodeName().equals(XMLString.TEXT_BIBLIOGRAPHY_ENTRY_TEMPLATE)) {
|
||||
String sType = Misc.getAttribute(child, XMLString.TEXT_BIBLIOGRAPHY_TYPE);
|
||||
if (sType!=null) {
|
||||
bibEntryTemplate.put(sType, (Element)child);
|
||||
}
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
return bibEntryTemplate;
|
||||
}
|
||||
|
||||
private void applyTemplate(Element template, Element bibMark) {
|
||||
Node child = template.getFirstChild();
|
||||
while (child!=null) {
|
||||
if (child.getNodeType()==Node.ELEMENT_NODE) {
|
||||
if (child.getNodeName().equals(XMLString.TEXT_INDEX_ENTRY_BIBLIOGRAPHY)) {
|
||||
String sField = Misc.getAttribute(child, XMLString.TEXT_BIBLIOGRAPHY_DATA_FIELD);
|
||||
if (sField!=null) {
|
||||
String sElementStyleName = Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
|
||||
String sValue = bibMark.getAttribute("text:"+sField);
|
||||
if (sField.equals("identifier")) {
|
||||
sValue = bibMarkCitation.get(sValue);
|
||||
}
|
||||
insertBibliographyItemElement(sElementStyleName,sValue);
|
||||
}
|
||||
}
|
||||
else if (child.getNodeName().equals(XMLString.TEXT_INDEX_ENTRY_SPAN)) {
|
||||
String sElementStyleName = Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
|
||||
String sValue = Misc.getPCDATA(child);
|
||||
insertBibliographyItemElement(sElementStyleName,sValue);
|
||||
}
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
/** Insert a new bibliography item
|
||||
*
|
||||
* @param sStyleName a paragraph style to apply to the item
|
||||
* @param sKey the key of the bibliography item
|
||||
*/
|
||||
protected abstract void insertBibliographyItem(String sStyleName, String sKey);
|
||||
|
||||
/** Insert an element of a bibliography item
|
||||
*
|
||||
* @param sStyleName a character style to apply to the element
|
||||
* @param sText the element text
|
||||
*/
|
||||
protected abstract void insertBibliographyItemElement(String sStyleName, String sText);
|
||||
|
||||
}
|
|
@ -16,20 +16,22 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Copyright: 2002-2014 by Henrik Just
|
||||
* Copyright: 2002-2015 by Henrik Just
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.4 (2014-09-03)
|
||||
* Version 1.6 (2015-06-16)
|
||||
*
|
||||
*/
|
||||
|
||||
package writer2latex.office;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -308,6 +310,10 @@ public class OfficeReader {
|
|||
private ListStyle outline = new ListStyle();
|
||||
private PropertySet footnotes = null;
|
||||
private PropertySet endnotes = null;
|
||||
|
||||
// Bibliographic data
|
||||
private Element bibliographyConfiguration = null;
|
||||
private List<Element> bibliographyMarks = new ArrayList<Element>();
|
||||
|
||||
// Special styles
|
||||
private StyleWithProperties[] heading = new StyleWithProperties[11];
|
||||
|
@ -582,6 +588,14 @@ public class OfficeReader {
|
|||
public boolean isIndexSourceStyle(String sStyleName) {
|
||||
return indexSourceStyles.contains(sStyleName);
|
||||
}
|
||||
|
||||
/** Get the text:bibliography-configuration element
|
||||
*
|
||||
* @return the bibliography configuration
|
||||
*/
|
||||
public Element getBibliographyConfiguration() {
|
||||
return bibliographyConfiguration;
|
||||
}
|
||||
|
||||
/** <p>Does this sequence name belong to a lof?</p>
|
||||
* @param sName the name of the sequence
|
||||
|
@ -738,6 +752,15 @@ public class OfficeReader {
|
|||
public boolean hasBookmarkRefTo(String sName) {
|
||||
return bookmarkRef.contains(sName);
|
||||
}
|
||||
|
||||
/** Get the raw list of all text:bibliography-mark elements. The marks are returned in document order and
|
||||
* includes any duplicates
|
||||
*
|
||||
* @return the list
|
||||
*/
|
||||
public List<Element> getBibliographyMarks() {
|
||||
return bibliographyMarks;
|
||||
}
|
||||
|
||||
/** <p>Is there a reference to this sequence field?
|
||||
* @param sId the id of the sequence field
|
||||
|
@ -1037,7 +1060,17 @@ public class OfficeReader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// bibliography configuration:
|
||||
if (stylesDOM==null) {
|
||||
list = contentDOM.getElementsByTagName(XMLString.TEXT_BIBLIOGRAPHY_CONFIGURATION);
|
||||
}
|
||||
else {
|
||||
list = stylesDOM.getElementsByTagName(XMLString.TEXT_BIBLIOGRAPHY_CONFIGURATION);
|
||||
}
|
||||
if (list.getLength()!=0) {
|
||||
bibliographyConfiguration = (Element) list.item(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1200,6 +1233,9 @@ public class OfficeReader {
|
|||
else if (sName.equals(XMLString.TEXT_BOOKMARK_REF)) {
|
||||
collectRefName(bookmarkRef,node);
|
||||
}
|
||||
else if (sName.equals(XMLString.TEXT_BIBLIOGRAPHY_MARK)) {
|
||||
bibliographyMarks.add(node);
|
||||
}
|
||||
else if (sName.equals(XMLString.TEXT_SEQUENCE_REF)) {
|
||||
collectRefName(sequenceRef,node);
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Copyright: 2002-2011 by Henrik Just
|
||||
* Copyright: 2002-2015 by Henrik Just
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.2 (2011-03-08)
|
||||
* Version 1.6 (2015-06-18)
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -249,6 +249,8 @@ public class XMLString {
|
|||
public static final String TEXT_FOOTNOTES_CONFIGURATION="text:footnotes-configuration";
|
||||
public static final String TEXT_ENDNOTES_CONFIGURATION="text:endnotes-configuration";
|
||||
public static final String TEXT_NOTES_CONFIGURATION="text:notes-configuration"; // oasis
|
||||
public static final String TEXT_BIBLIOGRAPHY_CONFIGURATION="text:bibliography-configuration";
|
||||
public static final String TEXT_SORT_KEY="text:sort-key";
|
||||
public static final String TEXT_SECTION_SOURCE="text:section-source";
|
||||
public static final String TEXT_SEQUENCE_DECLS="text:sequence-decls";
|
||||
public static final String TEXT_SEQUENCE_DECL="text:sequence-decl";
|
||||
|
@ -284,6 +286,10 @@ public class XMLString {
|
|||
public static final String TEXT_OBJECT_INDEX="text:object-index";
|
||||
public static final String TEXT_USER_INDEX="text:user-index";
|
||||
public static final String TEXT_BIBLIOGRAPHY="text:bibliography";
|
||||
public static final String TEXT_BIBLIOGRAPHY_SOURCE="text:bibliography-source";
|
||||
public static final String TEXT_BIBLIOGRAPHY_ENTRY_TEMPLATE="text:bibliography-entry-template";
|
||||
public static final String TEXT_INDEX_ENTRY_BIBLIOGRAPHY="text:index-entry-bibliography";
|
||||
public static final String TEXT_INDEX_ENTRY_SPAN="text:index-entry-span";
|
||||
public static final String TEXT_INDEX_TITLE_TEMPLATE="text:index-title-template";
|
||||
public static final String TEXT_INDEX_BODY="text:index-body";
|
||||
public static final String TEXT_INDEX_TITLE="text:index-title";
|
||||
|
@ -372,10 +378,18 @@ public class XMLString {
|
|||
public static final String TEXT_LIST_LEVEL_POSITION_AND_SPACE_MODE="text:list-level-position-and-space-mode"; // oasis 1.2
|
||||
public static final String TEXT_LABEL_FOLLOWED_BY="text:label-followed-by"; // oasis 1.2
|
||||
public static final String TEXT_LIST_TAB_STOP_POSITION="text:list-tab-stop-position"; // oasis 1.2
|
||||
|
||||
|
||||
public static final String TEXT_PREFIX="text:prefix";
|
||||
public static final String TEXT_SUFFIX="text:suffix";
|
||||
public static final String TEXT_NUMBERED_ENTRIES="text:numbered-entries";
|
||||
public static final String TEXT_SORT_BY_POSITION="text:sort-by-position";
|
||||
public static final String TEXT_SORT_ALGORITHM="text:sort-algorithm";
|
||||
public static final String TEXT_KEY="text:key";
|
||||
public static final String TEXT_SORT_ASCENDING="text:sort-ascending";
|
||||
public static final String TEXT_IDENTIFIER="text:identifier";
|
||||
public static final String TEXT_BIBLIOGRAPHY_TYPE="text:bibliography-type";
|
||||
public static final String TEXT_BIBILIOGRAPHIC_TYPE="text:bibiliographic-type"; // bug in OOo 1.0
|
||||
public static final String TEXT_BIBLIOGRAPHY_DATA_FIELD="text:bibliography-data-field";
|
||||
public static final String TEXT_ADDRESS="text:address";
|
||||
public static final String TEXT_ANNOTE="text:annote";
|
||||
public static final String TEXT_AUTHOR="text:author";
|
||||
|
|
53
source/java/writer2latex/util/StringComparator.java
Normal file
53
source/java/writer2latex/util/StringComparator.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/************************************************************************
|
||||
*
|
||||
* StringComparator.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-2015 by Henrik Just
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-05-19)
|
||||
*
|
||||
*/
|
||||
package writer2latex.util;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
|
||||
/** This is a <code>Comparator</code> implementation specific for objects compared by one or more string values.
|
||||
*
|
||||
* @param <T> the class to compare
|
||||
*/
|
||||
public abstract class StringComparator<T> implements Comparator<T> {
|
||||
|
||||
private Collator collator;
|
||||
|
||||
protected Collator getCollator() {
|
||||
return collator;
|
||||
}
|
||||
|
||||
protected StringComparator(String sLanguage, String sCountry) {
|
||||
if (sLanguage==null) { // use default locale
|
||||
collator = Collator.getInstance();
|
||||
}
|
||||
else {
|
||||
if (sCountry==null) { sCountry=""; }
|
||||
collator = Collator.getInstance(new Locale(sLanguage,sCountry));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,21 +20,22 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-11)
|
||||
* Version 1.6 (2015-06-19)
|
||||
*
|
||||
*/
|
||||
package writer2latex.xhtml;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import writer2latex.office.IndexMark;
|
||||
import writer2latex.office.OfficeReader;
|
||||
import writer2latex.office.XMLString;
|
||||
import writer2latex.util.Misc;
|
||||
import writer2latex.util.StringComparator;
|
||||
|
||||
// Helper class (a struct) to contain information about an alphabetical index entry.
|
||||
final class AlphabeticalEntry {
|
||||
|
@ -44,13 +45,13 @@ final class AlphabeticalEntry {
|
|||
|
||||
/** This class processes alphabetical index marks and the associated index table
|
||||
*/
|
||||
public class AlphabeticalIndexConverter extends IndexConverterBase {
|
||||
class AlphabeticalIndexConverter extends IndexConverterHelper {
|
||||
|
||||
private List<AlphabeticalEntry> index = new ArrayList<AlphabeticalEntry>(); // All words for the index
|
||||
private int nIndexIndex = -1; // Current index used for id's (of form idxN)
|
||||
private int nAlphabeticalIndex = -1; // File containing alphabetical index
|
||||
|
||||
public AlphabeticalIndexConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
AlphabeticalIndexConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
super(ofr,config,converter,XMLString.TEXT_ALPHABETICAL_INDEX_SOURCE,"index");
|
||||
}
|
||||
|
||||
|
@ -58,7 +59,7 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
|
|||
*
|
||||
* @return the file id
|
||||
*/
|
||||
public int getFileIndex() {
|
||||
int getFileIndex() {
|
||||
return nAlphabeticalIndex;
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,7 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
|
|||
* @param onode a text:alphabetical-index-mark node
|
||||
* @param hnode the link target will be added to this inline HTML node
|
||||
*/
|
||||
public void handleIndexMark(Node onode, Node hnode) {
|
||||
void handleIndexMark(Node onode, Node hnode) {
|
||||
handleIndexMark(Misc.getAttribute(onode,XMLString.TEXT_STRING_VALUE),hnode);
|
||||
}
|
||||
|
||||
|
@ -76,12 +77,12 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
|
|||
* @param onode a text:alphabetical-index-mark-start node
|
||||
* @param hnode the link target will be added to this inline HTML node
|
||||
*/
|
||||
public void handleIndexMarkStart(Node onode, Node hnode) {
|
||||
void handleIndexMarkStart(Node onode, Node hnode) {
|
||||
handleIndexMark(IndexMark.getIndexValue(onode),hnode);
|
||||
}
|
||||
|
||||
// Create an entry for an index mark
|
||||
private void handleIndexMark(String sWord, Node hnode) {
|
||||
void handleIndexMark(String sWord, Node hnode) {
|
||||
if (sWord!=null) {
|
||||
AlphabeticalEntry entry = new AlphabeticalEntry();
|
||||
entry.sWord = sWord;
|
||||
|
@ -96,14 +97,14 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
|
|||
* @param onode a text:alphabetical-index node
|
||||
* @param hnode the index will be added to this block HTML node
|
||||
*/
|
||||
@Override public void handleIndex(Element onode, Element hnode) {
|
||||
@Override void handleIndex(Element onode, Element hnode) {
|
||||
// Register the file index (we assume that there is only one alphabetical index)
|
||||
nAlphabeticalIndex = converter.getOutFileIndex();
|
||||
converter.setIndexFile(null);
|
||||
super.handleIndex(onode, hnode);
|
||||
}
|
||||
|
||||
@Override protected void populateIndex(Element source, Element container) {
|
||||
@Override void populateIndex(Element source, Element container) {
|
||||
sortEntries(source);
|
||||
String sEntryStyleName = getEntryStyleName(source);
|
||||
for (int i=0; i<=nIndexIndex; i++) {
|
||||
|
@ -117,30 +118,17 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
|
|||
}
|
||||
}
|
||||
|
||||
// Sort the list of words
|
||||
// Sort the list of words based on the language defined by the index source
|
||||
private void sortEntries(Element source) {
|
||||
// The index source may define a language to use for sorting
|
||||
Collator collator;
|
||||
String sLanguage = Misc.getAttribute(source,XMLString.FO_LANGUAGE);
|
||||
if (sLanguage==null) { // use default locale
|
||||
collator = Collator.getInstance();
|
||||
}
|
||||
else {
|
||||
String sCountry = Misc.getAttribute(source,XMLString.FO_COUNTRY);
|
||||
if (sCountry==null) { sCountry=""; }
|
||||
collator = Collator.getInstance(new Locale(sLanguage,sCountry));
|
||||
}
|
||||
// Sort the list of words using the collator
|
||||
for (int i = 0; i<=nIndexIndex; i++) {
|
||||
for (int j = i+1; j<=nIndexIndex ; j++) {
|
||||
AlphabeticalEntry entryi = index.get(i);
|
||||
AlphabeticalEntry entryj = index.get(j);
|
||||
if (collator.compare(entryi.sWord, entryj.sWord) > 0) {
|
||||
index.set(i,entryj);
|
||||
index.set(j,entryi);
|
||||
}
|
||||
}
|
||||
}
|
||||
Comparator<AlphabeticalEntry> comparator = new StringComparator<AlphabeticalEntry>(
|
||||
Misc.getAttribute(source,XMLString.FO_LANGUAGE),
|
||||
Misc.getAttribute(source, XMLString.FO_COUNTRY)) {
|
||||
|
||||
@Override public int compare(AlphabeticalEntry a, AlphabeticalEntry b) {
|
||||
return getCollator().compare(a.sWord, b.sWord);
|
||||
}
|
||||
};
|
||||
Collections.sort(index,comparator);
|
||||
}
|
||||
|
||||
// Get the style name to use for the individual words
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-12)
|
||||
* Version 1.6 (2015-06-16)
|
||||
*
|
||||
*/
|
||||
package writer2latex.xhtml;
|
||||
|
@ -32,41 +32,29 @@ import writer2latex.office.OfficeReader;
|
|||
import writer2latex.office.XMLString;
|
||||
import writer2latex.util.Misc;
|
||||
|
||||
public class BibliographyConverter extends ConverterHelper {
|
||||
/** This class handles the export of the bibliography. Most of the work is delegated to the
|
||||
* {@link XhtmlBibliographyGenerator}
|
||||
*/
|
||||
class BibliographyConverter extends IndexConverterHelper {
|
||||
|
||||
private XhtmlBibliographyGenerator bibGenerator;
|
||||
|
||||
public BibliographyConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
super(ofr,config,converter);
|
||||
BibliographyConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
super(ofr,config,converter,XMLString.TEXT_BIBLIOGRAPHY_SOURCE,"bibliography");
|
||||
bibGenerator = new XhtmlBibliographyGenerator(ofr,converter);
|
||||
}
|
||||
|
||||
public void handleBibliographyMark(Node onode, Node hnode) {
|
||||
Element anchor = converter.createLink("bibliography");
|
||||
hnode.appendChild(anchor);
|
||||
getTextCv().traversePCDATA(onode,anchor);
|
||||
void handleBibliographyMark(Node onode, Node hnode) {
|
||||
String sKey = Misc.getAttribute(onode, XMLString.TEXT_IDENTIFIER);
|
||||
if (sKey!=null) {
|
||||
Element anchor = converter.createLink("bib"+sKey);
|
||||
hnode.appendChild(anchor);
|
||||
anchor.appendChild(converter.createTextNode(bibGenerator.generateCitation(sKey)));
|
||||
}
|
||||
}
|
||||
|
||||
public void handleBibliography (Node onode, Node hnode) {
|
||||
// Use the content, not the template
|
||||
// This is a temp. solution. Later we want to be able to create
|
||||
// hyperlinks from the bib-item to the actual entry in the bibliography,
|
||||
// so we have to recreate the bibliography from the template.
|
||||
Node body = Misc.getChildByTagName(onode,XMLString.TEXT_INDEX_BODY);
|
||||
if (body!=null) {
|
||||
Element container = converter.createElement(converter.isHTML5() ? "section" : "div");
|
||||
String sStyleName = Misc.getAttribute(onode,XMLString.TEXT_STYLE_NAME);
|
||||
if (sStyleName!=null) {
|
||||
StyleInfo sectionInfo = new StyleInfo();
|
||||
getSectionSc().applyStyle(sStyleName,sectionInfo);
|
||||
applyStyle(sectionInfo,container);
|
||||
}
|
||||
|
||||
converter.addTarget(container,"bibliography");
|
||||
converter.addEpubType(container, "bibliography");
|
||||
hnode.appendChild(container);
|
||||
//asapNode = converter.createTarget("bibliography");
|
||||
Node title = Misc.getChildByTagName(body,XMLString.TEXT_INDEX_TITLE);
|
||||
if (title!=null) { getTextCv().traverseBlockText(title,container); }
|
||||
getTextCv().traverseBlockText(body,container);
|
||||
}
|
||||
@Override void populateIndex(Element source, Element container) {
|
||||
bibGenerator.populateBibliography(source, container);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-11)
|
||||
* Version 1.6 (2015-06-16)
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -36,7 +36,7 @@ import writer2latex.util.Misc;
|
|||
/** This is a base class for conversion of indexes (table of contents, bibliography, alphabetical index,
|
||||
* list of tables, list of figures)
|
||||
*/
|
||||
public abstract class IndexConverterBase extends ConverterHelper {
|
||||
abstract class IndexConverterHelper extends ConverterHelper {
|
||||
|
||||
private String sEpubType;
|
||||
private String sSourceName;
|
||||
|
@ -47,9 +47,9 @@ public abstract class IndexConverterBase extends ConverterHelper {
|
|||
* @param config the configuration
|
||||
* @param converter the converter
|
||||
* @param sSourceName the name of the source data element in the index
|
||||
* @param sEpubType the EPUB 3 semantic type
|
||||
* @param sEpubType the EPUB 3 semantic type of the index
|
||||
*/
|
||||
public IndexConverterBase(OfficeReader ofr, XhtmlConfig config, Converter converter,
|
||||
IndexConverterHelper(OfficeReader ofr, XhtmlConfig config, Converter converter,
|
||||
String sSourceName, String sEpubType) {
|
||||
super(ofr,config,converter);
|
||||
this.sSourceName = sSourceName;
|
||||
|
@ -61,14 +61,14 @@ public abstract class IndexConverterBase extends ConverterHelper {
|
|||
* @param source the index source
|
||||
* @param container an ul element to populate with list items
|
||||
*/
|
||||
protected abstract void populateIndex(Element source, Element container);
|
||||
abstract void populateIndex(Element source, Element container);
|
||||
|
||||
/** Handle an alphabetical index
|
||||
/** Handle an index
|
||||
*
|
||||
* @param onode a text:alphabetical-index node
|
||||
* @param onode an index node
|
||||
* @param hnode the index will be added to this block HTML node
|
||||
*/
|
||||
public void handleIndex(Element onode, Element hnode) {
|
||||
void handleIndex(Element onode, Element hnode) {
|
||||
Element source = Misc.getChildByTagName(onode,sSourceName);
|
||||
if (source!=null) {
|
||||
Element container = createContainer(onode, hnode);
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-11)
|
||||
* Version 1.6 (2015-06-16)
|
||||
*
|
||||
*/
|
||||
package writer2latex.xhtml;
|
||||
|
@ -59,7 +59,7 @@ final class IndexData {
|
|||
|
||||
/** This class processes table of content index marks and the associated table of content
|
||||
*/
|
||||
public class TOCConverter extends IndexConverterBase {
|
||||
class TOCConverter extends IndexConverterHelper {
|
||||
|
||||
private List<IndexData> indexes = new ArrayList<IndexData>(); // All tables of content
|
||||
private List<TocEntry> tocEntries = new ArrayList<TocEntry>(); // All potential(!) toc items
|
||||
|
@ -70,7 +70,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
|
||||
private int nExternalTocDepth = 1; // The number of levels to include in the "external" table of contents
|
||||
|
||||
public TOCConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
TOCConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
|
||||
super(ofr,config,converter,XMLString.TEXT_TABLE_OF_CONTENT_SOURCE,"toc");
|
||||
nExternalTocDepth = config.externalTocDepth();
|
||||
if (nExternalTocDepth==0) { // A value of zero means auto (i.e. determine from split level)
|
||||
|
@ -82,7 +82,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
*
|
||||
* @return the file id
|
||||
*/
|
||||
public int getFileIndex() {
|
||||
int getFileIndex() {
|
||||
return nTocFileIndex;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
* @param heading the link target will be added to this inline HTML node
|
||||
* @param sLabel the numbering label of this heading
|
||||
*/
|
||||
public void handleHeading(Element onode, Element heading, String sLabel) {
|
||||
void handleHeading(Element onode, Element heading, String sLabel) {
|
||||
int nLevel = getTextCv().getOutlineLevel(onode);
|
||||
String sTarget = "toc"+(++nTocIndex);
|
||||
converter.addTarget(heading,sTarget);
|
||||
|
@ -118,7 +118,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
|
||||
// Add in external content. For single file output we include all level 1 headings + their target
|
||||
// Targets are added only when the toc level is deeper than the split level
|
||||
public void handleHeadingExternal(Element onode, Element hnode, String sLabel) {
|
||||
void handleHeadingExternal(Element onode, Element hnode, String sLabel) {
|
||||
int nLevel = getTextCv().getOutlineLevel(onode);
|
||||
if (nLevel<=nExternalTocDepth) {
|
||||
// Add an empty div to use as target, if required
|
||||
|
@ -133,7 +133,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
}
|
||||
}
|
||||
|
||||
public void handleParagraph(Element onode, Element par, String sCurrentListLabel) {
|
||||
void handleParagraph(Element onode, Element par, String sCurrentListLabel) {
|
||||
String sStyleName = Misc.getAttribute(onode,XMLString.TEXT_STYLE_NAME);
|
||||
if (ofr.isIndexSourceStyle(getParSc().getRealParStyleName(sStyleName))) {
|
||||
converter.addTarget(par,"toc"+(++nTocIndex));
|
||||
|
@ -150,7 +150,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
* @param onode a text:toc-mark or text:toc-mark-start node
|
||||
* @param hnode the link target will be added to this inline HTML node
|
||||
*/
|
||||
public void handleTocMark(Node onode, Node hnode) {
|
||||
void handleTocMark(Node onode, Node hnode) {
|
||||
hnode.appendChild(converter.createTarget("toc"+(++nTocIndex)));
|
||||
TocEntry entry = new TocEntry();
|
||||
entry.onode = (Element) onode;
|
||||
|
@ -163,7 +163,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
* @param onode a text:alphabetical-index node
|
||||
* @param hnode the index will be added to this block HTML node
|
||||
*/
|
||||
@Override public void handleIndex(Element onode, Element hnode) {
|
||||
@Override void handleIndex(Element onode, Element hnode) {
|
||||
if (config.includeToc()) {
|
||||
if (!ofr.getTocReader((Element)onode).isByChapter()) {
|
||||
nTocFileIndex = converter.getOutFileIndex();
|
||||
|
@ -173,7 +173,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Override protected void populateIndex(Element source, Element container) {
|
||||
@Override void populateIndex(Element source, Element container) {
|
||||
// Actually we are not populating the index, but collects information to generate it later
|
||||
IndexData data = new IndexData();
|
||||
data.nOutFileIndex = converter.getOutFileIndex();
|
||||
|
@ -186,7 +186,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
/** Generate the content of all tables of content
|
||||
*
|
||||
*/
|
||||
public void generate() {
|
||||
void generate() {
|
||||
int nIndexCount = indexes.size();
|
||||
for (int i=0; i<nIndexCount; i++) {
|
||||
generateToc(indexes.get(i));
|
||||
|
@ -298,7 +298,7 @@ public class TOCConverter extends IndexConverterBase {
|
|||
}
|
||||
|
||||
// The panel is populated with a minitoc
|
||||
public void generatePanels(int nSplit) {
|
||||
void generatePanels(int nSplit) {
|
||||
// TODO: Include link to toc and index in appropriate places..
|
||||
int nLastIndex = converter.getOutFileIndex();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-11)
|
||||
* Version 1.6 (2015-06-16)
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -304,7 +304,7 @@ public class TextConverter extends ConverterHelper {
|
|||
}
|
||||
else if (nodeName.equals(XMLString.TEXT_BIBLIOGRAPHY)) {
|
||||
hnode = maybeSplit(hnode,null,1);
|
||||
bibCv.handleBibliography(child,hnode);
|
||||
bibCv.handleIndex((Element)child,(Element)hnode);
|
||||
}
|
||||
else if (nodeName.equals(XMLString.TEXT_SOFT_PAGE_BREAK)) {
|
||||
if (nPageBreakSplit==XhtmlConfig.ALL) { bPendingPageBreak = true; }
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/************************************************************************
|
||||
*
|
||||
* BibliographyGenerator.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-2015 by Henrik Just
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Version 1.6 (2015-06-18)
|
||||
*
|
||||
*/
|
||||
|
||||
package writer2latex.xhtml;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import writer2latex.base.BibliographyGenerator;
|
||||
import writer2latex.office.OfficeReader;
|
||||
|
||||
class XhtmlBibliographyGenerator extends BibliographyGenerator {
|
||||
|
||||
private Converter converter;
|
||||
private Element ul; // The container element
|
||||
private Element currentPar; // The paragraph of the current item
|
||||
|
||||
XhtmlBibliographyGenerator(OfficeReader ofr, Converter converter) {
|
||||
super(ofr);
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
/** Populate the bibliography
|
||||
*
|
||||
* @param bibliography a text:bibliography element
|
||||
* @param ul an XHTML list element to contain the code
|
||||
*/
|
||||
void populateBibliography(Element bibliography, Element ul) {
|
||||
this.ul = ul;
|
||||
generateBibliography(bibliography);
|
||||
}
|
||||
|
||||
@Override protected void insertBibliographyItem(String sStyleName, String sKey) {
|
||||
Element li = converter.createElement("li");
|
||||
converter.addTarget(li, "bib"+sKey);
|
||||
converter.addEpubType(li, "biblioentry");
|
||||
ul.appendChild(li);
|
||||
currentPar = converter.getTextCv().createParagraph(li, sStyleName);
|
||||
}
|
||||
|
||||
@Override protected void insertBibliographyItemElement(String sStyleName, String sText) {
|
||||
if (sStyleName!=null) {
|
||||
converter.getTextCv().createInline(currentPar, sStyleName).appendChild(converter.createTextNode(sText));
|
||||
}
|
||||
else {
|
||||
currentPar.appendChild(converter.createTextNode(sText));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue