commit 46cbd6d234c67facb375f18984645299fcc76ef4
Author: Thibaut Cuvelier <[email protected]>
Date:   Sun Nov 15 03:03:16 2020 +0100

    DocBook: refactor code about retrieving captions and labels.
    
    There was already an existing method in InsetCaptionable for captions, but 
not yet for labels. It was at least already useful at two places, that's why I 
moved it to InsetCaptionable.
---
 src/insets/InsetCaptionable.cpp |   52 ++++++++++++++++++++++++++--
 src/insets/InsetCaptionable.h   |    3 ++
 src/insets/InsetFloat.cpp       |   72 ++------------------------------------
 src/insets/InsetListings.cpp    |   45 +------------------------
 4 files changed, 57 insertions(+), 115 deletions(-)

diff --git a/src/insets/InsetCaptionable.cpp b/src/insets/InsetCaptionable.cpp
index a8a2108..474eaf0 100644
--- a/src/insets/InsetCaptionable.cpp
+++ b/src/insets/InsetCaptionable.cpp
@@ -13,9 +13,10 @@
 
 #include <config.h>
 
+#include "InsetBox.h"
 #include "InsetCaptionable.h"
-
 #include "InsetCaption.h"
+#include "InsetLabel.h"
 
 #include "Buffer.h"
 #include "BufferParams.h"
@@ -64,14 +65,59 @@ InsetCaption const * InsetCaptionable::getCaptionInset() 
const
                        }
                }
        }
-       return 0;
+       return nullptr;
+}
+
+
+InsetLabel const * InsetCaptionable::getLabelInset() const
+{
+       // A wrong hypothesis would be to limit the search to the caption: it 
is most likely there, but not necessarily!
+
+       // Iterate through the contents of the inset.
+       auto const end = paragraphs().end();
+       for (auto par = paragraphs().begin(); par != end; ++par) {
+               for (pos_type pos = 0; pos < par->size(); ++pos) {
+                       const Inset * inset = par->getInset(pos);
+
+                       // If this inset is a subfigure, skip it. Otherwise, 
you would return the label for the subfigure.
+                       if (dynamic_cast<const InsetBox *>(inset)) {
+                               continue;
+                       }
+
+                       // Maybe an inset is directly a label, in which case no 
more work is needed.
+                       if (inset && dynamic_cast<const InsetLabel *>(inset))
+                               return dynamic_cast<const InsetLabel *>(inset);
+
+                       // More likely, the label is hidden in an inset of a 
paragraph (only if a subtype of InsetText). Thus,
+                       // dig into that text.
+                       if (!dynamic_cast<const InsetText *>(inset))
+                               continue;
+
+                       auto insetAsText = dynamic_cast<const InsetText 
*>(inset);
+                       auto itIn = insetAsText->paragraphs().begin();
+                       auto endIn = insetAsText->paragraphs().end();
+                       for (; itIn != endIn; ++itIn) {
+                               for (pos_type posIn = 0; posIn < itIn->size(); 
++posIn) {
+                                       const Inset *insetIn = 
itIn->getInset(posIn);
+                                       if (insetIn && dynamic_cast<const 
InsetLabel *>(insetIn)) {
+                                               return dynamic_cast<const 
InsetLabel *>(insetIn);
+                                       }
+                               }
+                       }
+
+                       // Obviously, this solution does not scale with more 
levels of paragraphs and insets, but this should
+                       // be enough: it is only used in captions.
+               }
+       }
+
+       return nullptr;
 }
 
 
 docstring InsetCaptionable::getCaptionText(OutputParams const & runparams) 
