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 else
text_entry_ = size(); text_entry_ = size();
} }
forceAddEntry(entry);
return true;
}
void TexRow::RowEntryList::forceAddEntry(RowEntry const & entry)
{
if (size() == 0 || !(operator[](size() - 1) == entry)) if (size() == 0 || !(operator[](size() - 1) == entry))
push_back(RowEntry(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::TextEntry const TexRow::text_none = { -1, 0 };
TexRow::RowEntry const TexRow::row_none = { false, TexRow::text_none }; 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 bool TexRow::getIdFromRow(int row, int & id, int & pos) const
{ {
TextEntry t = text_none; TextEntry t = text_none;
@ -406,7 +446,12 @@ std::pair<int,int> TexRow::rowFromCursor(Cursor const & cur) const
std::pair<int,int> beg_rows = rowFromDocIterator(beg); std::pair<int,int> beg_rows = rowFromDocIterator(beg);
if (cur.selection()) { if (cur.selection()) {
DocIterator end = cur.selectionEnd(); DocIterator end = cur.selectionEnd();
if (!cur.selIsMultiCell()) 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(); end.top().backwardPos();
std::pair<int,int> end_rows = rowFromDocIterator(end); std::pair<int,int> end_rows = rowFromDocIterator(end);
return std::make_pair(std::min(beg_rows.first, end_rows.first), return std::make_pair(std::min(beg_rows.first, end_rows.first),

View File

@ -12,6 +12,19 @@
* Full author contact details are available in file CREDITS. * 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 #ifndef TEXROW_H
#define TEXROW_H #define TEXROW_H
@ -53,11 +66,11 @@ public:
}; };
}; };
// For each row we store a list of one TextEntry and several // For each row we store a list of one special TextEntry and several
// MathEntries. (The order is important.) We only want one text entry // 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 // 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 // other hand we want to record all math and table cells positions for
// precision. Usually the count of math cells is easier to handle. // enough precision. Usually the count of cells is easier to handle.
class RowEntryList : public std::vector<RowEntry> { class RowEntryList : public std::vector<RowEntry> {
public: public:
RowEntryList() : std::vector<RowEntry>(), text_entry_(-1) {} 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 // returns true if the row entry will appear in the row entry list
bool addEntry(RowEntry const &); 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 // returns the TextEntry or TexRow::text_none if none
TextEntry getTextEntry() const; TextEntry getTextEntry() const;
// returns the first entry, or TexRow::row_none if none // returns the first entry, or TexRow::row_none if none
RowEntry entry() const; RowEntry entry() const;
// appends a row
void append(RowEntryList const &);
private: private:
size_t text_entry_; size_t text_entry_;
}; };
@ -118,9 +138,16 @@ public:
/// returns true if this entry will appear on the current row /// returns true if this entry will appear on the current row
bool start(int id, int pos); bool start(int id, int pos);
/// Defines a cell and position for the current line /// Defines a cell and position for the current line. Always appear in the
/// returns true if this entry will appear on the current row /// current row.
bool startMath(uid_type id, idx_type cell); 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 /// Insert node when line is completed
void newline(); void newline();
@ -155,6 +182,10 @@ public:
/// Returns the number of rows contained /// Returns the number of rows contained
int rows() const { return rowlist_.size(); } 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 /// for debugging purpose
void prepend(docstring_list &) const; void prepend(docstring_list &) const;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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