Whitespace

This commit is contained in:
Richard Kimberly Heck 2020-07-08 12:15:34 -04:00
parent eeaea7cbbb
commit 8ae0841826
13 changed files with 906 additions and 881 deletions

View File

@ -1594,74 +1594,74 @@ string citationStyleToString(const CitationStyle & cs, bool const latex)
docstring authorsToDocBookAuthorGroup(docstring const & authorsString, XMLStream & xs, Buffer const & buf) docstring authorsToDocBookAuthorGroup(docstring const & authorsString, XMLStream & xs, Buffer const & buf)
{ {
// This function closely mimics getAuthorList, but produces DocBook instead of text. // This function closely mimics getAuthorList, but produces DocBook instead of text.
// It has been greatly simplified, as the complete list of authors is always produced. No separators are required, // It has been greatly simplified, as the complete list of authors is always produced. No separators are required,
// as the output has a database-like shape. // as the output has a database-like shape.
// constructName has also been merged within, as it becomes really simple and leads to no copy-paste. // constructName has also been merged within, as it becomes really simple and leads to no copy-paste.
if (authorsString.empty()) { if (authorsString.empty()) {
return docstring(); return docstring();
} }
// Split the input list of authors into individual authors. // Split the input list of authors into individual authors.
vector<docstring> const authors = getAuthors(authorsString); vector<docstring> const authors = getAuthors(authorsString);
// Retrieve the "et al." variation. // Retrieve the "et al." variation.
string const etal = buf.params().documentClass().getCiteMacro(buf.params().citeEngineType(), "_etal"); string const etal = buf.params().documentClass().getCiteMacro(buf.params().citeEngineType(), "_etal");
// Output the list of authors. // Output the list of authors.
xs << xml::StartTag("authorgroup"); xs << xml::StartTag("authorgroup");
auto it = authors.cbegin(); auto it = authors.cbegin();
auto en = authors.cend(); auto en = authors.cend();
for (size_t i = 0; it != en; ++it, ++i) { for (size_t i = 0; it != en; ++it, ++i) {
xs << xml::StartTag("author"); xs << xml::StartTag("author");
xs << xml::CR(); xs << xml::CR();
xs << xml::StartTag("personname"); xs << xml::StartTag("personname");
xs << xml::CR(); xs << xml::CR();
docstring name = *it; docstring name = *it;
// All authors go in a <personname>. If more structure is known, use it; otherwise (just "et al."), print it as such. // All authors go in a <personname>. If more structure is known, use it; otherwise (just "et al."), print it as such.
if (name == "others") { if (name == "others") {
xs << buf.B_(etal); xs << buf.B_(etal);
} else { } else {
name_parts parts = nameParts(name); name_parts parts = nameParts(name);
if (! parts.prefix.empty()) { if (! parts.prefix.empty()) {
xs << xml::StartTag("honorific"); xs << xml::StartTag("honorific");
xs << parts.prefix; xs << parts.prefix;
xs << xml::EndTag("honorific"); xs << xml::EndTag("honorific");
xs << xml::CR(); xs << xml::CR();
} }
if (! parts.prename.empty()) { if (! parts.prename.empty()) {
xs << xml::StartTag("firstname"); xs << xml::StartTag("firstname");
xs << parts.prename; xs << parts.prename;
xs << xml::EndTag("firstname"); xs << xml::EndTag("firstname");
xs << xml::CR(); xs << xml::CR();
} }
if (! parts.surname.empty()) { if (! parts.surname.empty()) {
xs << xml::StartTag("surname"); xs << xml::StartTag("surname");
xs << parts.surname; xs << parts.surname;
xs << xml::EndTag("surname"); xs << xml::EndTag("surname");
xs << xml::CR(); xs << xml::CR();
} }
if (! parts.suffix.empty()) { if (! parts.suffix.empty()) {
xs << xml::StartTag("othername", "role=\"suffix\""); xs << xml::StartTag("othername", "role=\"suffix\"");
xs << parts.suffix; xs << parts.suffix;
xs << xml::EndTag("othername"); xs << xml::EndTag("othername");
xs << xml::CR(); xs << xml::CR();
} }
} }
xs << xml::EndTag("personname"); xs << xml::EndTag("personname");
xs << xml::CR(); xs << xml::CR();
xs << xml::EndTag("author"); xs << xml::EndTag("author");
xs << xml::CR(); xs << xml::CR();
// Could add an affiliation after <personname>, but not stored in BibTeX. // Could add an affiliation after <personname>, but not stored in BibTeX.
} }
xs << xml::EndTag("authorgroup"); xs << xml::EndTag("authorgroup");
xs << xml::CR(); xs << xml::CR();
return docstring(); return docstring();
} }
} // namespace lyx } // namespace lyx

View File

@ -2143,22 +2143,22 @@ Buffer::ExportStatus Buffer::writeDocBookSource(odocstream & os,
XMLStream xs(os); XMLStream xs(os);
if (output_preamble) { if (output_preamble) {
// XML preamble, no doctype needed. // XML preamble, no doctype needed.
// Not using XMLStream for this, as the root tag would be in the tag stack and make troubles with the error // Not using XMLStream for this, as the root tag would be in the tag stack and make troubles with the error
// detection mechanisms (these are called before the end tag is output, and thus interact with the canary // detection mechanisms (these are called before the end tag is output, and thus interact with the canary
// parsep in output_docbook.cpp). // parsep in output_docbook.cpp).
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<!-- This DocBook file was created by LyX " << lyx_version << "<!-- This DocBook file was created by LyX " << lyx_version
<< "\n See http://www.lyx.org/ for more information -->\n"; << "\n See http://www.lyx.org/ for more information -->\n";
// Directly output the root tag, based on the current type of document. // Directly output the root tag, based on the current type of document.
string languageCode = params().language->code(); string languageCode = params().language->code();
string params = "xml:lang=\"" + languageCode + '"' string params = "xml:lang=\"" + languageCode + '"'
+ " xmlns=\"http://docbook.org/ns/docbook\"" + " xmlns=\"http://docbook.org/ns/docbook\""
+ " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" + " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
+ " xmlns:m=\"http://www.w3.org/1998/Math/MathML\"" + " xmlns:m=\"http://www.w3.org/1998/Math/MathML\""
+ " xmlns:xi=\"http://www.w3.org/2001/XInclude\"" + " xmlns:xi=\"http://www.w3.org/2001/XInclude\""
+ " version=\"5.2\""; + " version=\"5.2\"";
os << "<" << from_ascii(tclass.docbookroot()) << " " << from_ascii(params) << ">\n"; os << "<" << from_ascii(tclass.docbookroot()) << " " << from_ascii(params) << ">\n";
} }

View File

@ -336,8 +336,8 @@ public:
OutputWhat output = FullSource) const; OutputWhat output = FullSource) const;
/// ///
ExportStatus writeDocBookSource(odocstream & os, ExportStatus writeDocBookSource(odocstream & os,
OutputParams const & runparams_in, OutputParams const & runparams_in,
OutputWhat output = FullSource) const; OutputWhat output = FullSource) const;
/// ///
ExportStatus makeLyXHTMLFile(support::FileName const & filename, ExportStatus makeLyXHTMLFile(support::FileName const & filename,
OutputParams const & runparams_in) const; OutputParams const & runparams_in) const;

View File

