]> git.lyx.org Git - features.git/blobdiff - src/Paragraph.cpp
Rename XHTMLStream to XMLStream, move it to another file, and prepare for DocBook...
[features.git] / src / Paragraph.cpp
index 389b43699e6365812c44abae2ec30d92ac3fe8ef..10b6456adfd1e21449bc59cbec8923c10497c380 100644 (file)
 #include "OutputParams.h"
 #include "output_latex.h"
 #include "output_xhtml.h"
+#include "output_docbook.h"
 #include "ParagraphParameters.h"
 #include "SpellChecker.h"
-#include "sgml.h"
+#include "xml.h"
 #include "texstream.h"
 #include "TextClass.h"
 #include "TexRow.h"
@@ -516,7 +517,7 @@ public:
 
 
 Paragraph::Private::Private(Paragraph * owner, Layout const & layout)
-       : owner_(owner), inset_owner_(0), id_(-1), begin_of_body_(0), layout_(&layout)
+       : owner_(owner), inset_owner_(nullptr), id_(-1), begin_of_body_(0), layout_(&layout)
 {
        text_.reserve(100);
 }
@@ -581,18 +582,6 @@ void Paragraph::addChangesToToc(DocIterator const & cdit, Buffer const & buf,
 }
 
 
-void Paragraph::addChangesToBuffer(Buffer const & buf) const
-{
-       d->changes_.updateBuffer(buf);
-}
-
-
-bool Paragraph::isChangeUpdateRequired() const
-{
-       return d->changes_.isUpdateRequired();
-}
-
-
 bool Paragraph::isDeleted(pos_type start, pos_type end) const
 {
        LASSERT(start >= 0 && start <= size(), return false);
@@ -610,6 +599,28 @@ bool Paragraph::isChanged(pos_type start, pos_type end) const
        return d->changes_.isChanged(start, end);
 }
 
+// FIXME: Ideally the diverse isChanged() methods should account for that!
+bool Paragraph::hasChangedInsets(pos_type start, pos_type end) const
+{
+       LASSERT(start >= 0 && start <= size(), return false);
+       LASSERT(end > start && end <= size() + 1, return false);
+
+       for (auto const & icit : d->insetlist_) {
+               if (icit.pos < start)
+                       continue;
+               if (icit.pos >= end)
+                       break;
+               if (icit.inset && icit.inset->isChanged())
+                       return true;
+       }
+       return false;
+}
+
+bool Paragraph::isChanged() const
+{
+       return d->changes_.isChanged();
+}
+
 
 bool Paragraph::isMergedOnEndOfParDeletion(bool trackChanges) const
 {
@@ -660,8 +671,8 @@ void Paragraph::setChange(pos_type pos, Change const & change)
 
        // see comment in setChange(Change const &) above
        if (!change.deleted() && pos < size())
-                       if (Inset * inset = getInset(pos))
-                               inset->setChange(change);
+               if (Inset * inset = getInset(pos))
+                       inset->setChange(change);
 }
 
 
@@ -1754,7 +1765,7 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams,
        // Optimisation: avoid a full font instantiation if there is no
        // language change from previous call.
        static Font previous_font;
