package writer2latex.xhtml.content; 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 pro.litvinovg.xml.Debug; import writer2latex.office.XMLString; import writer2latex.xhtml.Converter; import writer2latex.xhtml.XhtmlConfig; import static writer2latex.util.Misc.*; //LinkedList stringList = new LinkedList(); public class Separator { private static final String NONE = "none"; private static final String SECTIONS = "sections"; private static final String DIV = "div"; private int splitLevel = 0; private boolean alignSplitToPages; private int lastSplitPageNum = 1; private Integer pageNumber = null; private String breakStyle = null; private static LinkedList headerStack = new LinkedList(); private static boolean pageOpened = false; //headings none private static String headingSeparation = "sections"; //sections div none private static boolean pagination; private static Converter converter = null; private Node prevPageContainer = null; private PageContainer pageContainer = null; public Separator(XhtmlConfig config,Converter converter) { this.converter = converter; headingSeparation = config.getHeadingTags(); pagination = config.pagination(); splitLevel = config.getXhtmlSplitLevel(); alignSplitToPages = config.getAlignSplitsToPages(); breakStyle = config.getPageBreakStyle(); pageContainer = converter.pageContainer; } public 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)){ prevPageContainer = 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; } public Node processPageBreak(Node currentNode, Node hnode, Integer pageNum){ if (noPageSeparation()){ return hnode; } if (pageOpened) { hnode = closePage(hnode); } hnode = openPage(hnode, pageNum); return hnode; } public boolean isPageOpened() { return pageOpened; } /** * Opens main document section heading tag */ public 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 public 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 curPageNum){ if (node == null){ System.out.println("Error: node is null on openPageDiv"); return node; } if (prevPageContainer != null && alignSplitToPages) { alignFilesByHeadings(node,curPageNum); } breakPage(node,curPageNum); Document doc = node.getOwnerDocument(); Element openBlock = (Element) doc.createElement(DIV); openBlock.setAttribute("class", "pageNum"); openBlock.setAttribute("page", Integer.toString(curPageNum)); // insert open section comment before header node node.appendChild((Node)openBlock); node = openBlock; return openBlock; } 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"); if (breakStyleIsSet()) { applyBreakStyle(pageBreak); } node.appendChild(pageBreak); } pageNumber = curPageNum; } private void applyBreakStyle(Element pageBreak) { pageBreak.setAttribute("style", breakStyle); } public boolean breakStyleIsSet() { if (breakStyle == null || breakStyle.isEmpty()) { return false; } else { return true; } } private void alignFilesByHeadings(Node node, int pageNum) { Document newdoc = node.getOwnerDocument(); Node prevPage = prevPageContainer.getParentNode(); String prevPageNum = getAttribute(prevPage, "page"); if (prevPageNum != null && prevPageNum.equals(Integer.toString(pageNum))) { if (isElement(prevPage, DIV)) { Node importedNode = newdoc.importNode(prevPage, true); node.appendChild(importedNode); Node prevDoc = prevPage.getParentNode(); if (prevDoc != null) { prevDoc.removeChild(prevPage); } } } //no more arrange needed till next file separation prevPageContainer = null; } private static Node exitPageDiv(Node node){ while ( !isRoot(node) && !isElement( node,DIV) ){ node = node.getParentNode(); } Node result = node.getParentNode(); if (node.getChildNodes().getLength() == 1){ if (node.getFirstChild().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 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; } } } public Node closePage(Node hnode){ if (pageOpened == false) { return hnode; } hnode = exitPageContainer(hnode); if (pagination){ hnode = exitPageDiv(hnode); } pageOpened = false; return hnode; } public Node openPage(Node hnode, Integer pageNum){ if (pageOpened == true) { return hnode; } if (pagination){ hnode = openPageDiv(hnode, pageNum); pageOpened = true; } hnode = enterPageContainer(hnode); return hnode; } 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); Debug.printStackTrace(); 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"); Debug.printStackTrace(); System.exit(1); } Element container = converter.createElement("div"); container.setAttribute("class", "pageContainer"); if (!pageContainer.getCurrentStyle().isEmpty()) { container.setAttribute("style", pageContainer.getCurrentStyle()); } hnode.appendChild(container); return container; } private static boolean noHeadingSeparation() { return headingSeparation.equals(NONE); } private static boolean noPageSeparation() { return !pagination; } 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; } }