X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=7fd271c41d619eaf42c6c23d460b5d18e2ad7650;hb=4db3e641ed6765e005343010cb90ee8af26f8f99;hp=fffcfa54bbba61efb780e4bc69b01b448c2f4bd2;hpb=82b872365488d862a02d71f765e69c55f5260b5d;p=lyx.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index fffcfa54bb..7fd271c41d 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -593,8 +593,8 @@ void Paragraph::addChangesToToc(DocIterator const & cdit, 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,7 +1044,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, unsigned int & column) { Inset * inset = owner_->getInset(i); - LASSERT(inset, /**/); + LBUFERR(inset); if (style.pass_thru) { odocstringstream ods; @@ -1782,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(); @@ -1805,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); @@ -1830,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) { @@ -1849,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)); } @@ -1881,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); @@ -1974,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 @@ -2831,17 +2822,20 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf, } -void doFontSwitch(XHTMLStream & xs, bool startrange, - bool & flag, FontState curstate, std::string tag, std::string attr = "") +namespace { +void doFontSwitch(vector & tagsToOpen, + vector & tagsToClose, + bool & flag, FontState curstate, html::FontTypes type) { if (curstate == FONT_ON) { - xs << html::StartTag(tag, attr); + tagsToOpen.push_back(html::FontTag(type)); flag = true; - } else if (flag && !startrange) { - xs << html::EndTag(tag); + } else if (flag) { + tagsToClose.push_back(html::EndFontTag(type)); flag = false; } } +} docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, @@ -2852,6 +2846,7 @@ 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; @@ -2859,76 +2854,296 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, 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.masterBuffer()->params(), i, outerfont); - bool const at_start = (i == initial); + Font const font = getFont(buf.masterBuffer()->params(), i, outerfont); // emphasis FontState curstate = font.fontInfo().emph(); if (font_old.emph() != curstate) - doFontSwitch(xs, at_start, emph_flag, curstate, "em"); + doFontSwitch(tagsToOpen, tagsToClose, emph_flag, curstate, html::FT_EMPH); // noun curstate = font.fontInfo().noun(); if (font_old.noun() != curstate) - doFontSwitch(xs, at_start, noun_flag, curstate, "dfn", "class='lyxnoun'"); + doFontSwitch(tagsToOpen, tagsToClose, noun_flag, curstate, html::FT_NOUN); // underbar curstate = font.fontInfo().underbar(); if (font_old.underbar() != curstate) - doFontSwitch(xs, at_start, ubar_flag, curstate, "u"); + doFontSwitch(tagsToOpen, tagsToClose, ubar_flag, curstate, html::FT_UBAR); // strikeout curstate = font.fontInfo().strikeout(); if (font_old.strikeout() != curstate) - doFontSwitch(xs, at_start, sout_flag, curstate, "del", "class='strikeout'"); - - // HTML does not really have an equivalent of the next two, so we will just - // output a single underscore with a class, and people can style it if they - // wish to do so + doFontSwitch(tagsToOpen, tagsToClose, sout_flag, curstate, html::FT_SOUT); // double underbar curstate = font.fontInfo().uuline(); if (font_old.uuline() != curstate) - doFontSwitch(xs, at_start, dbar_flag, curstate, "u", "class='dline'"); + doFontSwitch(tagsToOpen, tagsToClose, dbar_flag, curstate, html::FT_DBAR); // wavy line curstate = font.fontInfo().uwave(); if (font_old.uwave() != curstate) - doFontSwitch(xs, at_start, wave_flag, curstate, "u", "class='wavyline'"); + doFontSwitch(tagsToOpen, tagsToClose, wave_flag, curstate, html::FT_WAVE); // bold - if (font_old.series() != font.fontInfo().series()) { - if (font.fontInfo().series() == BOLD_SERIES) { - xs << html::StartTag("b"); - bold_flag = true; - } else if (bold_flag && i != initial) { - xs << html::EndTag("b"); - bold_flag = false; + // 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; } } + + // 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()) { @@ -3256,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_; } @@ -3383,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;