package writer2latex.xhtml; import java.util.LinkedList; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import writer2latex.office.XMLString; import static writer2latex.util.Misc.*; //LinkedList stringList = new LinkedList(); public class DocumentSeparator { private static final String NONE = "none"; private static final String SECTIONS = "sections"; private static final String DIV = "div"; private int splitLevel = 0; private boolean splitByPages = false; private int lastSplitPageNum = 1; private static LinkedList headerStack = new LinkedList(); private static boolean pageOpened = false; //headings none private static String headingSeparation = "sections"; //sections div none private static String pageSeparation = "sections"; private Converter converter = null; private XhtmlConfig config = null; private Node prevPageNode = null; 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; } protected Node processOutlineLevel(Node currentNode, Node hnode, int pageNum) { //Get outline level String sLevel = getAttribute(currentNode, XMLString.TEXT_OUTLINE_LEVEL); String title = getTitle(currentNode).trim(); if (sLevel == null || sLevel.isEmpty()) { return hnode; } if (title == null || title.isEmpty()) { return hnode; } int curLevel = Integer.parseInt(sLevel); if (needSplitFiles(curLevel,pageNum)){ prevPageNode = hnode; } if (pageOpened) { hnode = closePage(hnode); } if (headingSeparation.equals(SECTIONS)) { closeCommentHeadings(hnode, curLevel); } if (needSplitFiles(curLevel,pageNum)) { hnode = splitFiles(hnode); lastSplitPageNum = pageNum; } if (headingSeparation.equals(SECTIONS)) { openCommentHeading(hnode, title); headerStack.offerFirst(Integer.parseInt(sLevel)); } if (!noPageSeparation()) { hnode = openPage(hnode, pageNum); } return hnode; } private Node splitFiles(Node hnode) { hnode = converter.nextOutFile(); return hnode; } private boolean needSplitFiles(int curLevel,int pageNum) { if (splitLevel >= curLevel && (converter.outFileHasContent() || converter.getOutFileIndex() == 1)) { if (lastSplitPageNum != pageNum) { return true; } } return false; } protected Node processPageBreak(Node currentNode, Node hnode, Integer pageNum){ if (noPageSeparation()){ return hnode; } if (pageOpened) { hnode = closePage(hnode); } hnode = openPage(hnode, pageNum); return hnode; } /** * Opens main document section heading tag */ protected Node StartDocument(Node hnode, String title, int pageNum){ if (noHeadingSeparation() && noPageSeparation()){ return hnode; } if(headingSeparation.equals(SECTIONS)){ //Create global section openCommentHeading(hnode, title); } hnode = openPage(hnode, pageNum); return hnode; } //Method to close open tags at the end of the document protected static Node endDocument(Node hnode){ if (noHeadingSeparation() && noPageSeparation()){ return hnode; } if (pageOpened){ hnode = closePage(hnode); } if (headingSeparation.equals(SECTIONS)){ closeCommentHeadings(hnode, 0); //Close global section addCloseComment(hnode); } return hnode; } private Node openPageDiv(Node node,int pageNum){ if (node == null){ System.out.println("Error: node is null on openPageDiv"); return node; } if (prevPageNode != null && splitByPages) { arrangePageDivs(node,pageNum); } Document doc = node.getOwnerDocument(); Element openBlock = (Element) doc.createElement(DIV); openBlock.setAttribute("class", "pageNum"); openBlock.setAttribute("page", Integer.toString(pageNum)); // insert open section comment before header node node.appendChild((Node)openBlock); node = openBlock; return openBlock; } private void arrangePageDivs(Node node, int pageNum) { Document newdoc = node.getOwnerDocument(); Document olddoc = prevPageNode.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; } private static Node exitPageDiv(Node node){ while ( !isRoot(node) && !isElement( node,DIV) ){ node = node.getParentNode(); } Node result = node.getParentNode(); if (node.getChildNodes().getLength() == 0){ result.removeChild(node); } return result; } public static String getTitle(Node currentNode) { Node content = currentNode.cloneNode(true); NodeList contentNodes = content.getChildNodes(); String title = null; int i = 0; while (i < contentNodes.getLength()) { Node child = contentNodes.item(i); if (isElement(child) ){ 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); } title = content.getTextContent(); return title; } private static void openPageComment(Node hnode, Integer pageNum){ Document doc = hnode.getOwnerDocument(); Node openSection = doc.createComment(openPageCommentText(pageNum)); // insert open section comment before header node hnode.appendChild(openSection); } private static void openCommentHeading(Node hnode, String title){ Document doc = hnode.getOwnerDocument(); Node openSection = doc.createComment(openHeadingCommentText(title)); // insert open section comment before header node hnode.appendChild(openSection); } private static void addCloseComment(Node node){ Document doc = node.getOwnerDocument(); Node closeSection = doc.createComment(""); //insert open section comment before header node node.appendChild(closeSection); } private static void closeCommentHeadings(Node hnode, int nLevel){ if (headerStack.isEmpty()) { return; } //Close all sections with level less than current while (nLevel <= headerStack.peek()) { addCloseComment(hnode); headerStack.poll(); if (headerStack.isEmpty()) { break; } } } protected static Node closePage(Node hnode){ if (pageSeparation.equals(SECTIONS)){ //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 { addCloseComment(hnode); } } else if (pageSeparation.equals(DIV)){ hnode = exitPageDiv(hnode); } pageOpened = false; return hnode; } protected Node openPage(Node hnode, Integer pageNum){ if (pageSeparation.equals(SECTIONS)){ openPageComment(hnode, pageNum); pageOpened = true; } else if (pageSeparation.equals(DIV)){ hnode = openPageDiv(hnode, pageNum); pageOpened = true; } return hnode; } private static boolean noHeadingSeparation() { return headingSeparation.equals(NONE); } private static boolean noPageSeparation() { return pageSeparation.equals(NONE); } private static String openHeadingCommentText(String title) { String comment = "
\n\n" + title + "\n"; return comment; } private static String openPageCommentText(Integer pageNum) { String comment = "
\n\n" + pageNum + "\n" + pageNum + "\n"; return comment; } }