-       static Language const * previous_lang = 0;
+       static Language const * previous_lang = nullptr;
        Language const * lang = getParLanguage(bparams);
        if (lang != previous_lang) {
                previous_lang = lang;
@@ -1802,7 +1813,7 @@ Font const & Paragraph::getFirstFontSettings(BufferParams const & bparams) const
        // Optimisation: avoid a full font instantiation if there is no
        // language change from previous call.
        static Font previous_font;
-       static Language const * previous_lang = 0;
+       static Language const * previous_lang = nullptr;
        if (bparams.language != previous_lang) {
                previous_lang = bparams.language;
                previous_font = Font(inherit_font, bparams.language);
@@ -2112,15 +2123,17 @@ void Paragraph::setBeginOfBody()
        // remove unnecessary getChar() calls
        pos_type i = 0;
        pos_type end = size();
-       if (i < end && !(isNewline(i) || isEnvSeparator(i))) {
+       bool prev_char_deleted = false;
+       if (i < end && (!(isNewline(i) || isEnvSeparator(i)) || isDeleted(i))) {
                ++i;
                if (i < end) {
                        char_type previous_char = d->text_[i];
                        if (!(isNewline(i) || isEnvSeparator(i))) {
                                ++i;
-                               while (i < end && previous_char != ' ') {
+                               while (i < end && (previous_char != ' ' || prev_char_deleted)) {
                                        char_type temp = d->text_[i];
-                                       if (isNewline(i) || isEnvSeparator(i))
+                                       prev_char_deleted = isDeleted(i);
+                                       if (!isDeleted(i) && (isNewline(i) || isEnvSeparator(i)))
                                                break;
                                        ++i;
                                        previous_char = temp;
@@ -2551,6 +2564,10 @@ void Paragraph::latex(BufferParams const & bparams,
                Font const current_font = getFont(bparams, i, outerfont);
 
                Font const last_font = running_font;
+               bool const in_ct_deletion = (bparams.output_changes
+                                            && runningChange == change
+                                            && change.type == Change::DELETED
+                                            && !os.afterParbreak());
 
                // Do we need to close the previous font?
                if (open_font &&
@@ -2564,10 +2581,23 @@ void Paragraph::latex(BufferParams const & bparams,
                                alien_script.clear();
                        }
                        bool needPar = false;
+                       if (in_ct_deletion) {
+                               // We have to close and then reopen \lyxdeleted,
+                               // as strikeout needs to be on lowest level.
+                               os << '}';
+                               column += 1;
+                       }
                        column += running_font.latexWriteEndChanges(
                                    os, bparams, runparams, basefont,
                                    (i == body_pos-1) ? basefont : current_font,
                                    needPar);
+                       if (in_ct_deletion) {
+                               // We have to close and then reopen \lyxdeleted,
+                               // as strikeout needs to be on lowest level.
+                               OutputParams rp = runparams;
+                               column += Changes::latexMarkChange(os, bparams,
+                                       Change(Change::UNCHANGED), Change(Change::DELETED), rp);
+                       }
                        running_font = basefont;
                        open_font = false;
                }
@@ -2613,13 +2643,9 @@ void Paragraph::latex(BufferParams const & bparams,
 
                // Do we need to change font?
                if ((current_font != running_font ||
-                    current_font.language() != running_font.language()) &&
-                       i != body_pos - 1)
+                    current_font.language() != running_font.language())
+                   && i != body_pos - 1)
                {
-                       bool const in_ct_deletion = (bparams.output_changes
-                                                    && runningChange == change
-                                                    && change.type == Change::DELETED
-                                                    && !os.afterParbreak());
                        if (in_ct_deletion) {
                                // We have to close and then reopen \lyxdeleted,
                                // as strikeout needs to be on lowest level.
@@ -2707,7 +2733,7 @@ void Paragraph::latex(BufferParams const & bparams,
                                Inset const * inset = getInset(i);
                                InsetText const * textinset = inset
                                                        ? inset->asInsetText()
-                                                       : 0;
+                                                       : nullptr;
                                if (i + 1 == size() && textinset
                                    && !inset->getLayout().isDisplay()) {
                                        ParagraphList const & pars =
@@ -2732,6 +2758,16 @@ void Paragraph::latex(BufferParams const & bparams,
                                                runningChange, style, i, column);
                                if (incremented)
                                        --parInline;
+
+                               if (runparams.ctObject == OutputParams::CT_DISPLAYOBJECT
+                                   || runparams.ctObject == OutputParams::CT_UDISPLAYOBJECT) {
+                                       // Close \lyx*deleted and force its
+                                       // reopening (if needed)
+                                       os << '}';
+                                       column++;
+                                       runningChange = Change(Change::UNCHANGED);
+                                       runparams.ctObject = OutputParams::CT_NORMAL;
+                               }
                        }
                } else if (i >= start_pos && (end_pos == -1 || i < end_pos)) {
                        if (!bparams.useNonTeXFonts)
@@ -2895,7 +2931,7 @@ bool Paragraph::emptyTag() const
 }
 
 
-string Paragraph::getID(Buffer const & buf, OutputParams const & runparams)
+string Paragraph::getID(Buffer const &, OutputParams const &)
        const
 {
        for (pos_type i = 0; i < size(); ++i) {
@@ -2904,7 +2940,7 @@ string Paragraph::getID(Buffer const & buf, OutputParams const & runparams)
                        if (lyx_code == LABEL_CODE) {
                                InsetLabel const * const il = static_cast<InsetLabel const *>(inset);
                                docstring const & id = il->getParam("name");
-                               return "id='" + to_utf8(sgml::cleanID(buf, runparams, id)) + "'";
+                               return "id='" + to_utf8(xml::cleanID(id)) + "'";
                        }
                }
        }
@@ -2923,14 +2959,14 @@ pos_type Paragraph::firstWordDocBook(odocstream & os, OutputParams const & runpa
                        char_type c = d->text_[i];
                        if (c == ' ')
                                break;
-                       os << sgml::escapeChar(c);
+                       os << xml::escapeChar(c, XMLStream::ESCAPE_ALL);
                }
        }
        return i;
 }
 
 
-pos_type Paragraph::firstWordLyXHTML(XHTMLStream & xs, OutputParams const & runparams)
+pos_type Paragraph::firstWordLyXHTML(XMLStream & xs, OutputParams const & runparams)
        const
 {
        pos_type i;
@@ -3003,7 +3039,7 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                        if (style.pass_thru)
                                os.put(c);
                        else
-                               os << sgml::escapeChar(c);
+                               os << xml::escapeChar(c, XMLStream::EscapeSettings::ESCAPE_ALL);
                }
                font_old = font.fontInfo();
        }
@@ -3020,27 +3056,29 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
 
 
 namespace {
-void doFontSwitch(vector<html::FontTag> & tagsToOpen,
-                  vector<html::EndFontTag> & tagsToClose,
-                  bool & flag, FontState curstate, html::FontTypes type)
+
+void doFontSwitchXHTML(vector<xml::FontTag> & tagsToOpen,
+                  vector<xml::EndFontTag> & tagsToClose,
+                  bool & flag, FontState curstate, xml::FontTypes type)
 {
        if (curstate == FONT_ON) {
-               tagsToOpen.push_back(html::FontTag(type));
+               tagsToOpen.push_back(xhtmlStartFontTag(type));
                flag = true;
        } else if (flag) {
-               tagsToClose.push_back(html::EndFontTag(type));
+               tagsToClose.push_back(xhtmlEndFontTag(type));
                flag = false;
        }
 }
-} // namespace
+
+} // anonymous namespace
 
 
 docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
-                                   XHTMLStream & xs,
-                                   OutputParams const & runparams,
-                                   Font const & outerfont,
-                                   bool start_paragraph, bool close_paragraph,
-                                   pos_type initial) const
+                                                                                XMLStream & xs,
+                                                                                OutputParams const & runparams,
+                                                                                Font const & outerfont,
+                                                                                bool start_paragraph, bool close_paragraph,
+                                                                                pos_type initial) const
 {
        docstring retval;
 
@@ -3075,8 +3113,8 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
        string const default_family =
                buf.masterBuffer()->params().fonts_default_family;
 
-       vector<html::FontTag> tagsToOpen;
-       vector<html::EndFontTag> tagsToClose;
+       vector<xml::FontTag> tagsToOpen;
+       vector<xml::EndFontTag> tagsToClose;
 
        // parsing main loop
        for (pos_type i = initial; i < size(); ++i) {
@@ -3089,260 +3127,260 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
                // emphasis
                FontState curstate = font.fontInfo().emph();
                if (font_old.emph() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, emph_flag, curstate, html::FT_EMPH);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, emph_flag, curstate, xml::FT_EMPH);
 
                // noun
                curstate = font.fontInfo().noun();
                if (font_old.noun() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, noun_flag, curstate, html::FT_NOUN);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, noun_flag, curstate, xml::FT_NOUN);
 
                // underbar
                curstate = font.fontInfo().underbar();
                if (font_old.underbar() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, ubar_flag, curstate, html::FT_UBAR);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, ubar_flag, curstate, xml::FT_UBAR);
 
                // strikeout
                curstate = font.fontInfo().strikeout();
                if (font_old.strikeout() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, sout_flag, curstate, html::FT_SOUT);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, sout_flag, curstate, xml::FT_SOUT);
 
                // xout
                curstate = font.fontInfo().xout();
                if (font_old.xout() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, xout_flag, curstate, html::FT_XOUT);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, xout_flag, curstate, xml::FT_XOUT);
 
                // double underbar
                curstate = font.fontInfo().uuline();
                if (font_old.uuline() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, dbar_flag, curstate, html::FT_DBAR);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, dbar_flag, curstate, xml::FT_DBAR);
 
                // wavy line
                curstate = font.fontInfo().uwave();
                if (font_old.uwave() != curstate)
