commit 875f7d42e2eb6b9b4cef3c29213b12f85f9756bb
Author: Thibaut Cuvelier <[email protected]>
Date:   Sun Aug 2 04:03:17 2020 +0200

    DocBook: avoid generating empty paragraphs instead of new pages.
    
    As this required to first generate the paragraph before outputting it if 
necessary, tests like XMLStream::isTagOpen no more worked properly. This also 
refactors table handling to get rid of that case (and make code easier to read).
---
 .../docbook/bibliography_precooked_aastex.xml      |    5 -
 src/OutputParams.cpp                               |    2 +-
 src/OutputParams.h                                 |    3 +
 src/insets/InsetFloat.cpp                          |  177 +++++++++++---------
 src/insets/InsetTabular.cpp                        |    6 +-
 src/output_docbook.cpp                             |   24 ++-
 6 files changed, 123 insertions(+), 94 deletions(-)

diff --git a/autotests/export/docbook/bibliography_precooked_aastex.xml 
b/autotests/export/docbook/bibliography_precooked_aastex.xml
index bc10168..89b1714 100644
--- a/autotests/export/docbook/bibliography_precooked_aastex.xml
+++ b/autotests/export/docbook/bibliography_precooked_aastex.xml
@@ -967,11 +967,8 @@ v(p,\lambda)_{\pm} &amp; = &amp; 
\pm\lambda(E\mp\lambda|{\textbf{p}}|)^{1/2}\chi
 <bibliomixed xml:id='pet76'>Peterson, C. J. 1976, <!-- \aj -->, 81, 617 
</bibliomixed>
 <bibliomixed xml:id='spi85'>Spitzer, L. 1985, Dynamics of Star Clusters, J. 
Goodman and P. Hut, Dordrecht: Reidel, 109 </bibliomixed>
 </bibliography>
-<para>
-</para>
 <table xml:id="tbl-2">
 <caption>Terribly relevant tabular information.</caption>
-
 <tbody>
 <tr>
 <td align='center' valign='top'>Star </td>
@@ -1209,8 +1206,6 @@ v(p,\lambda)_{\pm} &amp; = &amp; 
\pm\lambda(E\mp\lambda|{\textbf{p}}|)^{1/2}\chi
 <TableComments>We can also attach a long-ish paragraph of explanatory material 
to a table. Use \tablerefs to append a list of references. The following 
references were from a different table: I've patched them in here to show how 
they look, but don't take them too seriously—I certainly have 
not.</TableComments>
 <TableRefs>(1) Barbuy, Spite, &amp; Spite 1985; (2) Bond 1980; (3) Carbon et 
al. 1987; (4) Hobbs &amp; Duncan 1987; (5) Gilroy et al. 1988: (6) Gratton 
&amp; Ortolani 1986; (7) Gratton &amp; Sneden 1987; (8) Gratton &amp; Sneden 
(1988); (9) Gratton &amp; Sneden 1991; (10) Kraft et al. 1982; (11) LCL, or 
Laird, 1990; (12) Leep &amp; Wallerstein 1981; (13) Luck &amp; Bond 1981; (14) 
Luck &amp; Bond 1985; (15) Magain 1987; (16) Magain 1989; (17) Peterson 1981; 
(18) Peterson, Kurucz, &amp; Carney 1990; (19) RMB; (20) Schuster &amp; Nissen 
1988; (21) Schuster &amp; Nissen 1989b; (22) Spite et al. 1984; (23) Spite 
&amp; Spite 1986; (24) Hobbs &amp; Thorburn 1991; (25) Hobbs et al. 1991; (26) 
Olsen 1983.</TableRefs>
 </table>
-
-
 </section>
 
 </article>
\ No newline at end of file
diff --git a/src/OutputParams.cpp b/src/OutputParams.cpp
index 465282c..a7e0fd5 100644
--- a/src/OutputParams.cpp
+++ b/src/OutputParams.cpp
@@ -35,7 +35,7 @@ OutputParams::OutputParams(Encoding const * enc)
          html_disable_captions(false), html_in_par(false),
          html_make_pars(true), docbook_in_par(false), docbook_make_pars(true),
          docbook_force_pars(false), 
