-/**\r
- * \file TocBackend.C\r
- * This file is part of LyX, the document processor.\r
- * Licence details can be found in the file COPYING.\r
- *\r
- * \author Jean-Marc Lasgouttes\r
- * \author Angus Leeming\r
- * \author Abdelrazak Younes\r
- *\r
- * Full author contact details are available in file CREDITS.\r
- */\r
-\r
-#include <config.h>\r
-\r
-#include "toc.h"\r
-\r
-#include "buffer.h"\r
-#include "bufferparams.h"\r
-#include "FloatList.h"\r
-#include "funcrequest.h"\r
-#include "LyXAction.h"\r
-#include "paragraph.h"\r
-#include "cursor.h"\r
-#include "debug.h"\r
-\r
-#include "frontends/LyXView.h"\r
-\r
-#include "insets/insetfloat.h"\r
-#include "insets/insetoptarg.h"\r
-#include "insets/insetwrap.h"\r
-\r
-#include "support/convert.h"\r
-\r
-#include <iostream>\r
-\r
-using std::vector;\r
-using std::max;\r
-using std::ostream;\r
-using std::string;\r
-using std::cout;\r
-using std::endl;\r
-\r
-namespace lyx {\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-// TocBackend::Item implementation\r
-\r
-TocBackend::Item::Item(ParConstIterator const & par_it, int d,\r
- std::string const & s)\r
- : par_it_(par_it), depth_(d), str_(s)\r
-{\r
-/*\r
- if (!uid_.empty())\r
- return;\r
-\r
- size_t pos = s.find(" ");\r
- if (pos == string::npos) {\r
- // Non labelled item\r
- uid_ = s;\r
- return;\r
- }\r
-\r
- string s2 = s.substr(0, pos);\r
-\r
- if (s2 == "Chapter" || s2 == "Part") {\r
- size_t pos2 = s.find(" ", pos + 1);\r
- if (pos2 == string::npos) {\r
- // Unnumbered Chapter?? This should not happen.\r
- uid_ = s.substr(pos + 1);\r
- return;\r
- }\r
- // Chapter or Part\r
- uid_ = s.substr(pos2 + 1);\r
- return;\r
- }\r
- // Numbered Item.\r
- uid_ = s.substr(pos + 1);\r
- */\r
-}\r
-\r
-bool const TocBackend::Item::isValid() const\r
-{\r
- return depth_ != -1;\r
-}\r
-\r
-\r
-int const TocBackend::Item::id() const\r
-{\r
- return par_it_->id();\r
-}\r
-\r
-\r
-int const TocBackend::Item::depth() const\r
-{\r
- return depth_;\r
-}\r
-\r
-\r
-std::string const & TocBackend::Item::str() const\r
-{\r
- return str_;\r
-}\r
-\r
-\r
-string const TocBackend::Item::asString() const\r
-{\r
- return string(4 * depth_, ' ') + str_;\r
-}\r
-\r
-\r
-void TocBackend::Item::goTo(LyXView & lv_) const\r
-{\r
- string const tmp = convert<string>(id());\r
- lv_.dispatch(FuncRequest(LFUN_GOTO_PARAGRAPH, tmp));\r
-}\r
-\r
-FuncRequest TocBackend::Item::action() const\r
-{\r
- return FuncRequest(LFUN_GOTO_PARAGRAPH, convert<string>(id()));\r
-}\r
-\r
-\r
-\r
-\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-// TocBackend implementation\r
-\r
-TocBackend::Toc const & TocBackend::toc(std::string const & type)\r
-{\r
- // Is the type already supported?\r
- TocList::const_iterator it = tocs_.find(type);\r
- BOOST_ASSERT(it != tocs_.end());\r
-\r
- return it->second;\r
-}\r
-\r
-\r
-bool TocBackend::addType(std::string const & type)\r
-{\r
- // Is the type already supported?\r
- TocList::iterator toclist_it = tocs_.find(type);\r
- if (toclist_it != tocs_.end())\r
- return false;\r
-\r
- tocs_.insert(make_pair(type, Toc()));\r
- types_.push_back(type);\r
-\r
- return true;\r
-}\r
-\r
-\r
-void TocBackend::update()\r
-{\r
- tocs_.clear();\r
- types_.clear();\r
-\r
- BufferParams const & bufparams = buffer_->params();\r
- const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();\r
-\r
- ParConstIterator pit = buffer_->par_iterator_begin();\r
- ParConstIterator end = buffer_->par_iterator_end();\r
- for (; pit != end; ++pit) {\r
-\r
- // the string that goes to the toc (could be the optarg)\r
- string tocstring;\r
-\r
- // For each paragraph, traverse its insets and look for\r
- // FLOAT_CODE or WRAP_CODE\r
- InsetList::const_iterator it = pit->insetlist.begin();\r
- InsetList::const_iterator end = pit->insetlist.end();\r
- for (; it != end; ++it) {\r
- switch (it->inset->lyxCode()) {\r
- case InsetBase::FLOAT_CODE:\r
- static_cast<InsetFloat*>(it->inset)\r
- ->addToToc(tocs_, *buffer_);\r
- break;\r
- case InsetBase::WRAP_CODE:\r
- static_cast<InsetWrap*>(it->inset)\r
- ->addToToc(tocs_, *buffer_);\r
- break;\r
- case InsetBase::OPTARG_CODE: {\r
- if (!tocstring.empty())\r
- break;\r
- Paragraph const & par = *static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();\r
- if (!pit->getLabelstring().empty())\r
- tocstring = pit->getLabelstring()\r
- + ' ';\r
- tocstring += par.asString(*buffer_, false);\r
- break;\r
- }\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- /// now the toc entry for the paragraph\r
- int const toclevel = pit->layout()->toclevel;\r
- if (toclevel != LyXLayout::NOT_IN_TOC\r
- && toclevel >= min_toclevel\r
- && toclevel <= bufparams.tocdepth) {\r
- // insert this into the table of contents\r
- if (tocstring.empty())\r
- tocstring = pit->asString(*buffer_, true);\r
- Item const item(pit, toclevel - min_toclevel, tocstring);\r
- tocs_["TOC"].push_back(item);\r
- //cout << "item inserted str " << item.str()\r
- // << " id " << item.id() << endl;\r
- }\r
- }\r
-\r
- TocList::iterator it = tocs_.begin();\r
- for (; it != tocs_.end(); ++it)\r
- types_.push_back(it->first);\r
-}\r
-\r
-\r
-TocBackend::TocIterator const TocBackend::item(std::string const & type, ParConstIterator const & par_it)\r
-{\r
- TocList::iterator toclist_it = tocs_.find(type);\r
- // Is the type supported?\r
- BOOST_ASSERT(toclist_it != tocs_.end());\r
-\r
- Toc const & toc_vector = toclist_it->second;\r
- TocBackend::TocIterator last = toc_vector.begin();\r
- TocBackend::TocIterator it = toc_vector.end();\r
- --it;\r
-\r
- for (; it != last; --it) {\r
- \r
- // A good solution for Items inside insets would be to do:\r
- //\r
- //if (std::distance(it->par_it_, current) <= 0)\r
- // return it;\r
- //\r
- // But for an unknown reason, std::distance(current, it->par_it_) always\r
- // returns a positive value and std::distance(it->par_it_, current) takes forever...\r
- // So for now, we do:\r
- if (it->par_it_.pit() <= par_it.pit())\r
- return it;\r
- }\r
-\r
- // We are before the first Toc Item:\r
- return last;\r
-}\r
-\r
-\r
-void TocBackend::asciiTocList(string const & type, ostream & os) const\r
-{\r
- TocList::const_iterator cit = tocs_.find(type);\r
- if (cit != tocs_.end()) {\r
- Toc::const_iterator ccit = cit->second.begin();\r
- Toc::const_iterator end = cit->second.end();\r
- for (; ccit != end; ++ccit)\r
- os << ccit->asString() << '\n';\r
- }\r
-}\r
-\r
-\r
-} // namespace lyx\r
+/**
+ * \file TocBackend.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "toc.h"
+
+#include "buffer.h"
+#include "bufferparams.h"
+#include "FloatList.h"
+#include "funcrequest.h"
+#include "LyXAction.h"
+#include "paragraph.h"
+#include "cursor.h"
+#include "debug.h"
+
+#include "frontends/LyXView.h"
+
+#include "insets/insetfloat.h"
+#include "insets/insetoptarg.h"
+#include "insets/insetwrap.h"
+
+#include "support/convert.h"
+
+#include <iostream>
+
+using std::vector;
+using std::max;
+using std::ostream;
+using std::string;
+using std::cout;
+using std::endl;
+
+namespace lyx {
+
+///////////////////////////////////////////////////////////////////////////
+// TocBackend::Item implementation
+
+TocBackend::Item::Item(ParConstIterator const & par_it, int d,
+ std::string const & s)
+ : par_it_(par_it), depth_(d), str_(s)
+{
+/*
+ if (!uid_.empty())
+ return;
+
+ size_t pos = s.find(" ");
+ if (pos == string::npos) {
+ // Non labelled item
+ uid_ = s;
+ return;
+ }
+
+ string s2 = s.substr(0, pos);
+
+ if (s2 == "Chapter" || s2 == "Part") {
+ size_t pos2 = s.find(" ", pos + 1);
+ if (pos2 == string::npos) {
+ // Unnumbered Chapter?? This should not happen.
+ uid_ = s.substr(pos + 1);
+ return;
+ }
+ // Chapter or Part
+ uid_ = s.substr(pos2 + 1);
+ return;
+ }
+ // Numbered Item.
+ uid_ = s.substr(pos + 1);
+ */
+}
+
+bool const TocBackend::Item::isValid() const
+{
+ return depth_ != -1;
+}
+
+
+int const TocBackend::Item::id() const
+{
+ return par_it_->id();
+}
+
+
+int const TocBackend::Item::depth() const
+{
+ return depth_;
+}
+
+
+std::string const & TocBackend::Item::str() const
+{
+ return str_;
+}
+
+
+string const TocBackend::Item::asString() const
+{
+ return string(4 * depth_, ' ') + str_;
+}
+
+
+void TocBackend::Item::goTo(LyXView & lv_) const
+{
+ string const tmp = convert<string>(id());
+ lv_.dispatch(FuncRequest(LFUN_GOTO_PARAGRAPH, tmp));
+}
+
+FuncRequest TocBackend::Item::action() const
+{
+ return FuncRequest(LFUN_GOTO_PARAGRAPH, convert<string>(id()));
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// TocBackend implementation
+
+TocBackend::Toc const & TocBackend::toc(std::string const & type)
+{
+ // Is the type already supported?
+ TocList::const_iterator it = tocs_.find(type);
+ BOOST_ASSERT(it != tocs_.end());
+
+ return it->second;
+}
+
+
+bool TocBackend::addType(std::string const & type)
+{
+ // Is the type already supported?
+ TocList::iterator toclist_it = tocs_.find(type);
+ if (toclist_it != tocs_.end())
+ return false;
+
+ tocs_.insert(make_pair(type, Toc()));
+ types_.push_back(type);
+
+ return true;
+}
+
+
+void TocBackend::update()
+{
+ tocs_.clear();
+ types_.clear();
+
+ BufferParams const & bufparams = buffer_->params();
+ const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
+
+ ParConstIterator pit = buffer_->par_iterator_begin();
+ ParConstIterator end = buffer_->par_iterator_end();
+ for (; pit != end; ++pit) {
+
+ // the string that goes to the toc (could be the optarg)
+ string tocstring;
+
+ // For each paragraph, traverse its insets and look for
+ // FLOAT_CODE or WRAP_CODE
+ InsetList::const_iterator it = pit->insetlist.begin();
+ InsetList::const_iterator end = pit->insetlist.end();
+ for (; it != end; ++it) {
+ switch (it->inset->lyxCode()) {
+ case InsetBase::FLOAT_CODE:
+ static_cast<InsetFloat*>(it->inset)
+ ->addToToc(tocs_, *buffer_);
+ break;
+ case InsetBase::WRAP_CODE:
+ static_cast<InsetWrap*>(it->inset)
+ ->addToToc(tocs_, *buffer_);
+ break;
+ case InsetBase::OPTARG_CODE: {
+ if (!tocstring.empty())
+ break;
+ Paragraph const & par = *static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();
+ if (!pit->getLabelstring().empty())
+ tocstring = pit->getLabelstring()
+ + ' ';
+ tocstring += par.asString(*buffer_, false);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /// now the toc entry for the paragraph
+ int const toclevel = pit->layout()->toclevel;
+ if (toclevel != LyXLayout::NOT_IN_TOC
+ && toclevel >= min_toclevel
+ && toclevel <= bufparams.tocdepth) {
+ // insert this into the table of contents
+ if (tocstring.empty())
+ tocstring = pit->asString(*buffer_, true);
+ Item const item(pit, toclevel - min_toclevel, tocstring);
+ tocs_["TOC"].push_back(item);
+ //cout << "item inserted str " << item.str()
+ // << " id " << item.id() << endl;
+ }
+ }
+
+ TocList::iterator it = tocs_.begin();
+ for (; it != tocs_.end(); ++it)
+ types_.push_back(it->first);
+}
+
+
+TocBackend::TocIterator const TocBackend::item(std::string const & type, ParConstIterator const & par_it)
+{
+ TocList::iterator toclist_it = tocs_.find(type);
+ // Is the type supported?
+ BOOST_ASSERT(toclist_it != tocs_.end());
+
+ Toc const & toc_vector = toclist_it->second;
+ TocBackend::TocIterator last = toc_vector.begin();
+ TocBackend::TocIterator it = toc_vector.end();
+ --it;
+
+ for (; it != last; --it) {
+
+ // A good solution for Items inside insets would be to do:
+ //
+ //if (std::distance(it->par_it_, current) <= 0)
+ // return it;
+ //
+ // But for an unknown reason, std::distance(current, it->par_it_) always
+ // returns a positive value and std::distance(it->par_it_, current) takes forever...
+ // So for now, we do:
+ if (it->par_it_.pit() <= par_it.pit())
+ return it;
+ }
+
+ // We are before the first Toc Item:
+ return last;
+}
+
+
+void TocBackend::asciiTocList(string const & type, ostream & os) const
+{
+ TocList::const_iterator cit = tocs_.find(type);
+ if (cit != tocs_.end()) {
+ Toc::const_iterator ccit = cit->second.begin();
+ Toc::const_iterator end = cit->second.end();
+ for (; ccit != end; ++ccit)
+ os << ccit->asString() << '\n';
+ }
+}
+
+
+} // namespace lyx