const
 {
        InsetCaption const * ins = getCaptionInset();
-       if (ins == 0)
+       if (!ins)
                return docstring();
 
        odocstringstream ods;
diff --git a/src/insets/InsetCaptionable.h b/src/insets/InsetCaptionable.h
index aa9a4cc..ac11f55 100644
--- a/src/insets/InsetCaptionable.h
+++ b/src/insets/InsetCaptionable.h
@@ -21,6 +21,7 @@
 namespace lyx {
 
 class InsetCaption;
+class InsetLabel;
 
 class InsetCaptionable : public InsetCollapsible
 {
@@ -36,6 +37,8 @@ protected:
        ///
        InsetCaption const * getCaptionInset() const;
        ///
+       InsetLabel const * getLabelInset() const;
+       ///
        docstring getCaptionText(OutputParams const &) const;
        ///
        docstring getCaptionHTML(OutputParams const &) const;
diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp
index 86e3f9b..f486fc7 100644
--- a/src/insets/InsetFloat.cpp
+++ b/src/insets/InsetFloat.cpp
@@ -514,63 +514,6 @@ std::vector<const InsetCollapsible *> 
findSubfiguresInParagraph(const Paragraph
 }
 
 
-namespace {
-
-const InsetLabel* findLabelInParagraph(const Paragraph &par)
-{
-       for (pos_type pos = 0; pos < par.size(); ++pos) {
-               // If this inset is a subfigure, skip it.
-               const Inset *inset = par.getInset(pos);
-               if (dynamic_cast<const InsetBox *>(inset)) {
-                       continue;
-               }
-
-               // Maybe an inset is directly a label, in which case no more 
work is needed.
-               if (inset && dynamic_cast<const InsetLabel *>(inset))
-                       return dynamic_cast<const InsetLabel *>(inset);
-
-               // More likely, the label is hidden in an inset of a paragraph 
(only if a subtype of InsetText).
-               if (!dynamic_cast<const InsetText *>(inset))
-                       continue;
-
-               auto insetAsText = dynamic_cast<const InsetText *>(inset);
-               auto itIn = insetAsText->paragraphs().begin();
-               auto endIn = insetAsText->paragraphs().end();
-               for (; itIn != endIn; ++itIn) {
-                       for (pos_type posIn = 0; posIn < itIn->size(); ++posIn) 
{
-                               const Inset *insetIn = itIn->getInset(posIn);
-                               if (insetIn && dynamic_cast<const InsetLabel 
*>(insetIn)) {
-                                       return dynamic_cast<const InsetLabel 
*>(insetIn);
-                               }
-                       }
-               }
-
-               // Obviously, this solution does not scale with more levels of 
paragraphs-insets, but this should be enough.
-       }
-
-       return nullptr;
-}
-
-} // anonymous namespace
-
-
-const InsetCaption* findCaptionInParagraph(const Paragraph &par)
-{
-       // Don't dive too deep, otherwise, this could be a subfigure caption.
-       for (pos_type pos = 0; pos < par.size(); ++pos) {
-               // If this inset is a subfigure, skip it.
-               const Inset *inset = par.getInset(pos);
-               if (dynamic_cast<const InsetBox *>(inset))
-                       continue;
-
-               if (inset && dynamic_cast<const InsetCaption *>(inset))
-                       return dynamic_cast<const InsetCaption *>(inset);
-       }
-
-       return nullptr;
-}
-
-
 /// Takes an unstructured subfigure container (typically, an InsetBox) and 
find the elements within:
 /// actual content (image or table), maybe a caption, maybe a label.
 std::tuple<InsetCode, const Inset *, const InsetCaption *, const InsetLabel *> 
docbookParseHopelessSubfigure(const InsetText * subfigure)
@@ -814,13 +757,11 @@ void docbookNoSubfigures(XMLStream & xs, OutputParams 
const & runparams, const I
 
 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 InsetCollapsible *> subfigures;
+       const InsetCaption* caption = getCaptionInset();
+       const InsetLabel* label = getLabelInset();
 
+       // Determine whether the float has subfigures.
+       std::vector<const InsetCollapsible *> subfigures;
        auto end = paragraphs().end();
        for (auto it = paragraphs().begin(); it != end; ++it) {
                std::vector<const InsetCollapsible *> foundSubfigures = 
findSubfiguresInParagraph(*it);
@@ -828,11 +769,6 @@ void InsetFloat::docbook(XMLStream & xs, OutputParams 
const & runparams) const
                        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.
diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp
index cff7bcc..7ac940d 100644
--- a/src/insets/InsetListings.cpp
+++ b/src/insets/InsetListings.cpp
@@ -482,42 +482,6 @@ docstring InsetListings::xhtml(XMLStream & os, 
OutputParams const & rp) const
 }
 
 
-namespace {
-
-const InsetLabel* findLabelInParagraph(const Paragraph &par)
-{
-       for (pos_type pos = 0; pos < par.size(); ++pos) {
-               const Inset *inset = par.getInset(pos);
-
-               // Maybe an inset is directly a label, in which case no more 
work is needed.
-               if (inset && dynamic_cast<const InsetLabel *>(inset))
-                       return dynamic_cast<const InsetLabel *>(inset);
-
-               // More likely, the label is hidden in an inset of a paragraph 
(only if a subtype of InsetText).
-               if (!dynamic_cast<const InsetText *>(inset))
-                       continue;
-
-               auto insetAsText = dynamic_cast<const InsetText *>(inset);
-               auto itIn = insetAsText->paragraphs().begin();
-               auto endIn = insetAsText->paragraphs().end();
-               for (; itIn != endIn; ++itIn) {
-                       for (pos_type posIn = 0; posIn < itIn->size(); ++posIn) 
{
-                               const Inset *insetIn = itIn->getInset(posIn);
-                               if (insetIn && dynamic_cast<const InsetLabel 
*>(insetIn)) {
-                                       return dynamic_cast<const InsetLabel 
*>(insetIn);
-                               }
-                       }
-               }
-
-               // Obviously, this solution does not scale with more levels of 
paragraphs-insets, but this should be enough.
-       }
-
-       return nullptr;
-}
-
-} // anonymous namespace
-
-
 void InsetListings::docbook(XMLStream & xs, OutputParams const & rp) const
 {
        InsetLayout const & il = getLayout();
@@ -531,14 +495,7 @@ void InsetListings::docbook(XMLStream & xs, OutputParams 
const & rp) const
        // TODO: parts of this code could be merged with InsetFloat and 
findLabelInParagraph.
        InsetCaption const * caption = getCaptionInset();
        if (caption) {
-               // Find the label in the caption, if any.
-               InsetLabel const * label;
-               auto const end = caption->paragraphs().end();
-               for (auto it = caption->paragraphs().begin(); it != end; ++it) {
-                       label = findLabelInParagraph(*it);
-                       if (label)
-                               break;
-               }
+               InsetLabel const * label = getLabelInset();
 
                // Ensure that the label will not be output a second time as an 
anchor.
                OutputParams rpNoLabel = rp;
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to