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.
#include <config.h>
+#include "InsetBox.h"
#include "InsetCaptionable.h"
-
#include "InsetCaption.h"
+#include "InsetLabel.h"
#include "Buffer.h"
#include "BufferParams.h"
}
}
}
- 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;
namespace lyx {
class InsetCaption;
+class InsetLabel;
class InsetCaptionable : public InsetCollapsible
{
///
InsetCaption const * getCaptionInset() const;
///
+ InsetLabel const * getLabelInset() const;
+ ///
docstring getCaptionText(OutputParams const &) const;
///
docstring getCaptionHTML(OutputParams const &) const;
}
-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)
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);
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.
}
-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();
// 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;