X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph.C;h=253a617e706b6fd1adebe28155fa42f6def03c15;hb=5c3d9a254640468e40b2d30467a26222c91d856d;hp=c5c3bad5a9dc4ecb122bda4e6714bd4cae899c89;hpb=58fd3c844a88ea74901e5d8b22e94939a67f70d5;p=lyx.git diff --git a/src/paragraph.C b/src/paragraph.C index c5c3bad5a9..253a617e70 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -1,12 +1,19 @@ -/* This file is part of - * ====================================================== +/** + * \file paragraph.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * LyX, The Document Processor + * \author Asger Alstrup + * \author Lars Gullik Bjønnes + * \author Jean-Marc Lasgouttes + * \author Angus Leeming + * \author John Levon + * \author André Pönitz + * \author Dekel Tsur + * \author Jürgen Vigna * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ====================================================== */ + * Full author contact details are available in file CREDITS. + */ #include @@ -15,62 +22,46 @@ #include "buffer.h" #include "bufferparams.h" -#include "BufferView.h" -#include "changes.h" #include "encoding.h" #include "debug.h" #include "gettext.h" #include "language.h" #include "latexrunparams.h" -#include "layout.h" +#include "lyxfont.h" #include "lyxrc.h" -#include "paragraph_funcs.h" -#include "ParameterStruct.h" +#include "lyxrow.h" #include "texrow.h" - -#include "Lsstream.h" +#include "vspace.h" #include "insets/insetbibitem.h" #include "insets/insetoptarg.h" -#include "insets/insetenv.h" -#include "support/filetools.h" #include "support/lstrings.h" -#include "support/lyxmanip.h" -#include "support/FileInfo.h" -#include "support/LAssert.h" #include "support/textutils.h" +#include "support/std_sstream.h" -#include -#include -#include -#include +using lyx::pos_type; -using namespace lyx::support; +using lyx::support::contains; +using lyx::support::subst; -using std::ostream; using std::endl; -using std::fstream; -using std::ios; -using std::lower_bound; -using std::upper_bound; - -using lyx::pos_type; +using std::string; +using std::ostream; +using std::ostringstream; Paragraph::Paragraph() - : pimpl_(new Paragraph::Pimpl(this)) + : y(0), height(0), pimpl_(new Paragraph::Pimpl(this)) { - enumdepth = 0; itemdepth = 0; params().clear(); } Paragraph::Paragraph(Paragraph const & lp) - : pimpl_(new Paragraph::Pimpl(*lp.pimpl_, this)) + : y(0), height(0), text_(lp.text_), pimpl_(new Paragraph::Pimpl(*lp.pimpl_, this)) { - enumdepth = 0; itemdepth = 0; // this is because of the dummy layout of the paragraphs that // follow footnotes @@ -83,8 +74,6 @@ Paragraph::Paragraph(Paragraph const & lp) for (; it != end; ++it) { // currently we hold Inset*, not InsetBase* it->inset = static_cast(it->inset->clone().release()); - // tell the new inset who is the boss now - it->inset->parOwner(this); } } @@ -94,11 +83,14 @@ void Paragraph::operator=(Paragraph const & lp) // needed as we will destroy the pimpl_ before copying it if (&lp != this) return; - lyxerr << "Paragraph::operator=()\n"; + + lyxerr << "Paragraph::operator=()" << endl; + + text_ = lp.text_; + delete pimpl_; pimpl_ = new Pimpl(*lp.pimpl_, this); - enumdepth = lp.enumdepth; itemdepth = lp.itemdepth; // this is because of the dummy layout of the paragraphs that // follow footnotes @@ -110,8 +102,6 @@ void Paragraph::operator=(Paragraph const & lp) InsetList::iterator end = insetlist.end(); for (; it != end; ++it) { it->inset = static_cast(it->inset->clone().release()); - // tell the new inset who is the boss now - it->inset->parOwner(this); } } @@ -125,7 +115,7 @@ Paragraph::~Paragraph() } -void Paragraph::write(Buffer const * buf, ostream & os, +void Paragraph::write(Buffer const & buf, ostream & os, BufferParams const & bparams, depth_type & dth) const { @@ -285,13 +275,14 @@ void Paragraph::insertInset(pos_type pos, InsetOld * inset) } -void Paragraph::insertInset(pos_type pos, InsetOld * inset, LyXFont const & font, Change change) +void Paragraph::insertInset(pos_type pos, InsetOld * inset, + LyXFont const & font, Change change) { pimpl_->insertInset(pos, inset, font, change); } -bool Paragraph::insetAllowed(InsetOld::Code code) +bool Paragraph::insetAllowed(InsetOld_code code) { //lyxerr << "Paragraph::InsertInsetAllowed" << endl; if (pimpl_->inset_owner) @@ -302,14 +293,14 @@ bool Paragraph::insetAllowed(InsetOld::Code code) InsetOld * Paragraph::getInset(pos_type pos) { - Assert(pos < size()); + BOOST_ASSERT(pos < size()); return insetlist.get(pos); } InsetOld const * Paragraph::getInset(pos_type pos) const { - Assert(pos < size()); + BOOST_ASSERT(pos < size()); return insetlist.get(pos); } @@ -318,7 +309,7 @@ InsetOld const * Paragraph::getInset(pos_type pos) const LyXFont const Paragraph::getFontSettings(BufferParams const & bparams, pos_type pos) const { - Assert(pos <= size()); + BOOST_ASSERT(pos <= size()); Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); Pimpl::FontList::const_iterator end = pimpl_->fontlist.end(); @@ -338,7 +329,7 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams, lyx::pos_type Paragraph::getEndPosOfFontSpan(lyx::pos_type pos) const { - Assert(pos <= size()); + BOOST_ASSERT(pos <= size()); Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); Pimpl::FontList::const_iterator end = pimpl_->fontlist.end(); @@ -347,7 +338,8 @@ lyx::pos_type Paragraph::getEndPosOfFontSpan(lyx::pos_type pos) const return cit->pos(); // This should not happen, but if so, we take no chances. - lyxerr << "Pararaph::getEndPosOfFontSpan: This should not happen!\n"; + //lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!" + // << endl; return pos; } @@ -370,7 +362,7 @@ LyXFont const Paragraph::getFirstFontSettings() const LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos, LyXFont const & outerfont) const { - Assert(pos >= 0); + BOOST_ASSERT(pos >= 0); LyXLayout_ptr const & lout = layout(); @@ -382,12 +374,12 @@ LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos, else layoutfont = lout->font; - LyXFont tmpfont = getFontSettings(bparams, pos); - tmpfont.realize(layoutfont); - tmpfont.realize(outerfont); - tmpfont.realize(bparams.getLyXTextClass().defaultfont()); + LyXFont font = getFontSettings(bparams, pos); + font.realize(layoutfont); + font.realize(outerfont); + font.realize(bparams.getLyXTextClass().defaultfont()); - return tmpfont; + return font; } @@ -414,9 +406,9 @@ LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams, /// Returns the height of the highest font in range -LyXFont::FONT_SIZE +LyXFont_size Paragraph::highestFontInRange(pos_type startpos, pos_type endpos, - LyXFont::FONT_SIZE const def_size) const + LyXFont_size def_size) const { if (pimpl_->fontlist.empty()) return def_size; @@ -492,10 +484,10 @@ Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const void Paragraph::setFont(pos_type pos, LyXFont const & font) { - Assert(pos <= size()); + BOOST_ASSERT(pos <= size()); // First, reduce font against layout/label font - // Update: The SetCharFont() routine in text2.C already + // Update: The setCharFont() routine in text2.C already // reduces font, so we don't need to do that here. (Asger) // No need to simplify this because it will disappear // in a new kernel. (Asger) @@ -645,7 +637,7 @@ int Paragraph::beginningOfBody() const // Unroll the first two cycles of the loop // and remember the previous character to - // remove unnecessary GetChar() calls + // remove unnecessary getChar() calls pos_type i = 0; if (i < size() && !isNewline(i)) { ++i; @@ -693,6 +685,47 @@ InsetBibitem * Paragraph::bibitem() const } +namespace { + +/* paragraphs inside floats need different alignment tags to avoid +unwanted space */ + +bool noTrivlistCentering(UpdatableInset const * inset) +{ + if (inset && inset->owner()) { + InsetOld::Code const code = inset->owner()->lyxCode(); + return code == InsetOld::FLOAT_CODE || + code == InsetOld::WRAP_CODE; + } + return false; +} + + +string correction(string const & orig) +{ + if (orig == "flushleft") + return "raggedright"; + if (orig == "flushright") + return "raggedleft"; + if (orig == "center") + return "centering"; + return orig; +} + + +string const corrected_env(string const & suffix, string const & env, + UpdatableInset const * inset) +{ + string output = suffix + "{"; + if (noTrivlistCentering(inset)) + output += correction(env); + else + output += env; + return output + "}"; +} + +} // namespace anon + // This could go to ParagraphParameters if we want to int Paragraph::startTeXParParams(BufferParams const & bparams, @@ -727,29 +760,34 @@ int Paragraph::startTeXParParams(BufferParams const & bparams, case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: break; - case LYX_ALIGN_LEFT: - if (getParLanguage(bparams)->babel() != "hebrew") { - os << "\\begin{flushleft}"; - column += 17; - } else { - os << "\\begin{flushright}"; - column += 18; - } + case LYX_ALIGN_LEFT: { + string output; + UpdatableInset const * const inset = pimpl_->inset_owner; + if (getParLanguage(bparams)->babel() != "hebrew") + output = corrected_env("\\begin", "flushleft", inset); + else + output = corrected_env("\\begin", "flushright", inset); + os << output; + column += output.size(); break; - case LYX_ALIGN_RIGHT: - if (getParLanguage(bparams)->babel() != "hebrew") { - os << "\\begin{flushright}"; - column += 18; - } else { - os << "\\begin{flushleft}"; - column += 17; - } + } case LYX_ALIGN_RIGHT: { + string output; + UpdatableInset const * const inset = pimpl_->inset_owner; + if (getParLanguage(bparams)->babel() != "hebrew") + output = corrected_env("\\begin", "flushright", inset); + else + output = corrected_env("\\begin", "flushleft", inset); + os << output; + column += output.size(); break; - case LYX_ALIGN_CENTER: - os << "\\begin{center}"; - column += 14; + } case LYX_ALIGN_CENTER: { + string output; + output = corrected_env("\\begin", "center", pimpl_->inset_owner); + os << output; + column += output.size(); break; } + } return column; } @@ -783,35 +821,41 @@ int Paragraph::endTeXParParams(BufferParams const & bparams, case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: break; - case LYX_ALIGN_LEFT: - if (getParLanguage(bparams)->babel() != "hebrew") { - os << "\\end{flushleft}"; - column = 15; - } else { - os << "\\end{flushright}"; - column = 16; - } + 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); + else + output = corrected_env("\\par\\end", "flushright", inset); + os << output; + column += output.size(); break; - case LYX_ALIGN_RIGHT: - if (getParLanguage(bparams)->babel() != "hebrew") { - os << "\\end{flushright}"; - column+= 16; - } else { - os << "\\end{flushleft}"; - column = 15; - } + } 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); + else + output = corrected_env("\\par\\end", "flushleft", inset); + os << output; + column += output.size(); break; - case LYX_ALIGN_CENTER: - os << "\\end{center}"; - column = 12; + } case LYX_ALIGN_CENTER: { + string output; + output = corrected_env("\\par\\end", "center", pimpl_->inset_owner); + os << output; + column += output.size(); break; } + } + return column; } // This one spits out the text of the paragraph -bool Paragraph::simpleTeXOnePar(Buffer const * buf, +bool Paragraph::simpleTeXOnePar(Buffer const & buf, BufferParams const & bparams, LyXFont const & outerfont, ostream & os, TexRow & texrow, @@ -824,7 +868,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf, LyXLayout_ptr style; // well we have to check if we are in an inset with unlimited - // lenght (all in one row) if that is true then we don't allow + // 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 = @@ -1012,6 +1056,17 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf, } +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 @@ -1071,7 +1126,10 @@ bool Paragraph::isLetter(pos_type pos) const bool Paragraph::isWord(pos_type pos) const { - return IsWordChar(getChar(pos)) ; + unsigned char const c = getChar(pos); + return !(IsSeparatorChar(c) + || IsKommaChar(c) + || IsInsetChar(c)); } @@ -1116,7 +1174,7 @@ bool Paragraph::isMultiLingual(BufferParams const & bparams) for (; cit != end; ++cit) if (cit->font().language() != ignore_language && cit->font().language() != latex_language && - cit->font().language() != doc_language) + cit->font().language() != doc_language) return true; return false; } @@ -1124,7 +1182,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 { #if 0 string s; @@ -1152,7 +1210,7 @@ string const Paragraph::asString(Buffer const * buffer, bool label) const } -string const Paragraph::asString(Buffer const * buffer, +string const Paragraph::asString(Buffer const & buffer, pos_type beg, pos_type end, bool label) const { ostringstream os; @@ -1161,14 +1219,14 @@ string const Paragraph::asString(Buffer const * buffer, os << params().labelString() << ' '; for (pos_type i = beg; i < end; ++i) { - value_type const c = getUChar(buffer->params, i); + value_type const c = getUChar(buffer.params(), i); if (IsPrintable(c)) os << c; else if (c == META_INSET) getInset(i)->ascii(buffer, os); } - return STRCONV(os.str()); + return os.str(); } @@ -1189,12 +1247,6 @@ void Paragraph::deleteInsetsLyXText(BufferView * bv) } -void Paragraph::resizeInsetsLyXText(BufferView * bv) -{ - insetlist.resizeInsetsLyXText(bv); -} - - void Paragraph::setContentsFromPar(Paragraph const & par) { pimpl_->setContentsFromPar(par); @@ -1221,14 +1273,14 @@ void Paragraph::cleanChanges() Change::Type Paragraph::lookupChange(lyx::pos_type pos) const { - Assert(!size() || pos < size()); + BOOST_ASSERT(!size() || pos < size()); return pimpl_->lookupChange(pos); } Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const { - Assert(!size() || pos < size()); + BOOST_ASSERT(!size() || pos < size()); return pimpl_->lookupChangeFull(pos); } @@ -1270,21 +1322,21 @@ void Paragraph::rejectChange(pos_type start, pos_type end) } -lyx::pos_type Paragraph::size() const +Paragraph::value_type Paragraph::getChar(pos_type pos) const { - return pimpl_->size(); -} + // This is in the critical path! + pos_type const siz = text_.size(); + BOOST_ASSERT(pos <= siz); -bool Paragraph::empty() const -{ - return pimpl_->empty(); -} - + if (pos == siz) { + lyxerr << "getChar() on pos " << pos << " in par id " + << id() << " of size " << siz + << " is a bit silly !" << endl; + return '\0'; + } -Paragraph::value_type Paragraph::getChar(pos_type pos) const -{ - return pimpl_->getChar(pos); + return text_[pos]; } @@ -1325,12 +1377,13 @@ UpdatableInset * Paragraph::inInset() const void Paragraph::clearContents() { - pimpl_->clear(); + text_.clear(); } + void Paragraph::setChar(pos_type pos, value_type c) { - pimpl_->setChar(pos, c); + text_[pos] = c; } @@ -1352,9 +1405,9 @@ bool Paragraph::isFreeSpacing() const return true; // for now we just need this, later should we need this in some - // other way we can always add a function to InsetOld::() too. + // other way we can always add a function to InsetOld too. if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return (pimpl_->inset_owner->owner()->lyxCode() == InsetOld::ERT_CODE); + return pimpl_->inset_owner->owner()->lyxCode() == InsetOld::ERT_CODE; return false; } @@ -1364,13 +1417,6 @@ bool Paragraph::allowEmpty() const if (layout()->keepempty) return true; if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return (pimpl_->inset_owner->owner()->lyxCode() == InsetOld::ERT_CODE); + return pimpl_->inset_owner->owner()->lyxCode() == InsetOld::ERT_CODE; return false; } - - -bool operator==(Paragraph const & lhs, Paragraph const & rhs) -{ -#warning FIXME this implementatoin must be completely wrong... - return &lhs == &rhs; -}