w2x: Refactoring of index export

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@250 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2015-06-11 18:39:29 +00:00
parent c447b5ee2a
commit 9194604f27
10 changed files with 978 additions and 568 deletions

View file

@ -2,6 +2,14 @@ Changelog for Writer2LaTeX version 1.4 -> 1.6
---------- version 1.5.3 ---------- ---------- version 1.5.3 ----------
[w2x] Added support for semantic inflection in EPUB 3 export for the types toc, index
(http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#sec-xhtml-semantic-inflection).
[w2x] Improved the semantic markup of the table of contents and the alphabetical index in HTML export using sections,
headings and lists
[w2x] Added support for background color of alphabetical index and bibliography
[w2x] Bugfix: Export of list-style-type now uses the correct values disc, circle, square (in that order) [w2x] Bugfix: Export of list-style-type now uses the correct values disc, circle, square (in that order)
[w2l] UI strings in the code are now externalized for localization [w2l] UI strings in the code are now externalized for localization

View file

@ -0,0 +1,164 @@
/************************************************************************
*
* AlphabeticalIndexConverter.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-11)
*
*/
package writer2latex.xhtml;
import java.text.Collator;
import java.util.ArrayList;
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;
// Helper class (a struct) to contain information about an alphabetical index entry.
final class AlphabeticalEntry {
String sWord; // the word for the index
int nIndex; // the original index of this entry
}
/** This class processes alphabetical index marks and the associated index table
*/
public class AlphabeticalIndexConverter extends IndexConverterBase {
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) {
super(ofr,config,converter,XMLString.TEXT_ALPHABETICAL_INDEX_SOURCE,"index");
}
/** Return the id of the file containing the alphabetical index
*
* @return the file id
*/
public int getFileIndex() {
return nAlphabeticalIndex;
}
/** Handle an alphabetical index mark
*
* @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) {
handleIndexMark(Misc.getAttribute(onode,XMLString.TEXT_STRING_VALUE),hnode);
}
/** Handle an alphabetical index mark start
*
* @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) {
handleIndexMark(IndexMark.getIndexValue(onode),hnode);
}
// Create an entry for an index mark
private void handleIndexMark(String sWord, Node hnode) {
if (sWord!=null) {
AlphabeticalEntry entry = new AlphabeticalEntry();
entry.sWord = sWord;
entry.nIndex = ++nIndexIndex;
index.add(entry);
hnode.appendChild(converter.createTarget("idx"+nIndexIndex));
}
}
/** Handle an alphabetical index
*
* @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) {
// 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) {
sortEntries(source);
String sEntryStyleName = getEntryStyleName(source);
for (int i=0; i<=nIndexIndex; i++) {
AlphabeticalEntry entry = index.get(i);
Element li = converter.createElement("li");
container.appendChild(li);
Element p = getTextCv().createParagraph(li,sEntryStyleName);
Element a = converter.createLink("idx"+entry.nIndex);
p.appendChild(a);
a.appendChild(converter.createTextNode(entry.sWord));
}
}
// Sort the list of words
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);
}
}
}
}
// Get the style name to use for the individual words
private String getEntryStyleName(Element source) {
// TODO: Should read the entire template
Node child = source.getFirstChild();
while (child!=null) {
if (child.getNodeType() == Node.ELEMENT_NODE
&& child.getNodeName().equals(XMLString.TEXT_ALPHABETICAL_INDEX_ENTRY_TEMPLATE)) {
// Note: There are actually three outline-levels: separator, 1, 2 and 3
int nLevel = Misc.getPosInteger(Misc.getAttribute(child,XMLString.TEXT_OUTLINE_LEVEL),0);
if (nLevel==1) {
return Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
}
}
child = child.getNextSibling();
}
return null;
}
}

View file

@ -0,0 +1,71 @@
/************************************************************************
*
* BibliographyConverter.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-11)
*
*/
package writer2latex.xhtml;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString;
import writer2latex.util.Misc;
public class BibliographyConverter extends ConverterHelper {
public BibliographyConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
super(ofr,config,converter);
}
public void handleBibliographyMark(Node onode, Node hnode) {
Element anchor = converter.createLink("bibliography");
hnode.appendChild(anchor);
getTextCv().traversePCDATA(onode,anchor);
}
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 div = converter.createElement("div");
String sStyleName = Misc.getAttribute(onode,XMLString.TEXT_STYLE_NAME);
if (sStyleName!=null) {
StyleInfo sectionInfo = new StyleInfo();
getSectionSc().applyStyle(sStyleName,sectionInfo);
applyStyle(sectionInfo,div);
}
converter.addTarget(div,"bibliography");
hnode.appendChild(div);
//asapNode = converter.createTarget("bibliography");
Node title = Misc.getChildByTagName(body,XMLString.TEXT_INDEX_TITLE);
if (title!=null) { getTextCv().traverseBlockText(title,div); }
getTextCv().traverseBlockText(body,div);
}
}
}

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-2014 by Henrik Just * Copyright: 2002-2015 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-18) * Version 1.6 (2015-06-11)
* *
*/ */
@ -192,6 +192,8 @@ public class Converter extends ConverterBase {
protected MathConverter getMathCv() { return mathCv; } protected MathConverter getMathCv() { return mathCv; }
protected int getType() { return nType; } protected int getType() { return nType; }
public boolean isHTML5() { return nType==XhtmlDocument.HTML5; }
protected int getOutFileIndex() { return nOutFileIndex; } protected int getOutFileIndex() { return nOutFileIndex; }
@ -236,7 +238,7 @@ public class Converter extends ConverterBase {
public void setOPS(boolean b) { bOPS = true; } public void setOPS(boolean b) { bOPS = true; }
public boolean isOPS() { return bOPS; } public boolean isOPS() { return bOPS; }
@Override public void convertInner() throws IOException { @Override public void convertInner() throws IOException {
sTargetFileName = Misc.trimDocumentName(sTargetFileName,XhtmlDocument.getExtension(nType)); sTargetFileName = Misc.trimDocumentName(sTargetFileName,XhtmlDocument.getExtension(nType));
@ -643,6 +645,7 @@ public class Converter extends ConverterBase {
htmlDOM = htmlDoc.getContentDOM(); htmlDOM = htmlDoc.getContentDOM();
Element rootElement = htmlDOM.getDocumentElement(); Element rootElement = htmlDOM.getDocumentElement();
styleCv.applyDefaultLanguage(rootElement); styleCv.applyDefaultLanguage(rootElement);
addEpubNs(rootElement);
rootElement.insertBefore(htmlDOM.createComment( rootElement.insertBefore(htmlDOM.createComment(
"This file was converted to xhtml by " "This file was converted to xhtml by "
+ (ofr.isText() ? "Writer" : (ofr.isSpreadsheet() ? "Calc" : "Impress")) + (ofr.isText() ? "Writer" : (ofr.isSpreadsheet() ? "Calc" : "Impress"))
@ -776,6 +779,20 @@ public class Converter extends ConverterBase {
return htmlDoc.getContentNode(); return htmlDoc.getContentNode();
} }
// Add epub namespace for the purpose of semantic inflection in EPUB 3
public void addEpubNs(Element elm) {
if (bOPS && nType==XhtmlDocument.HTML5) {
elm.setAttribute("xmlns:epub", "http://www.idpf.org/2007/ops");
}
}
// Add a type from the structural semantics vocabulary of EPUB 3
public void addEpubType(Element elm, String sType) {
if (bOPS && nType==XhtmlDocument.HTML5 && sType!=null) {
elm.setAttribute("epub:type", sType);
}
}
// create a target // create a target
public Element createTarget(String sId) { public Element createTarget(String sId) {

View file

@ -16,13 +16,19 @@
* 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.6 (2014-10-24) * Version 1.6 (2015-06-10)
* *
*/package writer2latex.xhtml; */
package writer2latex.xhtml;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import writer2latex.office.OfficeReader; import writer2latex.office.OfficeReader;
import writer2latex.office.OfficeStyleFamily; import writer2latex.office.OfficeStyleFamily;
@ -30,6 +36,9 @@ import writer2latex.office.StyleWithProperties;
import writer2latex.util.CSVList; import writer2latex.util.CSVList;
public class HeadingStyleConverter extends StyleConverterHelper { public class HeadingStyleConverter extends StyleConverterHelper {
// Sets of additional styles (other than the main heading style for the level)
private List<Set<String>> otherLevelStyles;
public HeadingStyleConverter(OfficeReader ofr, XhtmlConfig config, public HeadingStyleConverter(OfficeReader ofr, XhtmlConfig config,
Converter converter, int nType) { Converter converter, int nType) {
@ -37,6 +46,10 @@ public class HeadingStyleConverter extends StyleConverterHelper {
this.styleMap = config.getXHeadingStyleMap(); this.styleMap = config.getXHeadingStyleMap();
this.bConvertStyles = config.xhtmlFormatting()==XhtmlConfig.CONVERT_ALL || config.xhtmlFormatting()==XhtmlConfig.IGNORE_HARD; this.bConvertStyles = config.xhtmlFormatting()==XhtmlConfig.CONVERT_ALL || config.xhtmlFormatting()==XhtmlConfig.IGNORE_HARD;
this.bConvertHard = config.xhtmlFormatting()==XhtmlConfig.CONVERT_ALL || config.xhtmlFormatting()==XhtmlConfig.IGNORE_STYLES; this.bConvertHard = config.xhtmlFormatting()==XhtmlConfig.CONVERT_ALL || config.xhtmlFormatting()==XhtmlConfig.IGNORE_STYLES;
this.otherLevelStyles = new ArrayList<Set<String>>();
for (int i=0; i<=6; i++) {
otherLevelStyles.add(new HashSet<String>());
}
} }
@Override @Override
@ -44,6 +57,7 @@ public class HeadingStyleConverter extends StyleConverterHelper {
if (bConvertStyles) { if (bConvertStyles) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
for (int i=1; i<=6; i++) { for (int i=1; i<=6; i++) {
// Convert main style for this level
if (ofr.getHeadingStyle(i)!=null) { if (ofr.getHeadingStyle(i)!=null) {
CSVList props = new CSVList(";"); CSVList props = new CSVList(";");
getParSc().applyProperties(ofr.getHeadingStyle(i),props,true); getParSc().applyProperties(ofr.getHeadingStyle(i),props,true);
@ -51,6 +65,16 @@ public class HeadingStyleConverter extends StyleConverterHelper {
buf.append(sIndent).append("h").append(i) buf.append(sIndent).append("h").append(i)
.append(" {").append(props.toString()).append("}").append(config.prettyPrint() ? "\n" : " "); .append(" {").append(props.toString()).append("}").append(config.prettyPrint() ? "\n" : " ");
} }
// Convert other styles for this level
for (String sDisplayName : otherLevelStyles.get(i)) {
StyleWithProperties style = (StyleWithProperties)
getStyles().getStyleByDisplayName(sDisplayName);
CSVList props = new CSVList(";");
getParSc().applyProperties(style,props,true);
props.addValue("clear","left");
buf.append(sIndent).append("h").append(i).append(".").append(styleNames.getExportName(sDisplayName))
.append(" {").append(props.toString()).append("}").append(config.prettyPrint() ? "\n" : " ");
}
} }
return buf.toString(); return buf.toString();
} }
@ -88,8 +112,12 @@ public class HeadingStyleConverter extends StyleConverterHelper {
info.sClass = map.sBlockCss; info.sClass = map.sBlockCss;
} }
} }
else { else if (style!=ofr.getHeadingStyle(nLevel)) {
// TODO: Apply style if different from main style for this level // This is not the main style for this level, add class and remember
info.sClass = styleNames.getExportName(sDisplayName);
if (1<=nLevel && nLevel<=6) {
otherLevelStyles.get(nLevel).add(sDisplayName);
}
} }
} }
} }

View file

@ -0,0 +1,125 @@
/************************************************************************
*
* IndexConverterBase.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-11)
*
*/
package writer2latex.xhtml;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString;
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 {
private String sEpubType;
private String sSourceName;
/** Construct a new index converter
*
* @param ofr the office reader used to read the source document
* @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
*/
public IndexConverterBase(OfficeReader ofr, XhtmlConfig config, Converter converter,
String sSourceName, String sEpubType) {
super(ofr,config,converter);
this.sSourceName = sSourceName;
this.sEpubType = sEpubType;
}
/** Generate the actual contents of the index
*
* @param source the index source
* @param container an ul element to populate with list items
*/
protected abstract void populateIndex(Element source, Element container);
/** Handle an alphabetical index
*
* @param onode a text:alphabetical-index node
* @param hnode the index will be added to this block HTML node
*/
public void handleIndex(Element onode, Element hnode) {
Element source = Misc.getChildByTagName(onode,sSourceName);
if (source!=null) {
Element container = createContainer(onode, hnode);
generateTitle(source, container);
generateIndex(source, container);
}
}
// Create a container node for the index
private Element createContainer(Element source, Element hnode) {
Element container = converter.createElement(converter.isHTML5() ? "section" : "div");
hnode.appendChild(container);
converter.addEpubType(container, sEpubType);
String sName = source.getAttribute(XMLString.TEXT_NAME);
if (sName!=null) {
converter.addTarget(container,sName);
}
String sStyleName = source.getAttribute(XMLString.TEXT_STYLE_NAME);
if (sStyleName!=null) {
StyleInfo sectionInfo = new StyleInfo();
getSectionSc().applyStyle(sStyleName,sectionInfo);
applyStyle(sectionInfo,container);
}
return container;
}
// Generate the index title and add it to the container
private void generateTitle(Element source, Element container) {
Node title = Misc.getChildByTagName(source,XMLString.TEXT_INDEX_TITLE_TEMPLATE);
if (title!=null) {
Element h1 = converter.createElement("h1");
container.appendChild(h1);
String sStyleName = Misc.getAttribute(title,XMLString.TEXT_STYLE_NAME);
StyleInfo info = new StyleInfo();
info.sTagName = "h1";
getHeadingSc().applyStyle(1, sStyleName, info);
applyStyle(info,h1);
getTextCv().traversePCDATA(title,h1);
}
}
// Generate the index and add it to the container
private void generateIndex(Element source, Element container) {
Element ul = converter.createElement("ul");
// TODO: Support column formatting from the index source
ul.setAttribute("style", "list-style-type:none;margin:0;padding:0");
container.appendChild(ul);
populateIndex(source,ul);
}
}

View file

@ -0,0 +1,42 @@
/************************************************************************
*
* LOFConverter.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-10)
*
*/
package writer2latex.xhtml;
import org.w3c.dom.Node;
import writer2latex.office.OfficeReader;
public class LOFConverter extends ConverterHelper {
public LOFConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
super(ofr,config,converter);
}
public void handleLOF(Node onode, Node hnode) {
// TODO
}
}

View file

@ -0,0 +1,42 @@
/************************************************************************
*
* LOTConverter.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-10)
*
*/
package writer2latex.xhtml;
import org.w3c.dom.Node;
import writer2latex.office.OfficeReader;
public class LOTConverter extends ConverterHelper {
public LOTConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
super(ofr,config,converter);
}
public void handleLOT(Node onode, Node hnode) {
// TODO
}
}

View file

@ -0,0 +1,427 @@
/************************************************************************
*
* TOCConverter.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-11)
*
*/
package writer2latex.xhtml;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import writer2latex.office.IndexMark;
import writer2latex.office.ListCounter;
import writer2latex.office.OfficeReader;
import writer2latex.office.TocReader;
import writer2latex.office.XMLString;
import writer2latex.util.Misc;
import writer2latex.xhtml.l10n.L10n;
//Helper class (a struct) to contain information about a toc entry (ie. a heading, other paragraph or toc-mark)
final class TocEntry {
Element onode; // the original node
String sLabel = null; // generated label for the entry
int nFileIndex; // the file index for the generated content
int nOutlineLevel; // the outline level for this heading
int[] nOutlineNumber; // the natural outline number for this heading
}
//Helper class (a struct) to point back to indexes that should be processed
final class IndexData {
int nOutFileIndex; // the index of the out file containing the index
Element onode; // the original node
Element chapter; // the chapter containing this toc
Element hnode; // a block node where the index should be added
}
// TODO: This class needs some refactoring
/** This class processes table of content index marks and the associated table of content
*/
public class TOCConverter extends IndexConverterBase {
private List<IndexData> indexes = new ArrayList<IndexData>(); // All tables of content
private List<TocEntry> tocEntries = new ArrayList<TocEntry>(); // All potential(!) toc items
private int nTocFileIndex = -1; // file index for main toc
private Element currentChapter = null; // Node for the current chapter (level 1) heading
private int nTocIndex = -1; // Current index for id's (of form tocN)
private ListCounter naturalOutline = new ListCounter(); // Current "natural" outline number
private int nExternalTocDepth = 1; // The number of levels to include in the "external" table of contents
public 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)
nExternalTocDepth = Math.max(config.getXhtmlSplitLevel(),1);
}
}
/** Return the id of the file containing the alphabetical index
*
* @return the file id
*/
public int getFileIndex() {
return nTocFileIndex;
}
/** Handle a heading as a table of content entry
*
* @param onode the text:h element
* @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) {
int nLevel = getTextCv().getOutlineLevel(onode);
String sTarget = "toc"+(++nTocIndex);
converter.addTarget(heading,sTarget);
this.currentChapter = onode;
// 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
if (nLevel<=nExternalTocDepth) {
converter.addContentEntry(sLabel+converter.getPlainInlineText(onode), nLevel,
nLevel>config.getXhtmlSplitLevel() ? sTarget : null);
}
// Add to real toc
TocEntry entry = new TocEntry();
entry.onode = onode;
entry.sLabel = sLabel;
entry.nFileIndex = converter.getOutFileIndex();
entry.nOutlineLevel = nLevel;
entry.nOutlineNumber = naturalOutline.step(nLevel).getValues();
tocEntries.add(entry);
}
// 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) {
int nLevel = getTextCv().getOutlineLevel(onode);
if (nLevel<=nExternalTocDepth) {
// Add an empty div to use as target, if required
String sTarget = null;
if (nLevel>config.getXhtmlSplitLevel()) {
Element div = converter.createElement("div");
hnode.appendChild(div);
sTarget = "toc"+(++nTocIndex);
converter.addTarget(div,sTarget);
}
converter.addContentEntry(sLabel+converter.getPlainInlineText(onode), nLevel, sTarget);
}
}
public 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));
TocEntry entry = new TocEntry();
entry.onode = (Element) onode;
entry.sLabel = sCurrentListLabel;
entry.nFileIndex = converter.getOutFileIndex();
tocEntries.add(entry);
}
}
/** Handle a table of contents mark
*
* @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) {
hnode.appendChild(converter.createTarget("toc"+(++nTocIndex)));
TocEntry entry = new TocEntry();
entry.onode = (Element) onode;
entry.nFileIndex = converter.getOutFileIndex();
tocEntries.add(entry);
}
/** Handle a table of contents
*
* @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) {
if (config.includeToc()) {
if (!ofr.getTocReader((Element)onode).isByChapter()) {
nTocFileIndex = converter.getOutFileIndex();
}
converter.setTocFile(null);
super.handleIndex(onode,hnode);
}
}
@Override protected 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();
data.onode = source;
data.chapter = currentChapter;
data.hnode = container;
indexes.add(data);
}
/** Generate the content of all tables of content
*
*/
public void generate() {
int nIndexCount = indexes.size();
for (int i=0; i<nIndexCount; i++) {
generateToc(indexes.get(i));
}
}
private void generateToc(IndexData data) {
Element onode = data.onode;
Element chapter = data.chapter;
Element ul = data.hnode;
int nSaveOutFileIndex = converter.getOutFileIndex();
converter.changeOutFile(data.nOutFileIndex);
TocReader tocReader = ofr.getTocReader((Element)onode.getParentNode());
// TODO: Read the entire content of the entry templates!
String[] sEntryStyleName = new String[11];
for (int i=1; i<=10; i++) {
Element entryTemplate = tocReader.getTocEntryTemplate(i);
if (entryTemplate!=null) {
sEntryStyleName[i] = Misc.getAttribute(entryTemplate,XMLString.TEXT_STYLE_NAME);
}
}
int nStart = 0;
int nLen = tocEntries.size();
// Find the chapter
if (tocReader.isByChapter() && chapter!=null) {
for (int i=0; i<nLen; i++) {
TocEntry entry = tocEntries.get(i);
if (entry.onode==chapter) { nStart=i; break; }
}
}
// Generate entries
for (int i=nStart; i<nLen; i++) {
Element li = converter.createElement("li");
ul.appendChild(li);
TocEntry entry = tocEntries.get(i);
String sNodeName = entry.onode.getTagName();
if (XMLString.TEXT_H.equals(sNodeName)) {
int nLevel = getTextCv().getOutlineLevel(entry.onode);
if (nLevel==1 && tocReader.isByChapter() && entry.onode!=chapter) { break; }
if (tocReader.useOutlineLevel() && nLevel<=tocReader.getOutlineLevel()) {
Element p = getTextCv().createParagraph(li,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
Element span = converter.createElement("span");
p.appendChild(span);
span.setAttribute("class","SectionNumber");
span.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
getTextCv().traverseInlineText(entry.onode,a);
}
else {
String sStyleName = getParSc().getRealParStyleName(entry.onode.getAttribute(XMLString.TEXT_STYLE_NAME));
nLevel = tocReader.getIndexSourceStyleLevel(sStyleName);
if (tocReader.useIndexSourceStyles() && 1<=nLevel && nLevel<=tocReader.getOutlineLevel()) {
Element p = getTextCv().createParagraph(li,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
p.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
getTextCv().traverseInlineText(entry.onode,a);
}
}
}
else if (XMLString.TEXT_P.equals(sNodeName)) {
String sStyleName = getParSc().getRealParStyleName(entry.onode.getAttribute(XMLString.TEXT_STYLE_NAME));
int nLevel = tocReader.getIndexSourceStyleLevel(sStyleName);
if (tocReader.useIndexSourceStyles() && 1<=nLevel && nLevel<=tocReader.getOutlineLevel()) {
Element p = getTextCv().createParagraph(li,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
p.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
getTextCv().traverseInlineText(entry.onode,a);
}
}
else if (XMLString.TEXT_TOC_MARK.equals(sNodeName)) {
int nLevel = Misc.getPosInteger(entry.onode.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1);
if (tocReader.useIndexMarks() && nLevel<=tocReader.getOutlineLevel()) {
Element p = getTextCv().createParagraph(li,sEntryStyleName[nLevel]);
Element a = converter.createLink("toc"+i);
p.appendChild(a);
a.appendChild(converter.createTextNode(IndexMark.getIndexValue(entry.onode)));
}
}
else if (XMLString.TEXT_TOC_MARK_START.equals(sNodeName)) {
int nLevel = Misc.getPosInteger(entry.onode.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1);
if (tocReader.useIndexMarks() && nLevel<=tocReader.getOutlineLevel()) {
Element p = getTextCv().createParagraph(li,sEntryStyleName[nLevel]);
Element a = converter.createLink("toc"+i);
p.appendChild(a);
a.appendChild(converter.createTextNode(IndexMark.getIndexValue(entry.onode)));
}
}
}
converter.changeOutFile(nSaveOutFileIndex);
}
// The panel is populated with a minitoc
public void generatePanels(int nSplit) {
// TODO: Include link to toc and index in appropriate places..
int nLastIndex = converter.getOutFileIndex();
boolean bHasFrontMatter = false;
TocEntry fakeEntry = new TocEntry();
fakeEntry.nOutlineLevel = 0;
fakeEntry.nOutlineNumber = new int[11];
int nLen = tocEntries.size();
for (int nIndex=0; nIndex<=nLastIndex; nIndex++) {
converter.changeOutFile(nIndex);
Element panel = converter.getPanelNode();
if (panel!=null) {
// Get the last heading of level <= split level for this file
TocEntry entryCurrent = null;
for (int i=nLen-1; i>=0; i--) {
TocEntry entry = tocEntries.get(i);
if (XMLString.TEXT_H.equals(entry.onode.getTagName()) && entry.nFileIndex==nIndex && entry.nOutlineLevel<=nSplit) {
entryCurrent = entry; break;
}
}
if (entryCurrent==null) {
entryCurrent = fakeEntry;
if (nIndex==0) { bHasFrontMatter=true; }
}
// Determine the maximum outline level to include
int nMaxLevel = entryCurrent.nOutlineLevel;
if (nMaxLevel<nSplit) { nMaxLevel++; }
// Create minitoc with relevant entries
if (bHasFrontMatter) {
Element inline = createPanelLink(panel, nIndex, 0, 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.HOME)));
}
int nPrevFileIndex = 0;
for (int i=0; i<nLen; i++) {
TocEntry entry = tocEntries.get(i);
if (entry.nFileIndex>nPrevFileIndex+1) {
// Skipping a file index means we have passed an index
for (int k=nPrevFileIndex+1; k<entry.nFileIndex; k++) {
createIndexLink(panel,nIndex,k);
}
}
nPrevFileIndex = entry.nFileIndex;
String sNodeName = entry.onode.getTagName();
if (XMLString.TEXT_H.equals(sNodeName)) {
// Determine wether or not to include this heading
// Note that this condition misses the case where
// a heading of level n is followed by a heading of
// level n+2. This is considered a bug in the document!
boolean bInclude = entry.nOutlineLevel<=nMaxLevel;
if (bInclude) {
// Check that this heading matches the current
int nCompareLevels = entry.nOutlineLevel;
for (int j=1; j<nCompareLevels; j++) {
if (entry.nOutlineNumber[j]!=entryCurrent.nOutlineNumber[j]) {
bInclude = false;
}
}
}
if (bInclude) {
Element inline = createPanelLink(panel, nIndex, entry.nFileIndex, entry.nOutlineLevel);
// Add content of heading
if (entry.sLabel!=null && entry.sLabel.length()>0) {
inline.appendChild(converter.createTextNode(entry.sLabel));
if (!entry.sLabel.endsWith(" ")) {
inline.appendChild(converter.createTextNode(" "));
}
}
getTextCv().traverseInlineText(entry.onode,inline);
}
}
}
if (nPrevFileIndex<nLastIndex) {
// Trailing index
for (int k=nPrevFileIndex+1; k<=nLastIndex; k++) {
createIndexLink(panel,nIndex,k);
}
}
}
}
converter.changeOutFile(nLastIndex);
}
private void createIndexLink(Element panel, int nIndex, int nFileIndex) {
if (nFileIndex==nTocFileIndex) {
Element inline = createPanelLink(panel, nIndex, nTocFileIndex, 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.CONTENTS)));
}
else if (nFileIndex==getTextCv().getAlphabeticalIndex()) {
Element inline = createPanelLink(panel, nIndex, getTextCv().getAlphabeticalIndex(), 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.INDEX)));
}
}
private Element createPanelLink(Element panel, int nCurrentFile, int nLinkFile, int nOutlineLevel) {
// Create a link
Element p = converter.createElement("p");
p.setAttribute("class","level"+nOutlineLevel);
panel.appendChild(p);
Element inline;
if (nCurrentFile!=nLinkFile) {
inline = converter.createElement("a");
inline.setAttribute("href",converter.getOutFileName(nLinkFile,true));
}
else {
inline = converter.createElement("span");
inline.setAttribute("class","nolink");
}
p.appendChild(inline);
return inline;
}
}

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-2014 by Henrik Just * Copyright: 2002-2015 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.6 (2014-10-26) * Version 1.6 (2015-06-11)
* *
*/ */
@ -28,54 +28,21 @@ package writer2latex.xhtml;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Stack; import java.util.Stack;
import java.util.Vector;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Locale;
import java.text.Collator;
//import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import writer2latex.util.Misc; import writer2latex.util.Misc;
import writer2latex.xhtml.l10n.L10n;
import writer2latex.office.FontDeclaration; import writer2latex.office.FontDeclaration;
import writer2latex.office.OfficeStyle; import writer2latex.office.OfficeStyle;
import writer2latex.office.XMLString; import writer2latex.office.XMLString;
import writer2latex.office.IndexMark;
import writer2latex.office.ListCounter; import writer2latex.office.ListCounter;
import writer2latex.office.ListStyle; import writer2latex.office.ListStyle;
import writer2latex.office.PropertySet; import writer2latex.office.PropertySet;
import writer2latex.office.StyleWithProperties; import writer2latex.office.StyleWithProperties;
import writer2latex.office.OfficeReader; import writer2latex.office.OfficeReader;
import writer2latex.office.TocReader;
// Helper class (a struct) to contain information about an alphabetical
// index entry.
final class AlphabeticalEntry {
String sWord; // the word for the index
int nIndex; // the original index of this entry
}
// Helper class (a struct) to contain information about a toc entry
// (ie. a heading, other paragraph or toc-mark)
final class TocEntry {
Element onode; // the original node
String sLabel = null; // generated label for the entry
int nFileIndex; // the file index for the generated content
int nOutlineLevel; // the outline level for this heading
int[] nOutlineNumber; // the natural outline number for this heading
}
// Helper class (a struct) to point back to indexes that should be processed
final class IndexData {
int nOutFileIndex; // the index of the out file containing the index
Element onode; // the original node
Element chapter; // the chapter containing this toc
Element hnode; // a div node where the index should be added
}
/** This class handles text content /** This class handles text content
*/ */
@ -90,7 +57,6 @@ public class TextConverter extends ConverterHelper {
private int nPageBreakSplit = XhtmlConfig.NONE; // Should we split at page breaks? private int nPageBreakSplit = XhtmlConfig.NONE; // Should we split at page breaks?
// TODO: Collect soft page breaks between table rows // TODO: Collect soft page breaks between table rows
private boolean bPendingPageBreak = false; // We have encountered a page break which should be inserted asap private boolean bPendingPageBreak = false; // We have encountered a page break which should be inserted asap
private int nExternalTocDepth = 1; // The number of levels to include in the "external" table of contents
private int nSplit = 0; // The outline level at which to split files (0=no split) private int nSplit = 0; // The outline level at which to split files (0=no split)
private int nRepeatLevels = 5; // The number of levels to repeat when splitting (0=no repeat) private int nRepeatLevels = 5; // The number of levels to repeat when splitting (0=no repeat)
private int nLastSplitLevel = 1; // The outline level at which the last split occurred private int nLastSplitLevel = 1; // The outline level at which the last split occurred
@ -110,20 +76,12 @@ public class TextConverter extends ConverterHelper {
// Mode used to handle floats (depends on source doc type and config) // Mode used to handle floats (depends on source doc type and config)
private int nFloatMode; private int nFloatMode;
// Data used for index bookkeeping // Data used to handle all sorts of indexes
private Vector<IndexData> indexes = new Vector<IndexData>(); private TOCConverter tocCv;
private LOFConverter lofCv;
// Data used to handle Alphabetical Index private LOTConverter lotCv;
Vector<AlphabeticalEntry> index = new Vector<AlphabeticalEntry>(); // All words for the index private AlphabeticalIndexConverter indexCv;
private int nIndexIndex = -1; // Current index used for id's (of form idxN) private BibliographyConverter bibCv;
private int nAlphabeticalIndex = -1; // File containing alphabetical index
// Data used to handle Table of Contents
private Vector<TocEntry> tocEntries = new Vector<TocEntry>(); // All potential(!) toc items
private int nTocFileIndex = -1; // file index for main toc
private Element currentChapter = null; // Node for the current chapter (level 1) heading
private int nTocIndex = -1; // Current index for id's (of form tocN)
private ListCounter naturalOutline = new ListCounter(); // Current "natural" outline number
// Style names for foot- and endnotes // Style names for foot- and endnotes
private String sFntCitBodyStyle = null; private String sFntCitBodyStyle = null;
@ -148,17 +106,18 @@ public class TextConverter extends ConverterHelper {
// Display hidden text? // Display hidden text?
private boolean bDisplayHiddenText = false; private boolean bDisplayHiddenText = false;
public TextConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) { public TextConverter(OfficeReader ofr, XhtmlConfig config, Converter converter) {
super(ofr,config,converter); super(ofr,config,converter);
tocCv = new TOCConverter(ofr, config, converter);
lofCv = new LOFConverter(ofr, config, converter);
lotCv = new LOTConverter(ofr, config, converter);
bibCv = new BibliographyConverter(ofr, config, converter);
indexCv = new AlphabeticalIndexConverter(ofr, config, converter);
nSplitAfter = 1000*config.splitAfter(); nSplitAfter = 1000*config.splitAfter();
nPageBreakSplit = config.pageBreakSplit(); nPageBreakSplit = config.pageBreakSplit();
nSplit = config.getXhtmlSplitLevel(); nSplit = config.getXhtmlSplitLevel();
nRepeatLevels = converter.isOPS() ? 0 : config.getXhtmlRepeatLevels(); // never repeat headings in EPUB nRepeatLevels = converter.isOPS() ? 0 : config.getXhtmlRepeatLevels(); // never repeat headings in EPUB
nExternalTocDepth = config.externalTocDepth();
if (nExternalTocDepth==0) { // A value of zero means auto (i.e. determine from split level)
nExternalTocDepth = Math.max(nSplit,1);
}
nFloatMode = ofr.isText() && config.xhtmlFloatObjects() ? nFloatMode = ofr.isText() && config.xhtmlFloatObjects() ?
DrawConverter.FLOATING : DrawConverter.ABSOLUTE; DrawConverter.FLOATING : DrawConverter.ABSOLUTE;
outlineNumbering = new ListCounter(ofr.getOutlineStyle()); outlineNumbering = new ListCounter(ofr.getOutlineStyle());
@ -204,20 +163,21 @@ public class TextConverter extends ConverterHelper {
insertEndnotes(hnode); insertEndnotes(hnode);
// Generate all indexes // Generate all indexes
int nIndexCount = indexes.size(); bInToc = true;
for (int i=0; i<nIndexCount; i++) { tocCv.generate();
generateToc(indexes.get(i)); bInToc = false;
}
// Generate navigation links // Generate navigation links
generateHeaders(); generateHeaders();
generateFooters(); generateFooters();
generatePanels(); bInToc = true;
tocCv.generatePanels(nSplit);
bInToc = false;
} }
protected int getTocIndex() { return nTocFileIndex; } protected int getTocIndex() { return tocCv.getFileIndex(); }
protected int getAlphabeticalIndex() { return nAlphabeticalIndex; } protected int getAlphabeticalIndex() { return indexCv.getFileIndex(); }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// NAVIGATION (fill header, footer and panel with navigation links) // NAVIGATION (fill header, footer and panel with navigation links)
@ -229,137 +189,7 @@ public class TextConverter extends ConverterHelper {
// The footer is populated with prev/next navigation // The footer is populated with prev/next navigation
private void generateFooters() { } private void generateFooters() { }
// The panel is populated with a minitoc
// TODO: Include link to toc and index in appropriate places..
private void generatePanels() {
int nLastIndex = converter.getOutFileIndex();
bInToc = true;
boolean bHasFrontMatter = false;
TocEntry fakeEntry = new TocEntry();
fakeEntry.nOutlineLevel = 0;
fakeEntry.nOutlineNumber = new int[11];
int nLen = tocEntries.size();
for (int nIndex=0; nIndex<=nLastIndex; nIndex++) {
converter.changeOutFile(nIndex);
Element panel = converter.getPanelNode();
if (panel!=null) {
// Get the last heading of level <= split level for this file
TocEntry entryCurrent = null;
for (int i=nLen-1; i>=0; i--) {
TocEntry entry = tocEntries.get(i);
if (XMLString.TEXT_H.equals(entry.onode.getTagName()) && entry.nFileIndex==nIndex && entry.nOutlineLevel<=nSplit) {
entryCurrent = entry; break;
}
}
if (entryCurrent==null) {
entryCurrent = fakeEntry;
if (nIndex==0) { bHasFrontMatter=true; }
}
// Determine the maximum outline level to include
int nMaxLevel = entryCurrent.nOutlineLevel;
if (nMaxLevel<nSplit) { nMaxLevel++; }
// Create minitoc with relevant entries
if (bHasFrontMatter) {
Element inline = createPanelLink(panel, nIndex, 0, 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.HOME)));
}
int nPrevFileIndex = 0;
for (int i=0; i<nLen; i++) {
TocEntry entry = tocEntries.get(i);
if (entry.nFileIndex>nPrevFileIndex+1) {
// Skipping a file index means we have passed an index
for (int k=nPrevFileIndex+1; k<entry.nFileIndex; k++) {
createIndexLink(panel,nIndex,k);
}
}
nPrevFileIndex = entry.nFileIndex;
String sNodeName = entry.onode.getTagName();
if (XMLString.TEXT_H.equals(sNodeName)) {
// Determine wether or not to include this heading
// Note that this condition misses the case where
// a heading of level n is followed by a heading of
// level n+2. This is considered a bug in the document!
boolean bInclude = entry.nOutlineLevel<=nMaxLevel;
if (bInclude) {
// Check that this heading matches the current
int nCompareLevels = entry.nOutlineLevel;
for (int j=1; j<nCompareLevels; j++) {
if (entry.nOutlineNumber[j]!=entryCurrent.nOutlineNumber[j]) {
bInclude = false;
}
}
}
if (bInclude) {
Element inline = createPanelLink(panel, nIndex, entry.nFileIndex, entry.nOutlineLevel);
// Add content of heading
if (entry.sLabel!=null && entry.sLabel.length()>0) {
inline.appendChild(converter.createTextNode(entry.sLabel));
if (!entry.sLabel.endsWith(" ")) {
inline.appendChild(converter.createTextNode(" "));
}
}
traverseInlineText(entry.onode,inline);
}
}
}
if (nPrevFileIndex<nLastIndex) {
// Trailing index
for (int k=nPrevFileIndex+1; k<=nLastIndex; k++) {
createIndexLink(panel,nIndex,k);
}
}
}
}
bInToc = false;
converter.changeOutFile(nLastIndex);
}
private void createIndexLink(Element panel, int nIndex, int nFileIndex) {
if (nFileIndex==nTocFileIndex) {
Element inline = createPanelLink(panel, nIndex, nTocFileIndex, 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.CONTENTS)));
}
else if (nFileIndex==nAlphabeticalIndex) {
Element inline = createPanelLink(panel, nIndex, nAlphabeticalIndex, 1);
inline.appendChild(converter.createTextNode(converter.getL10n().get(L10n.INDEX)));
}
}
private Element createPanelLink(Element panel, int nCurrentFile, int nLinkFile, int nOutlineLevel) {
// Create a link
Element p = converter.createElement("p");
p.setAttribute("class","level"+nOutlineLevel);
panel.appendChild(p);
Element inline;
if (nCurrentFile!=nLinkFile) {
inline = converter.createElement("a");
inline.setAttribute("href",converter.getOutFileName(nLinkFile,true));
}
else {
inline = converter.createElement("span");
inline.setAttribute("class","nolink");
}
p.appendChild(inline);
return inline;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// BLOCK TEXT (returns current html node at end of block) // BLOCK TEXT (returns current html node at end of block)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -437,7 +267,7 @@ public class TextConverter extends ConverterHelper {
Node rememberNode = hnode; Node rememberNode = hnode;
hnode = maybeSplit(hnode,style,nOutlineLevel); hnode = maybeSplit(hnode,style,nOutlineLevel);
nCharacterCount+=OfficeReader.getCharacterCount(child); nCharacterCount+=OfficeReader.getCharacterCount(child);
handleHeading((Element)child,hnode,rememberNode!=hnode); handleHeading((Element)child,(Element)hnode,rememberNode!=hnode);
} }
else if (nodeName.equals(XMLString.TEXT_LIST) || // oasis else if (nodeName.equals(XMLString.TEXT_LIST) || // oasis
nodeName.equals(XMLString.TEXT_UNORDERED_LIST) || // old nodeName.equals(XMLString.TEXT_UNORDERED_LIST) || // old
@ -471,27 +301,27 @@ public class TextConverter extends ConverterHelper {
if (!ofr.getTocReader((Element)child).isByChapter()) { if (!ofr.getTocReader((Element)child).isByChapter()) {
hnode = maybeSplit(hnode,null,1); hnode = maybeSplit(hnode,null,1);
} }
handleTOC(child,hnode); tocCv.handleIndex((Element)child,(Element)hnode);
} }
else if (nodeName.equals(XMLString.TEXT_ILLUSTRATION_INDEX)) { else if (nodeName.equals(XMLString.TEXT_ILLUSTRATION_INDEX)) {
handleLOF(child,hnode); lofCv.handleLOF(child,hnode);
} }
else if (nodeName.equals(XMLString.TEXT_TABLE_INDEX)) { else if (nodeName.equals(XMLString.TEXT_TABLE_INDEX)) {
handleLOT(child,hnode); lotCv.handleLOT(child,hnode);
} }
else if (nodeName.equals(XMLString.TEXT_OBJECT_INDEX)) { else if (nodeName.equals(XMLString.TEXT_OBJECT_INDEX)) {
handleObjectIndex(child,hnode); // TODO
} }
else if (nodeName.equals(XMLString.TEXT_USER_INDEX)) { else if (nodeName.equals(XMLString.TEXT_USER_INDEX)) {
handleUserIndex(child,hnode); // TODO
} }
else if (nodeName.equals(XMLString.TEXT_ALPHABETICAL_INDEX)) { else if (nodeName.equals(XMLString.TEXT_ALPHABETICAL_INDEX)) {
hnode = maybeSplit(hnode,null,1); hnode = maybeSplit(hnode,null,1);
handleAlphabeticalIndex(child,hnode); indexCv.handleIndex((Element)child,(Element)hnode);
} }
else if (nodeName.equals(XMLString.TEXT_BIBLIOGRAPHY)) { else if (nodeName.equals(XMLString.TEXT_BIBLIOGRAPHY)) {
hnode = maybeSplit(hnode,null,1); hnode = maybeSplit(hnode,null,1);
handleBibliography(child,hnode); bibCv.handleBibliography(child,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; }
@ -604,7 +434,7 @@ public class TextConverter extends ConverterHelper {
return newhnode.getParentNode(); return newhnode.getParentNode();
} }
private void handleHeading(Element onode, Node hnode, boolean bAfterSplit) { private void handleHeading(Element onode, Element hnode, boolean bAfterSplit) {
int nListLevel = getOutlineLevel((Element)onode); int nListLevel = getOutlineLevel((Element)onode);
boolean bUnNumbered = "true".equals(Misc.getAttribute(onode,XMLString.TEXT_IS_LIST_HEADER)); boolean bUnNumbered = "true".equals(Misc.getAttribute(onode,XMLString.TEXT_IS_LIST_HEADER));
boolean bRestart = "true".equals(Misc.getAttribute(onode,XMLString.TEXT_RESTART_NUMBERING)); boolean bRestart = "true".equals(Misc.getAttribute(onode,XMLString.TEXT_RESTART_NUMBERING));
@ -616,7 +446,7 @@ public class TextConverter extends ConverterHelper {
/* /*
* Process a text:h tag * Process a text:h tag
*/ */
private void handleHeading(Element onode, Node hnode, boolean bAfterSplit, private void handleHeading(Element onode, Element hnode, boolean bAfterSplit,
ListStyle listStyle, int nListLevel, boolean bUnNumbered, ListStyle listStyle, int nListLevel, boolean bUnNumbered,
boolean bRestart, int nStartValue) { boolean bRestart, int nStartValue) {
@ -665,7 +495,6 @@ public class TextConverter extends ConverterHelper {
// Export the heading // Export the heading
if (!bTocOnly) { if (!bTocOnly) {
if (nLevel==1) { currentChapter = onode; }
// If split output, add headings of higher levels // If split output, add headings of higher levels
if (bAfterSplit && nSplit>0) { if (bAfterSplit && nSplit>0) {
int nFirst = nLevel-nRepeatLevels; int nFirst = nLevel-nRepeatLevels;
@ -706,24 +535,7 @@ public class TextConverter extends ConverterHelper {
// Add to toc // Add to toc
if (!bInToc) { if (!bInToc) {
String sTarget = "toc"+(++nTocIndex); tocCv.handleHeading(onode,heading,sLabel);
converter.addTarget(heading,sTarget);
// 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
if (nLevel<=nExternalTocDepth) {
converter.addContentEntry(sLabel+converter.getPlainInlineText(onode), nLevel,
nLevel>nSplit ? sTarget : null);
}
// Add to real toc
TocEntry entry = new TocEntry();
entry.onode = onode;
entry.sLabel = sLabel;
entry.nFileIndex = converter.getOutFileIndex();
entry.nOutlineLevel = nLevel;
entry.nOutlineNumber = naturalOutline.step(nLevel).getValues();
tocEntries.add(entry);
} }
// Convert content // Convert content
@ -748,19 +560,7 @@ public class TextConverter extends ConverterHelper {
} }
else { else {
if (!bInToc) { if (!bInToc) {
// Add in external content. For single file output we include all level 1 headings + their target tocCv.handleHeadingExternal(onode, hnode, sLabel);
// Targets are added only when the toc level is deeper than the split level
if (nLevel<=nExternalTocDepth) {
// Add an empty div to use as target, if required
String sTarget = null;
if (nLevel>nSplit) {
Element div = converter.createElement("div");
hnode.appendChild(div);
sTarget = "toc"+(++nTocIndex);
converter.addTarget(div,sTarget);
}
converter.addContentEntry(sLabel+converter.getPlainInlineText(onode), nLevel, sTarget);
}
} }
// Keep track of current headings for split output // Keep track of current headings for split output
currentHeading[nLevel] = null; currentHeading[nLevel] = null;
@ -799,15 +599,8 @@ public class TextConverter extends ConverterHelper {
} }
// Maybe add to toc // Maybe add to toc
if (ofr.isIndexSourceStyle(getParSc().getRealParStyleName(sStyleName))) { tocCv.handleParagraph((Element)onode, par, sCurrentListLabel);
converter.addTarget(par,"toc"+(++nTocIndex));
TocEntry entry = new TocEntry();
entry.onode = (Element) onode;
entry.sLabel = sCurrentListLabel;
entry.nFileIndex = converter.getOutFileIndex();
tocEntries.add(entry);
}
if (!bIsEmpty) { if (!bIsEmpty) {
par = createTextBackground(par, sStyleName); par = createTextBackground(par, sStyleName);
if (config.listFormatting()==XhtmlConfig.HARD_LABELS) { if (config.listFormatting()==XhtmlConfig.HARD_LABELS) {
@ -1205,7 +998,7 @@ public class TextConverter extends ConverterHelper {
Node rememberNode = hnode; Node rememberNode = hnode;
StyleWithProperties style = ofr.getParStyle(Misc.getAttribute(child, XMLString.TEXT_STYLE_NAME)); StyleWithProperties style = ofr.getParStyle(Misc.getAttribute(child, XMLString.TEXT_STYLE_NAME));
hnode = maybeSplit(hnode,style,nOutlineLevel); hnode = maybeSplit(hnode,style,nOutlineLevel);
handleHeading((Element)child, hnode, rememberNode!=hnode, handleHeading((Element)child, (Element)hnode, rememberNode!=hnode,
ofr.getListStyle(sStyleName), nLevel, ofr.getListStyle(sStyleName), nLevel,
bUnNumbered, bRestart, nStartValue); bUnNumbered, bRestart, nStartValue);
nDontSplitLevel--; nDontSplitLevel--;
@ -1228,284 +1021,7 @@ public class TextConverter extends ConverterHelper {
} }
return hnode; return hnode;
} }
//////////////////////////////////////////////////////////////////////////
// INDEXES
//////////////////////////////////////////////////////////////////////////
/* Process table of contents
*/
private void handleTOC(Node onode, Node hnode) {
if (!config.includeToc()) { return; }
if (!ofr.getTocReader((Element)onode).isByChapter()) {
nTocFileIndex = converter.getOutFileIndex();
}
converter.setTocFile(null);
Element div = converter.createElement("div");
hnode.appendChild(div);
IndexData data = new IndexData();
data.nOutFileIndex = converter.getOutFileIndex();
data.onode = (Element) onode;
data.chapter = currentChapter;
data.hnode = (Element) div;
indexes.add(data); // to be processed later with generateTOC
}
private void generateToc(IndexData data) {
if (!config.includeToc()) { return; }
Element onode = data.onode;
Element chapter = data.chapter;
Element div = data.hnode;
int nSaveOutFileIndex = converter.getOutFileIndex();
converter.changeOutFile(data.nOutFileIndex);
bInToc = true;
TocReader tocReader = ofr.getTocReader(onode);
StyleInfo sectionInfo = new StyleInfo();
getSectionSc().applyStyle(tocReader.getStyleName(),sectionInfo);
applyStyle(sectionInfo,div);
if (tocReader.getName()!=null) { converter.addTarget(div,tocReader.getName()); }
// Generate title
Element title = tocReader.getIndexTitleTemplate();
if (title!=null) {
String sStyleName = Misc.getAttribute(title,XMLString.TEXT_STYLE_NAME);
Element p = createParagraph(div,sStyleName);
traversePCDATA(title,p);
}
// TODO: Read the entire content of the entry templates!
String[] sEntryStyleName = new String[11];
for (int i=1; i<=10; i++) {
Element entryTemplate = tocReader.getTocEntryTemplate(i);
if (entryTemplate!=null) {
sEntryStyleName[i] = Misc.getAttribute(entryTemplate,XMLString.TEXT_STYLE_NAME);
}
}
int nStart = 0;
int nLen = tocEntries.size();
// Find the chapter
if (tocReader.isByChapter() && chapter!=null) {
for (int i=0; i<nLen; i++) {
TocEntry entry = tocEntries.get(i);
if (entry.onode==chapter) { nStart=i; break; }
}
}
// Generate entries
for (int i=nStart; i<nLen; i++) {
TocEntry entry = tocEntries.get(i);
String sNodeName = entry.onode.getTagName();
if (XMLString.TEXT_H.equals(sNodeName)) {
int nLevel = getOutlineLevel(entry.onode);
if (nLevel==1 && tocReader.isByChapter() && entry.onode!=chapter) { break; }
if (tocReader.useOutlineLevel() && nLevel<=tocReader.getOutlineLevel()) {
Element p = createParagraph(div,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
Element span = converter.createElement("span");
p.appendChild(span);
span.setAttribute("class","SectionNumber");
span.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
traverseInlineText(entry.onode,a);
}
else {
String sStyleName = getParSc().getRealParStyleName(entry.onode.getAttribute(XMLString.TEXT_STYLE_NAME));
nLevel = tocReader.getIndexSourceStyleLevel(sStyleName);
if (tocReader.useIndexSourceStyles() && 1<=nLevel && nLevel<=tocReader.getOutlineLevel()) {
Element p = createParagraph(div,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
p.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
traverseInlineText(entry.onode,a);
}
}
}
else if (XMLString.TEXT_P.equals(sNodeName)) {
String sStyleName = getParSc().getRealParStyleName(entry.onode.getAttribute(XMLString.TEXT_STYLE_NAME));
int nLevel = tocReader.getIndexSourceStyleLevel(sStyleName);
if (tocReader.useIndexSourceStyles() && 1<=nLevel && nLevel<=tocReader.getOutlineLevel()) {
Element p = createParagraph(div,sEntryStyleName[nLevel]);
if (entry.sLabel!=null) {
p.appendChild(converter.createTextNode(entry.sLabel));
}
Element a = converter.createLink("toc"+i);
p.appendChild(a);
traverseInlineText(entry.onode,a);
}
}
else if (XMLString.TEXT_TOC_MARK.equals(sNodeName)) {
int nLevel = Misc.getPosInteger(entry.onode.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1);
if (tocReader.useIndexMarks() && nLevel<=tocReader.getOutlineLevel()) {
Element p = createParagraph(div,sEntryStyleName[nLevel]);
Element a = converter.createLink("toc"+i);
p.appendChild(a);
a.appendChild(converter.createTextNode(IndexMark.getIndexValue(entry.onode)));
}
}
else if (XMLString.TEXT_TOC_MARK_START.equals(sNodeName)) {
int nLevel = Misc.getPosInteger(entry.onode.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1);
if (tocReader.useIndexMarks() && nLevel<=tocReader.getOutlineLevel()) {
Element p = createParagraph(div,sEntryStyleName[nLevel]);
Element a = converter.createLink("toc"+i);
p.appendChild(a);
a.appendChild(converter.createTextNode(IndexMark.getIndexValue(entry.onode)));
}
}
}
bInToc = false;
converter.changeOutFile(nSaveOutFileIndex);
}
/*
* Process list of illustrations
*/
private void handleLOF (Node onode, Node hnode) {
// later
}
/*
* Process list of tables
*/
private void handleLOT (Node onode, Node hnode) {
// later
}
/*
* Process Object index
*/
private void handleObjectIndex (Node onode, Node hnode) {
// later
}
/*
* Process User index
*/
private void handleUserIndex (Node onode, Node hnode) {
// later
}
/*
* Process Alphabetical index
*/
private void handleAlphabeticalIndex (Node onode, Node hnode) {
nAlphabeticalIndex = converter.getOutFileIndex();
converter.setIndexFile(null);
Node source = Misc.getChildByTagName(onode,XMLString.TEXT_ALPHABETICAL_INDEX_SOURCE);
if (source!=null) {
Element div = converter.createElement("div");
converter.addTarget(div,"alphabeticalindex");
hnode.appendChild(div);
// Generate title
Node title = Misc.getChildByTagName(source,XMLString.TEXT_INDEX_TITLE_TEMPLATE);
if (title!=null) {
String sStyleName = Misc.getAttribute(title,XMLString.TEXT_STYLE_NAME);
Element p = createParagraph(div,sStyleName);
traversePCDATA(title,p);
}
// Collect style name for entries
// TODO: Should read the entire template
String sEntryStyleName = null;
if (source.hasChildNodes()) {
NodeList nl = source.getChildNodes();
int nLen = nl.getLength();
for (int i = 0; i < nLen; i++) {
Node child = nl.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE
&& child.getNodeName().equals(XMLString.TEXT_ALPHABETICAL_INDEX_ENTRY_TEMPLATE)) {
// Note: There are actually three outline-levels: separator, 1, 2 and 3
int nLevel = Misc.getPosInteger(Misc.getAttribute(child,XMLString.TEXT_OUTLINE_LEVEL),1);
if (nLevel==1) {
sEntryStyleName = Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
}
}
}
}
// Sort the index entries
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));
}
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);
}
}
}
// Generate the index
Element table = converter.createElement("table");
table.setAttribute("style","width:100%");
div.appendChild(table);
Element tr = converter.createElement("tr");
table.appendChild(tr);
Element[] td = new Element[4];
for (int i=0; i<4; i++) {
td[i] = converter.createElement("td");
td[i].setAttribute("style","vertical-align:top");
tr.appendChild(td[i]);
}
int nColEntries = nIndexIndex/4+1;
int nColIndex = -1;
for (int i=0; i<=nIndexIndex; i++) {
if (i%nColEntries==0) { nColIndex++; }
AlphabeticalEntry entry = index.get(i);
Element p = createParagraph(td[nColIndex],sEntryStyleName);
Element a = converter.createLink("idx"+entry.nIndex);
p.appendChild(a);
a.appendChild(converter.createTextNode(entry.sWord));
}
}
}
/*
* Process Bibliography
*/
private 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 div = converter.createElement("div");
converter.addTarget(div,"bibliography");
hnode.appendChild(div);
//asapNode = converter.createTarget("bibliography");
Node title = Misc.getChildByTagName(body,XMLString.TEXT_INDEX_TITLE);
if (title!=null) { traverseBlockText(title,div); }
traverseBlockText(body,div);
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// INLINE TEXT // INLINE TEXT
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -1549,7 +1065,7 @@ public class TextConverter extends ConverterHelper {
/* /*
* Process inline text * Process inline text
*/ */
private void traverseInlineText (Node onode,Node hnode) { protected void traverseInlineText (Node onode,Node hnode) {
//String styleName = Misc.getAttribute(onode, XMLString.TEXT_STYLE_NAME); //String styleName = Misc.getAttribute(onode, XMLString.TEXT_STYLE_NAME);
if (onode.hasChildNodes()) { if (onode.hasChildNodes()) {
@ -1662,16 +1178,16 @@ public class TextConverter extends ConverterHelper {
handleBookmarkRef(child,hnode); handleBookmarkRef(child,hnode);
} }
else if (sName.equals(XMLString.TEXT_ALPHABETICAL_INDEX_MARK)) { else if (sName.equals(XMLString.TEXT_ALPHABETICAL_INDEX_MARK)) {
handleAlphabeticalIndexMark(child,hnode); if (!bInToc) { indexCv.handleIndexMark(child,hnode); }
} }
else if (sName.equals(XMLString.TEXT_ALPHABETICAL_INDEX_MARK_START)) { else if (sName.equals(XMLString.TEXT_ALPHABETICAL_INDEX_MARK_START)) {
handleAlphabeticalIndexMarkStart(child,hnode); if (!bInToc) { indexCv.handleIndexMarkStart(child,hnode); }
} }
else if (sName.equals(XMLString.TEXT_TOC_MARK)) { else if (sName.equals(XMLString.TEXT_TOC_MARK)) {
handleTocMark(child,hnode); tocCv.handleTocMark(child,hnode);
} }
else if (sName.equals(XMLString.TEXT_TOC_MARK_START)) { else if (sName.equals(XMLString.TEXT_TOC_MARK_START)) {
handleTocMark(child,hnode); tocCv.handleTocMark(child,hnode);
} }
else if (sName.equals(XMLString.TEXT_BIBLIOGRAPHY_MARK)) { else if (sName.equals(XMLString.TEXT_BIBLIOGRAPHY_MARK)) {
handleBibliographyMark(child,hnode); handleBibliographyMark(child,hnode);
@ -1722,7 +1238,7 @@ public class TextConverter extends ConverterHelper {
} }
} }
private void traversePCDATA(Node onode, Node hnode) { protected void traversePCDATA(Node onode, Node hnode) {
if (onode.hasChildNodes()) { if (onode.hasChildNodes()) {
NodeList nl = onode.getChildNodes(); NodeList nl = onode.getChildNodes();
int nLen = nl.getLength(); int nLen = nl.getLength();
@ -1946,42 +1462,12 @@ public class TextConverter extends ConverterHelper {
createReference(onode,hnode,"bkm"); createReference(onode,hnode,"bkm");
} }
private void handleAlphabeticalIndexMark(Node onode, Node hnode) {
if (bInToc) { return; }
String sWord = Misc.getAttribute(onode,XMLString.TEXT_STRING_VALUE);
if (sWord==null) { return; }
AlphabeticalEntry entry = new AlphabeticalEntry();
entry.sWord = sWord; entry.nIndex = ++nIndexIndex;
index.add(entry);
hnode.appendChild(converter.createTarget("idx"+nIndexIndex));
}
private void handleAlphabeticalIndexMarkStart(Node onode, Node hnode) {
if (bInToc) { return; }
String sWord = IndexMark.getIndexValue(onode);
if (sWord==null) { return; }
AlphabeticalEntry entry = new AlphabeticalEntry();
entry.sWord = sWord; entry.nIndex = ++nIndexIndex;
index.add(entry);
hnode.appendChild(converter.createTarget("idx"+nIndexIndex));
}
private void handleTocMark(Node onode, Node hnode) {
hnode.appendChild(converter.createTarget("toc"+(++nTocIndex)));
TocEntry entry = new TocEntry();
entry.onode = (Element) onode;
entry.nFileIndex = converter.getOutFileIndex();
tocEntries.add(entry);
}
private void handleBibliographyMark(Node onode, Node hnode) { private void handleBibliographyMark(Node onode, Node hnode) {
if (bInToc) { if (bInToc) {
traversePCDATA(onode,hnode); traversePCDATA(onode,hnode);
} }
else { else {
Element anchor = converter.createLink("bibliography"); bibCv.handleBibliographyMark(onode, hnode);
hnode.appendChild(anchor);
traversePCDATA(onode,anchor);
} }
} }
@ -2123,7 +1609,7 @@ public class TextConverter extends ConverterHelper {
} }
/* Create a styled paragraph node */ /* Create a styled paragraph node */
private Element createParagraph(Element node, String sStyleName) { protected Element createParagraph(Element node, String sStyleName) {
StyleInfo info = new StyleInfo(); StyleInfo info = new StyleInfo();
getParSc().applyStyle(sStyleName,info); getParSc().applyStyle(sStyleName,info);
Element par = converter.createElement(info.sTagName); Element par = converter.createElement(info.sTagName);
@ -2182,7 +1668,7 @@ public class TextConverter extends ConverterHelper {
return applyAttributes(newNode,ofr.getTextStyle(sStyleName)); return applyAttributes(newNode,ofr.getTextStyle(sStyleName));
} }
private int getOutlineLevel(Element node) { protected int getOutlineLevel(Element node) {
return ofr.isOpenDocument() ? return ofr.isOpenDocument() ?
Misc.getPosInteger(node.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1): Misc.getPosInteger(node.getAttribute(XMLString.TEXT_OUTLINE_LEVEL),1):
Misc.getPosInteger(node.getAttribute(XMLString.TEXT_LEVEL),1); Misc.getPosInteger(node.getAttribute(XMLString.TEXT_LEVEL),1);