#include "frontends/alert.h"
+#include "insets/InsetArgument.h"
#include "insets/InsetBibitem.h"
#include "insets/InsetLabel.h"
#include "insets/InsetSpecialChar.h"
// Do we have an open font change?
bool open_font = false;
- Change runningChange = Change(Change::UNCHANGED);
+ Change runningChange =
+ runparams.inDeletedInset && !inInset().canTrackChanges()
+ ? runparams.changeOfDeletedInset : Change(Change::UNCHANGED);
Encoding const * const prev_encoding = runparams.encoding;
runparams);
runningChange = Change(Change::UNCHANGED);
- os << "}] ";
+ os << (isEnvSeparator(i) ? "}]~" : "}] ");
column +=3;
}
// For InTitle commands, we have already opened a group
os << "{\\" << font.latexSize() << "\\par}";
}
- column += Changes::latexMarkChange(os, bparams, runningChange,
- Change(Change::UNCHANGED), runparams);
+ if (!runparams.inDeletedInset || inInset().canTrackChanges())
+ column += Changes::latexMarkChange(os, bparams, runningChange,
+ Change(Change::UNCHANGED), runparams);
// Needed if there is an optional argument but no contents.
if (body_pos > 0 && body_pos == size()) {
} // anonymous namespace
-std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf,
+std::tuple<std::vector<docstring>, std::vector<docstring>, std::vector<docstring>>
+ Paragraph::simpleDocBookOnePar(Buffer const & buf,
OutputParams const & runparams,
Font const & outerfont,
pos_type initial,
bool is_last_par,
bool ignore_fonts) const
{
- // Track whether we have opened these tags
- DocBookFontState fs;
-
- Layout const & style = *d->layout_;
- FontInfo font_old =
- style.labeltype == LABEL_MANUAL ? style.labelfont : style.font;
-
- string const default_family =
- buf.masterBuffer()->params().fonts_default_family;
-
- vector<xml::FontTag> tagsToOpen;
- vector<xml::EndFontTag> tagsToClose;
-
+ std::vector<docstring> prependedParagraphs;
std::vector<docstring> generatedParagraphs;
- DocBookFontState old_fs = fs;
+ std::vector<docstring> appendedParagraphs;
odocstringstream os;
- 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;
+ // If there is an argument that must be output before the main tag, do it before handling the rest of the paragraph.
+ // Also tag all arguments that shouldn't go in the main content right now, so that they are never generated at the
+ // wrong place.
+ OutputParams rp = runparams;
+ for (pos_type i = initial; i < size(); ++i) {
+ if (getInset(i) && getInset(i)->lyxCode() == ARG_CODE) {
+ const InsetArgument * arg = getInset(i)->asInsetArgument();
+ if (arg->docbookargumentbeforemaintag()) {
+ auto xs_local = XMLStream(os);
+ arg->docbook(xs_local, rp);
+
+ prependedParagraphs.push_back(os.str());
+ os.str(from_ascii(""));
+
+ rp.docbook_prepended_arguments.insert(arg);
+ } else if (arg->docbookargumentaftermaintag()) {
+ rp.docbook_appended_arguments.insert(arg);
+ }
+ }
+ }
+
+ // State variables for the main loop.
+ 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).
+ std::vector<char_type> delayedChars; // When a font tag ends with a space, output it after the closing font tag.
+ // This requires to store delayed characters at some point.
+
+ DocBookFontState fs; // Track whether we have opened font tags
+ DocBookFontState old_fs = fs;
+
+ Layout const & style = *d->layout_;
+ FontInfo font_old = style.labeltype == LABEL_MANUAL ? style.labelfont : style.font;
+ string const default_family = buf.masterBuffer()->params().fonts_default_family;
+
+ vector<xml::FontTag> tagsToOpen;
+ vector<xml::EndFontTag> tagsToClose;
// Parsing main loop.
for (pos_type i = initial; i < size(); ++i) {
+ bool ignore_fonts_i = ignore_fonts
+ || style.docbooknofontinside()
+ || (getInset(i) && getInset(i)->getLayout().docbooknofontinside());
+
// Don't show deleted material in the output.
if (isDeleted(i))
continue;
// If this is an InsetNewline, generate a new paragraph. Also reset the fonts, so that tags are closed in
// this paragraph.
if (getInset(i) && getInset(i)->lyxCode() == NEWLINE_CODE) {
- if (!ignore_fonts)
+ if (!ignore_fonts_i)
xs->closeFontTags();
// Output one paragraph (i.e. one string entry in generatedParagraphs).
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) {
+ if (!ignore_fonts_i) {
font_old = outerfont.fontInfo();
fs = old_fs;
}
// Determine which tags should be opened or closed regarding fonts.
Font const font = getFont(buf.masterBuffer()->params(), i, outerfont);
- if (!ignore_fonts) {
- tie(tagsToOpen, tagsToClose) = computeDocBookFontSwitch(font_old, font, default_family, fs);
-
- // FIXME XHTML
- // Other such tags? What about the other text ranges?
-
- vector<xml::EndFontTag>::const_iterator cit = tagsToClose.begin();
- vector<xml::EndFontTag>::const_iterator cen = tagsToClose.end();
- 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();
- }
-
+ tie(tagsToOpen, tagsToClose) = computeDocBookFontSwitch(font_old, font, default_family, fs);
+
+ if (!ignore_fonts_i) {
+ vector<xml::EndFontTag>::const_iterator cit = tagsToClose.begin();
+ vector<xml::EndFontTag>::const_iterator cen = tagsToClose.end();
+ 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();
+ }
+
+ if (!ignore_fonts_i) {
vector<xml::FontTag>::const_iterator sit = tagsToOpen.begin();
vector<xml::FontTag>::const_iterator sen = tagsToOpen.end();
for (; sit != sen; ++sit)
tagsToOpen.clear();
}
+ // Finally, write the next character or inset.
if (Inset const * inset = getInset(i)) {
- if (!runparams.for_toc || inset->isInToc()) {
- OutputParams np = runparams;
+ bool inset_is_argument_elsewhere = getInset(i)->asInsetArgument() &&
+ rp.docbook_appended_arguments.find(inset->asInsetArgument()) != rp.docbook_appended_arguments.end() &&
+ rp.docbook_prepended_arguments.find(inset->asInsetArgument()) != rp.docbook_prepended_arguments.end();
+
+ if ((!rp.for_toc || inset->isInToc()) && !inset_is_argument_elsewhere) {
+ // Arguments may need to be output
+ OutputParams np = rp;
np.local_font = &font;
// TODO: special case will bite here.
inset->docbook(*xs, np);
}
} else {
- char_type c = getUChar(buf.masterBuffer()->params(), runparams, i);
+ char_type c = getUChar(buf.masterBuffer()->params(), rp, i);
if (lyx::isSpace(c) && !ignore_fonts)
delayedChars.push_back(c);
else
// 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)
+ if (rp.docbook_in_listing && !is_last_par)
*xs << xml::CR();
// Finalise the last (and most likely only) paragraph.
generatedParagraphs.push_back(os.str());
- delete xs;
+ os.str(from_ascii(""));
+ delete xs;
+
+ // If there is an argument that must be output after the main tag, do it after handling the rest of the paragraph.
+ for (pos_type i = initial; i < size(); ++i) {
+ if (getInset(i) && getInset(i)->lyxCode() == ARG_CODE) {
+ const InsetArgument * arg = getInset(i)->asInsetArgument();
+ if (arg->docbookargumentaftermaintag()) {
+ // Don't use rp, as this argument would not generate anything.
+ auto xs_local = XMLStream(os);
+ arg->docbook(xs_local, runparams);
+
+ appendedParagraphs.push_back(os.str());
+ os.str(from_ascii(""));
+ }
+ }
+ }
- return generatedParagraphs;
+ return std::make_tuple(prependedParagraphs, generatedParagraphs, appendedParagraphs);
}
break;
odocstringstream os;
inset->toString(os);
- if (!os.str().empty()) {
- int const insetstringsize = os.str().length();
+ docstring const insetstring = os.str();
+ if (!insetstring.empty()) {
+ int const insetstringsize = insetstring.length();
for (int j = 0; j < insetstringsize && pos < parsize; ++i, ++j) {
- if (str[i] != os.str()[j]) {
+ if ((cs && str[i] != insetstring[j])
+ || (!cs && uppercase(str[i]) != uppercase(insetstring[j]))) {
nonmatch = true;
break;
}