@ -3004,13 +3004,13 @@ void doFontSwitchDocBook(vector<xml::FontTag> & tagsToOpen,
vector<xml::EndFontTag> & tagsToClose, vector<xml::EndFontTag> & tagsToClose,
bool & flag, FontState curstate, xml::FontTypes type) bool & flag, FontState curstate, xml::FontTypes type)
{ {
if (curstate == FONT_ON) { if (curstate == FONT_ON) {
tagsToOpen.push_back(docbookStartFontTag(type)); tagsToOpen.push_back(docbookStartFontTag(type));
flag = true; flag = true;
} else if (flag) { } else if (flag) {
tagsToClose.push_back(docbookEndFontTag(type)); tagsToClose.push_back(docbookEndFontTag(type));
flag = false; flag = false;
} }
} }
class OptionalFontType { class OptionalFontType {
@ -3024,42 +3024,42 @@ public:
OptionalFontType fontShapeToXml(FontShape fs) OptionalFontType fontShapeToXml(FontShape fs)
{ {
switch (fs) { switch (fs) {
case ITALIC_SHAPE: case ITALIC_SHAPE:
return {xml::FT_ITALIC}; return {xml::FT_ITALIC};
case SLANTED_SHAPE: case SLANTED_SHAPE:
return {xml::FT_SLANTED}; return {xml::FT_SLANTED};
case SMALLCAPS_SHAPE: case SMALLCAPS_SHAPE:
return {xml::FT_SMALLCAPS}; return {xml::FT_SMALLCAPS};
case UP_SHAPE: case UP_SHAPE:
case INHERIT_SHAPE: case INHERIT_SHAPE:
return {}; return {};
default: default:
// the other tags are for internal use // the other tags are for internal use
LATTEST(false); LATTEST(false);
return {}; return {};
} }
} }
OptionalFontType fontFamilyToXml(FontFamily fm) OptionalFontType fontFamilyToXml(FontFamily fm)
{ {
switch (fm) { switch (fm) {
case ROMAN_FAMILY: case ROMAN_FAMILY:
return {xml::FT_ROMAN}; return {xml::FT_ROMAN};
break; break;
case SANS_FAMILY: case SANS_FAMILY:
return {xml::FT_SANS}; return {xml::FT_SANS};
break; break;
case TYPEWRITER_FAMILY: case TYPEWRITER_FAMILY:
return {xml::FT_TYPE}; return {xml::FT_TYPE};
break; break;
case INHERIT_FAMILY: case INHERIT_FAMILY:
return {}; return {};
default: default:
// the other tags are for internal use // the other tags are for internal use
LATTEST(false); LATTEST(false);
return {}; return {};
} }
} }
OptionalFontType fontSizeToXml(FontSize fs) OptionalFontType fontSizeToXml(FontSize fs)
@ -3095,7 +3095,6 @@ OptionalFontType fontSizeToXml(FontSize fs)
LATTEST(false); LATTEST(false);
return {}; return {};
} }
} }
}// anonymous namespace }// anonymous namespace
@ -3108,198 +3107,198 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
bool start_paragraph, bool close_paragraph, bool start_paragraph, bool close_paragraph,
pos_type initial) const pos_type initial) const
{ {
// track whether we have opened these tags // track whether we have opened these tags
bool emph_flag = false; bool emph_flag = false;
bool bold_flag = false; bool bold_flag = false;
bool noun_flag = false; bool noun_flag = false;
bool ubar_flag = false; bool ubar_flag = false;
bool dbar_flag = false; bool dbar_flag = false;
bool sout_flag = false; bool sout_flag = false;
bool wave_flag = false; bool wave_flag = false;
// shape tags // shape tags
bool shap_flag = false; bool shap_flag = false;
// family tags // family tags
bool faml_flag = false; bool faml_flag = false;
// size tags // size tags
bool size_flag = false; bool size_flag = false;
Layout const & style = *d->layout_; Layout const & style = *d->layout_;
if (start_paragraph) if (start_paragraph)
xs.startDivision(allowEmpty()); xs.startDivision(allowEmpty());
FontInfo font_old = FontInfo font_old =
style.labeltype == LABEL_MANUAL ? style.labelfont : style.font; style.labeltype == LABEL_MANUAL ? style.labelfont : style.font;
FontShape curr_fs = INHERIT_SHAPE; FontShape curr_fs = INHERIT_SHAPE;
FontFamily curr_fam = INHERIT_FAMILY; FontFamily curr_fam = INHERIT_FAMILY;
FontSize curr_size = INHERIT_SIZE; FontSize curr_size = INHERIT_SIZE;
string const default_family = string const default_family =
buf.masterBuffer()->params().fonts_default_family; buf.masterBuffer()->params().fonts_default_family;
vector<xml::FontTag> tagsToOpen; vector<xml::FontTag> tagsToOpen;
vector<xml::EndFontTag> tagsToClose; 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) {
// let's not show deleted material in the output // let's not show deleted material in the output
if (isDeleted(i)) if (isDeleted(i))
continue; continue;
Font const font = getFont(buf.masterBuffer()->params(), i, outerfont); Font const font = getFont(buf.masterBuffer()->params(), i, outerfont);
// emphasis // emphasis
FontState curstate = font.fontInfo().emph(); FontState curstate = font.fontInfo().emph();
if (font_old.emph() != curstate) if (font_old.emph() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, emph_flag, curstate, xml::FT_EMPH); doFontSwitchDocBook(tagsToOpen, tagsToClose, emph_flag, curstate, xml::FT_EMPH);
// noun // noun
curstate = font.fontInfo().noun(); curstate = font.fontInfo().noun();
if (font_old.noun() != curstate) if (font_old.noun() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, noun_flag, curstate, xml::FT_NOUN); doFontSwitchDocBook(tagsToOpen, tagsToClose, noun_flag, curstate, xml::FT_NOUN);
// underbar // underbar
curstate = font.fontInfo().underbar(); curstate = font.fontInfo().underbar();
if (font_old.underbar() != curstate) if (font_old.underbar() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, ubar_flag, curstate, xml::FT_UBAR); doFontSwitchDocBook(tagsToOpen, tagsToClose, ubar_flag, curstate, xml::FT_UBAR);
// strikeout // strikeout
curstate = font.fontInfo().strikeout(); curstate = font.fontInfo().strikeout();
if (font_old.strikeout() != curstate) if (font_old.strikeout() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, sout_flag, curstate, xml::FT_SOUT); doFontSwitchDocBook(tagsToOpen, tagsToClose, sout_flag, curstate, xml::FT_SOUT);
// double underbar // double underbar
curstate = font.fontInfo().uuline(); curstate = font.fontInfo().uuline();
if (font_old.uuline() != curstate) if (font_old.uuline() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, dbar_flag, curstate, xml::FT_DBAR); doFontSwitchDocBook(tagsToOpen, tagsToClose, dbar_flag, curstate, xml::FT_DBAR);
// wavy line // wavy line
curstate = font.fontInfo().uwave(); curstate = font.fontInfo().uwave();
if (font_old.uwave() != curstate) if (font_old.uwave() != curstate)
doFontSwitchDocBook(tagsToOpen, tagsToClose, wave_flag, curstate, xml::FT_WAVE); doFontSwitchDocBook(tagsToOpen, tagsToClose, wave_flag, curstate, xml::FT_WAVE);
// bold // bold
// a little hackish, but allows us to reuse what we have. // a little hackish, but allows us to reuse what we have.
curstate = (font.fontInfo().series() == BOLD_SERIES ? FONT_ON : FONT_OFF); curstate = (font.fontInfo().series() == BOLD_SERIES ? FONT_ON : FONT_OFF);
if (font_old.series() != font.fontInfo().series()) if (font_old.series() != font.fontInfo().series())
doFontSwitchDocBook(tagsToOpen, tagsToClose, bold_flag, curstate, xml::FT_BOLD); doFontSwitchDocBook(tagsToOpen, tagsToClose, bold_flag, curstate, xml::FT_BOLD);
// Font shape // Font shape
curr_fs = font.fontInfo().shape(); curr_fs = font.fontInfo().shape();
FontShape old_fs = font_old.shape(); FontShape old_fs = font_old.shape();
if (old_fs != curr_fs) { if (old_fs != curr_fs) {
if (shap_flag) { if (shap_flag) {
OptionalFontType tag = fontShapeToXml(old_fs); OptionalFontType tag = fontShapeToXml(old_fs);
if (tag.has_value) { if (tag.has_value) {
tagsToClose.push_back(docbookEndFontTag(tag.ft)); tagsToClose.push_back(docbookEndFontTag(tag.ft));
} }
shap_flag = false; shap_flag = false;
} }
OptionalFontType tag = fontShapeToXml(curr_fs); OptionalFontType tag = fontShapeToXml(curr_fs);
if (tag.has_value) { if (tag.has_value) {
tagsToOpen.push_back(docbookStartFontTag(tag.ft)); tagsToOpen.push_back(docbookStartFontTag(tag.ft));
} }
} }
// Font family // Font family
curr_fam = font.fontInfo().family(); curr_fam = font.fontInfo().family();
FontFamily old_fam = font_old.family(); FontFamily old_fam = font_old.family();
if (old_fam != curr_fam) { if (old_fam != curr_fam) {
if (faml_flag) { if (faml_flag) {
OptionalFontType tag = fontFamilyToXml(old_fam); OptionalFontType tag = fontFamilyToXml(old_fam);
if (tag.has_value) { if (tag.has_value) {
tagsToClose.push_back(docbookEndFontTag(tag.ft)); tagsToClose.push_back(docbookEndFontTag(tag.ft));
} }
faml_flag = false; faml_flag = false;
} }
switch (curr_fam) { switch (curr_fam) {
case ROMAN_FAMILY: case ROMAN_FAMILY:
// we will treat a "default" font family as roman, since we have // we will treat a "default" font family as roman, since we have
// no other idea what to do. // no other idea what to do.
if (default_family != "rmdefault" && default_family != "default") { if (default_family != "rmdefault" && default_family != "default") {
tagsToOpen.push_back(docbookStartFontTag(xml::FT_ROMAN)); tagsToOpen.push_back(docbookStartFontTag(xml::FT_ROMAN));
faml_flag = true; faml_flag = true;
} }
break; break;
case SANS_FAMILY: case SANS_FAMILY:
if (default_family != "sfdefault") { if (default_family != "sfdefault") {
tagsToOpen.push_back(docbookStartFontTag(xml::FT_SANS)); tagsToOpen.push_back(docbookStartFontTag(xml::FT_SANS));
faml_flag = true; faml_flag = true;
} }
break; break;
case TYPEWRITER_FAMILY: case TYPEWRITER_FAMILY:
if (default_family != "ttdefault") { if (default_family != "ttdefault") {
tagsToOpen.push_back(docbookStartFontTag(xml::FT_TYPE)); tagsToOpen.push_back(docbookStartFontTag(xml::FT_TYPE));
faml_flag = true; faml_flag = true;
} }
break; break;
case INHERIT_FAMILY: case INHERIT_FAMILY:
break; break;
default: default:
// the other tags are for internal use // the other tags are for internal use
LATTEST(false); LATTEST(false);
break; break;
} }
} }
// Font size // Font size
curr_size = font.fontInfo().size(); curr_size = font.fontInfo().size();
FontSize old_size = font_old.size(); FontSize old_size = font_old.size();
if (old_size != curr_size) { if (old_size != curr_size) {
if (size_flag) { if (size_flag) {
OptionalFontType tag = fontSizeToXml(old_size); OptionalFontType tag = fontSizeToXml(old_size);
if (tag.has_value) { if (tag.has_value) {
tagsToClose.push_back(docbookEndFontTag(tag.ft)); tagsToClose.push_back(docbookEndFontTag(tag.ft));
} }
size_flag = false; size_flag = false;
} }
OptionalFontType tag = fontSizeToXml(curr_size); OptionalFontType tag = fontSizeToXml(curr_size);
if (tag.has_value) { if (tag.has_value) {
tagsToOpen.push_back(docbookStartFontTag(tag.ft)); tagsToOpen.push_back(docbookStartFontTag(tag.ft));
size_flag = true; size_flag = true;
} }
} }
// FIXME XHTML // FIXME XHTML
// Other such tags? What about the other text ranges? // Other such tags? What about the other text ranges?
vector<xml::EndFontTag>::const_iterator cit = tagsToClose.begin(); vector<xml::EndFontTag>::const_iterator cit = tagsToClose.begin();
vector<xml::EndFontTag>::const_iterator cen = tagsToClose.end(); vector<xml::EndFontTag>::const_iterator cen = tagsToClose.end();
for (; cit != cen; ++cit) for (; cit != cen; ++cit)
xs << *cit; xs << *cit;
vector<xml::FontTag>::const_iterator sit = tagsToOpen.begin(); vector<xml::FontTag>::const_iterator sit = tagsToOpen.begin();
vector<xml::FontTag>::const_iterator sen = tagsToOpen.end(); vector<xml::FontTag>::const_iterator sen = tagsToOpen.end();
for (; sit != sen; ++sit) for (; sit != sen; ++sit)
xs << *sit; xs << *sit;
tagsToClose.clear(); tagsToClose.clear();
tagsToOpen.clear(); tagsToOpen.clear();
if (Inset const * inset = getInset(i)) { if (Inset const * inset = getInset(i)) {
if (!runparams.for_toc || inset->isInToc()) { if (!runparams.for_toc || inset->isInToc()) {
OutputParams np = runparams; OutputParams np = runparams;
np.local_font = &font; np.local_font = &font;
// If the paragraph has size 1, then we are in the "special // If the paragraph has size 1, then we are in the "special
// case" where we do not output the containing paragraph info. // case" where we do not output the containing paragraph info.
if (!inset->getLayout().htmlisblock() && size() != 1) // TODO: htmlisblock here too! if (!inset->getLayout().htmlisblock() && size() != 1) // TODO: htmlisblock here too!
np.docbook_in_par = true; np.docbook_in_par = true;
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(), runparams, i);
xs << c; xs << c;
} }
font_old = font.fontInfo(); font_old = font.fontInfo();
} }
// FIXME, this code is just imported from XHTML // FIXME, this code is just imported from XHTML
// I'm worried about what happens if a branch, say, is itself // I'm worried about what happens if a branch, say, is itself
// wrapped in some font stuff. I think that will not work. // wrapped in some font stuff. I think that will not work.
xs.closeFontTags(); xs.closeFontTags();
if (runparams.docbook_in_listing) if (runparams.docbook_in_listing)
xs << xml::CR(); xs << xml::CR();
if (close_paragraph) if (close_paragraph)

View File

@ -554,29 +554,29 @@ int InsetIPAChar::plaintext(odocstringstream & os, OutputParams const &, size_t)
void InsetIPAChar::docbook(XMLStream & xs, OutputParams const &) const void InsetIPAChar::docbook(XMLStream & xs, OutputParams const &) const
{ {
switch (kind_) { switch (kind_) {
case TONE_FALLING: case TONE_FALLING:
xs << XMLStream::ESCAPE_NONE << "&#x2e5;"; xs << XMLStream::ESCAPE_NONE << "&#x2e5;";
xs << XMLStream::ESCAPE_NONE << "&#x2e9;"; xs << XMLStream::ESCAPE_NONE << "&#x2e9;";
break; break;
case TONE_RISING: case TONE_RISING:
xs << XMLStream::ESCAPE_NONE << "&#x2e9;"; xs << XMLStream::ESCAPE_NONE << "&#x2e9;";
xs << XMLStream::ESCAPE_NONE << "&#x2e5;"; xs << XMLStream::ESCAPE_NONE << "&#x2e5;";
break; break;
case TONE_HIGH_RISING: case TONE_HIGH_RISING:
xs << XMLStream::ESCAPE_NONE << "&#x2e7;"; xs << XMLStream::ESCAPE_NONE << "&#x2e7;";
xs << XMLStream::ESCAPE_NONE << "&#x2e5;"; xs << XMLStream::ESCAPE_NONE << "&#x2e5;";
break; break;
case TONE_LOW_RISING: case TONE_LOW_RISING:
xs << XMLStream::ESCAPE_NONE << "&#x2e9;"; xs << XMLStream::ESCAPE_NONE << "&#x2e9;";
xs << XMLStream::ESCAPE_NONE << "&#x2e7;"; xs << XMLStream::ESCAPE_NONE << "&#x2e7;";
break; break;
case TONE_HIGH_RISING_FALLING: case TONE_HIGH_RISING_FALLING:
xs << XMLStream::ESCAPE_NONE << "&#x2e8;"; xs << XMLStream::ESCAPE_NONE << "&#x2e8;";
xs << XMLStream::ESCAPE_NONE << "&#x2e5;"; xs << XMLStream::ESCAPE_NONE << "&#x2e5;";
xs << XMLStream::ESCAPE_NONE << "&#x2e8;"; xs << XMLStream::ESCAPE_NONE << "&#x2e8;";
break; break;
} }
} }

View File

@ -193,19 +193,19 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
InsetText::latex(ots, runparams); InsetText::latex(ots, runparams);
docstring latexString = trim(odss.str()); docstring latexString = trim(odss.str());
// Check whether there are unsupported things. // Check whether there are unsupported things.
if (latexString.find(from_utf8("@")) != latexString.npos) { if (latexString.find(from_utf8("@")) != latexString.npos) {
docstring error = from_utf8("Unsupported feature: an index entry contains an @. " docstring error = from_utf8("Unsupported feature: an index entry contains an @. "
"Complete entry: \"") + latexString + from_utf8("\""); "Complete entry: \"") + latexString + from_utf8("\"");
LYXERR0(error); LYXERR0(error);
xs << XMLStream::ESCAPE_NONE << (from_utf8("<!-- Output Error: ") + error + from_utf8(" -->\n")); xs << XMLStream::ESCAPE_NONE << (from_utf8("<!-- Output Error: ") + error + from_utf8(" -->\n"));
} }
// Handle several indices. // Handle several indices.
docstring indexType = from_utf8(""); docstring indexType = from_utf8("");
if (buffer().masterBuffer()->params().use_indices) { if (buffer().masterBuffer()->params().use_indices) {
indexType += " type=\"" + params_.index + "\""; indexType += " type=\"" + params_.index + "\"";
} }
// Split the string into its main constituents: terms, and command (see, see also, range). // Split the string into its main constituents: terms, and command (see, see also, range).
size_t positionVerticalBar = latexString.find(from_ascii("|")); // What comes before | is (sub)(sub)entries. size_t positionVerticalBar = latexString.find(from_ascii("|")); // What comes before | is (sub)(sub)entries.
@ -237,13 +237,13 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
docstring see = from_utf8(""); docstring see = from_utf8("");
vector<docstring> seeAlsoes; vector<docstring> seeAlsoes;
if (command.substr(0, 3) == "see") { if (command.substr(0, 3) == "see") {
// Unescape brackets. // Unescape brackets.
size_t index = 0; size_t index = 0;
while ((index = command.find(from_utf8("\\{"), index)) != std::string::npos) while ((index = command.find(from_utf8("\\{"), index)) != std::string::npos)
command.erase(index, 1); command.erase(index, 1);
index = 0; index = 0;
while ((index = command.find(from_utf8("\\}"), index)) != std::string::npos) while ((index = command.find(from_utf8("\\}"), index)) != std::string::npos)
command.erase(index, 1); command.erase(index, 1);
// Retrieve the part between brackets, and remove the complete seealso. // Retrieve the part between brackets, and remove the complete seealso.
size_t positionOpeningBracket = command.find(from_ascii("{")); size_t positionOpeningBracket = command.find(from_ascii("{"));
@ -258,14 +258,14 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
if (see.find(from_ascii(",")) != see.npos) { if (see.find(from_ascii(",")) != see.npos) {
docstring error = from_utf8("Several index terms found as \"see\"! Only one is acceptable. " docstring error = from_utf8("Several index terms found as \"see\"! Only one is acceptable. "
"Complete entry: \"") + latexString + from_utf8("\""); "Complete entry: \"") + latexString + from_utf8("\"");
LYXERR0(error); LYXERR0(error);
xs << XMLStream::ESCAPE_NONE << (from_utf8("<!-- Output Error: ") + error + from_utf8(" -->\n")); xs << XMLStream::ESCAPE_NONE << (from_utf8("<!-- Output Error: ") + error + from_utf8(" -->\n"));
} }
} }
// Remove the complete see/seealso from the commands, in case there is something else to parse. // Remove the complete see/seealso from the commands, in case there is something else to parse.
command = command.substr(positionClosingBracket + 1); command = command.substr(positionClosingBracket + 1);
} }
// Some parts of the strings are not parsed, as they do not have anything matching in DocBook: things like // Some parts of the strings are not parsed, as they do not have anything matching in DocBook: things like

