X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph.C;h=227568b43f2067155a02c48d60358c590768753c;hb=37d42d45f3f4a5d3e916a080af50b37ae4a9d118;hp=516228c5d78424e5ae26295602246fd671c7c94a;hpb=3d9f2089dd528ff458c1f18685fffac6a9530d9e;p=lyx.git diff --git a/src/paragraph.C b/src/paragraph.C index 516228c5d7..227568b43f 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -27,6 +27,7 @@ #include "debug.h" #include "gettext.h" #include "language.h" +#include "LaTeXFeatures.h" #include "lyxfont.h" #include "lyxrc.h" #include "lyxrow.h" @@ -42,18 +43,18 @@ #include "support/lstrings.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; @@ -70,10 +71,8 @@ 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)) { - //lyxerr << "sizeof Paragraph::Pimpl: " << sizeof(Paragraph::Pimpl) << endl; itemdepth = 0; params().clear(); } @@ -81,8 +80,9 @@ Paragraph::Paragraph() Paragraph::Paragraph(Paragraph const & par) : itemdepth(par.itemdepth), insetlist(par.insetlist), - rows(par.rows), y(par.y), height(par.height), - width(par.width), layout_(par.layout_), + 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)) { @@ -106,10 +106,9 @@ Paragraph & Paragraph::operator=(Paragraph const & par) for (; it != end; ++it) it->inset = it->inset->clone().release(); - rows = par.rows; - y = par.y; - height = par.height; - width = par.width; + rows_ = par.rows_; + dim_ = par.dim_; + rowSignature_ = par.rowSignature_; layout_ = par.layout(); text_ = par.text_; begin_of_body_ = par.begin_of_body_; @@ -161,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); @@ -190,7 +185,9 @@ 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"; column = 0; @@ -266,18 +263,11 @@ 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, Change change) { @@ -307,26 +297,12 @@ void Paragraph::insertInset(pos_type pos, InsetBase * inset, } -bool Paragraph::insetAllowed(InsetOld_code code) +bool Paragraph::insetAllowed(InsetBase_code code) { return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code); } -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); -} - - // Gets uninstantiated font setting at position. LyXFont const Paragraph::getFontSettings(BufferParams const & bparams, pos_type pos) const @@ -352,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); } @@ -408,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)); @@ -419,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)); @@ -431,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; @@ -525,7 +510,7 @@ void Paragraph::setFont(pos_type pos, LyXFont const & font) if (it->pos() >= pos) break; } - unsigned int i = distance(beg, it); + size_t const i = distance(beg, it); bool notfound = (it == endit); if (!notfound && pimpl_->fontlist[i].font() == font) @@ -585,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; } @@ -709,7 +696,7 @@ 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; @@ -718,13 +705,7 @@ InsetBibitem * Paragraph::bibitem() const bool Paragraph::forceDefaultParagraphs() const { - return inInset() && inInset()->forceDefaultParagraphs(inInset()); -} - - -bool Paragraph::autoBreakRows() const -{ - return inInset() && static_cast(inInset())->getAutoBreakRows(); + return inInset() && inInset()->forceDefaultParagraphs(0); } @@ -915,6 +896,15 @@ 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; @@ -945,7 +935,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, ++column; } if (!asdefault) - column += startTeXParParams(bparams, os, + column += startTeXParParams(bparams, os, runparams.moving_arg); } @@ -1024,23 +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.free_spacing = style->free_spacing; - rp.local_language = font.language()->babel(); - rp.intitle = style->intitle; - pimpl_->simpleTeXSpecialChars(buf, bparams, - os, texrow, rp, - 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) { @@ -1066,7 +1061,7 @@ 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; } @@ -1277,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) { @@ -1335,20 +1330,19 @@ bool Paragraph::emptyTag() const if (isInset(i)) { InsetBase const * inset = getInset(i); InsetBase::Code lyx_code = inset->lyxCode(); - if (lyx_code != InsetBase::TOC_CODE and - lyx_code != InsetBase::INCLUDE_CODE and - lyx_code != InsetBase::GRAPHICS_CODE and - lyx_code != InsetBase::ERT_CODE and - lyx_code != InsetBase::FLOAT_CODE and + 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 { - char c = getChar(i); - if(c!= ' ' and c!= '\t') + value_type c = getChar(i); + if (c != ' ' && c != '\t') return false; } - } return true; } @@ -1379,7 +1373,7 @@ pos_type Paragraph::getFirstWord(Buffer const & buf, ostream & os, OutputParams InsetBase const * inset = getInset(i); inset->docbook(buf, os, runparams); } else { - char c = getChar(i); + value_type c = getChar(i); if (c == ' ') break; bool ws; @@ -1395,14 +1389,13 @@ pos_type Paragraph::getFirstWord(Buffer const & buf, ostream & os, OutputParams bool Paragraph::onlyText(Buffer const & buf, LyXFont const & outerfont, pos_type initial) const { - LyXLayout_ptr const & style = layout(); 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 and font != font_old) + if (i != initial && font != font_old) return false; font_old = font; } @@ -1423,8 +1416,9 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf, LyXFont font_old = style->labeltype == LABEL_MANUAL ? style->labelfont : style->font; - if (style->pass_thru and not onlyText(buf, outerfont, initial)) + if (style->pass_thru && !onlyText(buf, outerfont, initial)) os << "]]>"; + // parsing main loop for (pos_type i = initial; i < size(); ++i) { LyXFont font = getFont(buf.params(), i, outerfont); @@ -1444,7 +1438,7 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf, InsetBase const * inset = getInset(i); inset->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); @@ -1463,31 +1457,11 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf, if (style->free_spacing) os << '\n'; - if (style->pass_thru and not onlyText(buf, outerfont, initial)) + if (style->pass_thru && !onlyText(buf, outerfont, initial)) os << "lyxCode() == InsetBase::HFILL_CODE; -} - - bool Paragraph::isNewline(pos_type pos) const { return isInset(pos) @@ -1495,49 +1469,24 @@ bool Paragraph::isNewline(pos_type pos) const } -bool Paragraph::isSeparator(pos_type pos) const -{ - return IsSeparatorChar(getChar(pos)); -} - - 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 { if (isInset(pos)) return getInset(pos)->isLetter(); - value_type const c = getChar(pos); - return !(IsSeparatorChar(c) - || IsKommaChar(c) - || IsInsetChar(c)); + else { + value_type const c = getChar(pos); + return IsLetterChar(c) || IsDigit(c); + } } @@ -1651,14 +1600,14 @@ 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; } @@ -1720,9 +1669,9 @@ void Paragraph::setChange(lyx::pos_type pos, Change::Type type) } -void Paragraph::markErased() +void Paragraph::markErased(bool erased) { - pimpl_->markErased(); + pimpl_->markErased(erased); } @@ -1756,7 +1705,7 @@ void Paragraph::layout(LyXLayout_ptr const & new_layout) } -UpdatableInset * Paragraph::inInset() const +InsetBase * Paragraph::inInset() const { return pimpl_->inset_owner; } @@ -1812,34 +1761,50 @@ bool Paragraph::allowEmpty() const } -RowList::iterator Paragraph::getRow(pos_type pos) +Row & Paragraph::getRow(pos_type pos, bool boundary) { - 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::iterator rit = rows_.end(); + RowList::iterator const begin = rows_.begin(); for (--rit; rit != begin && rit->pos() > pos; --rit) ; - return rit; + return *rit; } -RowList::const_iterator Paragraph::getRow(pos_type pos) const +Row const & Paragraph::getRow(pos_type pos, bool boundary) const { - RowList::const_iterator rit = rows.end(); - RowList::const_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::row(pos_type pos) const +size_t Paragraph::pos2row(pos_type pos) const { - RowList::const_iterator rit = rows.end(); - RowList::const_iterator const begin = rows.begin(); + 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) ; @@ -1881,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(); + } +}