mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
DocBook: implement prepended/appended arguments for all kinds of elements.
Previously, it was just in InsetText.
This commit is contained in:
parent
63f255dbd8
commit
358e4ace56
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
#include "frontends/alert.h"
|
#include "frontends/alert.h"
|
||||||
|
|
||||||
|
#include "insets/InsetArgument.h"
|
||||||
#include "insets/InsetBibitem.h"
|
#include "insets/InsetBibitem.h"
|
||||||
#include "insets/InsetLabel.h"
|
#include "insets/InsetLabel.h"
|
||||||
#include "insets/InsetSpecialChar.h"
|
#include "insets/InsetSpecialChar.h"
|
||||||
@ -3419,35 +3420,55 @@ std::tuple<vector<xml::FontTag>, vector<xml::EndFontTag>> computeDocBookFontSwit
|
|||||||
} // anonymous namespace
|
} // 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,
|
OutputParams const & runparams,
|
||||||
Font const & outerfont,
|
Font const & outerfont,
|
||||||
pos_type initial,
|
pos_type initial,
|
||||||
bool is_last_par,
|
bool is_last_par,
|
||||||
bool ignore_fonts) const
|
bool ignore_fonts) const
|
||||||
{
|
{
|
||||||
// Track whether we have opened these tags
|
std::vector<docstring> prependedParagraphs;
|
||||||
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> generatedParagraphs;
|
std::vector<docstring> generatedParagraphs;
|
||||||
DocBookFontState old_fs = fs;
|
std::vector<docstring> appendedParagraphs;
|
||||||
odocstringstream os;
|
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
|
// If there is an argument that must be output before the main tag, do it before handling the rest of the paragraph.
|
||||||
// characters at some point.
|
// Also tag all arguments that shouldn't go in the main content right now, so that they are never generated at the
|
||||||
std::vector<char_type> delayedChars;
|
// 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.
|
// Parsing main loop.
|
||||||
for (pos_type i = initial; i < size(); ++i) {
|
for (pos_type i = initial; i < size(); ++i) {
|
||||||
@ -3511,8 +3532,13 @@ std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf,
|
|||||||
|
|
||||||
// Finally, write the next character or inset.
|
// Finally, write the next character or inset.
|
||||||
if (Inset const * inset = getInset(i)) {
|
if (Inset const * inset = getInset(i)) {
|
||||||
if (!runparams.for_toc || inset->isInToc()) {
|
bool inset_is_argument_elsewhere = getInset(i)->asInsetArgument() &&
|
||||||
OutputParams np = runparams;
|
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;
|
np.local_font = &font;
|
||||||
|
|
||||||
// TODO: special case will bite here.
|
// TODO: special case will bite here.
|
||||||
@ -3520,7 +3546,7 @@ std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf,
|
|||||||
inset->docbook(*xs, np);
|
inset->docbook(*xs, np);
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
if (lyx::isSpace(c) && !ignore_fonts)
|
||||||
delayedChars.push_back(c);
|
delayedChars.push_back(c);
|
||||||
else
|
else
|
||||||
@ -3542,14 +3568,30 @@ std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf,
|
|||||||
|
|
||||||
// In listings, new lines (i.e. \n characters in the output) are very important. Avoid generating one for the
|
// 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.
|
// 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();
|
*xs << xml::CR();
|
||||||
|
|
||||||
// Finalise the last (and most likely only) paragraph.
|
// Finalise the last (and most likely only) paragraph.
|
||||||
generatedParagraphs.push_back(os.str());
|
generatedParagraphs.push_back(os.str());
|
||||||
delete xs;
|
os.str(from_ascii(""));
|
||||||
|
delete xs;
|
||||||
|
|
||||||
return generatedParagraphs;
|
// 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 std::tuple(prependedParagraphs, generatedParagraphs, appendedParagraphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,7 +204,8 @@ public:
|
|||||||
pos_type firstWordLyXHTML(XMLStream & xs, OutputParams const & runparams) const;
|
pos_type firstWordLyXHTML(XMLStream & xs, OutputParams const & runparams) const;
|
||||||
|
|
||||||
/// Outputs to stream the DocBook representation, one element per paragraph.
|
/// Outputs to stream the DocBook representation, one element per paragraph.
|
||||||
std::vector<docstring> simpleDocBookOnePar(Buffer const & buf,
|
std::tuple<std::vector<docstring>, std::vector<docstring>, std::vector<docstring>>
|
||||||
|
simpleDocBookOnePar(Buffer const & buf,
|
||||||
OutputParams const & runparams,
|
OutputParams const & runparams,
|
||||||
Font const & outerfont,
|
Font const & outerfont,
|
||||||
pos_type initial = 0,
|
pos_type initial = 0,
|
||||||
|
@ -98,7 +98,13 @@ void InsetERT::docbook(XMLStream & xs, OutputParams const & runparams) const
|
|||||||
// in an ERT, use simple line breaks.
|
// in an ERT, use simple line breaks.
|
||||||
// New line after each paragraph of the ERT, save the last one.
|
// New line after each paragraph of the ERT, save the last one.
|
||||||
while (true) { // For each paragraph in the ERT...
|
while (true) { // For each paragraph in the ERT...
|
||||||
auto pars = par->simpleDocBookOnePar(buffer(), runparams, text().outerFont(distance(begin, par)), 0, false, true);
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buffer(), runparams, text().outerFont(distance(begin, par)), 0, false, true);
|
||||||
|
|
||||||
|
for (docstring const & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
auto p = pars.begin();
|
auto p = pars.begin();
|
||||||
while (true) { // For each line of this ERT paragraph...
|
while (true) { // For each line of this ERT paragraph...
|
||||||
os << *p;
|
os << *p;
|
||||||
@ -108,6 +114,8 @@ void InsetERT::docbook(XMLStream & xs, OutputParams const & runparams) const
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
for (docstring const & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
|
|
||||||
++par;
|
++par;
|
||||||
if (par != end)
|
if (par != end)
|
||||||
|
@ -286,9 +286,17 @@ void makeBibliography(
|
|||||||
|
|
||||||
// Generate the entry. Concatenate the different parts of the paragraph if any.
|
// Generate the entry. Concatenate the different parts of the paragraph if any.
|
||||||
auto const begin = text.paragraphs().begin();
|
auto const begin = text.paragraphs().begin();
|
||||||
auto pars = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(begin, par)), 0);
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(begin, par)), 0);
|
||||||
|
|
||||||
|
for (auto & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
for (auto & parXML : pars)
|
for (auto & parXML : pars)
|
||||||
xs << XMLStream::ESCAPE_NONE << parXML;
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
|
for (auto & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
|
|
||||||
// End the precooked bibliography entry.
|
// End the precooked bibliography entry.
|
||||||
xs << xml::EndTag("bibliomixed");
|
xs << xml::EndTag("bibliomixed");
|
||||||
@ -432,7 +440,14 @@ void makeParagraph(
|
|||||||
// Open and close tags around each contained paragraph.
|
// Open and close tags around each contained paragraph.
|
||||||
auto nextpar = par;
|
auto nextpar = par;
|
||||||
++nextpar;
|
++nextpar;
|
||||||
auto pars = par->simpleDocBookOnePar(buf, runparams, text.outerFont(distance(begin, par)), 0, nextpar == end, special_case);
|
|
||||||
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buf, runparams, text.outerFont(distance(begin, par)), 0, nextpar == end, special_case);
|
||||||
|
|
||||||
|
for (docstring const & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
for (docstring const & parXML : pars) {
|
for (docstring const & parXML : pars) {
|
||||||
if (!xml::isNotOnlySpace(parXML))
|
if (!xml::isNotOnlySpace(parXML))
|
||||||
continue;
|
continue;
|
||||||
@ -445,6 +460,8 @@ void makeParagraph(
|
|||||||
if (close_par)
|
if (close_par)
|
||||||
closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr, runparams);
|
closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr, runparams);
|
||||||
}
|
}
|
||||||
|
for (docstring const & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -480,8 +497,13 @@ void makeEnvironment(Text const &text,
|
|||||||
// Nothing to do (otherwise, infinite loops).
|
// Nothing to do (otherwise, infinite loops).
|
||||||
} else if (style.latextype == LATEX_ENVIRONMENT) {
|
} else if (style.latextype == LATEX_ENVIRONMENT) {
|
||||||
// Generate the paragraph, if need be.
|
// Generate the paragraph, if need be.
|
||||||
auto pars = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(text.paragraphs().begin(), par)), 0, false, ignoreFonts);
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(text.paragraphs().begin(), par)), 0, false, ignoreFonts);
|
||||||
|
|
||||||
|
for (docstring const & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
if (mimicListing) {
|
if (mimicListing) {
|
||||||
auto p = pars.begin();
|
auto p = pars.begin();
|
||||||
while (p != pars.end()) {
|
while (p != pars.end()) {
|
||||||
@ -504,6 +526,8 @@ void makeEnvironment(Text const &text,
|
|||||||
xml::closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype());
|
xml::closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (docstring const & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
} else {
|
} else {
|
||||||
makeAny(text, buf, xs, runparams, par);
|
makeAny(text, buf, xs, runparams, par);
|
||||||
}
|
}
|
||||||
@ -604,14 +628,21 @@ ParagraphList::const_iterator makeListEnvironment(Text const &text,
|
|||||||
|
|
||||||
// Generate the content of the item.
|
// Generate the content of the item.
|
||||||
if (sep < par->size()) {
|
if (sep < par->size()) {
|
||||||
auto pars = par->simpleDocBookOnePar(buf, runparams,
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buf, runparams,
|
||||||
text.outerFont(std::distance(text.paragraphs().begin(), par)), sep);
|
text.outerFont(std::distance(text.paragraphs().begin(), par)), sep);
|
||||||
|
for (docstring const & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
for (auto &p : pars) {
|
for (auto &p : pars) {
|
||||||
xml::openTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(),
|
xml::openTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(),
|
||||||
par->layout().docbookiteminnertagtype());
|
par->layout().docbookiteminnertagtype());
|
||||||
xs << XMLStream::ESCAPE_NONE << p;
|
xs << XMLStream::ESCAPE_NONE << p;
|
||||||
xml::closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype());
|
xml::closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype());
|
||||||
}
|
}
|
||||||
|
for (docstring const & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
} else {
|
} else {
|
||||||
// DocBook doesn't like emptiness.
|
// DocBook doesn't like emptiness.
|
||||||
xml::compTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(),
|
xml::compTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(),
|
||||||
@ -656,14 +687,23 @@ void makeCommand(
|
|||||||
|
|
||||||
// Generate this command.
|
// Generate this command.
|
||||||
auto prevpar = text.paragraphs().getParagraphBefore(par);
|
auto prevpar = text.paragraphs().getParagraphBefore(par);
|
||||||
openParTag(xs, &*par, prevpar, runparams);
|
|
||||||
|
|
||||||
auto pars = par->simpleDocBookOnePar(buf, runparams,text.outerFont(distance(begin, par)));
|
std::vector<docstring> pars_prepend;
|
||||||
|
std::vector<docstring> pars;
|
||||||
|
std::vector<docstring> pars_append;
|
||||||
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buf, runparams,text.outerFont(distance(begin, par)));
|
||||||
|
|
||||||
|
for (docstring const & parXML : pars_prepend)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
|
|
||||||
|
openParTag(xs, &*par, prevpar, runparams);
|
||||||
for (auto & parXML : pars)
|
for (auto & parXML : pars)
|
||||||
// TODO: decide what to do with openParTag/closeParTag in new lines.
|
// TODO: decide what to do with openParTag/closeParTag in new lines.
|
||||||
xs << XMLStream::ESCAPE_NONE << parXML;
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
|
closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr, runparams);
|
||||||
|
|
||||||
closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr, runparams);
|
for (docstring const & parXML : pars_append)
|
||||||
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user