#include <config.h>
+#include "InsetFloat.h"
+
#include "InsetBox.h"
#include "InsetCaption.h"
-#include "InsetFloat.h"
#include "InsetGraphics.h"
#include "InsetLabel.h"
}
+CtObject InsetFloat::getCtObject(OutputParams const &) const
+{
+ return CtObject::OmitObject;
+}
+
+
LyXAlignment InsetFloat::contentAlignment() const
{
LyXAlignment align = LYX_ALIGN_NONE;
if (runparams.inDeletedInset) {
// This has to be done manually since we need it inside the float
- OutputParams::CtObject ctobject = runparams.ctObject;
- runparams.ctObject = OutputParams::CT_DISPLAYOBJECT;
+ CtObject ctobject = runparams.ctObject;
+ runparams.ctObject = CtObject::DisplayObject;
Changes::latexMarkChange(os, buffer().params(), Change(Change::UNCHANGED),
Change(Change::DELETED), runparams);
runparams.ctObject = ctobject;
}
-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;
-}
-
-
-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 docbookSubfigures(XMLStream & xs, OutputParams const & runparams, const InsetCaption * caption,
- const InsetLabel * label, std::vector<const InsetCollapsible *> & subfigures)
+ const InsetLabel * label, std::vector<const InsetCollapsible *> const & subfigures)
{
// Ensure there is no label output, it is supposed to be handled as xml:id.
OutputParams rpNoLabel = runparams;
}
-void docbookNoSubfigures(XMLStream & xs, OutputParams const & runparams, const InsetCaption * caption,
- const InsetLabel * label, Floating const & ftype, const InsetFloat * thisFloat)
+void docbookGenerateFillerMedia(XMLStream & xs)
{
- string const &titleTag = ftype.docbookCaption();
+ xs << xml::StartTag("mediaobject");
+ xs << xml::CR();
+ xs << xml::StartTag("textobject");
+ xs << xml::CR();
+ xs << xml::StartTag("phrase");
+ xs << "This figure is empty.";
+ xs << xml::EndTag("phrase");
+ xs << xml::CR();
+ xs << xml::EndTag("textobject");
+ xs << xml::CR();
+ xs << xml::EndTag("mediaobject");
+ xs << xml::CR();
+}
+
+
+void docbookGenerateFillerTable(XMLStream & xs, BufferParams::TableOutput format)
+{
+ switch (format) {
+ case BufferParams::HTMLTable:
+ xs << xml::StartTag("tr");
+ xs << xml::CR();
+ xs << xml::StartTag("td");
+ xs << "This table is empty.";
+ xs << xml::EndTag("td");
+ xs << xml::CR();
+ xs << xml::EndTag("tr");
+ xs << xml::CR();
+ break;
+ case BufferParams::CALSTable:
+ // CALS tables allow for <mediaobject>, use that instead.
+ docbookGenerateFillerMedia(xs);
+ break;
+ }
+}
+
+void docbookNoSubfigures(XMLStream & xs, OutputParams const & runparams, const InsetCaption * caption,
+ const InsetLabel * label, Floating const & ftype, const InsetFloat * thisFloat) {
// Ensure there is no label output, it is supposed to be handled as xml:id.
OutputParams rpNoLabel = runparams;
if (label)
if (ftype.docbookFloatType() == "table")
rpNoTitle.docbook_in_table = true;
- // Organisation: <float> <title if any/> <contents without title/> </float>.
+ // Generate the contents of the float (to check for emptiness).
+ odocstringstream osFloatContent;
+ bool hasFloat = false;
+
+ if (thisFloat) {
+ XMLStream xsFloatContent(osFloatContent);
+ thisFloat->InsetText::docbook(xsFloatContent, rpNoTitle);
+ hasFloat = !osFloatContent.str().empty();
+ }
+
+ // Do the same for the caption.
+ odocstringstream osCaptionContent;
+ bool hasCaption = false;
+
+ if (caption != nullptr) {
+ XMLStream xsCaptionContent(osCaptionContent);
+ caption->getCaptionAsDocBook(xsCaptionContent, rpNoLabel);
+ hasCaption = !osCaptionContent.str().empty();
+ }
+
+ // Organisation: <float with xml:id if any> <title if any/> <contents without title nor xml:id/> </float>.
+ // Titles and xml:id are generated with specific insets and must be dealt with using OutputParams.
+
+ // - Generate the attributes for the float tag.
docstring attr = docstring();
if (label)
attr += "xml:id=\"" + xml::cleanID(label->screenLabel()) + "\"";
attr += from_utf8(ftype.docbookAttr());
}
- xs << xml::StartTag(ftype.docbookTag(caption != nullptr), attr);
+ // - Open the float tag.
+ xs << xml::StartTag(ftype.docbookTag(hasCaption), attr);
xs << xml::CR();
- if (caption) {
+
+ // - Generate the caption.
+ if (hasCaption) {
+ string const &titleTag = ftype.docbookCaption();
xs << xml::StartTag(titleTag);
- caption->getCaptionAsDocBook(xs, rpNoLabel);
+ xs << XMLStream::ESCAPE_NONE << osCaptionContent.str();
xs << xml::EndTag(titleTag);
xs << xml::CR();
}
- thisFloat->InsetText::docbook(xs, rpNoTitle);
- xs << xml::EndTag(ftype.docbookTag(caption != nullptr));
+
+ // - Output the actual content of the float or some dummy content (to ensure that the output
+ // document is valid).
+ if (hasFloat)
+ xs << XMLStream::ESCAPE_NONE << osFloatContent.str();
+ else if (ftype.docbookFloatType() == "table")
+ docbookGenerateFillerTable(xs, thisFloat->buffer().params().docbook_table_output);
+ else
+ docbookGenerateFillerMedia(xs);
+
+ // - Close the float.
+ xs << xml::EndTag(ftype.docbookTag(hasCaption));
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 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.
- FloatList const &floats = buffer().params().documentClass().floats();
- Floating const &ftype = floats.getType(params_.type);
+ FloatList const & floats = buffer().params().documentClass().floats();
+ Floating const & ftype = floats.getType(params_.type);
// Switch on subfigures.
if (!subfigures.empty())
void InsetFloat::setNewLabel()
{
- docstring lab = _("float: ");
+ docstring lab = _("Float: ");
if (params_.subfloat)
- lab = _("subfloat: ");
+ lab = _("Subfloat: ");
lab += floatName(params_.type);