com.aspose.words

Class LayoutCollector

  • java.lang.Object
    • com.aspose.words.LayoutCollector
public class LayoutCollector 
extends java.lang.Object

This class allows to compute page numbers of document nodes.

When you create a LayoutCollector and specify a Document document object to attach to, the collector will record mapping of document nodes to layout objects when the document is formatted into pages.

You will be able to find out on which page a particular document node (e.g. run, paragraph or table cell) is located by using the getStartPageIndex(com.aspose.words.Node), getEndPageIndex(com.aspose.words.Node) and getNumPagesSpanned(com.aspose.words.Node) methods. These methods automatically build page layout model of the document and update fields if required.

When you no longer need to collect layout information, it is best to set the Document property to null to avoid unnecessary collection of more layout mappings.

Example:

Shows how to see the page spans of nodes.
// Open a blank document and create a DocumentBuilder
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Create a LayoutCollector object for our document that will have information about the nodes we placed
LayoutCollector layoutCollector = new LayoutCollector(doc);

// The document itself is a node that contains everything, which currently spans 0 pages
Assert.assertEquals(layoutCollector.getDocument(), doc);
Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);

// Populate the document with sections and page breaks
builder.write("Section 1");
builder.insertBreak(BreakType.PAGE_BREAK);
builder.insertBreak(BreakType.PAGE_BREAK);
doc.appendChild(new Section(doc));
doc.getLastSection().appendChild(new Body(doc));
builder.moveToDocumentEnd();
builder.write("Section 2");
builder.insertBreak(BreakType.PAGE_BREAK);
builder.insertBreak(BreakType.PAGE_BREAK);

// The collected layout data won't automatically keep up with the real document contents
Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);

// After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
// The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
layoutCollector.clear();
doc.updatePageLayout();
Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);

// We can also see the start/end pages of any other node, and their overall page spans
NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
for (Node node : (Iterable<Node>) nodes) {
    System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
    System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
}

// We can iterate over the layout entities using a LayoutEnumerator
LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());

// The LayoutEnumerator can traverse the collection of layout entities like a tree
// We can also point it to any node's corresponding layout entity like this
layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
Assert.assertEquals("¶", layoutEnumerator.getText());

Constructor Summary
LayoutCollector(Document doc)
Initializes an instance of this class.
 
Property Getters/Setters Summary
DocumentgetDocument()
void
           Gets or sets the document this collector instance is attached to.
 
Method Summary
voidclear()
Clears all collected layout data. Call this method after document was manually updated, or layout was rebuilt.
intgetEndPageIndex(Node node)
Gets 1-based index of the page where node ends. Returns 0 if node cannot be mapped to a page.
java.lang.ObjectgetEntity(Node node)
Returns an opaque position of the LayoutEnumerator which corresponds to the specified node. You can use returned value as an argument to LayoutEnumerator.Current given the document being enumerated and the document of the node are the same.
intgetNumPagesSpanned(Node node)
Gets number of pages the specified node spans. 0 if node is within a single page. This is the same as getEndPageIndex(com.aspose.words.Node) - getStartPageIndex(com.aspose.words.Node).
intgetStartPageIndex(Node node)
Gets 1-based index of the page where node begins. Returns 0 if node cannot be mapped to a page.
 

    • Constructor Detail

      • LayoutCollector

        public LayoutCollector(Document doc)
        Initializes an instance of this class.
        Parameters:
        doc - The document to which this collector instance will be attached to.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
    • Property Getters/Setters Detail

      • getDocument/setDocument

        public Document getDocument() / public void setDocument(Document value)
        
        Gets or sets the document this collector instance is attached to. If you need to access page indexes of the document nodes you need to set this property to point to a document instance, before page layout of the document is built. It is best to set this property to null afterwards, otherwise the collector continues to accumulate information from subsequent rebuilds of the document's page layout.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
    • Method Detail

      • clear

        public void clear()
        Clears all collected layout data. Call this method after document was manually updated, or layout was rebuilt.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
      • getEndPageIndex

        public int getEndPageIndex(Node node)
                           throws java.lang.Exception
        Gets 1-based index of the page where node ends. Returns 0 if node cannot be mapped to a page.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
      • getEntity

        public java.lang.Object getEntity(Node node)
                        throws java.lang.Exception
        Returns an opaque position of the LayoutEnumerator which corresponds to the specified node. You can use returned value as an argument to LayoutEnumerator.Current given the document being enumerated and the document of the node are the same.

        This method works for only Paragraph nodes, as well as indivisible inline nodes, e.g. BookmarkStart or Shape. It doesn't work for Run, CellRow or Table nodes, and nodes within header/footer.

        Note that the entity returned for a Paragraph node is a paragraph break span. Use the appropriate method to ascend to the parent line

        If you need to navigate to a Run of text then you can insert bookmark right before it and then navigate to the bookmark instead.

        If you need to navigate to a Cell node then you can move to a Paragraph node in this cell and then ascend to a parent entity. The same approach can be used for Row and Table nodes.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
      • getNumPagesSpanned

        public int getNumPagesSpanned(Node node)
                              throws java.lang.Exception
        Gets number of pages the specified node spans. 0 if node is within a single page. This is the same as getEndPageIndex(com.aspose.words.Node) - getStartPageIndex(com.aspose.words.Node).

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());
      • getStartPageIndex

        public int getStartPageIndex(Node node)
                             throws java.lang.Exception
        Gets 1-based index of the page where node begins. Returns 0 if node cannot be mapped to a page.

        Example:

        Shows how to see the page spans of nodes.
        // Open a blank document and create a DocumentBuilder
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        
        // Create a LayoutCollector object for our document that will have information about the nodes we placed
        LayoutCollector layoutCollector = new LayoutCollector(doc);
        
        // The document itself is a node that contains everything, which currently spans 0 pages
        Assert.assertEquals(layoutCollector.getDocument(), doc);
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // Populate the document with sections and page breaks
        builder.write("Section 1");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        doc.appendChild(new Section(doc));
        doc.getLastSection().appendChild(new Body(doc));
        builder.moveToDocumentEnd();
        builder.write("Section 2");
        builder.insertBreak(BreakType.PAGE_BREAK);
        builder.insertBreak(BreakType.PAGE_BREAK);
        
        // The collected layout data won't automatically keep up with the real document contents
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 0);
        
        // After we clear the layout collection and update it, the layout entity collection will be populated with up-to-date information about our nodes
        // The page span for the document now shows 5, which is what we would expect after placing 4 page breaks
        layoutCollector.clear();
        doc.updatePageLayout();
        Assert.assertEquals(layoutCollector.getNumPagesSpanned(doc), 5);
        
        // We can also see the start/end pages of any other node, and their overall page spans
        NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true);
        for (Node node : (Iterable<Node>) nodes) {
            System.out.println(MessageFormat.format("->  NodeType.{0}:", node.getNodeType()));
            System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1}, spanning {2} pages.", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node), layoutCollector.getNumPagesSpanned(node)));
        }
        
        // We can iterate over the layout entities using a LayoutEnumerator
        LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
        Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
        
        // The LayoutEnumerator can traverse the collection of layout entities like a tree
        // We can also point it to any node's corresponding layout entity like this
        layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true)));
        Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType());
        Assert.assertEquals("¶", layoutEnumerator.getText());