Add cursor<->row correspondance tracking for tables and subcaptions.

Please use the new function otexstream.append(str, texrow) to append an
odocstringstream with texrow information to the output when outputing to a
string buffer (e.g. case of subcaptions).
This commit is contained in:
Guillaume Munch 2015-10-13 23:51:50 +01:00
parent 73d3816e0f
commit f4f68a5764
8 changed files with 134 additions and 32 deletions

View File

@ -38,9 +38,15 @@ bool TexRow::RowEntryList::addEntry(RowEntry const & entry)
else
text_entry_ = size();
}
forceAddEntry(entry);
return true;
}
void TexRow::RowEntryList::forceAddEntry(RowEntry const & entry)
{
if (size() == 0 || !(operator[](size() - 1) == entry))
push_back(RowEntry(entry));
return true;
}
@ -60,6 +66,14 @@ TexRow::RowEntry TexRow::RowEntryList::entry() const
}
void TexRow::RowEntryList::append(RowEntryList const & row)
{
if (text_entry_ >= size())
text_entry_ = row.text_entry_ + size();
insert(end(), row.begin(), row.end());
}
TexRow::TextEntry const TexRow::text_none = { -1, 0 };
TexRow::RowEntry const TexRow::row_none = { false, TexRow::text_none };
@ -130,9 +144,17 @@ bool TexRow::start(int id, int pos)
}
bool TexRow::startMath(uid_type id, idx_type cell)
void TexRow::forceStart(int id, int pos)
{
return start(mathEntry(id,cell));
if (!enabled_)
return;
return current_row_.forceAddEntry(textEntry(id,pos));
}
void TexRow::startMath(uid_type id, idx_type cell)
{
start(mathEntry(id,cell));
}
@ -161,6 +183,24 @@ void TexRow::finalize()
}
void TexRow::append(TexRow const & texrow)
{
if (!enabled_ || !texrow.enabled_)
return;
RowList::const_iterator it = texrow.rowlist_.begin();
RowList::const_iterator const end = texrow.rowlist_.end();
if (it == end) {
current_row_.append(texrow.current_row_);
} else {
current_row_.append(*it++);
rowlist_.push_back(current_row_);
rowlist_.insert(rowlist_.end(), it, end);
current_row_ = texrow.current_row_;
}
}
bool TexRow::getIdFromRow(int row, int & id, int & pos) const
{
TextEntry t = text_none;
@ -267,8 +307,8 @@ public:
{
return row_it_ == row_end_;
}
bool operator==(RowListIterator const & a) const
{
return row_it_ == a.row_it_ && ((atEnd() && a.atEnd()) || it_ == a.it_);
@ -353,7 +393,7 @@ std::pair<int,int> TexRow::rowFromDocIterator(DocIterator const & dit) const
end_offset = 1;
break;
case -1: {
// ...or it is the row preceding the first that matches pos+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())
@ -406,8 +446,13 @@ std::pair<int,int> TexRow::rowFromCursor(Cursor const & cur) const
std::pair<int,int> beg_rows = rowFromDocIterator(beg);
if (cur.selection()) {
DocIterator end = cur.selectionEnd();
if (!cur.selIsMultiCell())
end.top().backwardPos();
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));
@ -460,7 +505,7 @@ LyXErr & operator<<(LyXErr & l, TexRow & texrow)
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";
l << i+1 << ":" << id << ":" << pos << "\n";
}
}
return l;

View File

