X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=d69fa55bb539459b0760adc24d19724a6da75ec3;hb=2b02b73f4a59bb73f9e819a960ea98c86ef8716f;hp=8da67e35089566542c78f066989d945aa5727ddf;hpb=9a48c8d22b0dd2ae1d0a78af3c2c0f4e3a65c26d;p=lyx.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 8da67e3508..d69fa55bb5 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -66,6 +66,7 @@ #include "support/textutils.h" #include "output_docbook.h" +#include #include #include #include @@ -1087,7 +1088,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, runparams.local_font = &basefont; } - if (fontswitch_inset && !closeLanguage && fontswitch_inset) { + if (fontswitch_inset && !closeLanguage) { // The directionality has been switched at inset. // Force markup inside. runparams.local_font = &basefont; @@ -1103,7 +1104,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, // add location information and throw again. e.par_id = id_; e.pos = i; - throw(e); + throw; } if (close) @@ -2638,10 +2639,10 @@ void Paragraph::latex(BufferParams const & bparams, if (closeLanguage) // Force language closing current_font.setLanguage(basefont.language()); + Font const nextfont = (i == body_pos-1) ? basefont : current_font; column += running_font.latexWriteEndChanges( os, bparams, runparams, basefont, - (i == body_pos-1) ? basefont : current_font, - needPar); + nextfont, needPar); if (in_ct_deletion) { // We have to close and then reopen \lyxdeleted, // as strikeout needs to be on lowest level. @@ -2649,9 +2650,12 @@ void Paragraph::latex(BufferParams const & bparams, column += Changes::latexMarkChange(os, bparams, Change(Change::UNCHANGED), Change(Change::DELETED), rp); } - running_font = basefont; open_font = false; - langClosed = true; + // Has the language been closed in the latexWriteEndChanges() call above? + langClosed = running_font.language() != basefont.language() + && running_font.language() != nextfont.language() + && (running_font.language()->encoding()->package() != Encoding::CJK); + running_font = basefont; } // if necessary, close language environment before opening CJK @@ -2875,7 +2879,7 @@ void Paragraph::latex(BufferParams const & bparams, // add location information and throw again. e.par_id = id(); e.pos = i; - throw(e); + throw; } } } @@ -3355,6 +3359,10 @@ std::vector Paragraph::simpleDocBookOnePar(Buffer const & buf, auto * xs = new XMLStream(os); // XMLStream has no copy constructor: to create a new object, the only solution // is to hold a pointer to the XMLStream (xs = XMLStream(os) is not allowed once the first object is built). + // When a font tag ends with a space, output it after the closing font tag. This requires to store delayed + // characters at some point. + std::vector delayedChars; + // Parsing main loop. for (pos_type i = initial; i < size(); ++i) { // Don't show deleted material in the output. @@ -3366,10 +3374,17 @@ std::vector Paragraph::simpleDocBookOnePar(Buffer const & buf, if (getInset(i) != nullptr && getInset(i)->lyxCode() == NEWLINE_CODE) { if (!ignore_fonts) xs->closeFontTags(); + + // Output one paragraph (i.e. one string entry in generatedParagraphs). generatedParagraphs.push_back(os.str()); - os = odocstringstream(); + + // Create a new XMLStream for the new paragraph, completely independent from the previous one. This implies + // that the string stream must be reset. + os.str(from_ascii("")); delete xs; xs = new XMLStream(os); + + // Restore the fonts for the new paragraph, so that the right tags are opened for the new entry. if (!ignore_fonts) { font_old = outerfont.fontInfo(); fs = old_fs; @@ -3389,6 +3404,13 @@ std::vector Paragraph::simpleDocBookOnePar(Buffer const & buf, for (; cit != cen; ++cit) *xs << *cit; + // Deal with the delayed characters *after* closing font tags. + if (!delayedChars.empty()) { + for (char_type c: delayedChars) + *xs << c; + delayedChars.clear(); + } + vector::const_iterator sit = tagsToOpen.begin(); vector::const_iterator sen = tagsToOpen.end(); for (; sit != sen; ++sit) @@ -3409,7 +3431,10 @@ std::vector Paragraph::simpleDocBookOnePar(Buffer const & buf, } } else { char_type c = getUChar(buf.masterBuffer()->params(), runparams, i); - *xs << c; + if (lyx::isSpace(c) && !ignore_fonts) + delayedChars.push_back(c); + else + *xs << c; } font_old = font.fontInfo(); } @@ -3420,7 +3445,13 @@ std::vector Paragraph::simpleDocBookOnePar(Buffer const & buf, if (!ignore_fonts) xs->closeFontTags(); - // In listings, new lines are very important. Avoid generating one for the last line. + // Deal with the delayed characters *after* closing font tags. + if (!delayedChars.empty()) + for (char_type c: delayedChars) + *xs << c; + + // In listings, new lines (i.e. \n characters in the output) are very important. Avoid generating one for the + // last line to get a clean output. if (runparams.docbook_in_listing && !is_last_par) *xs << xml::CR(); @@ -3905,9 +3936,6 @@ bool Paragraph::needsCProtection(bool const fragile) const Inset const * ins = getInset(i); if (ins->needsCProtection(maintext, fragile)) return true; - if (ins->getLayout().latextype() == InsetLayout::ENVIRONMENT) - // Environments need cprotection regardless the content - return true; // Now check math environments InsetMath const * im = getInset(i)->asInsetMath(); if (!im || im->cell(0).empty()) @@ -4341,10 +4369,8 @@ void Paragraph::changeCase(BufferParams const & bparams, pos_type pos, } int erasePos = pos - changes.size(); - for (size_t i = 0; i < changes.size(); i++) { - insertChar(pos, changes[i].first, - changes[i].second, - trackChanges); + for (auto const & change : changes) { + insertChar(pos, change.first, change.second, trackChanges); if (!eraseChar(erasePos, trackChanges)) { ++erasePos; ++pos; // advance @@ -4803,7 +4829,7 @@ void Paragraph::spellCheck() const // start the spell checker on the unit of meaning docstring word = asString(first, last, AS_STR_INSETS + AS_STR_SKIPDELETE); WordLangTuple wl = WordLangTuple(word, lang); - SpellChecker::Result result = word.size() ? + SpellChecker::Result result = !word.empty() ? speller->check(wl) : SpellChecker::WORD_OK; d->markMisspelledWords(first, last, result, word, skips); first = ++last;