mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
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:
parent
73d3816e0f
commit
f4f68a5764
@ -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;
|
||||
|
47
src/TexRow.h
47
src/TexRow.h
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 << ']';
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,6 +109,8 @@ private:
|
||||
///
|
||||
docstring getCaption(OutputParams const &) const;
|
||||
///
|
||||
void getCaption(otexstream & os, OutputParams const & runparams) const;
|
||||
|
||||
InsetFloatParams params_;
|
||||
};
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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_) {
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
TexRow & texrow() { return texrow_; }
|
||||
///
|
||||
void put(char_type const & c);
|
||||
///
|
||||
void append(docstring const &, TexRow const &);
|
||||
private:
|
||||
///
|
||||
odocstream & os_;
|
||||
|
Loading…
Reference in New Issue
Block a user