View File

@ -483,10 +483,10 @@ docstring InsetListings::xhtml(XMLStream & os, OutputParams const & rp) const
void InsetListings::docbook(XMLStream & xs, OutputParams const & rp) const void InsetListings::docbook(XMLStream & xs, OutputParams const & rp) const
{ {
InsetLayout const & il = getLayout(); InsetLayout const & il = getLayout();
// Forge the attributes. // Forge the attributes.
string attrs; string attrs;
if (!il.docbookattr().empty()) if (!il.docbookattr().empty())
attrs += " role=\"" + il.docbookattr() + "\""; attrs += " role=\"" + il.docbookattr() + "\"";
string const lang = params().getParamValue("language"); string const lang = params().getParamValue("language");

View File

@ -4165,7 +4165,7 @@ docstring InsetTableCell::xhtml(XMLStream & xs, OutputParams const & rp) const
void InsetTableCell::docbook(XMLStream & xs, OutputParams const & runparams) const void InsetTableCell::docbook(XMLStream & xs, OutputParams const & runparams) const
{ {
InsetText::docbook(xs, runparams); InsetText::docbook(xs, runparams);
} }

View File

@ -573,7 +573,7 @@ public:
/// ///
void latex(otexstream &, OutputParams const &) const; void latex(otexstream &, OutputParams const &) const;
/// ///
void docbook(XMLStream &, OutputParams const &) const; void docbook(XMLStream &, OutputParams const &) const;
/// ///
docstring xhtml(XMLStream &, OutputParams const &) const; docstring xhtml(XMLStream &, OutputParams const &) const;
/// ///
@ -908,8 +908,8 @@ public:
std::vector<unsigned int> const &, std::vector<unsigned int> const &,
bool onlydata, size_t max_length) const; bool onlydata, size_t max_length) const;
/// auxiliary function for docbook /// auxiliary function for docbook
void docbookRow(XMLStream &, row_type, OutputParams const &, void docbookRow(XMLStream &, row_type, OutputParams const &,
bool header = false) const; bool header = false) const;
/// ///
docstring xhtmlRow(XMLStream & xs, row_type, OutputParams const &, docstring xhtmlRow(XMLStream & xs, row_type, OutputParams const &,
bool header = false) const; bool header = false) const;

View File