docbook_anchors_to_ignore(std::set<docstring>()), docbook_in_float(false),
-         docbook_in_listing(false), for_toc(false), for_tooltip(false),
+         docbook_in_listing(false), docbook_in_table(false), for_toc(false), 
for_tooltip(false),
          for_search(false), for_preview(false), includeall(false)
 {
        // Note: in PreviewLoader::Impl::dumpPreamble
diff --git a/src/OutputParams.h b/src/OutputParams.h
index c2e85dc..31a7059 100644
--- a/src/OutputParams.h
+++ b/src/OutputParams.h
@@ -369,6 +369,9 @@ public:
        /// Is the current context a listing?
        bool docbook_in_listing;
 
+       /// Is the current context a table?
+       bool docbook_in_table;
+
        /// Are we generating this material for inclusion in a TOC-like entity?
        bool for_toc;
 
diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp
index 1cd614e..b0a48f2 100644
--- a/src/insets/InsetFloat.cpp
+++ b/src/insets/InsetFloat.cpp
@@ -563,32 +563,71 @@ const InsetCaption* findCaptionInParagraph(const 
Paragraph &par)
 }
 
 
-void InsetFloat::docbook(XMLStream & xs, OutputParams const & runparams) const
+void docbookSubfigures(XMLStream & xs, OutputParams const & runparams, const 
InsetCaption * caption,
+                                          const InsetLabel * label, 
std::vector<const InsetBox *> & subfigures)
 {
-       // Determine whether the float has a title or not. For this, iterate 
through the paragraphs and look
-       // for an InsetCaption. Do the same for labels and subfigures.
-       // The caption and the label for each subfigure is handled by recursive 
calls.
-       const InsetCaption* caption = nullptr;
-       const InsetLabel* label = nullptr;
-       std::vector<const InsetBox *> subfigures;
+       // Ensure there is no label output, it is supposed to be handled as 
xml:id.
+       OutputParams rpNoLabel = runparams;
+       if (label)
+               
rpNoLabel.docbook_anchors_to_ignore.emplace(label->screenLabel());
 
-       auto end = paragraphs().end();
-       for (auto it = paragraphs().begin(); it != end; ++it) {
-               std::vector<const InsetBox *> foundSubfigures = 
findSubfiguresInParagraph(*it);
-               if (!foundSubfigures.empty()) {
-                       subfigures.reserve(subfigures.size() + 
foundSubfigures.size());
-                       subfigures.insert(subfigures.end(), 
foundSubfigures.begin(), foundSubfigures.end());
+       // First, open the formal group.
+       docstring attr = docstring();
+       if (label)
+               attr += "xml:id=\"" + xml::cleanID(label->screenLabel()) + "\"";
+
+       xs.startDivision(false);
+       xs << xml::StartTag("formalgroup", attr);
+       xs << xml::CR();
+
+       xs << xml::StartTag("title", attr);
+       if (caption) {
+               caption->getCaptionAsDocBook(xs, rpNoLabel);
+       } else {
+               xs << "No caption";
+               // No caption has been detected, but this tag is required for 
the document to be valid DocBook.
+       }
+       xs << xml::EndTag("title");
+       xs << xml::CR();
+
+       // Deal with each subfigure individually. This should also deal with 
their caption and their label.
+       // This should be a recursive call to InsetFloat.
+       for (const InsetBox *subfigure: subfigures) {
+               // If there is no InsetFloat in the paragraphs, output a 
warning.
+               bool foundInsetFloat = false;
+               for (const auto & it : subfigure->paragraphs()) {
+                       for (pos_type posIn = 0; posIn < it.size(); ++posIn) {
+                               const Inset *inset = it.getInset(posIn);
+                               if (inset && dynamic_cast<const 
InsetFloat*>(inset)) {
+                                       foundInsetFloat = true;
+                                       break;
+                               }
+                       }
+
+                       if (foundInsetFloat)
+                               break;
                }
 
-               if (!caption)
-                       caption = findCaptionInParagraph(*it);
-               if (!label)
-                       label = findLabelInParagraph(*it);
+               if (!foundInsetFloat)
+                       xs << XMLStream::ESCAPE_NONE << "Error: no float found 
in the box. "
+                                                               "To use 
subfigures in DocBook, elements must be wrapped in a float "
+                                           "inset and have a title/caption.";
+               // TODO: could also output a table, that would ensure that the 
document is correct and *displays* correctly (but without the right semantics), 
instead of just an error.
+
+               // Finally, recurse.
+               subfigure->docbook(xs, runparams);
        }
 
-       // Gather a few things from global environment that are shared between 
all following cases.
-       FloatList const &floats = buffer().params().documentClass().floats();
-       Floating const &ftype = floats.getType(params_.type);
+       // Every subfigure is done: close the formal group.
+       xs << xml::EndTag("formalgroup");
+       xs << xml::CR();
+       xs.endDivision();
+}
+
+
+void docbookNoSubfigures(XMLStream & xs, OutputParams const & runparams, const 
InsetCaption * caption,
+                         const InsetLabel * label, Floating const & ftype, 
const InsetFloat * thisFloat)
+{
        string const &titleTag = ftype.docbookCaption();
 
        // Ensure there is no label output, it is supposed to be handled as 
xml:id.
@@ -600,65 +639,10 @@ void InsetFloat::docbook(XMLStream & xs, OutputParams 
const & runparams) const
        // captions, they cannot appear at the end of the float, albeit LyX is 
happy with that).
        OutputParams rpNoTitle = runparams;
        rpNoTitle.docbook_in_float = true;
+       if (ftype.floattype() == "table")
+               rpNoTitle.docbook_in_table = true;
 
-       // Deal with subfigures.
-       if (!subfigures.empty()) {
-               // First, open the formal group.
-               docstring attr = docstring();
-               if (label)
-                       attr += "xml:id=\"" + 
xml::cleanID(label->screenLabel()) + "\"";
-
-               xs.startDivision(false);
-               xs << xml::StartTag("formalgroup", attr);
-               xs << xml::CR();
-
-               xs << xml::StartTag("title", attr);
-               if (caption) {
-                       caption->getCaptionAsDocBook(xs, rpNoLabel);
-               } else {
-                       xs << "No caption";
-                       // No caption has been detected, but this tag is 
required for the document to be valid DocBook.
-               }
-               xs << xml::EndTag("title");
-               xs << xml::CR();
-
-               // Deal with each subfigure individually. This should also deal 
with their caption and their label.
-               // This should be a recursive call to InsetFloat.
-               for (const InsetBox *subfigure: subfigures) {
-                       // If there is no InsetFloat in the paragraphs, output 
a warning.
-                       bool foundInsetFloat = false;
-                       for (auto it = subfigure->paragraphs().begin(); it != 
subfigure->paragraphs().end(); ++it) {
-                               for (pos_type posIn = 0; posIn < it->size(); 
++posIn) {
-                                       const Inset *inset = 
it->getInset(posIn);
-                                       if (inset && dynamic_cast<const 
InsetFloat*>(inset)) {
-                                               foundInsetFloat = true;
-                                               break;
-                                       }
-                               }
-
-                               if (foundInsetFloat)
-                                       break;
-                       }
-
-                       if (!foundInsetFloat)
-                               xs << XMLStream::ESCAPE_NONE << "Error: no 
float found in the box. "
-                                                                       "To use 
subfigures in DocBook, elements must be wrapped in a float "
-                                                   "inset and have a 
title/caption.";
-                       // TODO: could also output a table, that would ensure 
that the document is correct and *displays* correctly (but without the right 
semantics), instead of just an error.
-
-                       // Finally, recurse.
-                       subfigure->docbook(xs, runparams);
-               }
-
-               // Every subfigure is done: close the formal group.
-               xs << xml::EndTag("formalgroup");
-               xs << xml::CR();
-               xs.endDivision();
-       }
-
-       // Here, ensured not to have subfigures.
-
-       // Organisation: <float> <title if any/> <contents without title/> 
</float>
+       // Organisation: <float> <title if any/> <contents without title/> 
</float>.
        docstring attr = docstring();
        if (label)
                attr += "xml:id=\"" + xml::cleanID(label->screenLabel()) + "\"";
@@ -676,12 +660,47 @@ void InsetFloat::docbook(XMLStream & xs, OutputParams 
const & runparams) const
                xs << xml::EndTag(titleTag);
                xs << xml::CR();
        }
-       InsetText::docbook(xs, rpNoTitle);
+       thisFloat->InsetText::docbook(xs, rpNoTitle);
        xs << xml::EndTag(ftype.docbookTag(caption != nullptr));
        xs << xml::CR();
 }
 
 