-                       doFontSwitch(tagsToOpen, tagsToClose, wave_flag, curstate, html::FT_WAVE);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, wave_flag, curstate, xml::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);
+                       doFontSwitchXHTML(tagsToOpen, tagsToClose, bold_flag, curstate, xml::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;
-                       }
+            if (shap_flag) {
+                switch (old_fs) {
+                case ITALIC_SHAPE:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_ITALIC), xml::FT_ITALIC));
+                    break;
+                case SLANTED_SHAPE:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_SLANTED), xml::FT_SLANTED));
+                    break;
+                case SMALLCAPS_SHAPE:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_SMALLCAPS), xml::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(xml::FontTag(fontToHtmlTag(xml::FT_ITALIC), xml::FT_ITALIC));
+                shap_flag = true;
+                break;
+            case SLANTED_SHAPE:
+                tagsToOpen.push_back(xml::FontTag(fontToHtmlTag(xml::FT_SLANTED), xml::FT_SLANTED));
+                shap_flag = true;
+                break;
+            case SMALLCAPS_SHAPE:
+                tagsToOpen.push_back(xml::FontTag(fontToHtmlTag(xml::FT_SMALLCAPS), xml::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;
-                       }
+            if (faml_flag) {
+                switch (old_fam) {
+                case ROMAN_FAMILY:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_ROMAN), xml::FT_ROMAN));
+                    break;
+                case SANS_FAMILY:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_SANS), xml::FT_SANS));
+                    break;
+                case TYPEWRITER_FAMILY:
+                    tagsToClose.push_back(xml::EndFontTag(fontToHtmlTag(xml::FT_TYPE), xml::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(xml::FontTag(fontToHtmlTag(xml::FT_ROMAN), xml::FT_ROMAN));
+                    faml_flag = true;
+                }
+                break;
+            case SANS_FAMILY:
+                if (default_family != "sfdefault") {
+                    tagsToOpen.push_back(xml::FontTag(fontToHtmlTag(xml::FT_SANS), xml::FT_SANS));
+                    faml_flag = true;
+                }
+                break;
+            case TYPEWRITER_FAMILY:
+                if (default_family != "ttdefault") {
+                    tagsToOpen.push_back(xml::FontTag(fontToHtmlTag(xml::FT_TYPE), xml::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 TINY_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_TINY));
-                                       break;
-                               case SCRIPT_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_SCRIPT));
-                                       break;
-                               case FOOTNOTE_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_FOOTNOTE));
-                                       break;
-                               case SMALL_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_SMALL));
-                                       break;
-                               case LARGE_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGE));
-                                       break;
-                               case LARGER_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGER));
-                                       break;
-                               case LARGEST_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_LARGEST));
-                                       break;
-                               case HUGE_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_HUGE));
-                                       break;
-                               case HUGER_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_HUGER));
-                                       break;
-                               case INCREASE_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_INCREASE));
-                                       break;
-                               case DECREASE_SIZE:
-                                       tagsToClose.push_back(html::EndFontTag(html::FT_SIZE_DECREASE));
-                                       break;
-                               case INHERIT_SIZE:
-                               case NORMAL_SIZE:
-                                       break;
-                               default:
-                                       // the other tags are for internal use
-                                       LATTEST(false);
-                                       break;
-                               }
-                               size_flag = false;
-                       }
-                       switch (curr_size) {
-                       case TINY_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_TINY));
-                               size_flag = true;
-                               break;
-                       case SCRIPT_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_SCRIPT));
-                               size_flag = true;
-                               break;
-                       case FOOTNOTE_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_FOOTNOTE));
-                               size_flag = true;
-                               break;
-                       case SMALL_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_SMALL));
-                               size_flag = true;
-                               break;
-                       case LARGE_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGE));
-                               size_flag = true;
-                               break;
-                       case LARGER_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGER));
-                               size_flag = true;
-                               break;
-                       case LARGEST_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_LARGEST));
-                               size_flag = true;
-                               break;
-                       case HUGE_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_HUGE));
-                               size_flag = true;
-                               break;
-                       case HUGER_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_HUGER));
-                               size_flag = true;
-                               break;
-                       case INCREASE_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_INCREASE));
-                               size_flag = true;
-                               break;
-                       case DECREASE_SIZE:
-                               tagsToOpen.push_back(html::FontTag(html::FT_SIZE_DECREASE));
-                               size_flag = true;
-                               break;
-                       case NORMAL_SIZE:
-                       case INHERIT_SIZE:
-                               break;
-                       default:
-                               // the other tags are for internal use
-                               LATTEST(false);
-                               break;
-                       }
+            if (size_flag) {
+                switch (old_size) {
+                case TINY_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_TINY), xml::FT_SIZE_TINY);
+                    break;
+                case SCRIPT_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_SCRIPT), xml::FT_SIZE_SCRIPT);
+                    break;
+                case FOOTNOTE_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_FOOTNOTE), xml::FT_SIZE_FOOTNOTE);
+                    break;
+                case SMALL_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_SMALL), xml::FT_SIZE_SMALL);
+                    break;
+                case LARGE_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGE), xml::FT_SIZE_LARGE);
+                    break;
+                case LARGER_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGER), xml::FT_SIZE_LARGER);
+                    break;
+                case LARGEST_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGEST), xml::FT_SIZE_LARGEST);
+                    break;
+                case HUGE_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_HUGE), xml::FT_SIZE_HUGE);
+                    break;
+                case HUGER_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_HUGER), xml::FT_SIZE_HUGER);
+                    break;
+                case INCREASE_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_INCREASE), xml::FT_SIZE_INCREASE);
+                    break;
+                case DECREASE_SIZE:
+                    tagsToClose.emplace_back(fontToHtmlTag(xml::FT_SIZE_DECREASE), xml::FT_SIZE_DECREASE);
+                    break;
+                case INHERIT_SIZE:
+                case NORMAL_SIZE:
+                    break;
+                default:
+                    // the other tags are for internal use
+                    LATTEST(false);
+                    break;
+                }
+                size_flag = false;
+            }
+            switch (curr_size) {
+            case TINY_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_TINY), xml::FT_SIZE_TINY);
+                size_flag = true;
+                break;
+            case SCRIPT_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_SCRIPT), xml::FT_SIZE_SCRIPT);
+                size_flag = true;
+                break;
+            case FOOTNOTE_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_FOOTNOTE), xml::FT_SIZE_FOOTNOTE);
+                size_flag = true;
+                break;
+            case SMALL_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_SMALL), xml::FT_SIZE_SMALL);
+                size_flag = true;
+                break;
+            case LARGE_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGE), xml::FT_SIZE_LARGE);
+                size_flag = true;
+                break;
+            case LARGER_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGER), xml::FT_SIZE_LARGER);
+                size_flag = true;
+                break;
+            case LARGEST_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_LARGEST), xml::FT_SIZE_LARGEST);
+                size_flag = true;
+                break;
+            case HUGE_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_HUGE), xml::FT_SIZE_HUGE);
+                size_flag = true;
+                break;
+            case HUGER_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_HUGER), xml::FT_SIZE_HUGER);
+                size_flag = true;
+                break;
+            case INCREASE_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_INCREASE), xml::FT_SIZE_INCREASE);
+                size_flag = true;
+                break;
+            case DECREASE_SIZE:
+                tagsToOpen.emplace_back(fontToHtmlTag(xml::FT_SIZE_DECREASE), xml::FT_SIZE_DECREASE);
+                size_flag = true;
+                break;
+            case INHERIT_SIZE:
+            case NORMAL_SIZE:
+                break;
+            default:
+                // the other tags are for internal use
+                LATTEST(false);
+                break;
+            }
                }
 
                // FIXME XHTML
                // Other such tags? What about the other text ranges?
 