@ -591,7 +591,7 @@ int InsetText::plaintext(odocstringstream & os,
void InsetText::docbook(XMLStream & xs, OutputParams const & rp) const void InsetText::docbook(XMLStream & xs, OutputParams const & rp) const
{ {
docbook(xs, rp, WriteEverything); docbook(xs, rp, WriteEverything);
} }
@ -612,13 +612,13 @@ void InsetText::docbook(XMLStream & xs, OutputParams const & rp, XHTMLOptions op
InsetLayout const & il = getLayout(); InsetLayout const & il = getLayout();
if (opts & WriteOuterTag && !il.docbooktag().empty() && il.docbooktag() != "NONE") { if (opts & WriteOuterTag && !il.docbooktag().empty() && il.docbooktag() != "NONE") {
docstring attrs = docstring(); docstring attrs = docstring();
if (!il.docbookattr().empty()) if (!il.docbookattr().empty())
attrs += from_ascii(il.docbookattr()); attrs += from_ascii(il.docbookattr());
if (il.docbooktag() == "link") if (il.docbooktag() == "link")
attrs += from_ascii(" xlink:href=\"") + text_.asString() + from_ascii("\""); attrs += from_ascii(" xlink:href=\"") + text_.asString() + from_ascii("\"");
xs << xml::StartTag(il.docbooktag(), attrs); xs << xml::StartTag(il.docbooktag(), attrs);
} }
// No need for labels that are generated from counters. // No need for labels that are generated from counters.

View File

@ -2444,23 +2444,23 @@ void InsetMathHull::docbook(XMLStream & xs, OutputParams const & runparams) cons
ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&amp;"), "<", "&lt;")); ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&amp;"), "<", "&lt;"));
ms << "</" << from_ascii("alt") << ">"; ms << "</" << from_ascii("alt") << ">";
// Actual transformation of the formula into MathML. This translation may fail (for example, due to custom macros). // Actual transformation of the formula into MathML. This translation may fail (for example, due to custom macros).
// The new output stream is required to deal with the errors: first write completely the formula into this // The new output stream is required to deal with the errors: first write completely the formula into this
// temporary stream; then, if it is possible without error, then copy it back to the "real" stream. Otherwise, // temporary stream; then, if it is possible without error, then copy it back to the "real" stream. Otherwise,
// some incomplete tags might be put into the real stream. // some incomplete tags might be put into the real stream.
try { try {
// First, generate the MathML expression. // First, generate the MathML expression.
odocstringstream ostmp; odocstringstream ostmp;
MathStream mstmp(ostmp, ms.xmlns(), ms.xmlMode()); MathStream mstmp(ostmp, ms.xmlns(), ms.xmlMode());
InsetMathGrid::mathmlize(mstmp); InsetMathGrid::mathmlize(mstmp);
// Then, output it (but only if the generation can be done without errors!). // Then, output it (but only if the generation can be done without errors!).
ms << MTag("math"); ms << MTag("math");
ms.cr(); ms.cr();
osmath << ostmp.str(); // osmath is not a XMLStream, so no need for XMLStream::ESCAPE_NONE. osmath << ostmp.str(); // osmath is not a XMLStream, so no need for XMLStream::ESCAPE_NONE.
ms << ETag("math"); ms << ETag("math");
} catch (MathExportException const &) { } catch (MathExportException const &) {
osmath << "MathML export failed. Please report this as a bug."; osmath << "MathML export failed. Please report this as a bug.";
} }
// Close the DocBook tag enclosing the formula. // Close the DocBook tag enclosing the formula.

View File

