mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 05:25:26 +00:00
texstring and otexstringstream
texstring is a pair of a docstring and a corresponding TexRow. The row count in the TexRow has to match the number of lines in the docstring. otexstringstream is an output string stream that can be used to create texstrings (i.e. it's an odocstringstream that records the TexRow information and let us extract a texstring from it). texstrings can be passed around and output to otexstream and otexrowstream, which produces an accurate TexRow information by concatenating TexRows.
This commit is contained in:
parent
79fd549621
commit
f3256ee2cd
@ -1118,7 +1118,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
|
||||
}
|
||||
}
|
||||
|
||||
int prev_rows = os.texrow().rows();
|
||||
size_t const previous_row_count = os.texrow().rows();
|
||||
|
||||
try {
|
||||
runparams.lastid = id_;
|
||||
@ -1138,7 +1138,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
|
||||
os << '}';
|
||||
}
|
||||
|
||||
if (os.texrow().rows() > prev_rows) {
|
||||
if (os.texrow().rows() > previous_row_count) {
|
||||
os.texrow().start(owner_->id(), i + 1);
|
||||
column = 0;
|
||||
} else {
|
||||
|
@ -34,13 +34,27 @@ using namespace std;
|
||||
namespace lyx {
|
||||
|
||||
|
||||
void TexString::validate()
|
||||
{
|
||||
size_t lines = 1 + count(str.begin(), str.end(), '\n');
|
||||
size_t rows = texrow.rows();
|
||||
bool valid = lines == rows;
|
||||
if (!valid)
|
||||
LYXERR0("TexString has " << lines << " lines but " << rows << " rows." );
|
||||
// Assert in devel mode. This is important to catch bugs early, otherwise
|
||||
// they might be hard to notice and find. Recover gracefully in release
|
||||
// mode.
|
||||
LASSERT(valid, texrow.setRows(lines));
|
||||
}
|
||||
|
||||
|
||||
bool TexRow::RowEntryList::addEntry(RowEntry entry)
|
||||
{
|
||||
if (!entry.is_math) {
|
||||
if (!isNone(text_entry_))
|
||||
return false;
|
||||
else
|
||||
if (isNone(text_entry_))
|
||||
text_entry_ = entry.text;
|
||||
else if (!v_.empty() && TexRow::sameParOrInsetMath(v_.back(), entry))
|
||||
return false;
|
||||
}
|
||||
forceAddEntry(entry);
|
||||
return true;
|
||||
@ -499,12 +513,18 @@ pair<int,int> TexRow::rowFromCursor(Cursor const & cur) const
|
||||
}
|
||||
|
||||
|
||||
int TexRow::rows() const
|
||||
size_t TexRow::rows() const
|
||||
{
|
||||
return rowlist_.size();
|
||||
}
|
||||
|
||||
|
||||
void TexRow::setRows(size_t r)
|
||||
{
|
||||
rowlist_.resize(r, RowEntryList());
|
||||
}
|
||||
|
||||
|
||||
// debugging functions
|
||||
|
||||
///
|
||||
@ -544,7 +564,7 @@ void TexRow::prepend(docstring_list & tex) const
|
||||
LyXErr & operator<<(LyXErr & l, TexRow const & texrow)
|
||||
{
|
||||
if (l.enabled()) {
|
||||
for (int i = 0; i < texrow.rows(); i++) {
|
||||
for (size_t i = 0; i < texrow.rows(); i++) {
|
||||
int id,pos;
|
||||
if (texrow.getIdFromRow(i+1,id,pos) && id>0)
|
||||
l << i+1 << ":" << id << ":" << pos << "\n";
|
||||
|
37
src/TexRow.h
37
src/TexRow.h
@ -89,6 +89,14 @@ public:
|
||||
///
|
||||
TexRow();
|
||||
|
||||
/// Copy can be expensive and is not usually useful for TexRow.
|
||||
/// Force explicit copy, prefer move instead. This also prevents
|
||||
/// move()s from being converted into copy silently.
|
||||
explicit TexRow(TexRow const & other) = default;
|
||||
TexRow(TexRow && other) = default;
|
||||
TexRow & operator=(TexRow const & other) = default;
|
||||
TexRow & operator=(TexRow && other) = default;
|
||||
|
||||
/// Clears structure.
|
||||
void reset();
|
||||
|
||||
@ -164,7 +172,9 @@ public:
|
||||
std::pair<int,int> rowFromCursor(Cursor const & dit) const;
|
||||
|
||||
/// Returns the number of rows contained
|
||||
int rows() const;
|
||||
size_t rows() const;
|
||||
/// Fill or trim to reach the row count \param r
|
||||
void setRows(size_t r);
|
||||
|
||||
/// appends texrow. the final line of this is merged with the first line of
|
||||
/// texrow.
|
||||
@ -183,6 +193,31 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/// TexString : dumb struct to pass around docstrings with TexRow information.
|
||||
/// They are best created using oTexStringstream.
|
||||
/// They can be output to otexrowstreams and otexstreams.
|
||||
/// A valid TexString has as many newlines in str as in texrow. Be careful not
|
||||
/// to introduce a mismatch between the line and the row counts, as this will
|
||||
/// assert in devel mode when outputting to a otexstream.
|
||||
struct TexString {
|
||||
///
|
||||
docstring str;
|
||||
///
|
||||
TexRow texrow;
|
||||
/// Copy can be expensive and is not usually useful for TexString.
|
||||
/// Force explicit copy, prefer move instead. This also prevents
|
||||
/// move()s from being converted into copy silently.
|
||||
explicit TexString(TexString const &) = default;
|
||||
TexString(TexString && other) = default;
|
||||
TexString & operator=(TexString const & other) = default;
|
||||
TexString & operator=(TexString && other) = default;
|
||||
///
|
||||
TexString() = default;
|
||||
/// ensure that the string and the TexRow have as many newlines.
|
||||
void validate();
|
||||
};
|
||||
|
||||
|
||||
// Standard container needs a complete type
|
||||
class TexRow::RowEntryList {
|
||||
// For each row we store a list of one special TextEntry and several
|
||||
|
@ -516,14 +516,14 @@ void InsetFloat::getCaption(otexstream & os,
|
||||
ins->getArgs(os, runparams);
|
||||
|
||||
os << '[';
|
||||
odocstringstream ods;
|
||||
otexstream oss(ods);
|
||||
ins->getArgument(oss, runparams);
|
||||
docstring arg = ods.str();
|
||||
otexstringstream os2;
|
||||
ins->getArgument(os2, runparams);
|
||||
TexString ts = os2.release();
|
||||
docstring & arg = ts.str;
|
||||
// Protect ']'
|
||||
if (arg.find(']') != docstring::npos)
|
||||
arg = '{' + arg + '}';
|
||||
os.append(arg, move(oss.texrow()));
|
||||
os << move(ts);
|
||||
os << ']';
|
||||
}
|
||||
|
||||
|
@ -49,13 +49,6 @@ unique_ptr<TexRow> otexrowstream::releaseTexRow()
|
||||
}
|
||||
|
||||
|
||||
void otexrowstream::append(docstring const & str, TexRow texrow)
|
||||
{
|
||||
os_ << str;
|
||||
texrow_->append(move(texrow));
|
||||
}
|
||||
|
||||
|
||||
void otexrowstream::put(char_type const & c)
|
||||
{
|
||||
os_.put(c);
|
||||
@ -76,6 +69,22 @@ void otexstream::put(char_type const & c)
|
||||
}
|
||||
|
||||
|
||||
size_t otexstringstream::length()
|
||||
{
|
||||
auto pos = ods_.tellp();
|
||||
return (pos >= 0) ? size_t(pos) : 0;
|
||||
}
|
||||
|
||||
|
||||
TexString otexstringstream::release()
|
||||
{
|
||||
TexString ts{ods_.str(), TexRow()};
|
||||
swap(ts.texrow, texrow());
|
||||
ods_ = odocstringstream();
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
BreakLine breakln;
|
||||
SafeBreakLine safebreakln;
|
||||
|
||||
@ -112,6 +121,7 @@ otexrowstream & operator<<(otexrowstream & ots, odocstream_manip pf)
|
||||
return ots;
|
||||
}
|
||||
|
||||
|
||||
otexstream & operator<<(otexstream & ots, odocstream_manip pf)
|
||||
{
|
||||
otexrowstream & otrs = ots;
|
||||
@ -123,6 +133,38 @@ otexstream & operator<<(otexstream & ots, odocstream_manip pf)
|
||||
}
|
||||
|
||||
|
||||
otexrowstream & operator<<(otexrowstream & ots, TexString ts)
|
||||
{
|
||||
ts.validate();
|
||||
ots.os() << move(ts.str);
|
||||
ots.texrow().append(move(ts.texrow));
|
||||
return ots;
|
||||
}
|
||||
|
||||
|
||||
otexstream & operator<<(otexstream & ots, TexString ts)
|
||||
{
|
||||
size_t const len = ts.str.length();
|
||||
// Check whether there is something to output
|
||||
if (len == 0)
|
||||
return ots;
|
||||
|
||||
otexrowstream & otrs = ots;
|
||||
if (ots.protectSpace()) {
|
||||
if (!ots.canBreakLine() && ts.str[0] == ' ')
|
||||
otrs << "{}";
|
||||
ots.protectSpace(false);
|
||||
}
|
||||
|
||||
if (len > 1)
|
||||
ots.canBreakLine(ts.str[len - 2] != '\n');
|
||||
ots.lastChar(ts.str[len - 1]);
|
||||
|
||||
otrs << move(ts);
|
||||
return ots;
|
||||
}
|
||||
|
||||
|
||||
otexrowstream & operator<<(otexrowstream & ots, docstring const & s)
|
||||
{
|
||||
ots.os() << s;
|
||||
|
@ -18,11 +18,9 @@
|
||||
namespace lyx {
|
||||
|
||||
class TexRow;
|
||||
class TexString;
|
||||
|
||||
|
||||
// declared below
|
||||
class otexstringstream;
|
||||
|
||||
/** Wrapper class for odocstream.
|
||||
This class is used to automatically count the lines of the exported latex
|
||||
code.
|
||||
@ -43,7 +41,7 @@ public:
|
||||
///
|
||||
void put(char_type const & c);
|
||||
///
|
||||
void append(docstring const & str, TexRow texrow);
|
||||
void append(TexString ts);
|
||||
private:
|
||||
///
|
||||
odocstream & os_;
|
||||
@ -54,6 +52,8 @@ private:
|
||||
///
|
||||
otexrowstream & operator<<(otexrowstream &, odocstream_manip);
|
||||
///
|
||||
otexrowstream & operator<<(otexrowstream &, TexString);
|
||||
///
|
||||
otexrowstream & operator<<(otexrowstream &, docstring const &);
|
||||
///
|
||||
otexrowstream & operator<<(otexrowstream &, std::string const &);
|
||||
@ -85,6 +85,8 @@ public:
|
||||
///
|
||||
void put(char_type const & c);
|
||||
///
|
||||
void append(TexString ts);
|
||||
///
|
||||
void canBreakLine(bool breakline) { canbreakline_ = breakline; }
|
||||
///
|
||||
bool canBreakLine() const { return canbreakline_; }
|
||||
@ -114,6 +116,25 @@ private:
|
||||
char_type lastchar_;
|
||||
};
|
||||
|
||||
|
||||
/// because we need to pass ods_ to the base class
|
||||
struct otexstringstream_helper { odocstringstream ods_; };
|
||||
|
||||
/// otexstringstream : a odocstringstream with tex/row correspondence
|
||||
class otexstringstream : otexstringstream_helper, public otexstream {
|
||||
public:
|
||||
otexstringstream() : otexstringstream_helper(), otexstream(ods_) {}
|
||||
///
|
||||
docstring str() const { return ods_.str(); }
|
||||
///
|
||||
size_t length();
|
||||
///
|
||||
bool empty() { return 0 == length(); }
|
||||
/// move-returns the contents and reset the texstream
|
||||
TexString release();
|
||||
};
|
||||
|
||||
|
||||
/// Helper structs for breaking a line
|
||||
struct BreakLine {
|
||||
char n;
|
||||
@ -133,6 +154,8 @@ otexstream & operator<<(otexstream &, SafeBreakLine);
|
||||
///
|
||||
otexstream & operator<<(otexstream &, odocstream_manip);
|
||||
///
|
||||
otexstream & operator<<(otexstream &, TexString);
|
||||
///
|
||||
otexstream & operator<<(otexstream &, docstring const &);
|
||||
///
|
||||
otexstream & operator<<(otexstream &, std::string const &);
|
||||
|
Loading…
Reference in New Issue
Block a user