+ // Compute the best end row.
+ if (beg_found
+ && (!sameParOrInsetMath(*it, *best_end_entry)
+ || comparePos(*it, *best_end_entry) <= 0)
+ && sameParOrInsetMath(*it, best_entry)) {
+ switch (comparePos(*it, best_entry)) {
+ case 0:
+ // Either it is the last one that matches pos...
+ best_end_entry = it;
+ end_is_next = false;
+ end_offset = 1;
+ break;
+ case -1: {
+ // ...or it is the row preceding the first that matches pos+1
+ if (!end_is_next) {
+ end_is_next = true;
+ if (it.row() != best_end_entry.row())
+ end_offset = 0;
+ best_end_entry = it;
+ }
+ break;
+ }
+ }
+ }
+ // Compute the best begin row. It is better than the previous one if it
+ // matches either at a deeper level, or at the same level but not
+ // before.
+ for (size_t i = best_slice; i < n; ++i) {
+ RowEntry entry_i = rowEntryFromCursorSlice(dit[i]);
+ if (sameParOrInsetMath(*it, entry_i)) {
+ if (comparePos(*it, entry_i) >= 0
+ && (i > best_slice
+ || !beg_found
+ || !sameParOrInsetMath(*it, *best_beg_entry)
+ || (comparePos(*it, *best_beg_entry) <= 0
+ && comparePos(entry_i, *best_beg_entry) != 0)
+ )
+ ) {
+ beg_found = true;
+ end_is_next = false;
+ end_offset = 1;
+ best_slice = i;
+ best_entry = entry_i;
+ best_beg_entry = best_end_entry = it;
+ }
+ //found CursorSlice
+ break;
+ }
+ }
+ }
+ if (!beg_found)
+ return std::make_pair(-1,-1);
+ int const best_beg_row = distance(rowlist_.begin(),
+ best_beg_entry.row()) + 1;
+ int const best_end_row = distance(rowlist_.begin(),
+ best_end_entry.row()) + end_offset;
+ return std::make_pair(best_beg_row, best_end_row);
+}
+
+
+std::pair<int,int> TexRow::rowFromCursor(Cursor const & cur) const
+{
+ DocIterator beg = cur.selectionBegin();
+ std::pair<int,int> beg_rows = rowFromDocIterator(beg);
+ if (cur.selection()) {
+ DocIterator end = cur.selectionEnd();
+ if (!cur.selIsMultiCell()
+ // backwardPos asserts without the following test, IMO it's not my
+ // duty to check this.
+ && (end.top().pit() != 0
+ || end.top().idx() != 0
+ || end.top().pos() != 0))
+ end.top().backwardPos();
+ std::pair<int,int> end_rows = rowFromDocIterator(end);
+ return std::make_pair(std::min(beg_rows.first, end_rows.first),
+ std::max(beg_rows.second, end_rows.second));
+ } else
+ return std::make_pair(beg_rows.first, beg_rows.second);
+}
+
+
+// debugging functions
+
+///
+docstring TexRow::asString(RowEntry const & entry)
+{
+ odocstringstream os;
+ if (entry.is_math)
+ os << "(1," << entry.math.id << "," << entry.math.cell << ")";
+ else
+ os << "(0," << entry.text.id << "," << entry.text.pos << ")";
+ return os.str();
+}
+
+
+///prepends the texrow to the source given by tex, for debugging purpose
+void TexRow::prepend(docstring_list & tex) const
+{
+ size_type const prefix_length = 25;
+ if (tex.size() < rowlist_.size())
+ tex.resize(rowlist_.size());
+ std::vector<RowEntryList>::const_iterator it = rowlist_.begin();
+ std::vector<RowEntryList>::const_iterator const beg = rowlist_.begin();
+ std::vector<RowEntryList>::const_iterator const end = rowlist_.end();
+ for (; it < end; ++it) {
+ docstring entry;
+ std::vector<RowEntry>::const_iterator it2 = it->begin();
+ std::vector<RowEntry>::const_iterator const end2 = it->end();
+ for (; it2 != end2; ++it2)
+ entry += asString(*it2);
+ if (entry.length() < prefix_length)
+ entry = entry + docstring(prefix_length - entry.length(), L' ');
+ ptrdiff_t i = it - beg;
+ tex[i] = entry + " " + tex[i];
+ }
+}
+
+
+
+LyXErr & operator<<(LyXErr & l, TexRow & texrow)
+{
+ if (l.enabled()) {
+ for (int i = 0; i < texrow.rows(); i++) {
+ int id,pos;
+ if (texrow.getIdFromRow(i+1,id,pos) && id>0)
+ l << i+1 << ":" << id << ":" << pos << "\n";
+ }