+///////////////////////////////////////////////////////////////////////////
+//
+// Toc implementation
+//
+///////////////////////////////////////////////////////////////////////////
+
+Toc::const_iterator TocBackend::findItem(Toc const & toc,
+ DocIterator const & dit)
+{
+ Toc::const_iterator last = toc.begin();
+ Toc::const_iterator it = toc.end();
+ if (it == last)
+ return it;
+ --it;
+ DocIterator dit_text = dit.getInnerText();
+
+ for (; it != last; --it) {
+ // We verify that we don't compare contents of two
+ // different document. This happens when you
+ // have parent and child documents.
+ if (&it->dit_[0].inset() != &dit_text[0].inset())
+ continue;
+ if (it->dit_ <= dit_text)
+ return it;
+ }
+
+ // We are before the first Toc Item:
+ return last;
+}
+
+
+Toc::iterator TocBackend::findItem(Toc & toc, int depth, docstring const & str)
+{
+ if (toc.empty())
+ return toc.end();
+ Toc::iterator it = toc.begin();
+ Toc::iterator itend = toc.end();
+ for (; it != itend; ++it) {
+ if (it->depth() == depth && it->str() == str)
+ break;
+ }
+ return it;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// TocBuilder implementation
+//
+///////////////////////////////////////////////////////////////////////////
+
+TocBuilder::TocBuilder(shared_ptr<Toc> toc)
+ : toc_(toc ? toc : make_shared<Toc>()),
+ stack_()
+{
+ LATTEST(toc);
+}
+
+void TocBuilder::pushItem(DocIterator const & dit, docstring const & s,
+ bool output_active, bool is_captioned)
+{
+ toc_->push_back(TocItem(dit, stack_.size(), s, output_active));
+ frame f = {
+ toc_->size() - 1, //pos
+ is_captioned, //is_captioned
+ };
+ stack_.push(f);
+}
+
+void TocBuilder::captionItem(DocIterator const & dit, docstring const & s,
+ bool output_active)