-               vector<html::EndFontTag>::const_iterator cit = tagsToClose.begin();
-               vector<html::EndFontTag>::const_iterator cen = tagsToClose.end();
+               vector<xml::EndFontTag>::const_iterator cit = tagsToClose.begin();
+               vector<xml::EndFontTag>::const_iterator cen = tagsToClose.end();
                for (; cit != cen; ++cit)
                        xs << *cit;
 
-               vector<html::FontTag>::const_iterator sit = tagsToOpen.begin();
-               vector<html::FontTag>::const_iterator sen = tagsToOpen.end();
+               vector<xml::FontTag>::const_iterator sit = tagsToOpen.begin();
+               vector<xml::FontTag>::const_iterator sen = tagsToOpen.end();
                for (; sit != sen; ++sit)
                        xs << *sit;
 
@@ -3364,7 +3402,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
                        char_type c = getUChar(buf.masterBuffer()->params(),
                                               runparams, i);
                        if (c == ' ' && (style.free_spacing || runparams.free_spacing))
-                               xs << XHTMLStream::ESCAPE_NONE << "&nbsp;";
+                               xs << XMLStream::ESCAPE_NONE << "&nbsp;";
                        else
                                xs << c;
                }
@@ -3616,7 +3654,7 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options, const Out
                        os.put(c);
                else if (c == META_INSET && (options & AS_STR_INSETS)) {
                        if (c == META_INSET && (options & AS_STR_PLAINTEXT)) {
-                               LASSERT(runparams != 0, return docstring());
+                               LASSERT(runparams != nullptr, return docstring());
                                getInset(i)->plaintext(os, *runparams);
                        } else {
                                getInset(i)->toString(os);
@@ -3863,14 +3901,14 @@ Inset * Paragraph::releaseInset(pos_type pos)
 Inset * Paragraph::getInset(pos_type pos)
 {
        return (pos < pos_type(d->text_.size()) && d->text_[pos] == META_INSET)
-                ? d->insetlist_.get(pos) : 0;
+                ? d->insetlist_.get(pos) : nullptr;
 }
 
 
 Inset const * Paragraph::getInset(pos_type pos) const
 {
        return (pos < pos_type(d->text_.size()) && d->text_[pos] == META_INSET)
-                ? d->insetlist_.get(pos) : 0;
+                ? d->insetlist_.get(pos) : nullptr;
 }
 
 
@@ -4137,7 +4175,7 @@ Language * Paragraph::Private::locateSpellRange(
                ++from;
        // don't check empty range
        if (from >= to)
-               return 0;
+               return nullptr;
        // get current language
        Language * lang = getSpellLanguage(from);
        pos_type last = from;