X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=72a26006322c93c1066e9b1dacc5462de6c87927;hb=3d4076b598deb18660e50ec9c327efc3b15f15d0;hp=a4eb93f9d5e5c83cc64ca7db0f7c0a1c54e0cf48;hpb=07ca50d90590c13446eb76927d136db63c70711b;p=lyx.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index a4eb93f9d5..72a2600632 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -660,8 +660,7 @@ void Paragraph::setChange(pos_type pos, Change const & change) Change const & Paragraph::lookupChange(pos_type pos) const { - LBUFERR(pos >= 0 && pos <= size(), - _("Invalid position given to lookupChange()")); + LBUFERR(pos >= 0 && pos <= size()); return d->changes_.lookup(pos); } @@ -768,7 +767,7 @@ 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, return false); LASSERT(pos >= 0 && pos <= size(), return false); @@ -786,6 +785,8 @@ bool Paragraph::insertInset(pos_type pos, Inset * inset, // Some insets require run of spell checker requestSpellCheck(pos); + + setFont(pos, font); return true; } @@ -1044,7 +1045,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, unsigned int & column) { Inset * inset = owner_->getInset(i); - LBUFERR(inset, ""); + LBUFERR(inset); if (style.pass_thru) { odocstringstream ods; @@ -1784,12 +1785,10 @@ void Paragraph::insertChar(pos_type pos, char_type c, bool Paragraph::insertInset(pos_type pos, Inset * inset, - Font const & font, Change const & change) + Change const & change) { - bool const success = insertInset(pos, inset, change); - // Set the font/language of the inset... - setFont(pos, font); - return success; + Font no_font; + return insertInset(pos, inset, no_font, change); } @@ -1806,7 +1805,7 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams, { if (pos > size()) { LYXERR0("pos: " << pos << " size: " << size()); - LBUFERR(false, _("Invalid position.")); + LBUFERR(false); } FontList::const_iterator cit = d->fontlist_.fontIterator(pos); @@ -1831,13 +1830,7 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams, FontSpan Paragraph::fontSpan(pos_type pos) const { - LBUFERR(pos <= size(), _("Invalid position")); - - // Last position is a special case. I suspect that it would - // actually make sense to extend the last font span to cover - // the last character (JMarc) - if (pos == size()) - return FontSpan(pos, pos); + LBUFERR(pos < size()); pos_type start = 0; FontList::const_iterator cit = d->fontlist_.begin(); @@ -1888,7 +1881,7 @@ Font const & Paragraph::getFirstFontSettings(BufferParams const & bparams) const Font const Paragraph::getFont(BufferParams const & bparams, pos_type pos, Font const & outerfont) const { - LBUFERR(pos >= 0, _("Invalid position.")); + LBUFERR(pos >= 0); Font font = getFontSettings(bparams, pos); @@ -2838,17 +2831,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, @@ -2859,6 +2855,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; @@ -2866,76 +2863,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()) { @@ -3263,7 +3480,7 @@ void Paragraph::setPlainOrDefaultLayout(DocumentClass const & tclass) Inset const & Paragraph::inInset() const { - LBUFERR(d->inset_owner_, _("Paragraph not properly initialized")); + LBUFERR(d->inset_owner_); return *d->inset_owner_; }