X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=7fd271c41d619eaf42c6c23d460b5d18e2ad7650;hb=26910d5ec49395d1372dd5b9259f1bf6ed23de0a;hp=d025a80b3ff1f02559a915845cd5b250c867f265;hpb=57d8b059e0c5b2c14247d3eeb9ada771fe5a502d;p=lyx.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index d025a80b3f..7fd271c41d 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -585,16 +585,16 @@ Paragraph::Private::Private(Private const & p, Paragraph * owner, void Paragraph::addChangesToToc(DocIterator const & cdit, - Buffer const & buf) const + Buffer const & buf, bool output_active) const { - d->changes_.addToToc(cdit, buf); + d->changes_.addToToc(cdit, buf, output_active); } bool Paragraph::isDeleted(pos_type start, pos_type end) const { - LASSERT(start >= 0 && start <= size(), /**/); - LASSERT(end > start && end <= size() + 1, /**/); + LASSERT(start >= 0 && start <= size(), return false); + LASSERT(end > start && end <= size() + 1, return false); return d->changes_.isDeleted(start, end); } @@ -602,8 +602,8 @@ bool Paragraph::isDeleted(pos_type start, pos_type end) const bool Paragraph::isChanged(pos_type start, pos_type end) const { - LASSERT(start >= 0 && start <= size(), /**/); - LASSERT(end > start && end <= size() + 1, /**/); + LASSERT(start >= 0 && start <= size(), return false); + LASSERT(end > start && end <= size() + 1, return false); return d->changes_.isChanged(start, end); } @@ -648,7 +648,7 @@ void Paragraph::setChange(Change const & change) void Paragraph::setChange(pos_type pos, Change const & change) { - LASSERT(pos >= 0 && pos <= size(), /**/); + LASSERT(pos >= 0 && pos <= size(), return); d->changes_.set(change, pos); // see comment in setChange(Change const &) above @@ -660,15 +660,15 @@ void Paragraph::setChange(pos_type pos, Change const & change) Change const & Paragraph::lookupChange(pos_type pos) const { - LASSERT(pos >= 0 && pos <= size(), /**/); + LBUFERR(pos >= 0 && pos <= size()); return d->changes_.lookup(pos); } void Paragraph::acceptChanges(pos_type start, pos_type end) { - LASSERT(start >= 0 && start <= size(), /**/); - LASSERT(end > start && end <= size() + 1, /**/); + LASSERT(start >= 0 && start <= size(), return); + LASSERT(end > start && end <= size() + 1, return); for (pos_type pos = start; pos < end; ++pos) { switch (lookupChange(pos).type) { @@ -702,8 +702,8 @@ void Paragraph::acceptChanges(pos_type start, pos_type end) void Paragraph::rejectChanges(pos_type start, pos_type end) { - LASSERT(start >= 0 && start <= size(), /**/); - LASSERT(end > start && end <= size() + 1, /**/); + LASSERT(start >= 0 && start <= size(), return); + LASSERT(end > start && end <= size() + 1, return); for (pos_type pos = start; pos < end; ++pos) { switch (lookupChange(pos).type) { @@ -738,7 +738,7 @@ void Paragraph::rejectChanges(pos_type start, pos_type end) void Paragraph::Private::insertChar(pos_type pos, char_type c, Change const & change) { - LASSERT(pos >= 0 && pos <= int(text_.size()), /**/); + LASSERT(pos >= 0 && pos <= int(text_.size()), return); // track change changes_.insert(change, pos); @@ -767,10 +767,10 @@ void Paragraph::Private::insertChar(pos_type pos, char_type c, bool Paragraph::insertInset(pos_type pos, Inset * inset, - Change const & change) + Font const & font, Change const & change) { - LASSERT(inset, /**/); - LASSERT(pos >= 0 && pos <= size(), /**/); + LASSERT(inset, return false); + LASSERT(pos >= 0 && pos <= size(), return false); // Paragraph::insertInset() can be used in cut/copy/paste operation where // d->inset_owner_ is not set yet. @@ -778,13 +778,14 @@ bool Paragraph::insertInset(pos_type pos, Inset * inset, return false; d->insertChar(pos, META_INSET, change); - LASSERT(d->text_[pos] == META_INSET, /**/); + LASSERT(d->text_[pos] == META_INSET, return false); // Add a new entry in the insetlist_. d->insetlist_.insert(inset, pos); // Some insets require run of spell checker requestSpellCheck(pos); + setFont(pos, font); return true; } @@ -846,8 +847,8 @@ bool Paragraph::eraseChar(pos_type pos, bool trackChanges) int Paragraph::eraseChars(pos_type start, pos_type end, bool trackChanges) { - LASSERT(start >= 0 && start <= size(), /**/); - LASSERT(end >= start && end <= size() + 1, /**/); + LASSERT(start >= 0 && start <= size(), return 0); + LASSERT(end >= start && end <= size() + 1, return 0); pos_type i = start; for (pos_type count = end - start; count; --count) { @@ -1043,10 +1044,12 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, unsigned int & column) { Inset * inset = owner_->getInset(i); - LASSERT(inset, /**/); + LBUFERR(inset); if (style.pass_thru) { - inset->plaintext(os.os(), runparams); + odocstringstream ods; + inset->plaintext(ods, runparams); + os << ods.str(); return; } @@ -1780,16 +1783,6 @@ void Paragraph::insertChar(pos_type pos, char_type c, } -bool Paragraph::insertInset(pos_type pos, Inset * inset, - Font const & font, Change const & change) -{ - bool const success = insertInset(pos, inset, change); - // Set the font/language of the inset... - setFont(pos, font); - return success; -} - - void Paragraph::resetFonts(Font const & font) { d->fontlist_.clear(); @@ -1803,7 +1796,7 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams, { if (pos > size()) { LYXERR0("pos: " << pos << " size: " << size()); - LASSERT(pos <= size(), /**/); + LBUFERR(false); } FontList::const_iterator cit = d->fontlist_.fontIterator(pos); @@ -1828,9 +1821,9 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams, FontSpan Paragraph::fontSpan(pos_type pos) const { - LASSERT(pos <= size(), /**/); - pos_type start = 0; + LBUFERR(pos < size()); + pos_type start = 0; FontList::const_iterator cit = d->fontlist_.begin(); FontList::const_iterator end = d->fontlist_.end(); for (; cit != end; ++cit) { @@ -1847,8 +1840,8 @@ FontSpan Paragraph::fontSpan(pos_type pos) const } // This should not happen, but if so, we take no chances. - // LYXERR0("Paragraph::getEndPosOfFontSpan: This should not happen!"); - return FontSpan(pos, pos); + LYXERR0("Paragraph::fontSpan: position not found in fontinfo table!"); + LASSERT(false, return FontSpan(pos, pos)); } @@ -1879,7 +1872,7 @@ Font const & Paragraph::getFirstFontSettings(BufferParams const & bparams) const Font const Paragraph::getFont(BufferParams const & bparams, pos_type pos, Font const & outerfont) const { - LASSERT(pos >= 0, /**/); + LBUFERR(pos >= 0); Font font = getFontSettings(bparams, pos); @@ -1972,7 +1965,7 @@ char_type Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const void Paragraph::setFont(pos_type pos, Font const & font) { - LASSERT(pos <= size(), /**/); + LASSERT(pos <= size(), return); // First, reduce font against layout/label font // Update: The setCharFont() routine in text2.cpp already @@ -2829,6 +2822,22 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf, } +namespace { +void doFontSwitch(vector & tagsToOpen, + vector & tagsToClose, + bool & flag, FontState curstate, html::FontTypes type) +{ + if (curstate == FONT_ON) { + tagsToOpen.push_back(html::FontTag(type)); + flag = true; + } else if (flag) { + tagsToClose.push_back(html::EndFontTag(type)); + flag = false; + } +} +} + + docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, XHTMLStream & xs, OutputParams const & runparams, @@ -2837,63 +2846,315 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, { docstring retval; + // track whether we have opened these tags bool emph_flag = false; bool bold_flag = false; + bool noun_flag = false; + bool ubar_flag = false; + bool dbar_flag = false; + bool sout_flag = false; + bool wave_flag = false; + // shape tags + bool shap_flag = false; + // family tags + bool faml_flag = false; + // size tags + bool size_flag = false; Layout const & style = *d->layout_; xs.startParagraph(allowEmpty()); - if (!runparams.for_toc && runparams.html_make_pars) { - // generate a magic label for this paragraph - string const attr = "id='" + magicLabel() + "'"; - xs << html::CompTag("a", attr); - } - FontInfo font_old = style.labeltype == LABEL_MANUAL ? style.labelfont : style.font; + FontShape curr_fs = INHERIT_SHAPE; + FontFamily curr_fam = INHERIT_FAMILY; + FontSize curr_size = FONT_SIZE_INHERIT; + + string const default_family = + buf.masterBuffer()->params().fonts_default_family; + + vector tagsToOpen; + vector tagsToClose; + // parsing main loop for (pos_type i = initial; i < size(); ++i) { // let's not show deleted material in the output if (isDeleted(i)) continue; - Font font = getFont(buf.params(), i, outerfont); + Font const font = getFont(buf.masterBuffer()->params(), i, outerfont); // emphasis - if (font_old.emph() != font.fontInfo().emph()) { - if (font.fontInfo().emph() == FONT_ON) { - xs << html::StartTag("em"); - emph_flag = true; - } else if (emph_flag && i != initial) { - xs << html::EndTag("em"); - emph_flag = false; + FontState curstate = font.fontInfo().emph(); + if (font_old.emph() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, emph_flag, curstate, html::FT_EMPH); + + // noun + curstate = font.fontInfo().noun(); + if (font_old.noun() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, noun_flag, curstate, html::FT_NOUN); + + // underbar + curstate = font.fontInfo().underbar(); + if (font_old.underbar() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, ubar_flag, curstate, html::FT_UBAR); + + // strikeout + curstate = font.fontInfo().strikeout(); + if (font_old.strikeout() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, sout_flag, curstate, html::FT_SOUT); + + // double underbar + curstate = font.fontInfo().uuline(); + if (font_old.uuline() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, dbar_flag, curstate, html::FT_DBAR); + + // wavy line + curstate = font.fontInfo().uwave(); + if (font_old.uwave() != curstate) + doFontSwitch(tagsToOpen, tagsToClose, wave_flag, curstate, html::FT_WAVE); + + // bold + // a little hackish, but allows us to reuse what we have. + curstate = (font.fontInfo().series() == BOLD_SERIES ? FONT_ON : FONT_OFF); + if (font_old.series() != font.fontInfo().series()) + doFontSwitch(tagsToOpen, tagsToClose, bold_flag, curstate, html::FT_BOLD); + + // Font shape + curr_fs = font.fontInfo().shape(); + FontShape old_fs = font_old.shape(); + if (old_fs != curr_fs) { + if (shap_flag) { + switch (old_fs) { + case ITALIC_SHAPE: + tagsToClose.push_back(html::EndFontTag(html::FT_ITALIC)); + break; + case SLANTED_SHAPE: + tagsToClose.push_back(html::EndFontTag(html::FT_SLANTED)); + break; + case SMALLCAPS_SHAPE: + tagsToClose.push_back(html::EndFontTag(html::FT_SMALLCAPS)); + break; + case UP_SHAPE: + case INHERIT_SHAPE: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; + } + shap_flag = false; + } + switch (curr_fs) { + case ITALIC_SHAPE: + tagsToOpen.push_back(html::FontTag(html::FT_ITALIC)); + shap_flag = true; + break; + case SLANTED_SHAPE: + tagsToOpen.push_back(html::FontTag(html::FT_SLANTED)); + shap_flag = true; + break; + case SMALLCAPS_SHAPE: + tagsToOpen.push_back(html::FontTag(html::FT_SMALLCAPS)); + shap_flag = true; + break; + case UP_SHAPE: + case INHERIT_SHAPE: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; } } - // bold - if (font_old.series() != font.fontInfo().series()) { - if (font.fontInfo().series() == BOLD_SERIES) { - xs << html::StartTag("strong"); - bold_flag = true; - } else if (bold_flag && i != initial) { - xs << html::EndTag("strong"); - bold_flag = false; + + // Font family + curr_fam = font.fontInfo().family(); + FontFamily old_fam = font_old.family(); + if (old_fam != curr_fam) { + if (faml_flag) { + switch (old_fam) { + case ROMAN_FAMILY: + tagsToClose.push_back(html::EndFontTag(html::FT_ROMAN)); + break; + case SANS_FAMILY: + tagsToClose.push_back(html::EndFontTag(html::FT_SANS)); + break; + case TYPEWRITER_FAMILY: + tagsToClose.push_back(html::EndFontTag(html::FT_TYPE)); + break; + case INHERIT_FAMILY: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; + } + faml_flag = false; + } + switch (curr_fam) { + case ROMAN_FAMILY: + // we will treat a "default" font family as roman, since we have + // no other idea what to do. + if (default_family != "rmdefault" && default_family != "default") { + tagsToOpen.push_back(html::FontTag(html::FT_ROMAN)); + faml_flag = true; + } + break; + case SANS_FAMILY: + if (default_family != "sfdefault") { + tagsToOpen.push_back(html::FontTag(html::FT_SANS)); + faml_flag = true; + } + break; + case TYPEWRITER_FAMILY: + if (default_family != "ttdefault") { + tagsToOpen.push_back(html::FontTag(html::FT_TYPE)); + faml_flag = true; + } + break; + case INHERIT_FAMILY: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; + } + } + + // Font size + curr_size = font.fontInfo().size(); + FontSize old_size = font_old.size(); + if (old_size != curr_size) { + if (size_flag) { + switch (old_size) { + case FONT_SIZE_TINY: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_TINY)); + break; + case FONT_SIZE_SCRIPT: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_SCRIPT)); + break; + case FONT_SIZE_FOOTNOTE: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_FOOTNOTE)); + break; + case FONT_SIZE_SMALL: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_SMALL)); + break; + case FONT_SIZE_LARGE: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGE)); + break; + case FONT_SIZE_LARGER: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGER)); + break; + case FONT_SIZE_LARGEST: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGEST)); + break; + case FONT_SIZE_HUGE: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_HUGE)); + break; + case FONT_SIZE_HUGER: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_HUGER)); + break; + case FONT_SIZE_INCREASE: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_INCREASE)); + break; + case FONT_SIZE_DECREASE: + tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_DECREASE)); + break; + case FONT_SIZE_INHERIT: + case FONT_SIZE_NORMAL: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; + } + size_flag = false; + } + switch (curr_size) { + case FONT_SIZE_TINY: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_TINY)); + size_flag = true; + break; + case FONT_SIZE_SCRIPT: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_SCRIPT)); + size_flag = true; + break; + case FONT_SIZE_FOOTNOTE: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_FOOTNOTE)); + size_flag = true; + break; + case FONT_SIZE_SMALL: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_SMALL)); + size_flag = true; + break; + case FONT_SIZE_LARGE: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGE)); + size_flag = true; + break; + case FONT_SIZE_LARGER: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGER)); + size_flag = true; + break; + case FONT_SIZE_LARGEST: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGEST)); + size_flag = true; + break; + case FONT_SIZE_HUGE: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_HUGE)); + size_flag = true; + break; + case FONT_SIZE_HUGER: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_HUGER)); + size_flag = true; + break; + case FONT_SIZE_INCREASE: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_INCREASE)); + size_flag = true; + break; + case FONT_SIZE_DECREASE: + tagsToOpen.push_back(html::FontTag(html::FT_SIZE_DECREASE)); + size_flag = true; + break; + case FONT_SIZE_NORMAL: + case FONT_SIZE_INHERIT: + break; + default: + // the other tags are for internal use + LATTEST(false); + break; } } + // FIXME XHTML // Other such tags? What about the other text ranges? + vector::const_iterator cit = tagsToClose.begin(); + vector::const_iterator cen = tagsToClose.end(); + for (; cit != cen; ++cit) + xs << *cit; + + vector::const_iterator sit = tagsToOpen.begin(); + vector::const_iterator sen = tagsToOpen.end(); + for (; sit != sen; ++sit) + xs << *sit; + + tagsToClose.clear(); + tagsToOpen.clear(); + Inset const * inset = getInset(i); if (inset) { if (!runparams.for_toc || inset->isInToc()) { OutputParams np = runparams; + np.local_font = &font; if (!inset->getLayout().htmlisblock()) np.html_in_par = true; retval += inset->xhtml(xs, np); } } else { - char_type c = getUChar(buf.params(), i); + char_type c = getUChar(buf.masterBuffer()->params(), i); if (style.pass_thru || runparams.pass_thru) xs << c; @@ -3130,7 +3391,8 @@ void Paragraph::forToc(docstring & os, size_t maxlen) const } -docstring Paragraph::stringify(pos_type beg, pos_type end, int options, OutputParams & runparams) const +docstring Paragraph::stringify(pos_type beg, pos_type end, int options, + OutputParams const & runparams) const { odocstringstream os; @@ -3139,13 +3401,16 @@ docstring Paragraph::stringify(pos_type beg, pos_type end, int options, OutputPa && !d->params_.labelString().empty()) os << d->params_.labelString() << ' '; + OutputParams op = runparams; + op.for_search = true; + for (pos_type i = beg; i < end; ++i) { char_type const c = d->text_[i]; if (isPrintable(c) || c == '\t' || (c == '\n' && (options & AS_STR_NEWLINES))) os.put(c); else if (c == META_INSET && (options & AS_STR_INSETS)) { - getInset(i)->plaintext(os, runparams); + getInset(i)->plaintext(os, op); } } @@ -3206,8 +3471,7 @@ void Paragraph::setPlainOrDefaultLayout(DocumentClass const & tclass) Inset const & Paragraph::inInset() const { - LASSERT(d->inset_owner_, throw ExceptionMessage(BufferException, - _("Memory problem"), _("Paragraph not properly initialized"))); + LBUFERR(d->inset_owner_); return *d->inset_owner_; } @@ -3333,7 +3597,8 @@ int Paragraph::fixBiblio(Buffer const & buffer) inset = new InsetBibitem(const_cast(&buffer), InsetCommandParams(BIBITEM_CODE)); - insertInset(0, inset, Change(track_changes ? Change::INSERTED + Font font(inherit_font, buffer.params().language); + insertInset(0, inset, font, Change(track_changes ? Change::INSERTED : Change::UNCHANGED)); return 1;