@ -12,6 +12,19 @@
* Full author contact details are available in file CREDITS.
*/
/* Note about debugging options:
*
* When compiled in devel mode and run with the option -dbg latex, two ways
* of debugging TexRow are available:
*
* 1. The source view panel prepends the full TexRow information to the LaTeX
* output.
*
* 2. Clicking on any line in the source view moves the buffer to the location
* recognised by TexRow.
*
*/
#ifndef TEXROW_H
#define TEXROW_H
@ -53,11 +66,11 @@ public:
};
};
// For each row we store a list of one TextEntry and several
// MathEntries. (The order is important.) We only want one text entry
// For each row we store a list of one special TextEntry and several
// RowEntries. (The order is important.) We only want one text entry
// because we do not want to store every position in the lyx file. On the
// other hand we want to record all math cells positions for enough
// precision. Usually the count of math cells is easier to handle.
// other hand we want to record all math and table cells positions for
// enough precision. Usually the count of cells is easier to handle.
class RowEntryList : public std::vector<RowEntry> {
public:
RowEntryList() : std::vector<RowEntry>(), text_entry_(-1) {}
@ -65,12 +78,19 @@ public:
// returns true if the row entry will appear in the row entry list
bool addEntry(RowEntry const &);
// the row entry will appear in the row entry list, but it never counts
// as a proper text entry.
void forceAddEntry(RowEntry const &);
// returns the TextEntry or TexRow::text_none if none
TextEntry getTextEntry() const;
// returns the first entry, or TexRow::row_none if none
RowEntry entry() const;
// appends a row
void append(RowEntryList const &);
private:
size_t text_entry_;
};
@ -79,7 +99,7 @@ public:
static bool isNone(RowEntry const &);
static const TextEntry text_none;
static const RowEntry row_none;
/// Returns true if TextEntry is devoid of information
static bool isNone(TextEntry const &);
@ -118,9 +138,16 @@ public:
/// returns true if this entry will appear on the current row
bool start(int id, int pos);
/// Defines a cell and position for the current line
/// returns true if this entry will appear on the current row
bool startMath(uid_type id, idx_type cell);
/// Defines a cell and position for the current line. Always appear in the
/// current row.
void startMath(uid_type id, idx_type cell);
/// Defines the paragraph for the current cell-like inset. Always appears
/// in the current row like a math cell, but is detached from the normal
/// text flow. Note: since the cell idx is not recorded it does not work as
/// well as for math grids; if we were to do that properly we would need to
/// access the id of the parent Tabular inset from the CursorSlice.
void forceStart(int id, int pos);
/// Insert node when line is completed
void newline();
@ -155,6 +182,10 @@ public:
/// Returns the number of rows contained
int rows() const { return rowlist_.size(); }
/// appends texrow. the final line of this is merged with the first line of
/// texrow.
void append(TexRow const & texrow);
/// for debugging purpose
void prepend(docstring_list &) const;

View File

@ -329,6 +329,8 @@ void InsetCaption::getArgument(otexstream & os,
rp.par_end = paragraphs().size();
// Output the contents of the inset
if (!paragraphs().empty())
os.texrow().forceStart(paragraphs()[0].id(), 0);
latexParagraphs(buffer(), text(), os, rp);
runparams.encoding = rp.encoding;

View File

@ -327,12 +327,11 @@ void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const
OutputParams rp = runparams_in;
rp.moving_arg = true;
docstring const caption = getCaption(rp);
if (!caption.empty()) {
os << caption;
}
getCaption(os, rp);
os << '{';
// The main argument is the contents of the float. This is not a moving argument.
if (!paragraphs().empty())
os.texrow().forceStart(paragraphs()[0].id(), 0);
rp.moving_arg = false;
rp.inFloat = OutputParams::SUBFLOAT;
InsetText::latex(os, rp);
@ -493,29 +492,38 @@ bool InsetFloat::allowsCaptionVariation(std::string const & newtype) const
docstring InsetFloat::getCaption(OutputParams const & runparams) const
{
TexRow texrow(false);
odocstringstream ods;
otexstream os(ods, texrow);
getCaption(os, runparams);
return ods.str();
}
void InsetFloat::getCaption(otexstream & os,
OutputParams const & runparams) const
{
if (paragraphs().empty())
return docstring();
return;
InsetCaption const * ins = getCaptionInset();
if (ins == 0)
return docstring();
return;
ins->getArgs(os, runparams);
os << '[';
TexRow texrow;
odocstringstream ods;
otexstream os(ods, texrow);
ins->getArgs(os, runparams);
ods << '[';
odocstringstream odss;
otexstream oss(odss, texrow);
otexstream oss(ods, texrow);
ins->getArgument(oss, runparams);
docstring arg = odss.str();
docstring arg = ods.str();
// Protect ']'
if (arg.find(']') != docstring::npos)
arg = '{' + arg + '}';
ods << arg;
ods << ']';
return ods.str();
os.append(arg, texrow);
os << ']';
}

View File

@ -109,6 +109,8 @@ private:
///
docstring getCaption(OutputParams const &) const;
///
void getCaption(otexstream & os, OutputParams const & runparams) const;
InsetFloatParams params_;
};

View File

@ -2572,6 +2572,9 @@ void Tabular::TeXRow(otexstream & os, row_type row,
shared_ptr<InsetTableCell> inset = cellInset(cell);
Paragraph const & par = inset->paragraphs().front();
os.texrow().forceStart(par.id(), 0);
bool rtl = par.isRTL(buffer().params())
&& !par.empty()
&& getPWidth(cell).zero()

View File

@ -29,6 +29,14 @@ using lyx::support::split;
namespace lyx {
void otexrowstream::append(docstring const & str, TexRow const & texrow)
{
os_ << str;
texrow_.append(texrow);
}
void otexrowstream::put(char_type const & c)
{
os_.put(c);
@ -36,6 +44,7 @@ void otexrowstream::put(char_type const & c)
texrow_.newline();
}
void otexstream::put(char_type const & c)
{
if (protectspace_) {

View File

@ -33,6 +33,8 @@ public:
TexRow & texrow() { return texrow_; }
///
void put(char_type const & c);
///
void append(docstring const &, TexRow const &);
private:
///
odocstream & os_;