Initial work for InsetTOC. This does actually write a TOC, but without

any links. That is the next step.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32459 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2009-12-10 18:30:48 +00:00
parent d2f85c7978
commit ffe73b795b
9 changed files with 139 additions and 12 deletions

View File

@ -122,6 +122,8 @@ public:
///
std::string const & htmllabelattr() const;
///
std::string defaultCSSClass() const;
///
bool htmllabelfirst() const { return htmllabelfirst_; }
///
docstring htmlstyle() const;
@ -254,8 +256,6 @@ private:
/// generates the default CSS for this layout
void makeDefaultCSS() const;
///
std::string defaultCSSClass() const;
///
std::string defaultCSSItemClass() const { return defaultCSSClass() + "_item"; }
///
std::string defaultCSSLabelClass() const { return defaultCSSClass() + "_label"; }

View File

@ -2394,6 +2394,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
XHTMLStream & xs,
OutputParams const & runparams,
Font const & outerfont,
bool fortoc,
pos_type initial) const
{
docstring retval;
@ -2435,11 +2436,14 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
Inset const * inset = getInset(i);
if (inset) {
InsetCommand const * ic = inset->asInsetCommand();
InsetLayout const & il = inset->getLayout();
OutputParams np = runparams;
if (!il.htmlisblock())
np.html_in_par = true;
retval += inset->xhtml(xs, np);
if (!fortoc || il.isInToc() || (ic && ic->isInToc())) {
OutputParams np = runparams;
if (!il.htmlisblock())
np.html_in_par = true;
retval += inset->xhtml(xs, np);
}
} else {
char_type c = d->text_[i];

View File

@ -166,6 +166,7 @@ public:
XHTMLStream & xs,
OutputParams const & runparams,
Font const & outerfont,
bool fortoc = false,
pos_type initial = 0) const;
///

View File

@ -37,6 +37,7 @@ class DocIterator;
class FuncRequest;
class FuncStatus;
class InsetCollapsable;
class InsetCommand;
class InsetIterator;
class InsetLayout;
class InsetList;
@ -138,6 +139,10 @@ public:
virtual InsetTabular * asInsetTabular() { return 0; }
/// is this inset based on the InsetTabular class?
virtual InsetTabular const * asInsetTabular() const { return 0; }
/// is this inset based on the InsetCommand class?
virtual InsetCommand * asInsetCommand() { return 0; }
/// is this inset based on the InsetCommand class?
virtual InsetCommand const * asInsetCommand() const { return 0; }
/// the real dispatcher
void dispatch(Cursor & cur, FuncRequest & cmd);

View File

@ -58,6 +58,12 @@ public:
docstring const getFirstNonOptParam() const { return p_.getFirstNonOptParam(); }
/// update label and references.
virtual void updateCommand(docstring const &, bool) {}
///
virtual InsetCommand * asInsetCommand() { return this; }
///
virtual InsetCommand const * asInsetCommand() const { return this; }
/// whether to include this inset in the strings generated for the TOC
virtual bool isInToc() const { return false; }
protected:
///
@ -109,8 +115,6 @@ private:
virtual docstring screenLabel() const = 0;
///
bool showInsetDialog(BufferView * bv) const;
private:
///
InsetCommandParams p_;
///

View File

@ -47,12 +47,14 @@ public:
///
static ParamInfo const & findInfo(std::string const &);
///
static std::string defaultCommand() { return "href"; };
static std::string defaultCommand() { return "href"; }
///
static bool isCompatibleCommand(std::string const & s)
{ return s == "href"; }
/// Force inset into LTR environment if surroundings are RTL?
bool forceLTR() const { return true; }
///
virtual bool isInToc() const { return true; }
private:
Inset * clone() const { return new InsetHyperlink(*this); }
};

View File

