Finish disentangling tocString(). We introduce a new method, forToc(),

that also makes sure it doesn't do more work than it needs to do, by
limiting the size to 40 characters. Previously, InsetBranch::addToToc()
would have added a string representing the entire contents of the
branch! It's hard to imagine that having to recalculate that sort of
thing doesn't cause some problems with speed, especially in documents
with lots of notes and branches and such.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36974 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2010-12-20 21:55:09 +00:00
parent ac86039473
commit 9e9c96035c
30 changed files with 154 additions and 39 deletions

View File

@ -2928,11 +2928,8 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options) const
|| (c == '\n' && (options & AS_STR_NEWLINES)))
os.put(c);
else if (c == META_INSET && (options & AS_STR_INSETS)) {
Inset const * inset = getInset(i);
if ((options & AS_STR_INTOC) && !inset->isInToc())
continue;
inset->toString(os);
if (inset->asInsetMath())
getInset(i)->toString(os);
if (getInset(i)->asInsetMath())
os << " ";
}
}
@ -2941,6 +2938,22 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options) const
}
void Paragraph::forToc(docstring & os, size_t maxlen) const
{
for (pos_type i = 0; i < size() && os.length() < maxlen; ++i) {
if (isDeleted(i))
continue;
char_type const c = d->text_[i];
if (isPrintable(c))
os += c;
else if (c == '\t' || c == '\n')
os += ' ';
else if (c == META_INSET)
getInset(i)->forToc(os, maxlen);
}
}
docstring Paragraph::stringify(pos_type beg, pos_type end, int options, OutputParams & runparams) const
{
odocstringstream os;

View File

@ -102,8 +102,7 @@ enum AsStringParameter
AS_STR_LABEL = 1, ///< Prefix with paragraph label.
AS_STR_INSETS = 2, ///< Go into insets.
AS_STR_NEWLINES = 4, ///< Get also newline characters.
AS_STR_SKIPDELETE = 8, ///< Skip deleted text in change tracking.
AS_STR_INTOC = 16 ///< Skip insets that are not supposed to go into the TOC
AS_STR_SKIPDELETE = 8 ///< Skip deleted text in change tracking.
};
@ -151,6 +150,8 @@ public:
///
docstring asString(pos_type beg, pos_type end,
int options = AS_STR_NONE) const;
///
void forToc(docstring &, size_t maxlen) const;
/// Extract only the explicitly visible text (without any formatting),
/// descending into insets

View File

@ -1923,6 +1923,15 @@ docstring Text::asString(pit_type beg, pit_type end, int options) const
}
void Text::forToc(docstring & os, size_t maxlen, bool shorten) const
{
LASSERT(maxlen > 10, maxlen = 30);
for (size_t i = 0; i != pars_.size() && os.length() < maxlen; ++i)
pars_[i].forToc(os, maxlen);
if (shorten && os.length() >= maxlen)
os = os.substr(0, maxlen - 3) + from_ascii("...");
}
void Text::charsTranspose(Cursor & cur)
{

View File

@ -126,6 +126,12 @@ public:
///
docstring asString(pit_type beg, pit_type end,
int options = AS_STR_NONE) const;
/// Appends a possibly abbreviated representation of our text
/// to \param os, where \param maxlen defines the maximum size
/// of \param os. If \param shorten is true, then we will shorten
/// \param os to maxlen chars and replace the final three by "...,
/// if \param os is longer than maxlen chars.
void forToc(docstring & os, size_t maxlen, bool shorten = true) const;
/// insert a character at cursor position
/// FIXME: replace Cursor with DocIterator.

View File

@ -149,7 +149,7 @@ bool TocBackend::updateItem(DocIterator const & dit)
*static_cast<InsetArgument&>(inset).paragraphs().begin();
if (!par.labelString().empty())
tocstring = par.labelString() + ' ';
tocstring += inset_par.asString(AS_STR_INSETS | AS_STR_INTOC);
tocstring += inset_par.asString(AS_STR_INSETS);
break;
}
}
@ -157,7 +157,7 @@ bool TocBackend::updateItem(DocIterator const & dit)
int const toclevel = par.layout().toclevel;
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel
&& tocstring.empty())
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS | AS_STR_INTOC);
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
const_cast<TocItem &>(*toc_item).str_ = tocstring;

View File

