#include "support/textutils.h"
#include "output_docbook.h"
+#include <algorithm>
#include <atomic>
#include <sstream>
#include <vector>
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;
// add location information and throw again.
e.par_id = id_;
e.pos = i;
- throw(e);
+ throw;
}
if (close)
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.
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
// add location information and throw again.
e.par_id = id();
e.pos = i;
- throw(e);
+ throw;
}
}
}
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<char_type> delayedChars;
+
// Parsing main loop.
for (pos_type i = initial; i < size(); ++i) {
// Don't show deleted material in the output.
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;
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<xml::FontTag>::const_iterator sit = tagsToOpen.begin();
vector<xml::FontTag>::const_iterator sen = tagsToOpen.end();
for (; sit != sen; ++sit)
}
} 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();
}
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();
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())
}
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
// 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;