+void InsetFloat::docbook(XMLStream & xs, OutputParams const & runparams) const
+{
+       // Determine whether the float has a title or not. For this, iterate 
through the paragraphs and look
+       // for an InsetCaption. Do the same for labels and subfigures.
+       // The caption and the label for each subfigure is handled by recursive 
calls.
+       const InsetCaption* caption = nullptr;
+       const InsetLabel* label = nullptr;
+       std::vector<const InsetBox *> subfigures;
+
+       auto end = paragraphs().end();
+       for (auto it = paragraphs().begin(); it != end; ++it) {
+               std::vector<const InsetBox *> foundSubfigures = 
findSubfiguresInParagraph(*it);
+               if (!foundSubfigures.empty()) {
+                       subfigures.reserve(subfigures.size() + 
foundSubfigures.size());
+                       subfigures.insert(subfigures.end(), 
foundSubfigures.begin(), foundSubfigures.end());
+               }
+
+               if (!caption)
+                       caption = findCaptionInParagraph(*it);
+               if (!label)
+                       label = findLabelInParagraph(*it);
+       }
+
+       // Gather a few things from global environment that are shared between 
all following cases.
+       FloatList const &floats = buffer().params().documentClass().floats();
+       Floating const &ftype = floats.getType(params_.type);
+
+       // Switch on subfigures.
+       if (!subfigures.empty())
+               docbookSubfigures(xs, runparams, caption, label, subfigures);
+       else
+               docbookNoSubfigures(xs, runparams, caption, label, ftype, this);
+}
+
+
 bool InsetFloat::insetAllowed(InsetCode code) const
 {
        // The case that code == FLOAT_CODE is handled in Text3.cpp,
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index 87988af..b449ab3 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -3658,8 +3658,8 @@ void Tabular::docbook(XMLStream & xs, OutputParams const 
& runparams) const
        docstring ret;
 
        // Some tables are inline. Likely limitation: cannot output a table 
within a table; is that really a limitation?
-       bool hasTableStarted = xs.isTagOpen(xml::StartTag("informaltable")) || 
xs.isTagOpen(xml::StartTag("table"));
-       if (!hasTableStarted) {
+       if (!runparams.docbook_in_table) { // Check on the *outer* set of 
parameters, so that the table can be closed
+               // properly at the end of this function.
                xs << xml::StartTag("informaltable");
                xs << xml::CR();
        }
@@ -3742,7 +3742,7 @@ void Tabular::docbook(XMLStream & xs, OutputParams const 
& runparams) const
        xs << xml::CR();
 
        // If this method started the table tag, also make it close it.
-       if (!hasTableStarted) {
+       if (!runparams.docbook_in_table) {
                xs << xml::EndTag("informaltable");
                xs << xml::CR();
        }
diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp
index 94aac87..5e15edc 100644
--- a/src/output_docbook.cpp
+++ b/src/output_docbook.cpp
@@ -463,14 +463,26 @@ ParagraphList::const_iterator makeParagraphs(
                                ((open_par && (!runparams.docbook_in_par || 
nextpar != pend))
                                || (!open_par && runparams.docbook_in_par && 
par == pbegin && nextpar != pend));
 
-               if (open_par)
-                       openParTag(xs, lay);
+               // Determine if this paragraph has some real content. Things 
like new pages are not caught
+               // by Paragraph::empty(), even though they do not generate 
anything useful in DocBook.
+               odocstringstream os2;
+               XMLStream xs2(os2);
+               par->simpleDocBookOnePar(buf, xs2, 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);
+               docstring cleaned = os2.str();
+               static const lyx::regex reg("[ \\r\\n]*");
+               cleaned = from_utf8(lyx::regex_replace(to_utf8(cleaned), reg, 
string("")));
 
-               if (close_par) {
-                       closeTag(xs, lay);
-                       xs << xml::CR();
+               if (!cleaned.empty()) {
+                       if (open_par)
+                               openParTag(xs, lay);
+
+                       xs << XMLStream::ESCAPE_NONE << os2.str();
+
+                       if (close_par) {
+                               closeTag(xs, lay);
+                               xs << xml::CR();
+                       }
                }
        }
        return pend;
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to