]> git.lyx.org Git - features.git/commitdiff
DocBook: refactor code about retrieving captions and labels.
authorThibaut Cuvelier <tcuvelier@lyx.org>
Sun, 15 Nov 2020 02:03:16 +0000 (03:03 +0100)
committerThibaut Cuvelier <tcuvelier@lyx.org>
Sun, 15 Nov 2020 03:03:04 +0000 (04:03 +0100)
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
src/insets/InsetCaptionable.h
src/insets/InsetFloat.cpp
src/insets/InsetListings.cpp

index a8a2108ce9bd8917c061065d6c6dc03c7a478827..474eaf059e7fa14ed022ae0cc0b0907b0e96493c 100644 (file)
 
 #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;
index aa9a4cc4262862dca58fd36abf71e8d9fd1e3cb8..ac11f55ca20a661b52640122b3bba828f3801f73 100644 (file)
@@ -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;
index 86e3f9b3386f58a2e891126b0242a54634fd8d8e..f486fc7980a3dd9c2129844433c0ebd163fc6238 100644 (file)
@@ -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.
index cff7bcc9c1b9232a5f8a5e300f4657c4f0f63ff8..7ac940d7421ba52459bf7b3a0888bbe70144cb73 100644 (file)
@@ -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;