@ -13,12 +13,18 @@
#include "InsetTOC.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "LaTeXFeatures.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
#include "output_xhtml.h"
#include "Paragraph.h"
#include "TextClass.h"
#include "TocBackend.h"
#include "support/debug.h"
#include "support/gettext.h"
#include <ostream>
@ -67,4 +73,99 @@ int InsetTOC::docbook(odocstream & os, OutputParams const &) const
}
docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
{
// we'll use our own stream, because we are going to defer everything.
// that's how we deal with the fact that we're probably inside a standard
// paragraph, and we don't want to be.
odocstringstream ods;
XHTMLStream xs(ods);
// FIXME XHTML
// This is temporary. We'll get the main TOC working first. The rest will
// then be a fairly simple adapation of this code, I hope.
if (getCmdName() != "tableofcontents")
return docstring();
Toc const & toc = buffer().tocBackend().toc("tableofcontents");
if (toc.empty())
return docstring();
xs << StartTag("div", "class='toc'");
// we want to figure out look like a chapter, section, or whatever.
// so we're going to look for the layout with the minimum toclevel
// number. we'll take the first one, just because.
DocumentClass const & dc = buffer().params().documentClass();
TextClass::LayoutList::const_iterator lit = dc.begin();
TextClass::LayoutList::const_iterator len = dc.end();
int minlevel = 1000;
Layout const * lay = NULL;
for (; lit != len; ++lit) {
int const level = lit->toclevel;
if (level == Layout::NOT_IN_TOC || level >= minlevel)
continue;
lay = &*lit;
minlevel = level;
}
string const tocclass = lay ? lay->defaultCSSClass() + " ": "";
string const tocattr = "class='" + tocclass + "tochead'";
xs << StartTag("div", tocattr)
<< _("Table of Contents")
<< EndTag("div");
Toc::const_iterator it = toc.begin();
Toc::const_iterator const en = toc.end();
int lastdepth = 0;
for (; it != en; ++it) {
Paragraph const & par = it->dit().innerParagraph();
Font const dummy;
int const depth = it->depth();
if (depth > lastdepth) {
xs.cr();
// open as many tags as we need to open to get to this level
// this includes the tag for the current level
for (int i = lastdepth + 1; i <= depth; ++i) {
stringstream attr;
attr << "class='lyxtoc-" << i << "'";
xs << StartTag("div", attr.str());
}
lastdepth = depth;
}
else if (depth < lastdepth) {
// close as many as we have to close to get back to this level
// this includes closing the last tag at this level
for (int i = lastdepth; i >= depth; --i)
xs << EndTag("div");
// now open our tag
stringstream attr;
attr << "class='lyxtoc-" << depth << "'";
xs << StartTag("div", attr.str());
lastdepth = depth;
} else {
// no change of level, so close and open
xs << EndTag("div");
stringstream attr;
attr << "class='lyxtoc-" << depth << "'";
xs << StartTag("div", attr.str());
}
par.simpleLyXHTMLOnePar(buffer(), xs, op, dummy, true);
}
for (int i = lastdepth; i > 0; --i)
xs << EndTag("div");
xs << EndTag("div");
return ods.str();
}
void InsetTOC::validate(LaTeXFeatures & features) const
{
if (features.runparams().flavor != OutputParams::HTML)
return;
features.addPreambleSnippet("<style type=\"text/css\">\n"
"div.lyxtoc-1 { margin-left: 2em; text-indent: -2em; }\n"
"span.bibtexlabel:before{ content: \"[\"; }\n"
"span.bibtexlabel:after{ content: \"] \"; }\n"
"</style>");
}
} // namespace lyx

View File

@ -34,12 +34,16 @@ public:
///
int docbook(odocstream &, OutputParams const &) const;
///
docstring xhtml(XHTMLStream & xs, OutputParams const &) const;
///
static ParamInfo const & findInfo(std::string const &);
///
static std::string defaultCommand() { return "tableofcontents"; };
static std::string defaultCommand() { return "tableofcontents"; }
///
static bool isCompatibleCommand(std::string const & cmd)
{ return cmd == defaultCommand(); }
///
void validate(LaTeXFeatures & features) const;
private:
Inset * clone() const { return new InsetTOC(*this); }
};

View File

@ -238,6 +238,7 @@ void XHTMLStream::clearTagDeque()
StartTag const & tag = pending_tags_.front();
// tabs?
os_ << tag.asTag();
cr();
tag_stack_.push_back(tag);
pending_tags_.pop_front();
}
@ -306,6 +307,7 @@ XHTMLStream & XHTMLStream::operator<<(CompTag const & tag)
clearTagDeque();
// tabs?
os_ << tag.asTag();
cr();
return *this;
}
@ -350,7 +352,8 @@ XHTMLStream & XHTMLStream::operator<<(EndTag const & etag)
if (dit->tag_ == etag.tag_) {
// it was pending, so we just erase it
writeError("Tried to close pending tag `" + etag.tag_
+ "' when other tags were pending. Tag discarded.");
+ "' when other tags were pending. Last pending tag is `"
+ pending_tags_.back().tag_ + "'. Tag discarded.");
pending_tags_.erase(dit);
return *this;
}
@ -378,6 +381,7 @@ XHTMLStream & XHTMLStream::operator<<(EndTag const & etag)
if (etag.tag_ == tag_stack_.back().tag_) {
// output it...
os_ << etag.asEndTag();
cr();
// ...and forget about it
tag_stack_.pop_back();
return *this;
@ -420,12 +424,14 @@ XHTMLStream & XHTMLStream::operator<<(EndTag const & etag)
TagStack fontstack;
while (curtag.tag_ != etag.tag_) {
os_ << curtag.asEndTag();
cr();
fontstack.push_back(curtag);
tag_stack_.pop_back();
curtag = tag_stack_.back();
}
// now close our tag...
os_ << etag.asEndTag();
cr();
tag_stack_.pop_back();
// ...and restore the other tags.
@ -705,7 +711,7 @@ ParagraphList::const_iterator makeEnvironmentHtml(Buffer const & buf,
openItemTag(xs, style);
}
par->simpleLyXHTMLOnePar(buf, xs, runparams,
text.outerFont(distance(begin, par)), sep);
text.outerFont(distance(begin, par)), false, sep);
++par;
// We may not want to close the tag yet, in particular,
// if we're not at the end...