X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetCaptionable.cpp;h=474eaf059e7fa14ed022ae0cc0b0907b0e96493c;hb=8124e6c02ea1fd6779bb6c47ffe2bca2c8bd2d97;hp=f90776ab0408541f1dd672470239359efbd7ac97;hpb=9b7ccbfc8016398705583d6973395dfb46dceb8f;p=lyx.git diff --git a/src/insets/InsetCaptionable.cpp b/src/insets/InsetCaptionable.cpp index f90776ab04..474eaf059e 100644 --- a/src/insets/InsetCaptionable.cpp +++ b/src/insets/InsetCaptionable.cpp @@ -13,15 +13,22 @@ #include +#include "InsetBox.h" #include "InsetCaptionable.h" +#include "InsetCaption.h" +#include "InsetLabel.h" #include "Buffer.h" #include "BufferParams.h" #include "BufferView.h" #include "FloatList.h" +#include "InsetList.h" +#include "output_xhtml.h" #include "TextClass.h" #include "TocBackend.h" +#include "support/docstream.h" + using namespace std; @@ -40,26 +47,133 @@ docstring InsetCaptionable::floatName(string const & type) const BufferParams const & bp = buffer().params(); FloatList const & floats = bp.documentClass().floats(); FloatList::const_iterator it = floats[type]; - // FIXME UNICODE - return (it == floats.end()) ? from_ascii(type) : bp.B_(it->second.name()); + return (it == floats.end()) ? from_utf8(type) : bp.B_(it->second.name()); +} + + +InsetCaption const * InsetCaptionable::getCaptionInset() const +{ + ParagraphList::const_iterator pit = paragraphs().begin(); + for (; pit != paragraphs().end(); ++pit) { + InsetList::const_iterator it = pit->insetList().begin(); + for (; it != pit->insetList().end(); ++it) { + Inset & inset = *it->inset; + if (inset.lyxCode() == CAPTION_CODE) { + InsetCaption const * ins = + static_cast(it->inset); + return ins; + } + } + } + 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(inset)) { + continue; + } + + // Maybe an inset is directly a label, in which case no more work is needed. + if (inset && dynamic_cast(inset)) + return dynamic_cast(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(inset)) + continue; + + auto insetAsText = dynamic_cast(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(insetIn)) { + return dynamic_cast(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) + return docstring(); + + odocstringstream ods; + ins->getCaptionAsPlaintext(ods, runparams); + return ods.str(); +} + + +docstring InsetCaptionable::getCaptionDocBook(OutputParams const & runparams) const +{ + InsetCaption const * ins = getCaptionInset(); + if (ins == nullptr) + return docstring(); + + odocstringstream ods; + XMLStream xs(ods); + ins->getCaptionAsDocBook(xs, runparams); + return ods.str(); +} + + +docstring InsetCaptionable::getCaptionHTML(OutputParams const & runparams) const +{ + InsetCaption const * ins = getCaptionInset(); + if (ins == 0) + return docstring(); + + odocstringstream ods; + XMLStream xs(ods); + docstring def = ins->getCaptionAsHTML(xs, runparams); + if (!def.empty()) + // should already have been escaped + xs << XMLStream::ESCAPE_NONE << def << '\n'; + return ods.str(); } -void InsetCaptionable::addToToc(DocIterator const & cpit, bool output_active) const +void InsetCaptionable::addToToc(DocIterator const & cpit, bool output_active, + UpdateType utype, TocBackend & backend) const { DocIterator pit = cpit; pit.push_back(CursorSlice(const_cast(*this))); docstring str; - int length = output_active ? INT_MAX : TOC_ENTRY_LENGTH; - text().forOutliner(str, length); - shared_ptr b = buffer().tocBackend().builder(caption_type_); - b->pushItem(pit, str, output_active); + // Leave str empty if we generate for output (e.g. xhtml lists of figures). + // This ensures that there is a caption if and only if the string is + // non-empty. + if (utype != OutputUpdate) + text().forOutliner(str, TOC_ENTRY_LENGTH); + TocBuilder & b = backend.builder(caption_type_); + b.pushItem(pit, str, output_active); // Proceed with the rest of the inset. - InsetCollapsable::addToToc(cpit, output_active); - b->pop(); + InsetCollapsible::addToToc(cpit, output_active, utype, backend); + b.pop(); } -void InsetCaptionable::updateBuffer(ParIterator const & it, UpdateType utype) +void InsetCaptionable::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted) { Counters & cnts = buffer().masterBuffer()->params().documentClass().counters(); @@ -76,7 +190,7 @@ void InsetCaptionable::updateBuffer(ParIterator const & it, UpdateType utype) // Tell captions what the current float is cnts.current_float(caption_type_); cnts.isSubfloat(subflt); - InsetCollapsable::updateBuffer(it, utype); + InsetCollapsible::updateBuffer(it, utype, deleted); // Restore counters cnts.current_float(saveflt); if (utype == OutputUpdate) @@ -87,7 +201,7 @@ void InsetCaptionable::updateBuffer(ParIterator const & it, UpdateType utype) bool InsetCaptionable::insetAllowed(InsetCode c) const { - return (c == CAPTION_CODE) || InsetCollapsable::insetAllowed(c); + return (c == CAPTION_CODE) || InsetCollapsible::insetAllowed(c); }