w2phtml/src/main/java/writer2latex/xhtml/DocumentSeparator.java

397 lines
11 KiB
Java
Raw Normal View History

2016-07-10 16:03:41 +03:00
package writer2latex.xhtml;
import java.util.ArrayList;
import java.util.Arrays;
2016-07-10 16:03:41 +03:00
import java.util.LinkedList;
import java.util.List;
2016-07-10 16:03:41 +03:00
import org.w3c.dom.Document;
2016-09-21 17:22:55 +03:00
import org.w3c.dom.Element;
2016-07-10 16:03:41 +03:00
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import writer2latex.office.XMLString;
2019-04-21 16:03:07 +03:00
import static writer2latex.util.Misc.*;
2016-07-10 16:03:41 +03:00
//LinkedList<String> stringList = new LinkedList<String>();
2019-04-21 20:02:37 +03:00
public class DocumentSeparator {
2016-07-10 16:03:41 +03:00
2016-09-21 17:22:55 +03:00
private static final String NONE = "none";
private static final String SECTIONS = "sections";
private static final String DIV = "div";
2019-04-21 20:02:37 +03:00
private int splitLevel = 0;
private boolean splitByPages = false;
2019-04-22 16:04:39 +03:00
private int lastSplitPageNum = 1;
2020-01-25 20:38:53 +01:00
private Integer pageNumber = null;
2020-01-27 11:45:31 +01:00
private String breakStyle = null;
2019-04-22 16:04:39 +03:00
2016-07-10 16:03:41 +03:00
private static LinkedList<Integer> headerStack = new LinkedList<Integer>();
2016-09-21 17:22:55 +03:00
private static boolean pageOpened = false;
//headings none
2019-04-21 16:03:07 +03:00
private static String headingSeparation = "sections";
//sections div none
2019-04-21 16:03:07 +03:00
private static String pageSeparation = "sections";
2020-01-22 13:08:43 +01:00
private static Converter converter = null;
2019-04-21 20:02:37 +03:00
private XhtmlConfig config = null;
2019-04-22 16:04:39 +03:00
private Node prevPageNode = null;
private List<String> pageContanerStyles = new ArrayList<String>(Arrays.asList(""));
2019-04-21 20:02:37 +03:00
public DocumentSeparator(XhtmlConfig config,Converter converter) {
this.config = config;
this.converter = converter;
headingSeparation = config.getHeadingTags();
pageSeparation = config.getPageTags();
splitLevel = config.getXhtmlSplitLevel();
splitByPages = pageSeparation.equals(DIV) ? true : false;
2020-01-27 11:45:31 +01:00
breakStyle = config.getPageBreakStyle();
2019-04-21 20:02:37 +03:00
}
2016-07-10 16:03:41 +03:00
protected Node processOutlineLevel(Node currentNode, Node hnode, int pageNum) {
2016-08-11 18:38:59 +03:00
2016-09-25 16:30:52 +03:00
//Get outline level
2019-04-21 16:03:07 +03:00
String sLevel = getAttribute(currentNode, XMLString.TEXT_OUTLINE_LEVEL);
2018-07-31 13:23:38 +03:00
String title = getTitle(currentNode).trim();
2016-09-25 16:30:52 +03:00
if (sLevel == null || sLevel.isEmpty()) {
2016-09-21 15:03:49 +03:00
return hnode;
2016-08-11 18:38:59 +03:00
}
2018-07-31 13:23:38 +03:00
if (title == null || title.isEmpty()) {
return hnode;
}
2019-04-21 20:02:37 +03:00
int curLevel = Integer.parseInt(sLevel);
2019-04-22 16:04:39 +03:00
if (needSplitFiles(curLevel,pageNum)){
prevPageNode = hnode;
}
2016-07-10 16:03:41 +03:00
2016-09-25 16:30:52 +03:00
if (pageOpened) {
hnode = closePage(hnode);
}
2019-04-22 16:04:39 +03:00
if (headingSeparation.equals(SECTIONS)) {
2019-04-21 20:02:37 +03:00
closeCommentHeadings(hnode, curLevel);
2019-04-22 12:12:42 +03:00
}
2019-04-22 16:04:39 +03:00
if (needSplitFiles(curLevel,pageNum)) {
hnode = splitFiles(hnode);
lastSplitPageNum = pageNum;
}
if (headingSeparation.equals(SECTIONS)) {
2019-04-21 18:12:09 +03:00
openCommentHeading(hnode, title);
2016-09-25 16:30:52 +03:00
headerStack.offerFirst(Integer.parseInt(sLevel));
2019-04-22 16:04:39 +03:00
2016-09-25 16:30:52 +03:00
}
2019-04-22 16:04:39 +03:00
if (!noPageSeparation()) {
hnode = openPage(hnode, pageNum);
2016-09-25 16:30:52 +03:00
}
2019-04-22 16:04:39 +03:00
2016-09-25 16:30:52 +03:00
2019-04-22 16:04:39 +03:00
return hnode;
}
private Node splitFiles(Node hnode) {
hnode = converter.nextOutFile();
2016-09-21 15:03:49 +03:00
return hnode;
2016-07-10 16:03:41 +03:00
}
2019-04-22 16:04:39 +03:00
private boolean needSplitFiles(int curLevel,int pageNum) {
if (splitLevel >= curLevel && (converter.outFileHasContent() || converter.getOutFileIndex() == 1)) {
if (lastSplitPageNum != pageNum) {
return true;
}
}
return false;
}
2016-09-25 16:30:52 +03:00
2019-04-22 16:04:39 +03:00
protected Node processPageBreak(Node currentNode, Node hnode, Integer pageNum){
2019-04-21 16:03:07 +03:00
if (noPageSeparation()){
2016-09-21 15:03:49 +03:00
return hnode;
2016-08-11 18:38:59 +03:00
}
2016-09-25 16:30:52 +03:00
if (pageOpened) {
hnode = closePage(hnode);
}
hnode = openPage(hnode, pageNum);
2016-09-21 15:03:49 +03:00
return hnode;
2016-07-10 16:03:41 +03:00
}
2016-09-25 16:30:52 +03:00
/**
* Opens main document section heading tag
*/
2020-01-22 13:08:43 +01:00
protected Node startDocument(Node hnode, String title, int pageNum){
2016-09-21 17:22:55 +03:00
2019-04-21 16:03:07 +03:00
if (noHeadingSeparation() && noPageSeparation()){
2016-09-21 15:03:49 +03:00
return hnode;
2016-08-11 18:38:59 +03:00
}
2019-04-21 16:03:07 +03:00
if(headingSeparation.equals(SECTIONS)){
2016-09-21 17:22:55 +03:00
//Create global section
2019-04-21 18:12:09 +03:00
openCommentHeading(hnode, title);
}
2016-09-21 17:22:55 +03:00
hnode = openPage(hnode, pageNum);
2016-08-11 18:38:59 +03:00
2016-09-21 15:03:49 +03:00
return hnode;
2016-07-10 16:03:41 +03:00
}
//Method to close open tags at the end of the document
2020-01-22 13:08:43 +01:00
protected Node endDocument(Node hnode){
2019-04-21 16:03:07 +03:00
if (noHeadingSeparation() && noPageSeparation()){
2016-09-21 15:03:49 +03:00
return hnode;
2016-08-11 18:38:59 +03:00
}
2016-09-21 17:22:55 +03:00
if (pageOpened){
hnode = closePage(hnode);
2016-07-10 16:03:41 +03:00
}
2019-04-21 16:03:07 +03:00
if (headingSeparation.equals(SECTIONS)){
2019-04-21 18:12:09 +03:00
closeCommentHeadings(hnode, 0);
2016-09-21 17:22:55 +03:00
//Close global section
2019-04-21 16:03:07 +03:00
addCloseComment(hnode);
2016-09-21 17:22:55 +03:00
}
return hnode;
}
2020-01-25 20:38:53 +01:00
private Node openPageDiv(Node node,int curPageNum){
2019-04-21 16:03:07 +03:00
if (node == null){
2019-04-21 18:12:09 +03:00
System.out.println("Error: node is null on openPageDiv");
2019-04-21 16:03:07 +03:00
return node;
2016-10-17 17:33:55 +03:00
}
2019-04-22 16:04:39 +03:00
if (prevPageNode != null && splitByPages) {
2020-01-25 20:38:53 +01:00
arrangePageDivs(node,curPageNum);
2019-04-22 16:04:39 +03:00
}
2020-01-25 20:38:53 +01:00
breakPage(node,curPageNum);
2019-04-21 16:03:07 +03:00
Document doc = node.getOwnerDocument();
2019-04-21 18:12:09 +03:00
Element openBlock = (Element) doc.createElement(DIV);
2016-09-21 17:22:55 +03:00
openBlock.setAttribute("class", "pageNum");
2020-01-25 20:38:53 +01:00
openBlock.setAttribute("page", Integer.toString(curPageNum));
2016-09-21 17:22:55 +03:00
// insert open section comment before header node
2019-04-21 16:03:07 +03:00
node.appendChild((Node)openBlock);
node = openBlock;
2016-09-21 17:22:55 +03:00
return openBlock;
}
2020-01-25 20:38:53 +01:00
private void breakPage(Node node, int curPageNum) {
if (pageNumber != null && pageNumber != curPageNum) {
Document doc = node.getOwnerDocument();
Element pageBreak = (Element) doc.createElement(DIV);
pageBreak.setAttribute("class", "pageBreak");
2020-01-27 11:45:31 +01:00
if (breakStyleIsSet()) {
applyBreakStyle(pageBreak);
}
2020-01-25 20:38:53 +01:00
node.appendChild(pageBreak);
}
pageNumber = curPageNum;
}
2020-01-27 11:45:31 +01:00
private void applyBreakStyle(Element pageBreak) {
pageBreak.setAttribute("style", breakStyle);
}
public boolean breakStyleIsSet() {
if (breakStyle == null || breakStyle.isEmpty()) {
return false;
} else {
return true;
}
}
2019-04-22 16:04:39 +03:00
private void arrangePageDivs(Node node, int pageNum) {
Document newdoc = node.getOwnerDocument();
String prevPageNum = getAttribute(prevPageNode, "page");
if (prevPageNum != null && prevPageNum.equals(Integer.toString(pageNum))) {
if (isElement(prevPageNode, DIV)) {
Node importedNode = newdoc.importNode(prevPageNode, true);
node.appendChild(importedNode);
Node prevDocContent = prevPageNode.getParentNode();
if (prevDocContent != null) {
prevDocContent.removeChild(prevPageNode);
}
}
}
//no more arrange needed till next file separation
prevPageNode = null;
}
2019-04-21 16:03:07 +03:00
private static Node exitPageDiv(Node node){
2016-09-25 16:30:52 +03:00
2019-04-22 16:04:39 +03:00
while ( !isRoot(node) && !isElement( node,DIV) ){
2019-04-21 16:03:07 +03:00
node = node.getParentNode();
}
Node result = node.getParentNode();
if (node.getChildNodes().getLength() == 0){
result.removeChild(node);
2016-09-25 18:43:29 +03:00
}
return result;
2016-07-10 16:03:41 +03:00
}
2016-08-11 17:09:29 +03:00
2019-04-22 16:04:39 +03:00
public static String getTitle(Node currentNode) {
2016-08-11 17:09:29 +03:00
Node content = currentNode.cloneNode(true);
NodeList contentNodes = content.getChildNodes();
String title = null;
int i = 0;
while (i < contentNodes.getLength()) {
Node child = contentNodes.item(i);
2019-04-21 16:03:07 +03:00
if (isElement(child) ){
2016-08-11 17:09:29 +03:00
if (child.getNodeName().equals(XMLString.TEXT_TAB) ||
child.getNodeName().equals(XMLString.TEXT_LINE_BREAK) ){
Document doc = child.getOwnerDocument();
Node testSpace = doc.createTextNode(" ");
content.insertBefore(testSpace, child);
content.removeChild(child);
}
}
i++;
}
NodeList notes = ((Element) content).getElementsByTagName(XMLString.TEXT_NOTE);
int j = 0;
while (j < notes.getLength()){
Node note = notes.item(j);
note.getParentNode().removeChild(note);
}
2016-08-11 17:09:29 +03:00
title = content.getTextContent();
return title;
}
2019-04-21 16:03:07 +03:00
private static void openPageComment(Node hnode, Integer pageNum){
2016-07-10 16:03:41 +03:00
Document doc = hnode.getOwnerDocument();
2019-04-21 16:03:07 +03:00
Node openSection = doc.createComment(openPageCommentText(pageNum));
2016-07-10 16:03:41 +03:00
// insert open section comment before header node
hnode.appendChild(openSection);
}
2019-04-21 16:03:07 +03:00
2019-04-21 18:12:09 +03:00
private static void openCommentHeading(Node hnode, String title){
2016-07-10 16:03:41 +03:00
Document doc = hnode.getOwnerDocument();
2019-04-21 16:03:07 +03:00
Node openSection = doc.createComment(openHeadingCommentText(title));
2016-07-10 16:03:41 +03:00
// insert open section comment before header node
hnode.appendChild(openSection);
}
2019-04-21 16:03:07 +03:00
private static void addCloseComment(Node node){
Document doc = node.getOwnerDocument();
Node closeSection = doc.createComment("</Section>");
2016-07-10 16:03:41 +03:00
//insert open section comment before header node
2019-04-21 16:03:07 +03:00
node.appendChild(closeSection);
2016-07-10 16:03:41 +03:00
}
2019-04-21 18:12:09 +03:00
private static void closeCommentHeadings(Node hnode, int nLevel){
if (headerStack.isEmpty()) {
return;
}
//Close all sections with level less than current
while (nLevel <= headerStack.peek()) {
2019-04-21 16:03:07 +03:00
addCloseComment(hnode);
headerStack.poll();
if (headerStack.isEmpty()) {
break;
}
}
}
2020-01-22 13:08:43 +01:00
protected Node closePage(Node hnode){
2020-01-22 21:39:16 +01:00
if (pageOpened == false) {
return hnode;
}
2020-01-22 13:08:43 +01:00
hnode = exitPageContainer(hnode);
2019-04-21 16:03:07 +03:00
if (pageSeparation.equals(SECTIONS)){
2016-09-25 18:43:29 +03:00
//If section is empty. In case we are closing section
// the last comment is opened page section
if (hnode.getLastChild().getNodeType() == Node.COMMENT_NODE){
hnode.removeChild(hnode.getLastChild());
} else {
2019-04-21 16:03:07 +03:00
addCloseComment(hnode);
2016-09-25 18:43:29 +03:00
}
2019-04-21 16:03:07 +03:00
} else if (pageSeparation.equals(DIV)){
2016-09-21 17:22:55 +03:00
hnode = exitPageDiv(hnode);
}
pageOpened = false;
return hnode;
}
2019-04-22 16:04:39 +03:00
protected Node openPage(Node hnode, Integer pageNum){
2020-01-22 21:39:16 +01:00
if (pageOpened == true) {
return hnode;
}
2019-04-21 16:03:07 +03:00
if (pageSeparation.equals(SECTIONS)){
openPageComment(hnode, pageNum);
2016-09-25 16:30:52 +03:00
pageOpened = true;
2016-09-21 17:22:55 +03:00
}
2019-04-21 16:03:07 +03:00
else if (pageSeparation.equals(DIV)){
2016-09-21 17:22:55 +03:00
hnode = openPageDiv(hnode, pageNum);
2016-09-25 16:30:52 +03:00
pageOpened = true;
}
2020-01-22 13:08:43 +01:00
hnode = enterPageContainer(hnode);
2016-09-25 16:30:52 +03:00
2016-09-21 17:22:55 +03:00
return hnode;
}
2020-01-22 13:08:43 +01:00
private Node exitPageContainer(Node hnode) {
String className = ((Element) hnode).getAttribute("class");
if (!className.equals("pageContainer")) {
System.out.println("Can't exit not my container!");
Debug.printNode(hnode);
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
System.exit(1);
}
Element parentNode = (Element) hnode.getParentNode();
return parentNode;
}
private Node enterPageContainer(Node hnode) {
if (hnode == null) {
System.out.println("Enter page container error. hnode is null");
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
System.exit(1);
}
Element container = converter.createElement("div");
container.setAttribute("class", "pageContainer");
if (!getLastPageContainerStyle().isEmpty()) {
container.setAttribute("style", getLastPageContainerStyle());
2020-01-22 13:08:43 +01:00
}
hnode.appendChild(container);
return container;
}
2019-04-21 16:03:07 +03:00
private static boolean noHeadingSeparation() {
return headingSeparation.equals(NONE);
}
private static boolean noPageSeparation() {
return pageSeparation.equals(NONE);
}
private static String openHeadingCommentText(String title) {
String comment = "<Section>\n<Description>\n<Metadata name=\"Title\">" + title
+ "</Metadata>\n</Description>";
return comment;
}
private static String openPageCommentText(Integer pageNum) {
String comment = "<Section>\n<Description>\n<Metadata name=\"Title\">" + pageNum
+ "</Metadata>\n<Metadata name=\"Page\">" + pageNum + "</Metadata>\n</Description>";
return comment;
}
public void setPageContainerStyle(String style){
pageContanerStyles.set(0, style);
}
public void addPageContainerStyle(String style){
pageContanerStyles.add(style);
}
public void rmPageContainerStyle() {
int size = pageContanerStyles.size();
if (size < 2) {
System.out.println("Tried to remove last container (page) style!");
System.exit(1);
}
pageContanerStyles.remove(size-1);
}
private String getLastPageContainerStyle() {
return pageContanerStyles.get(pageContanerStyles.size()-1);
2020-01-22 16:42:14 +01:00
}
2020-01-27 11:45:31 +01:00
2016-07-10 16:03:41 +03:00
}