@ -254,6 +254,11 @@ docstring Inset::toolTip(BufferView const &, int, int) const
}
void Inset::forToc(docstring &, size_t) const
{
}
docstring Inset::contextMenu(BufferView const &, int, int) const
{
return contextMenuName();

View File

@ -69,6 +69,8 @@ std::string insetName(InsetCode);
/// returns the Inset name corresponding to the \c InsetCode.
/// Eg, insetDisplayName(BRANCH_CODE) == _("Branch")
docstring insetDisplayName(InsetCode);
///
static int const TOC_ENTRY_LENGTH = 40;
/// Common base class to all insets
@ -320,11 +322,14 @@ public:
/// paragraph closes. this is appropriate e.g. for floats.
virtual docstring xhtml(XHTMLStream & xs, OutputParams const &) const;
// FIXME This method is used for things other than generating strings
// for the TOC. E.g., it is called by Paragraph::asString() to get the
// contents of the inset. These two functions should be disentangled.
///
/// Writes a string representation of the inset to the odocstream.
/// This one should be called when you want the whole contents of
/// the inset.
virtual void toString(odocstream &) const {}
/// Appends a potentially abbreviated version of the inset to
/// \param str. Intended for use by the TOC.
virtual void forToc(docstring & str,
size_t maxlen = TOC_ENTRY_LENGTH) const;
/// can the contents of the inset be edited on screen ?
// true for InsetCollapsables (not ButtonOnly) (not InsetInfo), InsetText

View File

@ -245,6 +245,13 @@ void InsetBranch::toString(odocstream & os) const
}
void InsetBranch::forToc(docstring & os, size_t maxlen) const
{
if (isBranchSelected())
InsetCollapsable::forToc(os, maxlen);
}
void InsetBranch::validate(LaTeXFeatures & features) const
{
if (isBranchSelected())
@ -293,7 +300,8 @@ void InsetBranch::addToToc(DocIterator const & cpit)
pit.push_back(CursorSlice(*this));
Toc & toc = buffer().tocBackend().toc("branch");
docstring const str = params_.branch + ": " + text().getPar(0).asString();
docstring str = params_.branch + ": ";
text().forToc(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, toolTipText()));
// Proceed with the rest of the inset.
InsetCollapsable::addToToc(cpit);

View File

@ -75,6 +75,8 @@ private:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
void validate(LaTeXFeatures &) const;
///
docstring contextMenuName() const;

View File

@ -113,7 +113,8 @@ void InsetCaption::addToToc(DocIterator const & cpit)
pit.push_back(CursorSlice(*this));
Toc & toc = buffer().tocBackend().toc(type_);
docstring const str = full_label_ + ". " + text().getPar(0).asString();
docstring str = full_label_ + ". ";
text().forToc(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str));
// Proceed with the rest of the inset.

View File

@ -546,6 +546,12 @@ void InsetCitation::toString(odocstream & os) const
}
void InsetCitation::forToc(docstring & os, size_t) const
{
os += screenLabel();
}
// Have to overwrite the default InsetCommand method in order to check that
// the \cite command is valid. Eg, the user has natbib enabled, inputs some
// citations and then changes his mind, turning natbib support off. The output

View File

@ -53,6 +53,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
void validate(LaTeXFeatures &) const;
///
void updateBuffer(ParIterator const & it, UpdateType);

View File

@ -67,8 +67,8 @@ void InsetFoot::addToToc(DocIterator const & cpit)
pit.push_back(CursorSlice(*this));
Toc & toc = buffer().tocBackend().toc("footnote");
docstring str;
str = custom_label_ + ": " + text().getPar(0).asString();
docstring str = custom_label_ + ": ";
text().forToc(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, toolTipText()));
// Proceed with the rest of the inset.
InsetFootlike::addToToc(cpit);

View File

@ -242,6 +242,17 @@ void InsetHyperlink::toString(odocstream & os) const
}
void InsetHyperlink::forToc(docstring & os, size_t) const
{
docstring const & n = getParam("name");
if (!n.empty()) {
os += n;
return;
}
os += getParam("target");
}
docstring InsetHyperlink::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y*/) const
{
docstring url = getParam("target");

View File

@ -38,6 +38,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
docstring toolTip(BufferView const & bv, int x, int y) const;
///
docstring contextMenuName() const;

View File

@ -360,8 +360,9 @@ void InsetIndex::addToToc(DocIterator const & cpit)
{
DocIterator pit = cpit;
pit.push_back(CursorSlice(*this));
docstring const item = text().asString(0, 1, AS_STR_LABEL | AS_STR_INSETS);
buffer().tocBackend().toc("index").push_back(TocItem(pit, 0, item));
docstring str;
text().forToc(str, TOC_ENTRY_LENGTH);
buffer().tocBackend().toc("index").push_back(TocItem(pit, 0, str));
// Proceed with the rest of the inset.
InsetCollapsable::addToToc(cpit);
}

View File

@ -58,7 +58,7 @@ void InsetMarginal::addToToc(DocIterator const & cpit)
Toc & toc = buffer().tocBackend().toc("marginalnote");
docstring str;
str = text().getPar(0).asString();
text().forToc(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, toolTipText()));
// Proceed with the rest of the inset.
InsetFootlike::addToToc(cpit);

View File

@ -202,8 +202,8 @@ void InsetNote::addToToc(DocIterator const & cpit)
Toc & toc = buffer().tocBackend().toc("note");
InsetLayout const & il = getLayout();
docstring const label = translateIfPossible(il.labelstring());
docstring const str = label + from_ascii(": ") + text().getPar(0).asString();
docstring str = translateIfPossible(il.labelstring()) + from_ascii(": ");
text().forToc(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, toolTipText()));
// Proceed with the rest of the inset.
InsetCollapsable::addToToc(cpit);