@ -47,122 +47,124 @@ namespace lyx {
namespace { namespace {
std::string const fontToDocBookTag(xml::FontTypes type) { std::string const fontToDocBookTag(xml::FontTypes type)
switch (type) { {
case xml::FontTypes::FT_EMPH: switch (type) {
case xml::FontTypes::FT_BOLD: case xml::FontTypes::FT_EMPH:
return "emphasis"; case xml::FontTypes::FT_BOLD:
case xml::FontTypes::FT_NOUN: return "emphasis";
return "person"; case xml::FontTypes::FT_NOUN:
case xml::FontTypes::FT_UBAR: return "person";
case xml::FontTypes::FT_WAVE: case xml::FontTypes::FT_UBAR:
case xml::FontTypes::FT_DBAR: case xml::FontTypes::FT_WAVE:
case xml::FontTypes::FT_SOUT: case xml::FontTypes::FT_DBAR:
case xml::FontTypes::FT_XOUT: case xml::FontTypes::FT_SOUT:
case xml::FontTypes::FT_ITALIC: case xml::FontTypes::FT_XOUT:
case xml::FontTypes::FT_UPRIGHT: case xml::FontTypes::FT_ITALIC:
case xml::FontTypes::FT_SLANTED: case xml::FontTypes::FT_UPRIGHT:
case xml::FontTypes::FT_SMALLCAPS: case xml::FontTypes::FT_SLANTED:
case xml::FontTypes::FT_ROMAN: case xml::FontTypes::FT_SMALLCAPS:
case xml::FontTypes::FT_SANS: case xml::FontTypes::FT_ROMAN:
return "emphasis"; case xml::FontTypes::FT_SANS:
case xml::FontTypes::FT_TYPE: return "emphasis";
return "code"; case xml::FontTypes::FT_TYPE:
case xml::FontTypes::FT_SIZE_TINY: return "code";
case xml::FontTypes::FT_SIZE_SCRIPT: case xml::FontTypes::FT_SIZE_TINY:
case xml::FontTypes::FT_SIZE_FOOTNOTE: case xml::FontTypes::FT_SIZE_SCRIPT:
case xml::FontTypes::FT_SIZE_SMALL: case xml::FontTypes::FT_SIZE_FOOTNOTE:
case xml::FontTypes::FT_SIZE_NORMAL: case xml::FontTypes::FT_SIZE_SMALL:
case xml::FontTypes::FT_SIZE_LARGE: case xml::FontTypes::FT_SIZE_NORMAL:
case xml::FontTypes::FT_SIZE_LARGER: case xml::FontTypes::FT_SIZE_LARGE:
case xml::FontTypes::FT_SIZE_LARGEST: case xml::FontTypes::FT_SIZE_LARGER:
case xml::FontTypes::FT_SIZE_HUGE: case xml::FontTypes::FT_SIZE_LARGEST:
case xml::FontTypes::FT_SIZE_HUGER: case xml::FontTypes::FT_SIZE_HUGE:
case xml::FontTypes::FT_SIZE_INCREASE: case xml::FontTypes::FT_SIZE_HUGER:
case xml::FontTypes::FT_SIZE_DECREASE: case xml::FontTypes::FT_SIZE_INCREASE:
return "emphasis"; case xml::FontTypes::FT_SIZE_DECREASE:
default: return "emphasis";
return ""; default:
} return "";
}
} }
string fontToRole(xml::FontTypes type) { string fontToRole(xml::FontTypes type)
// Specific fonts are achieved with roles. The only common ones are "" for basic emphasis, {
// and "bold"/"strong" for bold. With some specific options, other roles are copied into // Specific fonts are achieved with roles. The only common ones are "" for basic emphasis,
// HTML output (via the DocBook XSLT sheets); otherwise, if not recognised, they are just ignored. // and "bold"/"strong" for bold. With some specific options, other roles are copied into
// Hence, it is not a problem to have many roles by default here. // HTML output (via the DocBook XSLT sheets); otherwise, if not recognised, they are just ignored.
// See https://www.sourceware.org/ml/docbook/2003-05/msg00269.html // Hence, it is not a problem to have many roles by default here.
switch (type) { // See https://www.sourceware.org/ml/docbook/2003-05/msg00269.html
case xml::FontTypes::FT_ITALIC: switch (type) {
case xml::FontTypes::FT_EMPH: case xml::FontTypes::FT_ITALIC:
return ""; case xml::FontTypes::FT_EMPH:
case xml::FontTypes::FT_BOLD: return "";
return "bold"; case xml::FontTypes::FT_BOLD:
case xml::FontTypes::FT_NOUN: return "bold";
return ""; // Outputs a <person> case xml::FontTypes::FT_NOUN:
case xml::FontTypes::FT_TYPE: return ""; // Outputs a <person>
return ""; // Outputs a <code> case xml::FontTypes::FT_TYPE:
return ""; // Outputs a <code>
// All other roles are non-standard for DocBook. // All other roles are non-standard for DocBook.
case xml::FontTypes::FT_UBAR: case xml::FontTypes::FT_UBAR:
return "ubar"; return "ubar";
case xml::FontTypes::FT_WAVE: case xml::FontTypes::FT_WAVE:
return "wave"; return "wave";
case xml::FontTypes::FT_DBAR: case xml::FontTypes::FT_DBAR:
return "dbar"; return "dbar";
case xml::FontTypes::FT_SOUT: case xml::FontTypes::FT_SOUT:
return "sout"; return "sout";
case xml::FontTypes::FT_XOUT: case xml::FontTypes::FT_XOUT:
return "xout"; return "xout";
case xml::FontTypes::FT_UPRIGHT: case xml::FontTypes::FT_UPRIGHT:
return "upright"; return "upright";
case xml::FontTypes::FT_SLANTED: case xml::FontTypes::FT_SLANTED:
return "slanted"; return "slanted";
case xml::FontTypes::FT_SMALLCAPS: case xml::FontTypes::FT_SMALLCAPS:
return "smallcaps"; return "smallcaps";
case xml::FontTypes::FT_ROMAN: case xml::FontTypes::FT_ROMAN:
return "roman"; return "roman";
case xml::FontTypes::FT_SANS: case xml::FontTypes::FT_SANS:
return "sans"; return "sans";
case xml::FontTypes::FT_SIZE_TINY: case xml::FontTypes::FT_SIZE_TINY:
return "tiny"; return "tiny";
case xml::FontTypes::FT_SIZE_SCRIPT: case xml::FontTypes::FT_SIZE_SCRIPT:
return "size_script"; return "size_script";
case xml::FontTypes::FT_SIZE_FOOTNOTE: case xml::FontTypes::FT_SIZE_FOOTNOTE:
return "size_footnote"; return "size_footnote";
case xml::FontTypes::FT_SIZE_SMALL: case xml::FontTypes::FT_SIZE_SMALL:
return "size_small"; return "size_small";
case xml::FontTypes::FT_SIZE_NORMAL: case xml::FontTypes::FT_SIZE_NORMAL:
return "size_normal"; return "size_normal";
case xml::FontTypes::FT_SIZE_LARGE: case xml::FontTypes::FT_SIZE_LARGE:
return "size_large"; return "size_large";
case xml::FontTypes::FT_SIZE_LARGER: case xml::FontTypes::FT_SIZE_LARGER:
return "size_larger"; return "size_larger";
case xml::FontTypes::FT_SIZE_LARGEST: case xml::FontTypes::FT_SIZE_LARGEST:
return "size_largest"; return "size_largest";
case xml::FontTypes::FT_SIZE_HUGE: case xml::FontTypes::FT_SIZE_HUGE:
return "size_huge"; return "size_huge";
case xml::FontTypes::FT_SIZE_HUGER: case xml::FontTypes::FT_SIZE_HUGER:
return "size_huger"; return "size_huger";
case xml::FontTypes::FT_SIZE_INCREASE: case xml::FontTypes::FT_SIZE_INCREASE:
return "size_increase"; return "size_increase";
case xml::FontTypes::FT_SIZE_DECREASE: case xml::FontTypes::FT_SIZE_DECREASE:
return "size_decrease"; return "size_decrease";
default: default:
return ""; return "";
} }
} }
string fontToAttribute(xml::FontTypes type) { string fontToAttribute(xml::FontTypes type) {
// If there is a role (i.e. nonstandard use of a tag), output the attribute. Otherwise, the sheer tag is sufficient // If there is a role (i.e. nonstandard use of a tag), output the attribute. Otherwise, the sheer tag is sufficient
// for the font. // for the font.
string role = fontToRole(type); string role = fontToRole(type);
if (!role.empty()) { if (!role.empty()) {
return "role='" + role + "'"; return "role='" + role + "'";
} else { } else {
return ""; return "";
} }
} }
} // end anonymous namespace } // end anonymous namespace
@ -170,13 +172,13 @@ string fontToAttribute(xml::FontTypes type) {
xml::FontTag docbookStartFontTag(xml::FontTypes type) xml::FontTag docbookStartFontTag(xml::FontTypes type)
{ {
return xml::FontTag(from_utf8(fontToDocBookTag(type)), from_utf8(fontToAttribute(type)), type); return xml::FontTag(from_utf8(fontToDocBookTag(type)), from_utf8(fontToAttribute(type)), type);
} }
xml::EndFontTag docbookEndFontTag(xml::FontTypes type) xml::EndFontTag docbookEndFontTag(xml::FontTypes type)
{ {
return xml::EndFontTag(from_utf8(fontToDocBookTag(type)), type); return xml::EndFontTag(from_utf8(fontToDocBookTag(type)), type);
} }
@ -184,63 +186,68 @@ namespace {
// convenience functions // convenience functions
void openParTag(XMLStream &xs, Layout const &lay) { void openParTag(XMLStream &xs, Layout const &lay)
if (lay.docbookwrappertag() != "NONE") { {
xs << xml::StartTag(lay.docbookwrappertag(), lay.docbookwrapperattr()); if (lay.docbookwrappertag() != "NONE") {
} xs << xml::StartTag(lay.docbookwrappertag(), lay.docbookwrapperattr());
}
string tag = lay.docbooktag(); string tag = lay.docbooktag();
if (tag == "Plain Layout") if (tag == "Plain Layout")
tag = "para"; tag = "para";
xs << xml::ParTag(tag, lay.docbookattr()); xs << xml::ParTag(tag, lay.docbookattr());
} }
void closeTag(XMLStream &xs, Layout const &lay) { void closeTag(XMLStream &xs, Layout const &lay)
string tag = lay.docbooktag(); {
if (tag == "Plain Layout") string tag = lay.docbooktag();
tag = "para"; if (tag == "Plain Layout")
tag = "para";
xs << xml::EndTag(tag); xs << xml::EndTag(tag);
if (lay.docbookwrappertag() != "NONE") if (lay.docbookwrappertag() != "NONE")
xs << xml::EndTag(lay.docbookwrappertag()); xs << xml::EndTag(lay.docbookwrappertag());
} }
void openLabelTag(XMLStream & xs, Layout const & lay) // Mostly for definition lists. void openLabelTag(XMLStream & xs, Layout const & lay) // Mostly for definition lists.
{ {
xs << xml::StartTag(lay.docbookitemlabeltag(), lay.docbookitemlabelattr()); xs << xml::StartTag(lay.docbookitemlabeltag(), lay.docbookitemlabelattr());
} }
void closeLabelTag(XMLStream & xs, Layout const & lay) void closeLabelTag(XMLStream & xs, Layout const & lay)
{ {
xs << xml::EndTag(lay.docbookitemlabeltag()); xs << xml::EndTag(lay.docbookitemlabeltag());
xs << xml::CR(); xs << xml::CR();
} }
void openItemTag(XMLStream &xs, Layout const &lay) { void openItemTag(XMLStream &xs, Layout const &lay)
{
xs << xml::StartTag(lay.docbookitemtag(), lay.docbookitemattr()); xs << xml::StartTag(lay.docbookitemtag(), lay.docbookitemattr());
} }
// Return true when new elements are output in a paragraph, false otherwise. // Return true when new elements are output in a paragraph, false otherwise.
bool openInnerItemTag(XMLStream &xs, Layout const &lay) { bool openInnerItemTag(XMLStream &xs, Layout const &lay)
if (lay.docbookiteminnertag() != "NONE") { {
xs << xml::CR(); if (lay.docbookiteminnertag() != "NONE") {
xs << xml::ParTag(lay.docbookiteminnertag(), lay.docbookiteminnerattr()); xs << xml::CR();
xs << xml::ParTag(lay.docbookiteminnertag(), lay.docbookiteminnerattr());
if (lay.docbookiteminnertag() == "para") { if (lay.docbookiteminnertag() == "para") {
return true; return true;
} }
} }
return false; return false;
} }
void closeInnerItemTag(XMLStream &xs, Layout const &lay) { void closeInnerItemTag(XMLStream &xs, Layout const &lay)
{
if (lay.docbookiteminnertag()!= "NONE") { if (lay.docbookiteminnertag()!= "NONE") {
xs << xml::EndTag(lay.docbookiteminnertag()); xs << xml::EndTag(lay.docbookiteminnertag());
xs << xml::CR(); xs << xml::CR();
@ -248,164 +255,171 @@ void closeInnerItemTag(XMLStream &xs, Layout const &lay) {
} }
inline void closeItemTag(XMLStream &xs, Layout const &lay) { inline void closeItemTag(XMLStream &xs, Layout const &lay)
xs << xml::EndTag(lay.docbookitemtag()) << xml::CR(); {
xs << xml::EndTag(lay.docbookitemtag()) << xml::CR();
} }
// end of convenience functions // end of convenience functions
ParagraphList::const_iterator findLastParagraph( ParagraphList::const_iterator findLastParagraph(
ParagraphList::const_iterator p, ParagraphList::const_iterator p,
ParagraphList::const_iterator const &pend) { ParagraphList::const_iterator const & pend) {
for (++p; p != pend && p->layout().latextype == LATEX_PARAGRAPH; ++p); for (++p; p != pend && p->layout().latextype == LATEX_PARAGRAPH; ++p);
return p; return p;
} }
ParagraphList::const_iterator findEndOfEnvironment( ParagraphList::const_iterator findEndOfEnvironment(
ParagraphList::const_iterator const &pstart, ParagraphList::const_iterator const & pstart,
ParagraphList::const_iterator const &pend) { ParagraphList::const_iterator const & pend)
ParagraphList::const_iterator p = pstart; {
Layout const &bstyle = p->layout(); ParagraphList::const_iterator p = pstart;
size_t const depth = p->params().depth(); Layout const &bstyle = p->layout();
for (++p; p != pend; ++p) { size_t const depth = p->params().depth();
Layout const &style = p->layout(); for (++p; p != pend; ++p) {
// It shouldn't happen that e.g. a section command occurs inside Layout const &style = p->layout();
// a quotation environment, at a higher depth, but as of 6/2009, // It shouldn't happen that e.g. a section command occurs inside
// it can happen. We pretend that it's just at lowest depth. // a quotation environment, at a higher depth, but as of 6/2009,
if (style.latextype == LATEX_COMMAND) // it can happen. We pretend that it's just at lowest depth.
return p; if (style.latextype == LATEX_COMMAND)
return p;
// If depth is down, we're done // If depth is down, we're done
if (p->params().depth() < depth) if (p->params().depth() < depth)
return p; return p;
// If depth is up, we're not done // If depth is up, we're not done
if (p->params().depth() > depth) if (p->params().depth() > depth)
continue; continue;
// FIXME I am not sure about the first check. // FIXME I am not sure about the first check.
// Surely we *could* have different layouts that count as // Surely we *could* have different layouts that count as
// LATEX_PARAGRAPH, right? // LATEX_PARAGRAPH, right?
if (style.latextype == LATEX_PARAGRAPH || style != bstyle) if (style.latextype == LATEX_PARAGRAPH || style != bstyle)
return p; return p;
} }
return pend; return pend;
} }
ParagraphList::const_iterator makeParagraphs(Buffer const &buf, ParagraphList::const_iterator makeParagraphs(
XMLStream &xs, Buffer const &buf,
OutputParams const &runparams, XMLStream &xs,
Text const &text, OutputParams const &runparams,
ParagraphList::const_iterator const &pbegin, Text const &text,
ParagraphList::const_iterator const &pend) { ParagraphList::const_iterator const & pbegin,
ParagraphList::const_iterator const begin = text.paragraphs().begin(); ParagraphList::const_iterator const & pend)
ParagraphList::const_iterator par = pbegin; {
for (; par != pend; ++par) { ParagraphList::const_iterator const begin = text.paragraphs().begin();
Layout const &lay = par->layout(); ParagraphList::const_iterator par = pbegin;
if (!lay.counter.empty()) for (; par != pend; ++par) {
buf.masterBuffer()->params(). Layout const &lay = par->layout();
documentClass().counters().step(lay.counter, OutputUpdate); if (!lay.counter.empty())
buf.masterBuffer()->params().
documentClass().counters().step(lay.counter, OutputUpdate);
// We want to open the paragraph tag if: // We want to open the paragraph tag if:
// (i) the current layout permits multiple paragraphs // (i) the current layout permits multiple paragraphs
// (ii) we are either not already inside a paragraph (HTMLIsBlock) OR // (ii) we are either not already inside a paragraph (HTMLIsBlock) OR
// we are, but this is not the first paragraph // we are, but this is not the first paragraph
// //
// But there is also a special case, and we first see whether we are in it. // But there is also a special case, and we first see whether we are in it.
// We do not want to open the paragraph tag if this paragraph contains // We do not want to open the paragraph tag if this paragraph contains
// only one item, and that item is "inline", i.e., not HTMLIsBlock (such // only one item, and that item is "inline", i.e., not HTMLIsBlock (such
// as a branch). On the other hand, if that single item has a font change // as a branch). On the other hand, if that single item has a font change
// applied to it, then we still do need to open the paragraph. // applied to it, then we still do need to open the paragraph.
// //
// Obviously, this is very fragile. The main reason we need to do this is // Obviously, this is very fragile. The main reason we need to do this is
// because of branches, e.g., a branch that contains an entire new section. // because of branches, e.g., a branch that contains an entire new section.
// We do not really want to wrap that whole thing in a <div>...</div>. // We do not really want to wrap that whole thing in a <div>...</div>.
bool special_case = false; bool special_case = false;
Inset const *specinset = par->size() == 1 ? par->getInset(0) : 0; Inset const *specinset = par->size() == 1 ? par->getInset(0) : 0;
if (specinset && !specinset->getLayout().htmlisblock()) { // TODO: Convert htmlisblock to a DocBook parameter? if (specinset && !specinset->getLayout().htmlisblock()) { // TODO: Convert htmlisblock to a DocBook parameter?
Layout const &style = par->layout(); Layout const &style = par->layout();
FontInfo const first_font = style.labeltype == LABEL_MANUAL ? FontInfo const first_font = style.labeltype == LABEL_MANUAL ?
style.labelfont : style.font; style.labelfont : style.font;
FontInfo const our_font = FontInfo const our_font =
par->getFont(buf.masterBuffer()->params(), 0, par->getFont(buf.masterBuffer()->params(), 0,
text.outerFont(distance(begin, par))).fontInfo(); text.outerFont(distance(begin, par))).fontInfo();
if (first_font == our_font) if (first_font == our_font)
special_case = true; special_case = true;
} }
// Plain layouts must be ignored. // Plain layouts must be ignored.
if (!special_case && buf.params().documentClass().isPlainLayout(lay) && !runparams.docbook_force_pars) if (!special_case && buf.params().documentClass().isPlainLayout(lay) && !runparams.docbook_force_pars)
special_case = true; special_case = true;
// TODO: Could get rid of this with a DocBook equivalent to htmlisblock? // TODO: Could get rid of this with a DocBook equivalent to htmlisblock?
if (!special_case && par->size() == 1 && par->getInset(0)) { if (!special_case && par->size() == 1 && par->getInset(0)) {
Inset const * firstInset = par->getInset(0); Inset const * firstInset = par->getInset(0);
// Floats cannot be in paragraphs. // Floats cannot be in paragraphs.
special_case = to_ascii(firstInset->layoutName()).substr(0, 6) == "Float:"; special_case = to_ascii(firstInset->layoutName()).substr(0, 6) == "Float:";
// Bibliographies cannot be in paragraphs. // Bibliographies cannot be in paragraphs.
if (!special_case && firstInset->asInsetCommand()) if (!special_case && firstInset->asInsetCommand())
special_case = firstInset->asInsetCommand()->params().getCmdName() == "bibtex"; special_case = firstInset->asInsetCommand()->params().getCmdName() == "bibtex";
// Equations do not deserve their own paragraph (DocBook allows them outside paragraphs). // Equations do not deserve their own paragraph (DocBook allows them outside paragraphs).
if (!special_case && firstInset->asInsetMath()) if (!special_case && firstInset->asInsetMath())
special_case = true; special_case = true;
// ERTs are in comments, not paragraphs. // ERTs are in comments, not paragraphs.
if (!special_case && firstInset->lyxCode() == lyx::ERT_CODE) if (!special_case && firstInset->lyxCode() == lyx::ERT_CODE)
special_case = true; special_case = true;
// Listings should not get into their own paragraph. // Listings should not get into their own paragraph.
if (!special_case && firstInset->lyxCode() == lyx::LISTINGS_CODE) if (!special_case && firstInset->lyxCode() == lyx::LISTINGS_CODE)
special_case = true; special_case = true;
} }
bool const open_par = runparams.docbook_make_pars bool const open_par = runparams.docbook_make_pars
&& (!runparams.docbook_in_par || par != pbegin) && (!runparams.docbook_in_par || par != pbegin)
&& !special_case; && !special_case;
// We want to issue the closing tag if either: // We want to issue the closing tag if either:
// (i) We opened it, and either docbook_in_par is false, // (i) We opened it, and either docbook_in_par is false,
// or we're not in the last paragraph, anyway. // or we're not in the last paragraph, anyway.
// (ii) We didn't open it and docbook_in_par is true, // (ii) We didn't open it and docbook_in_par is true,
// but we are in the first par, and there is a next par. // but we are in the first par, and there is a next par.
ParagraphList::const_iterator nextpar = par; ParagraphList::const_iterator nextpar = par;
++nextpar; ++nextpar;
bool const close_par = bool const close_par =
((open_par && (!runparams.docbook_in_par || nextpar != pend)) ((open_par && (!runparams.docbook_in_par || nextpar != pend))
|| (!open_par && runparams.docbook_in_par && par == pbegin && nextpar != pend)); || (!open_par && runparams.docbook_in_par && par == pbegin && nextpar != pend));
if (open_par) { if (open_par) {
openParTag(xs, lay); openParTag(xs, lay);
} }
par->simpleDocBookOnePar(buf, xs, runparams, text.outerFont(distance(begin, par)), open_par, close_par, 0); par->simpleDocBookOnePar(buf, xs, runparams, text.outerFont(distance(begin, par)), open_par, close_par, 0);
if (close_par) { if (close_par) {
closeTag(xs, lay); closeTag(xs, lay);
xs << xml::CR(); xs << xml::CR();
} }
} }
return pend; return pend;
} }
bool isNormalEnv(Layout const &lay) { bool isNormalEnv(Layout const &lay)
return lay.latextype == LATEX_ENVIRONMENT {
|| lay.latextype == LATEX_BIB_ENVIRONMENT; return lay.latextype == LATEX_ENVIRONMENT
|| lay.latextype == LATEX_BIB_ENVIRONMENT;
} }
ParagraphList::const_iterator makeEnvironment(Buffer const &buf, ParagraphList::const_iterator makeEnvironment(
XMLStream &xs, Buffer const &buf,
OutputParams const &runparams, XMLStream &xs,
Text const &text, OutputParams const &runparams,
ParagraphList::const_iterator const &pbegin, Text const &text,
ParagraphList::const_iterator const &pend) { ParagraphList::const_iterator const & pbegin,
ParagraphList::const_iterator const & pend)
{
ParagraphList::const_iterator const begin = text.paragraphs().begin(); ParagraphList::const_iterator const begin = text.paragraphs().begin();
ParagraphList::const_iterator par = pbegin; ParagraphList::const_iterator par = pbegin;
Layout const &bstyle = par->layout(); Layout const &bstyle = par->layout();
@ -429,10 +443,10 @@ ParagraphList::const_iterator makeEnvironment(Buffer const &buf,
Counters & cnts = buf.masterBuffer()->params().documentClass().counters(); Counters & cnts = buf.masterBuffer()->params().documentClass().counters();
docstring const & cntr = style.counter; docstring const & cntr = style.counter;
if (!style.counter.empty() if (!style.counter.empty()
&& (par == pbegin || !isNormalEnv(style)) && (par == pbegin || !isNormalEnv(style))
&& cnts.hasCounter(cntr) && cnts.hasCounter(cntr)
) )
cnts.step(cntr, OutputUpdate); cnts.step(cntr, OutputUpdate);
ParagraphList::const_iterator send; ParagraphList::const_iterator send;
// Actual content of this paragraph. // Actual content of this paragraph.
@ -553,35 +567,39 @@ ParagraphList::const_iterator makeEnvironment(Buffer const &buf,
} }
void makeCommand(Buffer const &buf, void makeCommand(
XMLStream &xs, Buffer const & buf,
OutputParams const &runparams, XMLStream & xs,
Text const &text, OutputParams const & runparams,
ParagraphList::const_iterator const &pbegin) { Text const & text,
Layout const &style = pbegin->layout(); ParagraphList::const_iterator const & pbegin)
if (!style.counter.empty()) {
buf.masterBuffer()->params(). Layout const &style = pbegin->layout();
documentClass().counters().step(style.counter, OutputUpdate); if (!style.counter.empty())
buf.masterBuffer()->params().
documentClass().counters().step(style.counter, OutputUpdate);
// No need for labels, as they are handled by DocBook tags. // No need for labels, as they are handled by DocBook tags.
openParTag(xs, style); openParTag(xs, style);
ParagraphList::const_iterator const begin = text.paragraphs().begin(); ParagraphList::const_iterator const begin = text.paragraphs().begin();
pbegin->simpleDocBookOnePar(buf, xs, runparams, pbegin->simpleDocBookOnePar(buf, xs, runparams,
text.outerFont(distance(begin, pbegin))); text.outerFont(distance(begin, pbegin)));
closeTag(xs, style); closeTag(xs, style);
xs << xml::CR(); xs << xml::CR();
} }
pair<ParagraphList::const_iterator, ParagraphList::const_iterator> makeAny(Text const &text, pair<ParagraphList::const_iterator, ParagraphList::const_iterator> makeAny(
Buffer const &buf, Text const &text,
XMLStream &xs, Buffer const &buf,
OutputParams const &ourparams, XMLStream &xs,
ParagraphList::const_iterator par, OutputParams const &ourparams,
ParagraphList::const_iterator send, ParagraphList::const_iterator par,
ParagraphList::const_iterator pend) { ParagraphList::const_iterator send,
Layout const &style = par->layout(); ParagraphList::const_iterator pend)
{
Layout const & style = par->layout();
switch (style.latextype) { switch (style.latextype) {
case LATEX_COMMAND: { case LATEX_COMMAND: {
@ -696,13 +714,15 @@ bool hasAbstractBetween(ParagraphList const &paragraphs, pit_type const bpitAbst
} }
pit_type generateDocBookParagraphWithoutSectioning(Text const &text, pit_type generateDocBookParagraphWithoutSectioning(
Buffer const &buf, Text const & text,
XMLStream &xs, Buffer const & buf,
OutputParams const &runparams, XMLStream & xs,
ParagraphList const &paragraphs, OutputParams const & runparams,
pit_type bpit, ParagraphList const & paragraphs,
pit_type epit) { pit_type bpit,
pit_type epit)
{
auto par = paragraphs.iterator_at(bpit); auto par = paragraphs.iterator_at(bpit);
auto lastStartedPar = par; auto lastStartedPar = par;
ParagraphList::const_iterator send; ParagraphList::const_iterator send;
@ -719,14 +739,16 @@ pit_type generateDocBookParagraphWithoutSectioning(Text const &text,
} }
void outputDocBookInfo(Text const &text, void outputDocBookInfo(
Buffer const &buf, Text const & text,
XMLStream &xs, Buffer const & buf,
OutputParams const &runparams, XMLStream & xs,
ParagraphList const &paragraphs, OutputParams const & runparams,
DocBookInfoTag const &info, ParagraphList const & paragraphs,
pit_type bpitAbstract, DocBookInfoTag const & info,
pit_type const epitAbstract) { pit_type bpitAbstract,
pit_type const epitAbstract)
{
// Consider everything between bpitAbstract and epitAbstract (excluded) as paragraphs for the abstract. // Consider everything between bpitAbstract and epitAbstract (excluded) as paragraphs for the abstract.
// Use bpitAbstract >= epitAbstract to indicate there is no abstract. // Use bpitAbstract >= epitAbstract to indicate there is no abstract.
@ -773,11 +795,13 @@ void outputDocBookInfo(Text const &text,
} }
void docbookFirstParagraphs(Text const &text, void docbookFirstParagraphs(
Buffer const &buf, Text const &text,
XMLStream &xs, Buffer const &buf,
OutputParams const &runparams, XMLStream &xs,
pit_type epit) { OutputParams const &runparams,
pit_type epit)
{
// Handle the beginning of the document, supposing it has sections. // Handle the beginning of the document, supposing it has sections.
// Major role: output the first <info> tag. // Major role: output the first <info> tag.
@ -793,15 +817,17 @@ bool isParagraphEmpty(const Paragraph &par)
InsetList const &insets = par.insetList(); InsetList const &insets = par.insetList();
size_t insetsLength = distance(insets.begin(), insets.end()); size_t insetsLength = distance(insets.begin(), insets.end());
bool hasParagraphOnlyNote = insetsLength == 1 && insets.get(0) && insets.get(0)->asInsetCollapsible() && bool hasParagraphOnlyNote = insetsLength == 1 && insets.get(0) && insets.get(0)->asInsetCollapsible() &&
dynamic_cast<InsetNote *>(insets.get(0)); dynamic_cast<InsetNote *>(insets.get(0));
return hasParagraphOnlyNote; return hasParagraphOnlyNote;
} }
void docbookSimpleAllParagraphs(Text const &text, void docbookSimpleAllParagraphs(
Buffer const &buf, Text const & text,
XMLStream &xs, Buffer const & buf,
OutputParams const &runparams) { XMLStream & xs,
OutputParams const & runparams)
{
// Handle the document, supposing it has no sections (i.e. a "simple" document). // Handle the document, supposing it has no sections (i.e. a "simple" document).
// First, the <info> tag. // First, the <info> tag.
@ -836,25 +862,25 @@ void docbookSimpleAllParagraphs(Text const &text,
void docbookParagraphs(Text const &text, void docbookParagraphs(Text const &text,
Buffer const &buf, Buffer const &buf,
XMLStream &xs, XMLStream &xs,
OutputParams const &runparams) { OutputParams const &runparams) {
ParagraphList const &paragraphs = text.paragraphs(); ParagraphList const &paragraphs = text.paragraphs();
if (runparams.par_begin == runparams.par_end) { if (runparams.par_begin == runparams.par_end) {
runparams.par_begin = 0; runparams.par_begin = 0;
runparams.par_end = paragraphs.size(); runparams.par_end = paragraphs.size();
} }
pit_type bpit = runparams.par_begin; pit_type bpit = runparams.par_begin;
pit_type const epit = runparams.par_end; pit_type const epit = runparams.par_end;
LASSERT(bpit < epit, LASSERT(bpit < epit,
{ {
xs << XMLStream::ESCAPE_NONE << "<!-- DocBook output error! -->\n"; xs << XMLStream::ESCAPE_NONE << "<!-- DocBook output error! -->\n";
return; return;
}); });
ParagraphList::const_iterator const pend = ParagraphList::const_iterator const pend =
(epit == (int) paragraphs.size()) ? (epit == (int) paragraphs.size()) ?
paragraphs.end() : paragraphs.iterator_at(epit); paragraphs.end() : paragraphs.iterator_at(epit);
std::stack<std::pair<int, string>> headerLevels; // Used to determine when to open/close sections: store the depth std::stack<std::pair<int, string>> headerLevels; // Used to determine when to open/close sections: store the depth
// of the section and the tag that was used to open it. // of the section and the tag that was used to open it.
@ -893,13 +919,13 @@ void docbookParagraphs(Text const &text,
// Think about adding <section> and/or </section>s. // Think about adding <section> and/or </section>s.
const bool isLayoutSectioning = style.category() == from_utf8("Sectioning"); const bool isLayoutSectioning = style.category() == from_utf8("Sectioning");
if (isLayoutSectioning) { if (isLayoutSectioning) {
int level = style.toclevel; int level = style.toclevel;
// Need to close a previous section if it has the same level or a higher one (close <section> if opening a <h2> // Need to close a previous section if it has the same level or a higher one (close <section> if opening a <h2>
// after a <h2>, <h3>, <h4>, <h5> or <h6>). More examples: // after a <h2>, <h3>, <h4>, <h5> or <h6>). More examples:
// - current: h2; back: h1; do not close any <section> // - current: h2; back: h1; do not close any <section>
// - current: h1; back: h2; close two <section> (first the <h2>, then the <h1>, so a new <h1> can come) // - current: h1; back: h2; close two <section> (first the <h2>, then the <h1>, so a new <h1> can come)
while (!headerLevels.empty() && level <= headerLevels.top().first) { while (!headerLevels.empty() && level <= headerLevels.top().first) {
int stackLevel = headerLevels.top().first; int stackLevel = headerLevels.top().first;
docstring stackTag = from_utf8("</" + headerLevels.top().second + ">"); docstring stackTag = from_utf8("</" + headerLevels.top().second + ">");
headerLevels.pop(); headerLevels.pop();
@ -907,15 +933,15 @@ void docbookParagraphs(Text const &text,
// Output the tag only if it corresponds to a legit section. // Output the tag only if it corresponds to a legit section.
if (stackLevel != Layout::NOT_IN_TOC) if (stackLevel != Layout::NOT_IN_TOC)
xs << XMLStream::ESCAPE_NONE << stackTag << xml::CR(); xs << XMLStream::ESCAPE_NONE << stackTag << xml::CR();
} }
// Open the new section: first push it onto the stack, then output it in DocBook. // Open the new section: first push it onto the stack, then output it in DocBook.
string sectionTag = (currentlyInAppendix && style.docbooksectiontag() == "chapter") ? string sectionTag = (currentlyInAppendix && style.docbooksectiontag() == "chapter") ?
"appendix" : style.docbooksectiontag(); "appendix" : style.docbooksectiontag();
headerLevels.push(std::make_pair(level, sectionTag)); headerLevels.push(std::make_pair(level, sectionTag));
// Some sectioning-like elements should not be output (such as FrontMatter). // Some sectioning-like elements should not be output (such as FrontMatter).
if (level != Layout::NOT_IN_TOC) { if (level != Layout::NOT_IN_TOC) {
// Look for a label in the title, i.e. a InsetLabel as a child. // Look for a label in the title, i.e. a InsetLabel as a child.
docstring id = docstring(); docstring id = docstring();
for (pos_type i = 0; i < par->size(); ++i) { for (pos_type i = 0; i < par->size(); ++i) {
@ -940,7 +966,7 @@ void docbookParagraphs(Text const &text,
tag += from_utf8(">"); tag += from_utf8(">");
xs << XMLStream::ESCAPE_NONE << tag; xs << XMLStream::ESCAPE_NONE << tag;
xs << xml::CR(); xs << xml::CR();
} }
} }
// Close all sections before the bibliography. // Close all sections before the bibliography.

430
src/xml.h
View File

@ -38,93 +38,93 @@ struct CR;
class XMLStream { class XMLStream {
public: public:
/// ///
explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {} explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {}
/// ///
odocstream & os() { return os_; } odocstream & os() { return os_; }
/// ///
// int & tab() { return tab_; } // int & tab() { return tab_; }
/// closes any font tags that are eligible to be closed, /// closes any font tags that are eligible to be closed,
/// i.e., last on the tag_stack_. /// i.e., last on the tag_stack_.
/// \return false if there are open font tags we could not close. /// \return false if there are open font tags we could not close.
/// because they are "blocked" by open non-font tags on the stack. /// because they are "blocked" by open non-font tags on the stack.
bool closeFontTags(); bool closeFontTags();
/// sets a mark so we know what tags to close at the end. /// sets a mark so we know what tags to close at the end.
/// normally called at the start of a paragraph. /// normally called at the start of a paragraph.
void startDivision(bool keep_empty); void startDivision(bool keep_empty);
/// clears the mark set by previous method. /// clears the mark set by previous method.
/// there should not be any other tags open before it on the stack, /// there should not be any other tags open before it on the stack,
/// but if there are, we will close them. /// but if there are, we will close them.
void endDivision(); void endDivision();
/// ///
XMLStream & operator<<(docstring const &); XMLStream & operator<<(docstring const &);
/// ///
XMLStream & operator<<(const char *); XMLStream & operator<<(const char *);
/// ///
XMLStream & operator<<(char_type); XMLStream & operator<<(char_type);
/// ///
XMLStream & operator<<(int); XMLStream & operator<<(int);
/// ///
XMLStream & operator<<(char); XMLStream & operator<<(char);
/// ///
XMLStream & operator<<(xml::StartTag const &); XMLStream & operator<<(xml::StartTag const &);
/// ///
XMLStream & operator<<(xml::EndTag const &); XMLStream & operator<<(xml::EndTag const &);
/// ///
XMLStream & operator<<(xml::CompTag const &); XMLStream & operator<<(xml::CompTag const &);
/// ///
XMLStream & operator<<(xml::ParTag const &); XMLStream & operator<<(xml::ParTag const &);
/// ///
XMLStream & operator<<(xml::FontTag const &); XMLStream & operator<<(xml::FontTag const &);
/// ///
XMLStream & operator<<(xml::CR const &); XMLStream & operator<<(xml::CR const &);
/// ///
enum EscapeSettings { enum EscapeSettings {
ESCAPE_NONE, ESCAPE_NONE,
ESCAPE_AND, // meaning & ESCAPE_AND, // meaning &
ESCAPE_ALL // meaning <, >, &, at present ESCAPE_ALL // meaning <, >, &, at present
}; };
/// Sets what we are going to escape on the NEXT write. /// Sets what we are going to escape on the NEXT write.
/// Everything is reset for the next time. /// Everything is reset for the next time.
XMLStream & operator<<(EscapeSettings); XMLStream & operator<<(EscapeSettings);
/// This routine is for debugging the tag stack, etc. Code /// This routine is for debugging the tag stack, etc. Code
/// for it is disabled by default, however, so you will need /// for it is disabled by default, however, so you will need
/// to enable it if you want to use it. /// to enable it if you want to use it.
void dumpTagStack(std::string const & msg); void dumpTagStack(std::string const & msg);
/// ///
bool isTagOpen(xml::StartTag const &, int maxdepth = -1) const; bool isTagOpen(xml::StartTag const &, int maxdepth = -1) const;
/// ///
bool isTagOpen(xml::EndTag const &, int maxdepth = -1) const; bool isTagOpen(xml::EndTag const &, int maxdepth = -1) const;
/// ///
bool isTagPending(xml::StartTag const &, int maxdepth = -1) const; bool isTagPending(xml::StartTag const &, int maxdepth = -1) const;
private: private:
/// ///
void clearTagDeque(); void clearTagDeque();
/// ///
void writeError(std::string const &) const; void writeError(std::string const &) const;
/// ///
void writeError(docstring const &) const; void writeError(docstring const &) const;
/// ///
odocstream & os_; odocstream & os_;
/// ///
EscapeSettings escape_; EscapeSettings escape_;
// What we would really like to do here is simply use a // What we would really like to do here is simply use a
// deque<StartTag>. But we want to store both StartTags and // deque<StartTag>. But we want to store both StartTags and
// sub-classes thereof on this stack, which means we run into the // sub-classes thereof on this stack, which means we run into the
// so-called polymorphic class problem with the STL. We therefore have // so-called polymorphic class problem with the STL. We therefore have
// to use a deque<StartTag *>, which leads to the question who will // to use a deque<StartTag *>, which leads to the question who will
// own these pointers and how they will be deleted, so we use shared // own these pointers and how they will be deleted, so we use shared
// pointers. // pointers.
/// ///
typedef std::shared_ptr<xml::StartTag> TagPtr; typedef std::shared_ptr<xml::StartTag> TagPtr;
typedef std::deque<TagPtr> TagDeque; typedef std::deque<TagPtr> TagDeque;
/// ///
template <typename T> template <typename T>
TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); } TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); }
/// ///
TagDeque pending_tags_; TagDeque pending_tags_;
/// ///
TagDeque tag_stack_; TagDeque tag_stack_;
}; };
namespace xml { namespace xml {
@ -160,69 +160,69 @@ struct EndFontTag;
/// be escaped before being passed to the constructor. /// be escaped before being passed to the constructor.
struct StartTag struct StartTag
{ {
/// ///
explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {} explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {}
/// ///
explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {} explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {}
/// ///
explicit StartTag(docstring const & tag, docstring const & attr, explicit StartTag(docstring const & tag, docstring const & attr,
bool keepempty = false) bool keepempty = false)
: tag_(tag), attr_(attr), keepempty_(keepempty) {} : tag_(tag), attr_(attr), keepempty_(keepempty) {}
/// ///
explicit StartTag(std::string const & tag, std::string const & attr, explicit StartTag(std::string const & tag, std::string const & attr,
bool keepempty = false) bool keepempty = false)
: tag_(from_ascii(tag)), attr_(from_ascii(attr)), keepempty_(keepempty) {} : tag_(from_ascii(tag)), attr_(from_ascii(attr)), keepempty_(keepempty) {}
/// ///
explicit StartTag(std::string const & tag, docstring const & attr, explicit StartTag(std::string const & tag, docstring const & attr,
bool keepempty = false) bool keepempty = false)
: tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {} : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {}
/// ///
virtual ~StartTag() {} virtual ~StartTag() {}
/// <tag_ attr_> /// <tag_ attr_>
virtual docstring writeTag() const; virtual docstring writeTag() const;
/// </tag_> /// </tag_>
virtual docstring writeEndTag() const; virtual docstring writeEndTag() const;
/// ///
virtual FontTag const * asFontTag() const { return nullptr; } virtual FontTag const * asFontTag() const { return nullptr; }
/// ///
virtual bool operator==(StartTag const & rhs) const virtual bool operator==(StartTag const & rhs) const
{ return tag_ == rhs.tag_; } { return tag_ == rhs.tag_; }
/// ///
virtual bool operator!=(StartTag const & rhs) const virtual bool operator!=(StartTag const & rhs) const
{ return !(*this == rhs); } { return !(*this == rhs); }
/// ///
virtual bool operator==(FontTag const & rhs) const; virtual bool operator==(FontTag const & rhs) const;
/// ///
docstring tag_; docstring tag_;
/// ///
docstring attr_; docstring attr_;
/// whether to keep things like "<tag></tag>" or discard them /// whether to keep things like "<tag></tag>" or discard them
/// you would want this for td, e.g, but maybe not for a div /// you would want this for td, e.g, but maybe not for a div
bool keepempty_; bool keepempty_;
}; };
/// ///
struct EndTag struct EndTag
{ {
/// ///
explicit EndTag(std::string tag) : tag_(from_ascii(tag)) {} explicit EndTag(std::string tag) : tag_(from_ascii(tag)) {}
/// ///
explicit EndTag(docstring tag) : tag_(tag) {} explicit EndTag(docstring tag) : tag_(tag) {}
/// ///
virtual ~EndTag() {} virtual ~EndTag() {}
/// </tag_> /// </tag_>
virtual docstring writeEndTag() const; virtual docstring writeEndTag() const;
/// ///
bool operator==(StartTag const & rhs) const bool operator==(StartTag const & rhs) const
{ return tag_ == rhs.tag_; } { return tag_ == rhs.tag_; }
/// ///
bool operator!=(StartTag const & rhs) const bool operator!=(StartTag const & rhs) const
{ return !(*this == rhs); } { return !(*this == rhs); }
/// ///
virtual EndFontTag const * asFontTag() const { return 0; } virtual EndFontTag const * asFontTag() const { return 0; }
/// ///
docstring tag_; docstring tag_;
}; };
@ -231,18 +231,18 @@ struct EndTag
/// be escaped before being passed to the constructor. /// be escaped before being passed to the constructor.
struct CompTag struct CompTag
{ {
/// ///
explicit CompTag(std::string const & tag) explicit CompTag(std::string const & tag)
: tag_(tag) {} : tag_(tag) {}
/// ///
explicit CompTag(std::string const & tag, std::string const & attr) explicit CompTag(std::string const & tag, std::string const & attr)
: tag_(tag), attr_(attr) {} : tag_(tag), attr_(attr) {}
/// <tag_ attr_ /> /// <tag_ attr_ />
docstring writeTag() const; docstring writeTag() const;
/// ///
std::string tag_; std::string tag_;
/// ///
std::string attr_; std::string attr_;
}; };
@ -250,84 +250,84 @@ struct CompTag
/// parid is only used for HTML output; XML is supposed to use attr for this. /// parid is only used for HTML output; XML is supposed to use attr for this.
struct ParTag : public StartTag struct ParTag : public StartTag
{ {
/// ///
explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {} explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {}
/// ///
~ParTag() {} ~ParTag() {}
}; };
/// ///
enum FontTypes { enum FontTypes {
// ranges // ranges
FT_EMPH, FT_EMPH,
FT_NOUN, FT_NOUN,
FT_UBAR, FT_UBAR,
FT_DBAR, FT_DBAR,
FT_WAVE, FT_WAVE,
FT_SOUT, FT_SOUT,
FT_XOUT, FT_XOUT,
// bold // bold
FT_BOLD, FT_BOLD,
// shapes // shapes
FT_UPRIGHT, FT_UPRIGHT,
FT_ITALIC, FT_ITALIC,
FT_SLANTED, FT_SLANTED,
FT_SMALLCAPS, FT_SMALLCAPS,
// families // families
FT_ROMAN, FT_ROMAN,
FT_SANS, FT_SANS,
FT_TYPE, FT_TYPE,
// sizes // sizes
FT_SIZE_TINY, FT_SIZE_TINY,
FT_SIZE_SCRIPT, FT_SIZE_SCRIPT,
FT_SIZE_FOOTNOTE, FT_SIZE_FOOTNOTE,
FT_SIZE_SMALL, FT_SIZE_SMALL,
FT_SIZE_NORMAL, FT_SIZE_NORMAL,
FT_SIZE_LARGE, FT_SIZE_LARGE,
FT_SIZE_LARGER, FT_SIZE_LARGER,
FT_SIZE_LARGEST, FT_SIZE_LARGEST,
FT_SIZE_HUGE, FT_SIZE_HUGE,
FT_SIZE_HUGER, FT_SIZE_HUGER,
FT_SIZE_INCREASE, FT_SIZE_INCREASE,
FT_SIZE_DECREASE FT_SIZE_DECREASE
// When updating this list, also update fontToTag in both output_docbook.cpp and output_xhtml.cpp, // When updating this list, also update fontToTag in both output_docbook.cpp and output_xhtml.cpp,
// fontToRole in output_docbook.cpp, and fontToAttribute in output_xhtml.cpp. // fontToRole in output_docbook.cpp, and fontToAttribute in output_xhtml.cpp.
}; };
/// ///
struct FontTag : public StartTag struct FontTag : public StartTag
{ {
/// ///
FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {} FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {}
/// ///
FontTag(std::string const & tag, FontTypes type): StartTag(from_utf8(tag)), font_type_(type) {} FontTag(std::string const & tag, FontTypes type): StartTag(from_utf8(tag)), font_type_(type) {}
/// ///
FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {} FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {}
/// ///
FontTag(std::string const & tag, std::string const & attr, FontTypes type): StartTag(from_utf8(tag), from_utf8(attr)), font_type_(type) {} FontTag(std::string const & tag, std::string const & attr, FontTypes type): StartTag(from_utf8(tag), from_utf8(attr)), font_type_(type) {}
/// ///
FontTag const * asFontTag() const override { return this; } FontTag const * asFontTag() const override { return this; }
/// ///
bool operator==(StartTag const &) const override; bool operator==(StartTag const &) const override;
/// ///
FontTypes font_type_; FontTypes font_type_;
}; };
/// ///
struct EndFontTag : public EndTag struct EndFontTag : public EndTag
{ {
/// ///
EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {} EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {}
/// ///
EndFontTag(std::string const & tag, FontTypes type): EndTag(from_utf8(tag)), font_type_(type) {} EndFontTag(std::string const & tag, FontTypes type): EndTag(from_utf8(tag)), font_type_(type) {}
/// ///
EndFontTag const * asFontTag() const override { return this; } EndFontTag const * asFontTag() const override { return this; }
/// ///
FontTypes font_type_; FontTypes font_type_;
}; };