X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph.C;h=227568b43f2067155a02c48d60358c590768753c;hb=37d42d45f3f4a5d3e916a080af50b37ae4a9d118;hp=1dec5968edb708a13aa3997c57942645e511ab28;hpb=1eaa3eb913b16f4e6f5991b9c53b0b9ab3f84948;p=lyx.git diff --git a/src/paragraph.C b/src/paragraph.C index 1dec5968ed..227568b43f 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -27,11 +27,13 @@ #include "debug.h" #include "gettext.h" #include "language.h" +#include "LaTeXFeatures.h" #include "lyxfont.h" #include "lyxrc.h" #include "lyxrow.h" #include "outputparams.h" #include "paragraph_funcs.h" +#include "ParagraphList_fwd.h" #include "sgml.h" #include "texrow.h" #include "vspace.h" @@ -40,21 +42,22 @@ #include "insets/insetoptarg.h" #include "support/lstrings.h" -#include "support/std_sstream.h" #include "support/textutils.h" -#include "support/tostr.h" +#include "support/convert.h" #include #include +#include #include #include +#include using lyx::pos_type; -using lyx::support::contains; using lyx::support::subst; +using std::distance; using std::endl; using std::list; using std::stack; @@ -63,9 +66,12 @@ using std::ostream; using std::ostringstream; +ParagraphList::ParagraphList() +{} + + Paragraph::Paragraph() - : y(0), height(0), begin_of_body_(0), - pimpl_(new Paragraph::Pimpl(this)) + : begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this)) { itemdepth = 0; params().clear(); @@ -73,16 +79,14 @@ Paragraph::Paragraph() Paragraph::Paragraph(Paragraph const & par) - : y(0), height(0), text_(par.text_), begin_of_body_(par.begin_of_body_), + : itemdepth(par.itemdepth), insetlist(par.insetlist), + dim_(par.dim_), + rows_(par.rows_), rowSignature_(par.rowSignature_), + layout_(par.layout_), + text_(par.text_), begin_of_body_(par.begin_of_body_), pimpl_(new Paragraph::Pimpl(*par.pimpl_, this)) { - itemdepth = 0; - // this is because of the dummy layout of the paragraphs that - // follow footnotes - layout_ = par.layout(); - - // copy everything behind the break-position to the new paragraph - insetlist = par.insetlist; + //lyxerr << "Paragraph::Paragraph(Paragraph const&)" << endl; InsetList::iterator it = insetlist.begin(); InsetList::iterator end = insetlist.end(); for (; it != end; ++it) @@ -90,30 +94,29 @@ Paragraph::Paragraph(Paragraph const & par) } -void Paragraph::operator=(Paragraph const & par) +Paragraph & Paragraph::operator=(Paragraph const & par) { // needed as we will destroy the pimpl_ before copying it - if (&par != this) - return; - - lyxerr << "Paragraph::operator=()" << endl; - - text_ = par.text_; - - delete pimpl_; - pimpl_ = new Pimpl(*par.pimpl_, this); - - itemdepth = par.itemdepth; - // this is because of the dummy layout of the paragraphs that - // follow footnotes - layout_ = par.layout(); - - // copy everything behind the break-position to the new paragraph - insetlist = par.insetlist; - InsetList::iterator it = insetlist.begin(); - InsetList::iterator end = insetlist.end(); - for (; it != end; ++it) - it->inset = it->inset->clone().release(); + if (&par != this) { + itemdepth = par.itemdepth; + + insetlist = par.insetlist; + InsetList::iterator it = insetlist.begin(); + InsetList::iterator end = insetlist.end(); + for (; it != end; ++it) + it->inset = it->inset->clone().release(); + + rows_ = par.rows_; + dim_ = par.dim_; + rowSignature_ = par.rowSignature_; + layout_ = par.layout(); + text_ = par.text_; + begin_of_body_ = par.begin_of_body_; + + delete pimpl_; + pimpl_ = new Pimpl(*par.pimpl_, this); + } + return *this; } @@ -134,12 +137,12 @@ void Paragraph::write(Buffer const & buf, ostream & os, if (dth != params().depth()) { if (params().depth() > dth) { while (params().depth() > dth) { - os << "\n\\begin_deeper "; + os << "\n\\begin_deeper"; ++dth; } } else { while (params().depth() < dth) { - os << "\n\\end_deeper "; + os << "\n\\end_deeper"; --dth; } } @@ -157,10 +160,6 @@ void Paragraph::write(Buffer const & buf, ostream & os, int column = 0; for (pos_type i = 0; i < size(); ++i) { - if (!i) { - os << '\n'; - column = 0; - } Change change = pimpl_->lookupChangeFull(i); Changes::lyxMarkChange(os, column, curtime, running_change, change); @@ -186,15 +185,17 @@ void Paragraph::write(Buffer const & buf, ostream & os, // the file inset->write(buf, os); } else { - os << "\n\\begin_inset "; + if (i) + os << '\n'; + os << "\\begin_inset "; inset->write(buf, os); - os << "\n\\end_inset \n\n"; + os << "\n\\end_inset\n\n"; column = 0; } } break; case '\\': - os << "\n\\backslash \n"; + os << "\n\\backslash\n"; column = 0; break; case '.': @@ -262,64 +263,43 @@ int Paragraph::erase(pos_type start, pos_type end) void Paragraph::insert(pos_type start, string const & str, LyXFont const & font) { - int size = str.size(); - for (int i = 0 ; i < size ; ++i) + for (size_t i = 0, n = str.size(); i != n ; ++i) insertChar(start + i, str[i], font); } -bool Paragraph::checkInsertChar(LyXFont &) -{ - return true; -} - - -void Paragraph::insertChar(pos_type pos, Paragraph::value_type c) +void Paragraph::insertChar(pos_type pos, Paragraph::value_type c, + Change change) { - insertChar(pos, c, LyXFont(LyXFont::ALL_INHERIT)); + pimpl_->insertChar(pos, c, change); } void Paragraph::insertChar(pos_type pos, Paragraph::value_type c, LyXFont const & font, Change change) { - pimpl_->insertChar(pos, c, font, change); + pimpl_->insertChar(pos, c, change); + setFont(pos, font); } -void Paragraph::insertInset(pos_type pos, InsetBase * inset) +void Paragraph::insertInset(pos_type pos, InsetBase * inset, Change change) { - insertInset(pos, inset, LyXFont(LyXFont::ALL_INHERIT)); + pimpl_->insertInset(pos, inset, change); } void Paragraph::insertInset(pos_type pos, InsetBase * inset, - LyXFont const & font, Change change) + LyXFont const & font, Change change) { - pimpl_->insertInset(pos, inset, font, change); + pimpl_->insertInset(pos, inset, change); + setFont(pos, font); } -bool Paragraph::insetAllowed(InsetOld_code code) +bool Paragraph::insetAllowed(InsetBase_code code) { - //lyxerr << "Paragraph::InsertInsetAllowed" << endl; - if (pimpl_->inset_owner) - return pimpl_->inset_owner->insetAllowed(code); - return true; -} - - -InsetBase * Paragraph::getInset(pos_type pos) -{ - BOOST_ASSERT(pos < size()); - return insetlist.get(pos); -} - - -InsetBase const * Paragraph::getInset(pos_type pos) const -{ - BOOST_ASSERT(pos < size()); - return insetlist.get(pos); + return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code); } @@ -327,7 +307,10 @@ InsetBase const * Paragraph::getInset(pos_type pos) const LyXFont const Paragraph::getFontSettings(BufferParams const & bparams, pos_type pos) const { - BOOST_ASSERT(pos <= size()); + if (pos > size()) { + lyxerr << " pos: " << pos << " size: " << size() << endl; + BOOST_ASSERT(pos <= size()); + } Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); Pimpl::FontList::const_iterator end = pimpl_->fontlist.end(); @@ -345,20 +328,30 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams, } -lyx::pos_type Paragraph::getEndPosOfFontSpan(lyx::pos_type pos) const +FontSpan Paragraph::fontSpan(lyx::pos_type pos) const { BOOST_ASSERT(pos <= size()); + lyx::pos_type start = 0; Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); Pimpl::FontList::const_iterator end = pimpl_->fontlist.end(); - for (; cit != end; ++cit) - if (cit->pos() >= pos) - return cit->pos(); + for (; cit != end; ++cit) { + if (cit->pos() >= pos) { + if (pos >= beginOfBody()) + return FontSpan(std::max(start, beginOfBody()), + cit->pos()); + else + return FontSpan(start, + std::min(beginOfBody() - 1, + cit->pos())); + } + start = cit->pos() + 1; + } // This should not happen, but if so, we take no chances. //lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!" // << endl; - return pos; + return FontSpan(pos, pos); } @@ -401,8 +394,8 @@ LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos, } -LyXFont const Paragraph::getLabelFont(BufferParams const & bparams, - LyXFont const & outerfont) const +LyXFont const Paragraph::getLabelFont + (BufferParams const & bparams, LyXFont const & outerfont) const { LyXFont tmpfont = layout()->labelfont; tmpfont.setLanguage(getParLanguage(bparams)); @@ -412,8 +405,8 @@ LyXFont const Paragraph::getLabelFont(BufferParams const & bparams, } -LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams, - LyXFont const & outerfont) const +LyXFont const Paragraph::getLayoutFont + (BufferParams const & bparams, LyXFont const & outerfont) const { LyXFont tmpfont = layout()->font; tmpfont.setLanguage(getParLanguage(bparams)); @@ -424,9 +417,8 @@ LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams, /// Returns the height of the highest font in range -LyXFont_size -Paragraph::highestFontInRange(pos_type startpos, pos_type endpos, - LyXFont_size def_size) const +LyXFont_size Paragraph::highestFontInRange + (pos_type startpos, pos_type endpos, LyXFont_size def_size) const { if (pimpl_->fontlist.empty()) return def_size; @@ -518,7 +510,7 @@ void Paragraph::setFont(pos_type pos, LyXFont const & font) if (it->pos() >= pos) break; } - unsigned int i = std::distance(beg, it); + size_t const i = distance(beg, it); bool notfound = (it == endit); if (!notfound && pimpl_->fontlist[i].font() == font) @@ -578,7 +570,9 @@ int Paragraph::stripLeadingSpaces() int i = 0; while (!empty() && (isNewline(0) || isLineSeparator(0))) { - pimpl_->eraseIntern(0); + // Set Change::Type to Change::INSERTED to quietly remove it + setChange(0, Change::INSERTED); + erase(0); ++i; } @@ -644,7 +638,7 @@ void Paragraph::applyLayout(LyXLayout_ptr const & new_layout) } -int Paragraph::beginOfBody() const +pos_type Paragraph::beginOfBody() const { return begin_of_body_; } @@ -702,26 +696,27 @@ InsetBibitem * Paragraph::bibitem() const { if (!insetlist.empty()) { InsetBase * inset = insetlist.begin()->inset; - if (inset->lyxCode() == InsetBase::BIBTEX_CODE) + if (inset->lyxCode() == InsetBase::BIBITEM_CODE) return static_cast(inset); } return 0; } +bool Paragraph::forceDefaultParagraphs() const +{ + return inInset() && inInset()->forceDefaultParagraphs(0); +} + + namespace { // paragraphs inside floats need different alignment tags to avoid -// unwanted space +// unwanted space -bool noTrivlistCentering(UpdatableInset const * inset) +bool noTrivlistCentering(InsetBase::Code code) { - if (inset && inset->owner()) { - InsetBase::Code const code = inset->owner()->lyxCode(); - return code == InsetBase::FLOAT_CODE || - code == InsetBase::WRAP_CODE; - } - return false; + return code == InsetBase::FLOAT_CODE || code == InsetBase::WRAP_CODE; } @@ -738,10 +733,10 @@ string correction(string const & orig) string const corrected_env(string const & suffix, string const & env, - UpdatableInset const * inset) + InsetBase::Code code) { string output = suffix + "{"; - if (noTrivlistCentering(inset)) + if (noTrivlistCentering(code)) output += correction(env); else output += env; @@ -773,7 +768,7 @@ int Paragraph::startTeXParParams(BufferParams const & bparams, case LYX_ALIGN_CENTER: if (moving_arg) { os << "\\protect"; - column = 8; + column += 8; } break; } @@ -786,27 +781,25 @@ int Paragraph::startTeXParParams(BufferParams const & bparams, break; case LYX_ALIGN_LEFT: { string output; - UpdatableInset const * const inset = pimpl_->inset_owner; if (getParLanguage(bparams)->babel() != "hebrew") - output = corrected_env("\\begin", "flushleft", inset); + output = corrected_env("\\begin", "flushleft", ownerCode()); else - output = corrected_env("\\begin", "flushright", inset); + output = corrected_env("\\begin", "flushright", ownerCode()); os << output; column += output.size(); break; } case LYX_ALIGN_RIGHT: { string output; - UpdatableInset const * const inset = pimpl_->inset_owner; if (getParLanguage(bparams)->babel() != "hebrew") - output = corrected_env("\\begin", "flushright", inset); + output = corrected_env("\\begin", "flushright", ownerCode()); else - output = corrected_env("\\begin", "flushleft", inset); + output = corrected_env("\\begin", "flushleft", ownerCode()); os << output; column += output.size(); break; } case LYX_ALIGN_CENTER: { string output; - output = corrected_env("\\begin", "center", pimpl_->inset_owner); + output = corrected_env("\\begin", "center", ownerCode()); os << output; column += output.size(); break; @@ -847,27 +840,25 @@ int Paragraph::endTeXParParams(BufferParams const & bparams, break; case LYX_ALIGN_LEFT: { string output; - UpdatableInset const * const inset = pimpl_->inset_owner; if (getParLanguage(bparams)->babel() != "hebrew") - output = corrected_env("\\par\\end", "flushleft", inset); + output = corrected_env("\\par\\end", "flushleft", ownerCode()); else - output = corrected_env("\\par\\end", "flushright", inset); + output = corrected_env("\\par\\end", "flushright", ownerCode()); os << output; column += output.size(); break; } case LYX_ALIGN_RIGHT: { string output; - UpdatableInset const * const inset = pimpl_->inset_owner; if (getParLanguage(bparams)->babel() != "hebrew") - output = corrected_env("\\par\\end", "flushright", inset); + output = corrected_env("\\par\\end", "flushright", ownerCode()); else - output = corrected_env("\\par\\end", "flushleft", inset); + output = corrected_env("\\par\\end", "flushleft", ownerCode()); os << output; column += output.size(); break; } case LYX_ALIGN_CENTER: { string output; - output = corrected_env("\\par\\end", "center", pimpl_->inset_owner); + output = corrected_env("\\par\\end", "center", ownerCode()); os << output; column += output.size(); break; @@ -883,7 +874,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, BufferParams const & bparams, LyXFont const & outerfont, ostream & os, TexRow & texrow, - OutputParams const & runparams) + OutputParams const & runparams) const { lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl; @@ -895,8 +886,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // length (all in one row) if that is true then we don't allow // any special options in the paragraph and also we don't allow // any environment other then "Standard" to be valid! - bool asdefault = - (inInset() && inInset()->forceDefaultParagraphs(inInset())); + bool asdefault = forceDefaultParagraphs(); if (asdefault) { style = bparams.getLyXTextClass().defaultLayout(); @@ -906,21 +896,29 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, LyXFont basefont; + LaTeXFeatures features(buf, bparams, runparams.nice); + + // output change tracking marks only if desired, + // if dvipost is installed, + // and with dvi/ps (other formats don't work) + bool const output = bparams.output_changes + && runparams.flavor == OutputParams::LATEX + && features.isAvailable("dvipost"); + // Maybe we have to create a optional argument. pos_type body_pos = beginOfBody(); unsigned int column = 0; if (body_pos > 0) { - os << '['; - ++column; + // the optional argument is kept in curly brackets in + // case it contains a ']' + os << "[{"; + column += 2; basefont = getLabelFont(bparams, outerfont); } else { basefont = getLayoutFont(bparams, outerfont); } - bool moving_arg = runparams.moving_arg; - moving_arg |= style->needprotect; - // Which font is currently active? LyXFont running_font(basefont); // Do we have an open font change? @@ -937,7 +935,8 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, ++column; } if (!asdefault) - column += startTeXParParams(bparams, os, moving_arg); + column += startTeXParParams(bparams, os, + runparams.moving_arg); } for (pos_type i = 0; i < size(); ++i) { @@ -951,8 +950,8 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, } basefont = getLayoutFont(bparams, outerfont); running_font = basefont; - os << ']'; - ++column; + os << "}] "; + column +=3; } if (style->isCommand()) { os << '{'; @@ -961,7 +960,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, if (!asdefault) column += startTeXParParams(bparams, os, - moving_arg); + runparams.moving_arg); } value_type c = getChar(i); @@ -1015,22 +1014,28 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, Change::Type change = pimpl_->lookupChange(i); - column += Changes::latexMarkChange(os, running_change, change); + column += Changes::latexMarkChange(os, running_change, + change, output); running_change = change; - OutputParams rp = runparams; - rp.moving_arg = moving_arg; - rp.free_spacing = style->free_spacing; - pimpl_->simpleTeXSpecialChars(buf, bparams, - os, texrow, runparams, - font, running_font, - basefont, outerfont, open_font, - running_change, - *style, i, column, c); + // do not output text which is marked deleted + // if change tracking output is not desired + if (output || running_change != Change::DELETED) { + OutputParams rp = runparams; + rp.free_spacing = style->free_spacing; + rp.local_font = &font; + rp.intitle = style->intitle; + pimpl_->simpleTeXSpecialChars(buf, bparams, + os, texrow, rp, + font, running_font, + basefont, outerfont, open_font, + running_change, + *style, i, column, c); + } } column += Changes::latexMarkChange(os, - running_change, Change::UNCHANGED); + running_change, Change::UNCHANGED, output); // If we have an open font definition, we have to close it if (open_font) { @@ -1056,12 +1061,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // Needed if there is an optional argument but no contents. if (body_pos > 0 && body_pos == size()) { - os << "]~"; + os << "}]~"; return_value = false; } if (!asdefault) { - column += endTeXParParams(bparams, os, moving_arg); + column += endTeXParParams(bparams, os, runparams.moving_arg); } lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl; @@ -1267,7 +1272,7 @@ void Paragraph::simpleLinuxDocOnePar(Buffer const & buf, os << '<' << tag_name(*j) << '>'; } - char c = getChar(i); + value_type c = getChar(i); if (c == Paragraph::META_INSET) { @@ -1319,167 +1324,148 @@ void Paragraph::simpleLinuxDocOnePar(Buffer const & buf, } +bool Paragraph::emptyTag() const +{ + for (pos_type i = 0; i < size(); ++i) { + if (isInset(i)) { + InsetBase const * inset = getInset(i); + InsetBase::Code lyx_code = inset->lyxCode(); + if (lyx_code != InsetBase::TOC_CODE && + lyx_code != InsetBase::INCLUDE_CODE && + lyx_code != InsetBase::GRAPHICS_CODE && + lyx_code != InsetBase::ERT_CODE && + lyx_code != InsetBase::FLOAT_CODE && + lyx_code != InsetBase::TABULAR_CODE) { + return false; + } + } else { + value_type c = getChar(i); + if (c != ' ' && c != '\t') + return false; + } + } + return true; +} + + +string Paragraph::getID(Buffer const & buf, OutputParams const & runparams) const +{ + for (pos_type i = 0; i < size(); ++i) { + if (isInset(i)) { + InsetBase const * inset = getInset(i); + InsetBase::Code lyx_code = inset->lyxCode(); + if (lyx_code == InsetBase::LABEL_CODE) { + string const id = static_cast(inset)->getContents(); + return "id=\"" + sgml::cleanID(buf, runparams, id) + "\""; + } + } + + } + return string(); +} + + +pos_type Paragraph::getFirstWord(Buffer const & buf, ostream & os, OutputParams const & runparams) const +{ + pos_type i; + for (i = 0; i < size(); ++i) { + if (isInset(i)) { + InsetBase const * inset = getInset(i); + inset->docbook(buf, os, runparams); + } else { + value_type c = getChar(i); + if (c == ' ') + break; + bool ws; + string str; + boost::tie(ws, str) = sgml::escapeChar(c); + + os << str; + } + } + return i; +} + + +bool Paragraph::onlyText(Buffer const & buf, LyXFont const & outerfont, pos_type initial) const +{ + LyXFont font_old; + + for (pos_type i = initial; i < size(); ++i) { + LyXFont font = getFont(buf.params(), i, outerfont); + if (isInset(i)) + return false; + if (i != initial && font != font_old) + return false; + font_old = font; + } + + return true; +} + + void Paragraph::simpleDocBookOnePar(Buffer const & buf, ostream & os, - LyXFont const & outerfont, OutputParams const & runparams, - lyx::depth_type depth, - bool labelid) const + LyXFont const & outerfont, + pos_type initial) const { bool emph_flag = false; LyXLayout_ptr const & style = layout(); - LyXLayout_ptr const & defaultstyle = - buf.params().getLyXTextClass().defaultLayout(); - LyXFont font_old = style->labeltype == LABEL_MANUAL ? style->labelfont : style->font; - int char_line_count = depth; - bool label_closed = true; - bool para_closed = true; - - if (style->latextype == LATEX_ITEM_ENVIRONMENT) { - string ls = ""; - Counters & counters = buf.params().getLyXTextClass().counters(); - if (!style->free_spacing) - os << string(depth,' '); - if (!style->labeltag().empty()) { - os << "<" << style->labeltag() << ">\n"; - label_closed = false; - } else { - if (!defaultstyle->latexparam().empty()) { - counters.step("para"); - ls = tostr(counters.value("para")); - ls = " id=\"" - + subst(defaultstyle->latexparam(), "#", ls) + '"'; - } - os << "<" << style->itemtag() << ">\n" - << string(depth, ' ') << "<" - << defaultstyle->latexname() << ls << ">\n"; - para_closed = false; - } - } + if (style->pass_thru && !onlyText(buf, outerfont, initial)) + os << "]]>"; // parsing main loop - for (pos_type i = 0; i < size(); ++i) { + for (pos_type i = initial; i < size(); ++i) { LyXFont font = getFont(buf.params(), i, outerfont); // handle tag if (font_old.emph() != font.emph()) { if (font.emph() == LyXFont::ON) { - if (style->latexparam() == "CDATA") - os << "]]>"; os << ""; - if (style->latexparam() == "CDATA") - os << "latexparam() == "CDATA") - os << "]]>"; + } else if (i != initial) { os << ""; - if (style->latexparam() == "CDATA") - os << "latexparam() == "CDATA") - os << "]]>"; - inset->docbook(buf, os, runparams); - if (style->latexparam() == "CDATA") - os << "docbook(buf, os, runparams); } else { - char c = getChar(i); + value_type c = getChar(i); bool ws; string str; boost::tie(ws, str) = sgml::escapeChar(c); - if (style->pass_thru) { + if (style->pass_thru) os << c; - } else if (isFreeSpacing() || c != ' ') { - os << str; - } else if (!style->labeltag().empty() && !label_closed) { - ++char_line_count; - os << "\nlabeltag() << "><" - << style->itemtag() << "><" - << defaultstyle->latexname() << ">"; - label_closed = true; - para_closed = false; - } else { - os << ' '; - } + else + os << str; } font_old = font; } if (emph_flag) { - if (style->latexparam() == "CDATA") - os << "]]>"; os << ""; - if (style->latexparam() == "CDATA") - os << " not closed... - os << "labeltag() << ">\n<" - << style->itemtag() << "><" - << defaultstyle->latexname() << "> "; - } - if (!para_closed) { - os << "\n" << string(depth, ' ') << "latexname() << ">\n"; - } if (style->free_spacing) os << '\n'; -} - - -namespace { - -/// return true if the char is a meta-character for an inset -inline -bool IsInsetChar(char c) -{ - return (c == Paragraph::META_INSET); -} - -} // namespace anon - - - -bool Paragraph::isHfill(pos_type pos) const -{ - return IsInsetChar(getChar(pos)) - && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE; -} - - -bool Paragraph::isInset(pos_type pos) const -{ - return IsInsetChar(getChar(pos)); + if (style->pass_thru && !onlyText(buf, outerfont, initial)) + os << "lyxCode() == InsetBase::NEWLINE_CODE; -} - - -bool Paragraph::isSeparator(pos_type pos) const -{ - return IsSeparatorChar(getChar(pos)); + return isInset(pos) + && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE; } @@ -1487,37 +1473,20 @@ bool Paragraph::isLineSeparator(pos_type pos) const { value_type const c = getChar(pos); return IsLineSeparatorChar(c) - || (IsInsetChar(c) && getInset(pos) && + || (c == Paragraph::META_INSET && getInset(pos) && getInset(pos)->isLineSeparator()); } -bool Paragraph::isKomma(pos_type pos) const -{ - return IsKommaChar(getChar(pos)); -} - - /// Used by the spellchecker bool Paragraph::isLetter(pos_type pos) const { - value_type const c = getChar(pos); - if (IsLetterChar(c)) - return true; if (isInset(pos)) return getInset(pos)->isLetter(); - // We want to pass the ' and escape chars to ispell - string const extra = lyxrc.isp_esc_chars + '\''; - return contains(extra, c); -} - - -bool Paragraph::isWord(pos_type pos) const -{ - unsigned char const c = getChar(pos); - return !(IsSeparatorChar(c) - || IsKommaChar(c) - || IsInsetChar(c)); + else { + value_type const c = getChar(pos); + return IsLetterChar(c) || IsDigit(c); + } } @@ -1526,7 +1495,9 @@ Paragraph::getParLanguage(BufferParams const & bparams) const { if (!empty()) return getFirstFontSettings().language(); +#ifdef WITH_WARNINGS #warning FIXME we should check the prev par as well (Lgb) +#endif return bparams.language; } @@ -1535,8 +1506,7 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const { return lyxrc.rtl_support && getParLanguage(bparams)->RightToLeft() - && !(inInset() && inInset()->owner() && - inInset()->owner()->lyxCode() == InsetBase::ERT_CODE); + && ownerCode() != InsetBase::ERT_CODE; } @@ -1553,7 +1523,7 @@ void Paragraph::changeLanguage(BufferParams const & bparams, } -bool Paragraph::isMultiLingual(BufferParams const & bparams) +bool Paragraph::isMultiLingual(BufferParams const & bparams) const { Language const * doc_language = bparams.language; Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); @@ -1570,8 +1540,7 @@ bool Paragraph::isMultiLingual(BufferParams const & bparams) // Convert the paragraph to a string. // Used for building the table of contents -string const Paragraph::asString(Buffer const & buffer, - bool label) const +string const Paragraph::asString(Buffer const & buffer, bool label) const { OutputParams runparams; return asString(buffer, runparams, label); @@ -1631,21 +1600,16 @@ string const Paragraph::asString(Buffer const & buffer, if (IsPrintable(c)) os << c; else if (c == META_INSET) - getInset(i)->plaintext(buffer, os, runparams); + getInset(i)->textString(buffer, os, runparams); } return os.str(); } -void Paragraph::setInsetOwner(UpdatableInset * inset) +void Paragraph::setInsetOwner(InsetBase * inset) { pimpl_->inset_owner = inset; - InsetList::iterator it = insetlist.begin(); - InsetList::iterator end = insetlist.end(); - for (; it != end; ++it) - if (it->inset) - it->inset->setOwner(inset); } @@ -1675,14 +1639,14 @@ void Paragraph::cleanChanges() Change::Type Paragraph::lookupChange(lyx::pos_type pos) const { - BOOST_ASSERT(!size() || pos < size()); + BOOST_ASSERT(empty() || pos < size()); return pimpl_->lookupChange(pos); } Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const { - BOOST_ASSERT(!size() || pos < size()); + BOOST_ASSERT(empty() || pos < size()); return pimpl_->lookupChangeFull(pos); } @@ -1702,13 +1666,12 @@ bool Paragraph::isChangeEdited(pos_type start, pos_type end) const void Paragraph::setChange(lyx::pos_type pos, Change::Type type) { pimpl_->setChange(pos, type); - } -void Paragraph::markErased() +void Paragraph::markErased(bool erased) { - pimpl_->markErased(); + pimpl_->markErased(erased); } @@ -1724,26 +1687,6 @@ void Paragraph::rejectChange(pos_type start, pos_type end) } -Paragraph::value_type Paragraph::getChar(pos_type pos) const -{ - // This is in the critical path! - pos_type const siz = text_.size(); - - BOOST_ASSERT(0 <= pos); - BOOST_ASSERT(pos <= siz); - - if (pos == siz) { - lyxerr << "getChar() on pos " << pos << " in par id " - << id() << " of size " << siz - << " is a bit silly !" << endl; - BOOST_ASSERT(false); - return '\0'; - } - - return text_[pos]; -} - - int Paragraph::id() const { return pimpl_->id_; @@ -1752,11 +1695,6 @@ int Paragraph::id() const LyXLayout_ptr const & Paragraph::layout() const { -/* - InsetBase * inset = inInset(); - if (inset && inset->lyxCode() == InsetBase::ENVIRONMENT_CODE) - return static_cast(inset)->layout(); -*/ return layout_; } @@ -1767,12 +1705,19 @@ void Paragraph::layout(LyXLayout_ptr const & new_layout) } -UpdatableInset * Paragraph::inInset() const +InsetBase * Paragraph::inInset() const { return pimpl_->inset_owner; } +InsetBase::Code Paragraph::ownerCode() const +{ + return pimpl_->inset_owner + ? pimpl_->inset_owner->lyxCode() : InsetBase::NO_CODE; +} + + void Paragraph::clearContents() { text_.clear(); @@ -1804,9 +1749,7 @@ bool Paragraph::isFreeSpacing() const // for now we just need this, later should we need this in some // other way we can always add a function to InsetBase too. - if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE; - return false; + return ownerCode() == InsetBase::ERT_CODE; } @@ -1814,21 +1757,59 @@ bool Paragraph::allowEmpty() const { if (layout()->keepempty) return true; - if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE; - return false; + return ownerCode() == InsetBase::ERT_CODE; +} + + +Row & Paragraph::getRow(pos_type pos, bool boundary) +{ + BOOST_ASSERT(!rows().empty()); + + // If boundary is set we should return the row on which + // the character before is inside. + if (pos > 0 && boundary) + --pos; + + RowList::iterator rit = rows_.end(); + RowList::iterator const begin = rows_.begin(); + + for (--rit; rit != begin && rit->pos() > pos; --rit) + ; + + return *rit; } -RowList::iterator Paragraph::getRow(pos_type pos) +Row const & Paragraph::getRow(pos_type pos, bool boundary) const { - RowList::iterator rit = rows.end(); - RowList::iterator const begin = rows.begin(); + BOOST_ASSERT(!rows().empty()); + + // If boundary is set we should return the row on which + // the character before is inside. + if (pos > 0 && boundary) + --pos; + + RowList::const_iterator rit = rows_.end(); + RowList::const_iterator const begin = rows_.begin(); for (--rit; rit != begin && rit->pos() > pos; --rit) ; - return rit; + return *rit; +} + + +size_t Paragraph::pos2row(pos_type pos) const +{ + BOOST_ASSERT(!rows().empty()); + + RowList::const_iterator rit = rows_.end(); + RowList::const_iterator const begin = rows_.begin(); + + for (--rit; rit != begin && rit->pos() > pos; --rit) + ; + + return rit - begin; } @@ -1865,3 +1846,13 @@ unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const return Encodings::TransformChar(c, Encodings::FORM_ISOLATED); } } + + +void Paragraph::dump() const +{ + lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl; + for (size_t i = 0; i != rows_.size(); ++i) { + lyxerr << " row " << i << ": "; + rows_[i].dump(); + } +}