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:
henrikjust 2015-06-19 15:29:06 +00:00
parent a475b5fd42
commit 67ceaae08a
12 changed files with 508 additions and 97 deletions

View file

@ -2,13 +2,16 @@ Changelog for Writer2LaTeX version 1.4 -> 1.6
---------- version 1.5.3 ---------- ---------- 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] 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 [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. 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 [w2x] Added support for semantic inflection in EPUB 3 export for the types footnote(s), endnote(s), toc, index,
and bibliography bibliography and biblioentry
(http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#sec-xhtml-semantic-inflection). (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 [w2x] Improved the semantic markup of footnotes, endnotes, table of contents and alphabetical index in HTML export

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.6 (2015-06-16) * Version 1.6 (2015-06-19)
* *
*/ */
@ -33,7 +33,7 @@ public class ConverterFactory {
// Version information // Version information
private static final String VERSION = "1.5.3"; 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 /** Return the Writer2LaTeX version in the form
* (major version).(minor version).(patch level)<br/> * (major version).(minor version).(patch level)<br/>

View 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);
}

View file

@ -16,20 +16,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2014 by Henrik Just * Copyright: 2002-2015 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-03) * Version 1.6 (2015-06-16)
* *
*/ */
package writer2latex.office; package writer2latex.office;
import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -308,6 +310,10 @@ public class OfficeReader {
private ListStyle outline = new ListStyle(); private ListStyle outline = new ListStyle();
private PropertySet footnotes = null; private PropertySet footnotes = null;
private PropertySet endnotes = null; private PropertySet endnotes = null;
// Bibliographic data
private Element bibliographyConfiguration = null;
private List<Element> bibliographyMarks = new ArrayList<Element>();
// Special styles // Special styles
private StyleWithProperties[] heading = new StyleWithProperties[11]; private StyleWithProperties[] heading = new StyleWithProperties[11];
@ -582,6 +588,14 @@ public class OfficeReader {
public boolean isIndexSourceStyle(String sStyleName) { public boolean isIndexSourceStyle(String sStyleName) {
return indexSourceStyles.contains(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> /** <p>Does this sequence name belong to a lof?</p>
* @param sName the name of the sequence * @param sName the name of the sequence
@ -738,6 +752,15 @@ public class OfficeReader {
public boolean hasBookmarkRefTo(String sName) { public boolean hasBookmarkRefTo(String sName) {
return bookmarkRef.contains(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? /** <p>Is there a reference to this sequence field?
* @param sId the id of the 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)) { else if (sName.equals(XMLString.TEXT_BOOKMARK_REF)) {
collectRefName(bookmarkRef,node); collectRefName(bookmarkRef,node);
} }
else if (sName.equals(XMLString.TEXT_BIBLIOGRAPHY_MARK)) {
bibliographyMarks.add(node);
}
else if (sName.equals(XMLString.TEXT_SEQUENCE_REF)) { else if (sName.equals(XMLString.TEXT_SEQUENCE_REF)) {
collectRefName(sequenceRef,node); collectRefName(sequenceRef,node);
} }

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2015 by Henrik Just
* *
* All Rights Reserved. * 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_FOOTNOTES_CONFIGURATION="text:footnotes-configuration";
public static final String TEXT_ENDNOTES_CONFIGURATION="text:endnotes-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_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_SECTION_SOURCE="text:section-source";
public static final String TEXT_SEQUENCE_DECLS="text:sequence-decls"; public static final String TEXT_SEQUENCE_DECLS="text:sequence-decls";
public static final String TEXT_SEQUENCE_DECL="text:sequence-decl"; 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_OBJECT_INDEX="text:object-index";
public static final String TEXT_USER_INDEX="text:user-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="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_TITLE_TEMPLATE="text:index-title-template";
public static final String TEXT_INDEX_BODY="text:index-body"; public static final String TEXT_INDEX_BODY="text:index-body";
public static final String TEXT_INDEX_TITLE="text:index-title"; 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_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_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_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_IDENTIFIER="text:identifier";
public static final String TEXT_BIBLIOGRAPHY_TYPE="text:bibliography-type"; 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_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_ADDRESS="text:address";
public static final String TEXT_ANNOTE="text:annote"; public static final String TEXT_ANNOTE="text:annote";
public static final String TEXT_AUTHOR="text:author"; public static final String TEXT_AUTHOR="text:author";

View 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));
}
}
}

View file

@ -20,21 +20,22 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.6 (2015-06-11) * Version 1.6 (2015-06-19)
* *
*/ */
package writer2latex.xhtml; package writer2latex.xhtml;
import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import writer2latex.office.IndexMark; import writer2latex.office.IndexMark;
import writer2latex.office.OfficeReader; import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString; import writer2latex.office.XMLString;
import writer2latex.util.Misc; import writer2latex.util.Misc;
import writer2latex.util.StringComparator;
// Helper class (a struct) to contain information about an alphabetical index entry. // Helper class (a struct) to contain information about an alphabetical index entry.
final class AlphabeticalEntry { final class AlphabeticalEntry {
@ -44,13 +45,13 @@ final class AlphabeticalEntry {
/** This class processes alphabetical index marks and the associated index table /** 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 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 nIndexIndex = -1; // Current index used for id's (of form idxN)
private int nAlphabeticalIndex = -1; // File containing alphabetical index 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"); super(ofr,config,converter,XMLString.TEXT_ALPHABETICAL_INDEX_SOURCE,"index");
} }
@ -58,7 +59,7 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
* *
* @return the file id * @return the file id
*/ */
public int getFileIndex() { int getFileIndex() {
return nAlphabeticalIndex; return nAlphabeticalIndex;
} }
@ -67,7 +68,7 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
* @param onode a text:alphabetical-index-mark node * @param onode a text:alphabetical-index-mark node
* @param hnode the link target will be added to this inline HTML 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); 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 onode a text:alphabetical-index-mark-start node
* @param hnode the link target will be added to this inline HTML 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); handleIndexMark(IndexMark.getIndexValue(onode),hnode);
} }
// Create an entry for an index mark // Create an entry for an index mark
private void handleIndexMark(String sWord, Node hnode) { void handleIndexMark(String sWord, Node hnode) {
if (sWord!=null) { if (sWord!=null) {
AlphabeticalEntry entry = new AlphabeticalEntry(); AlphabeticalEntry entry = new AlphabeticalEntry();
entry.sWord = sWord; entry.sWord = sWord;
@ -96,14 +97,14 @@ public class AlphabeticalIndexConverter extends IndexConverterBase {
* @param onode a text:alphabetical-index node * @param onode a text:alphabetical-index node
* @param hnode the index will be added to this block HTML 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) // Register the file index (we assume that there is only one alphabetical index)
nAlphabeticalIndex = converter.getOutFileIndex(); nAlphabeticalIndex = converter.getOutFileIndex();
converter.setIndexFile(null); converter.setIndexFile(null);
super.handleIndex(onode, hnode); super.handleIndex(onode, hnode);
} }
@Override protected void populateIndex(Element source, Element container) { @Override void populateIndex(Element source, Element container) {
sortEntries(source); sortEntries(source);
String sEntryStyleName = getEntryStyleName(source); String sEntryStyleName = getEntryStyleName(source);
for (int i=0; i<=nIndexIndex; i++) { 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) { private void sortEntries(Element source) {
// The index source may define a language to use for sorting Comparator<AlphabeticalEntry> comparator = new StringComparator<AlphabeticalEntry>(
Collator collator; Misc.getAttribute(source,XMLString.FO_LANGUAGE),
String sLanguage = Misc.getAttribute(source,XMLString.FO_LANGUAGE); Misc.getAttribute(source, XMLString.FO_COUNTRY)) {
if (sLanguage==null) { // use default locale
collator = Collator.getInstance(); @Override public int compare(AlphabeticalEntry a, AlphabeticalEntry b) {
} return getCollator().compare(a.sWord, b.sWord);
else { }
String sCountry = Misc.getAttribute(source,XMLString.FO_COUNTRY); };
if (sCountry==null) { sCountry=""; } Collections.sort(index,comparator);
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);
}
}
}
} }
// Get the style name to use for the individual words // Get the style name to use for the individual words

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.6 (2015-06-12) * Version 1.6 (2015-06-16)
* *
*/ */
package writer2latex.xhtml; package writer2latex.xhtml;
@ -32,41 +32,29 @@ import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString; import writer2latex.office.XMLString;
import writer2latex.util.Misc; 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) { BibliographyConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
super(ofr,config,converter); super(ofr,config,converter,XMLString.TEXT_BIBLIOGRAPHY_SOURCE,"bibliography");
bibGenerator = new XhtmlBibliographyGenerator(ofr,converter);
} }
public void handleBibliographyMark(Node onode, Node hnode) { void handleBibliographyMark(Node onode, Node hnode) {
Element anchor = converter.createLink("bibliography"); String sKey = Misc.getAttribute(onode, XMLString.TEXT_IDENTIFIER);
hnode.appendChild(anchor); if (sKey!=null) {
getTextCv().traversePCDATA(onode,anchor); Element anchor = converter.createLink("bib"+sKey);
hnode.appendChild(anchor);
anchor.appendChild(converter.createTextNode(bibGenerator.generateCitation(sKey)));
}
} }
public void handleBibliography (Node onode, Node hnode) { @Override void populateIndex(Element source, Element container) {
// Use the content, not the template bibGenerator.populateBibliography(source, container);
// 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);
}
} }
} }

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * 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, /** This is a base class for conversion of indexes (table of contents, bibliography, alphabetical index,
* list of tables, list of figures) * list of tables, list of figures)
*/ */
public abstract class IndexConverterBase extends ConverterHelper { abstract class IndexConverterHelper extends ConverterHelper {
private String sEpubType; private String sEpubType;
private String sSourceName; private String sSourceName;
@ -47,9 +47,9 @@ public abstract class IndexConverterBase extends ConverterHelper {
* @param config the configuration * @param config the configuration
* @param converter the converter * @param converter the converter
* @param sSourceName the name of the source data element in the index * @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) { String sSourceName, String sEpubType) {
super(ofr,config,converter); super(ofr,config,converter);
this.sSourceName = sSourceName; this.sSourceName = sSourceName;
@ -61,14 +61,14 @@ public abstract class IndexConverterBase extends ConverterHelper {
* @param source the index source * @param source the index source
* @param container an ul element to populate with list items * @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 * @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); Element source = Misc.getChildByTagName(onode,sSourceName);
if (source!=null) { if (source!=null) {
Element container = createContainer(onode, hnode); Element container = createContainer(onode, hnode);

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.6 (2015-06-11) * Version 1.6 (2015-06-16)
* *
*/ */
package writer2latex.xhtml; package writer2latex.xhtml;
@ -59,7 +59,7 @@ final class IndexData {
/** This class processes table of content index marks and the associated table of content /** 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<IndexData> indexes = new ArrayList<IndexData>(); // All tables of content
private List<TocEntry> tocEntries = new ArrayList<TocEntry>(); // All potential(!) toc items 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 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"); super(ofr,config,converter,XMLString.TEXT_TABLE_OF_CONTENT_SOURCE,"toc");
nExternalTocDepth = config.externalTocDepth(); nExternalTocDepth = config.externalTocDepth();
if (nExternalTocDepth==0) { // A value of zero means auto (i.e. determine from split level) 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 * @return the file id
*/ */
public int getFileIndex() { int getFileIndex() {
return nTocFileIndex; 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 heading the link target will be added to this inline HTML node
* @param sLabel the numbering label of this heading * @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); int nLevel = getTextCv().getOutlineLevel(onode);
String sTarget = "toc"+(++nTocIndex); String sTarget = "toc"+(++nTocIndex);
converter.addTarget(heading,sTarget); 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 // 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 // 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); int nLevel = getTextCv().getOutlineLevel(onode);
if (nLevel<=nExternalTocDepth) { if (nLevel<=nExternalTocDepth) {
// Add an empty div to use as target, if required // 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); String sStyleName = Misc.getAttribute(onode,XMLString.TEXT_STYLE_NAME);
if (ofr.isIndexSourceStyle(getParSc().getRealParStyleName(sStyleName))) { if (ofr.isIndexSourceStyle(getParSc().getRealParStyleName(sStyleName))) {
converter.addTarget(par,"toc"+(++nTocIndex)); 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 onode a text:toc-mark or text:toc-mark-start node
* @param hnode the link target will be added to this inline HTML 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))); hnode.appendChild(converter.createTarget("toc"+(++nTocIndex)));
TocEntry entry = new TocEntry(); TocEntry entry = new TocEntry();
entry.onode = (Element) onode; entry.onode = (Element) onode;
@ -163,7 +163,7 @@ public class TOCConverter extends IndexConverterBase {
* @param onode a text:alphabetical-index node * @param onode a text:alphabetical-index node
* @param hnode the index will be added to this block HTML 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 (config.includeToc()) {
if (!ofr.getTocReader((Element)onode).isByChapter()) { if (!ofr.getTocReader((Element)onode).isByChapter()) {
nTocFileIndex = converter.getOutFileIndex(); 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 // Actually we are not populating the index, but collects information to generate it later
IndexData data = new IndexData(); IndexData data = new IndexData();
data.nOutFileIndex = converter.getOutFileIndex(); data.nOutFileIndex = converter.getOutFileIndex();
@ -186,7 +186,7 @@ public class TOCConverter extends IndexConverterBase {
/** Generate the content of all tables of content /** Generate the content of all tables of content
* *
*/ */
public void generate() { void generate() {
int nIndexCount = indexes.size(); int nIndexCount = indexes.size();
for (int i=0; i<nIndexCount; i++) { for (int i=0; i<nIndexCount; i++) {
generateToc(indexes.get(i)); generateToc(indexes.get(i));
@ -298,7 +298,7 @@ public class TOCConverter extends IndexConverterBase {
} }
// The panel is populated with a minitoc // 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.. // TODO: Include link to toc and index in appropriate places..
int nLastIndex = converter.getOutFileIndex(); int nLastIndex = converter.getOutFileIndex();

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * 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)) { else if (nodeName.equals(XMLString.TEXT_BIBLIOGRAPHY)) {
hnode = maybeSplit(hnode,null,1); hnode = maybeSplit(hnode,null,1);
bibCv.handleBibliography(child,hnode); bibCv.handleIndex((Element)child,(Element)hnode);
} }
else if (nodeName.equals(XMLString.TEXT_SOFT_PAGE_BREAK)) { else if (nodeName.equals(XMLString.TEXT_SOFT_PAGE_BREAK)) {
if (nPageBreakSplit==XhtmlConfig.ALL) { bPendingPageBreak = true; } if (nPageBreakSplit==XhtmlConfig.ALL) { bPendingPageBreak = true; }

View file

@ -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));
}
}
}