View File

@ -333,6 +333,12 @@ void InsetQuotes::toString(odocstream & os) const
}
void InsetQuotes::forToc(docstring & os, size_t) const
{
os += displayString();
}
void InsetQuotes::validate(LaTeXFeatures & features) const
{
bool const use_babel = features.useBabel();

View File

@ -88,6 +88,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t maxlen) const;
///
void validate(LaTeXFeatures &) const;

View File

@ -237,6 +237,14 @@ void InsetRef::toString(odocstream & os) const
}
void InsetRef::forToc(docstring & os, size_t) const
{
odocstringstream ods;
plaintext(ods, OutputParams(0));
os += ods.str();
}
void InsetRef::updateBuffer(ParIterator const & it, UpdateType)
{
docstring const & ref = getParam("reference");

View File

@ -61,6 +61,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
void validate(LaTeXFeatures & features) const;
///
void updateBuffer(ParIterator const & it, UpdateType);

View File

@ -740,6 +740,13 @@ void InsetSpace::toString(odocstream & os) const
}
void InsetSpace::forToc(docstring & os, size_t) const
{
// There's no need to be cute here.
os += " ";
}
bool InsetSpace::isStretchableSpace() const
{
return params_.kind == InsetSpaceParams::HFILL

View File

@ -132,6 +132,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
bool hasSettings() const { return true; }
///
InsetCode lyxCode() const { return SPACE_CODE; }

View File

@ -324,6 +324,14 @@ void InsetSpecialChar::toString(odocstream & os) const
}
void InsetSpecialChar::forToc(docstring & os, size_t) const
{
odocstringstream ods;
plaintext(ods, OutputParams(0));
os += ods.str();
}
void InsetSpecialChar::validate(LaTeXFeatures & features) const
{
if (kind_ == MENU_SEPARATOR)

View File

@ -69,6 +69,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
InsetCode lyxCode() const { return SPECIALCHAR_CODE; }
/// We don't need \begin_inset and \end_inset
bool directWrite() const { return true; }

View File

@ -674,6 +674,13 @@ void InsetText::toString(odocstream & os) const
}
void InsetText::forToc(docstring & os, size_t maxlen) const
{
if (!getLayout().isInToc())
return;
text().forToc(os, maxlen, false);
}
void InsetText::addToToc(DocIterator const & cdit)
{
@ -682,7 +689,7 @@ void InsetText::addToToc(DocIterator const & cdit)
Toc & toc = buffer().tocBackend().toc("tableofcontents");
BufferParams const & bufparams = buffer_->params();
const int min_toclevel = bufparams.documentClass().min_toclevel();
int const min_toclevel = bufparams.documentClass().min_toclevel();
// For each paragraph, traverse its insets and let them add
// their toc items
@ -700,21 +707,8 @@ void InsetText::addToToc(DocIterator const & cdit)
dit.pos() = it->pos;
//lyxerr << (void*)&inset << " code: " << inset.lyxCode() << std::endl;
inset.addToToc(dit);
switch (inset.lyxCode()) {
case ARG_CODE: {
if (!tocstring.empty())
break;
dit.pos() = 0;
Paragraph const & insetpar =
*static_cast<InsetArgument&>(inset).paragraphs().begin();
if (!par.labelString().empty())
tocstring = par.labelString() + ' ';
tocstring += insetpar.asString(AS_STR_INSETS | AS_STR_INTOC);
break;
}
default:
break;
}
if (inset.lyxCode() == ARG_CODE && tocstring.empty())
inset.asInsetText()->text().forToc(tocstring, TOC_ENTRY_LENGTH);
}
// now the toc entry for the paragraph
int const toclevel = par.layout().toclevel;
@ -722,7 +716,7 @@ void InsetText::addToToc(DocIterator const & cdit)
dit.pos() = 0;
// insert this into the table of contents
if (tocstring.empty())
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS | AS_STR_INTOC);
par.forToc(tocstring, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(dit, toclevel - min_toclevel,
tocstring, tocstring));
}

View File

@ -166,6 +166,8 @@ public:
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
///
void addToToc(DocIterator const &);
///
Inset * clone() const { return new InsetText(*this); }

View File

@ -1989,6 +1989,14 @@ void InsetMathHull::toString(odocstream & os) const
}
void InsetMathHull::forToc(docstring & os, size_t) const
{
odocstringstream ods;
plaintext(ods, OutputParams(0));
os += ods.str();
}
docstring InsetMathHull::contextMenuName() const
{
return from_ascii("context-math");

View File

@ -132,6 +132,8 @@ public:
docstring xhtml(XHTMLStream &, OutputParams const &) const;
///
void toString(odocstream &) const;
///
void forToc(docstring &, size_t) const;
/// get notification when the cursor leaves this inset
bool notifyCursorLeaves(Cursor const & old, Cursor & cur);