Native support for \lstlistoflistings

This commit is contained in:
Georg Baum 2012-04-16 21:40:59 +02:00
parent 503bd6cf71
commit 27733452f7
11 changed files with 173 additions and 24 deletions

View File

@ -39685,6 +39685,27 @@ reference "lst:Example-Listing"
\end_inset \end_inset
\change_inserted -195340706 1334604968
.
A list of listings which contains all listings with captions can be created
via the
\family sans
Insert\SpecialChar \menuseparator
List
\begin_inset space ~
\end_inset
/
\begin_inset space ~
\end_inset
TOC\SpecialChar \menuseparator
List of Listings
\family default
submenu.
The list entries are the listing caption and the listing number.
\change_unchanged
\end_layout \end_layout
\begin_layout Standard \begin_layout Standard

View File

@ -170,22 +170,32 @@ InsetLayout Phantom
ForcePlain true ForcePlain true
End End
InsetLayout IncludeListings InsetLayout ListOfListings
# We need the [[List of Listings]] context, since "Listings" is also # We need the [[List of Listings]] context, since "Listings" is also
# the name of the inset and translated differently. # the name of the inset and translated differently.
# "Listings[[List of Listings]]" is the name of the "List of listings" # "Listings[[List of Listings]]" is the name of the "List of listings"
# ("Listings" is the predefined english name) in listings.sty, so it # ("Listings" is the predefined english name) in listings.sty, so it
# must be used here as well. # must be used here as well.
BabelPreamble BabelPreamble
\addto\captions$$lang{\renewcommand{\lstlistingname}{_(Listing)}}
\addto\captions$$lang{\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}} \addto\captions$$lang{\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}}
EndBabelPreamble EndBabelPreamble
# The commands do not need to be defined in LangPreamble, since # The command does not need to be defined in LangPreamble, since
# listings.sty does that already. However they need to be redefined # listings.sty does that already. However it needs to be redefined
# in order to be used for non-english single-language documents.
LangPreamble
\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}
EndLangPreamble
End
InsetLayout IncludeListings
BabelPreamble
\addto\captions$$lang{\renewcommand{\lstlistingname}{_(Listing)}}
EndBabelPreamble
# The command does not need to be defined in LangPreamble, since
# listings.sty does that already. However it needs to be redefined
# in order to be used for non-english single-language documents. # in order to be used for non-english single-language documents.
LangPreamble LangPreamble
\renewcommand{\lstlistingname}{_(Listing)} \renewcommand{\lstlistingname}{_(Listing)}
\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}
EndLangPreamble EndLangPreamble
End End

View File

@ -60,7 +60,7 @@ latex_length(slen):
''' '''
import string import string
from parser_tools import find_token from parser_tools import find_token, find_end_of_inset
from unicode_symbols import unicode_reps from unicode_symbols import unicode_reps
@ -131,7 +131,38 @@ def put_cmd_in_ert(arg):
ret += ["\\end_layout", "\\end_inset"] ret += ["\\end_layout", "\\end_inset"]
return ret return ret
def get_ert(lines, i):
'Convert an ERT inset into LaTeX.'
if not lines[i].startswith("\\begin_inset ERT"):
return ""
j = find_end_of_inset(lines, i)
if j == -1:
return ""
while i < j and not lines[i].startswith("status"):
i = i + 1
i = i + 1
ret = ""
first = True
while i < j:
if lines[i] == "\\begin_layout Plain Layout":
if first:
first = False
else:
ret = ret + "\n"
while i + 1 < j and lines[i+1] == "":
i = i + 1
elif lines[i] == "\\end_layout":
while i + 1 < j and lines[i+1] == "":
i = i + 1
elif lines[i] == "\\backslash":
ret = ret + "\\"
else:
ret = ret + lines[i]
i = i + 1
return ret
def lyx2latex(document, lines): def lyx2latex(document, lines):
'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.' 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'

View File

@ -34,10 +34,10 @@ from parser_tools import del_token, find_token, find_end_of, find_end_of_inset,
#find_token_backwards, is_in_inset, get_value, get_quoted_value, \ #find_token_backwards, is_in_inset, get_value, get_quoted_value, \
#del_token, check_token #del_token, check_token
from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
#from lyx2lyx_tools import insert_to_preamble, \ #from lyx2lyx_tools import insert_to_preamble, \
# put_cmd_in_ert, lyx2latex, latex_length, revert_flex_inset, \ # lyx2latex, latex_length, revert_flex_inset, \
# revert_font_attrs, hex2ratio, str2bool # revert_font_attrs, hex2ratio, str2bool
#################################################################### ####################################################################
@ -690,6 +690,46 @@ def convert_table_rotation(document):
i += 1 i += 1
def convert_listoflistings(document):
'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
# We can support roundtrip because the command is so simple
i = 0
while True:
i = find_token(document.body, "\\begin_inset ERT", i)
if i == -1:
return
j = find_end_of_inset(document.body, i)
if j == -1:
document.warning("Malformed lyx document: Can't find end of ERT inset")
i += 1
continue
ert = get_ert(document.body, i)
if ert == "\\lstlistoflistings{}":
document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
i = i + 4
else:
i = j + 1
def revert_listoflistings(document):
'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
i = 0
while True:
i = find_token(document.body, "\\begin_inset CommandInset toc", i)
if i == -1:
return
if document.body[i+1] == "LatexCommand lstlistoflistings":
j = find_end_of_inset(document.body, i)
if j == -1:
document.warning("Malformed lyx document: Can't find end of TOC inset")
i += 1
continue
subst = put_cmd_in_ert("\\lstlistoflistings{}")
document.body[i:j+1] = subst
add_to_preamble(document, ["\\usepackage{listings}"])
i = i + 1
## ##
# Conversion hub # Conversion hub
# #
@ -711,10 +751,12 @@ convert = [
[426, []], [426, []],
[427, []], [427, []],
[428, [convert_cell_rotation]], [428, [convert_cell_rotation]],
[429, [convert_table_rotation]] [429, [convert_table_rotation]],
[430, [convert_listoflistings]],
] ]
revert = [ revert = [
[429, [revert_listoflistings]],
[428, [revert_table_rotation]], [428, [revert_table_rotation]],
[427, [revert_cell_rotation]], [427, [revert_cell_rotation]],
[426, [revert_tipa]], [426, [revert_tipa]],

View File

@ -451,6 +451,7 @@ Menuset
Item "Table of Contents|C" "inset-insert toc" Item "Table of Contents|C" "inset-insert toc"
FloatListInsert FloatListInsert
IndicesLists IndicesLists
Item "List of Listings|L" "inset-insert toc CommandInset toc LatexCommand lstlistoflistings \end_inset"
Item "Nomenclature|N" "nomencl-print" Item "Nomenclature|N" "nomencl-print"
Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex" Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex"
End End

View File

@ -496,9 +496,11 @@ void TocWidget::filterContents()
static QString decodeType(QString const & str) static QString decodeType(QString const & str)
{ {
QString type = str; QString type = str;
if (type.contains("tableofcontents")) { if (type.contains("tableofcontents"))
type = "tableofcontents"; type = "tableofcontents";
} else if (type.contains("floatlist")) { else if (type.contains("lstlistoflistings"))
type = "listing";
else if (type.contains("floatlist")) {
if (type.contains("\"figure")) if (type.contains("\"figure"))
type = "figure"; type = "figure";
else if (type.contains("\"table")) else if (type.contains("\"table"))

View File

@ -37,6 +37,15 @@ using namespace std;
namespace lyx { namespace lyx {
namespace {
string cmd2type(string const & cmd)
{
if (cmd == "lstlistoflistings")
return "listing";
return cmd;
}
}
InsetTOC::InsetTOC(Buffer * buf, InsetCommandParams const & p) InsetTOC::InsetTOC(Buffer * buf, InsetCommandParams const & p)
: InsetCommand(buf, p) : InsetCommand(buf, p)
@ -53,10 +62,18 @@ ParamInfo const & InsetTOC::findInfo(string const & /* cmdName */)
} }
bool InsetTOC::isCompatibleCommand(string const & cmd)
{
return cmd == defaultCommand() || cmd == "lstlistoflistings";
}
docstring InsetTOC::screenLabel() const docstring InsetTOC::screenLabel() const
{ {
if (getCmdName() == "tableofcontents") if (getCmdName() == "tableofcontents")
return buffer().B_("Table of Contents"); return buffer().B_("Table of Contents");
if (getCmdName() == "lstlistoflistings")
return buffer().B_("List of Listings");
return _("Unknown TOC type"); return _("Unknown TOC type");
} }
@ -76,10 +93,27 @@ void InsetTOC::doDispatch(Cursor & cur, FuncRequest & cmd) {
} }
docstring InsetTOC::layoutName() const
{
if (getCmdName() == "lstlistoflistings")
return from_ascii("ListOfListings");
return docstring();
}
void InsetTOC::validate(LaTeXFeatures & features) const
{
InsetCommand::validate(features);
features.useInsetLayout(getLayout());
if (getCmdName() == "lstlistoflistings")
features.require("listings");
}
int InsetTOC::plaintext(odocstream & os, OutputParams const &) const int InsetTOC::plaintext(odocstream & os, OutputParams const &) const
{ {
os << screenLabel() << "\n\n"; os << screenLabel() << "\n\n";
buffer().tocBackend().writePlaintextTocList(getCmdName(), os); buffer().tocBackend().writePlaintextTocList(cmd2type(getCmdName()), os);
return PLAINTEXT_NEWLINE; return PLAINTEXT_NEWLINE;
} }
@ -94,6 +128,9 @@ int InsetTOC::docbook(odocstream & os, OutputParams const &) const
docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
{ {
if (getCmdName() != "tableofcontents")
return docstring();
Layout const & lay = buffer().params().documentClass().htmlTOCLayout(); Layout const & lay = buffer().params().documentClass().htmlTOCLayout();
string const & tocclass = lay.defaultCSSClass(); string const & tocclass = lay.defaultCSSClass();
string const tocattr = "class='tochead " + tocclass + "'"; string const tocattr = "class='tochead " + tocclass + "'";
@ -104,15 +141,14 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
odocstringstream ods; odocstringstream ods;
XHTMLStream xs(ods); XHTMLStream xs(ods);
Toc const & toc = buffer().tocBackend().toc("tableofcontents"); Toc const & toc = buffer().tocBackend().toc(cmd2type(getCmdName()));
if (toc.empty()) if (toc.empty())
return docstring(); return docstring();
xs << html::StartTag("div", "class='toc'"); xs << html::StartTag("div", "class='toc'");
// Title of TOC // Title of TOC
static string toctitle = N_("Table of Contents"); docstring title = screenLabel();
docstring title = buffer().B_(toctitle);
xs << html::StartTag("div", tocattr) xs << html::StartTag("div", tocattr)
<< title << title
<< html::EndTag("div"); << html::EndTag("div");

View File

@ -19,8 +19,8 @@ namespace lyx {
/// Used to insert table of contents and similar lists /// Used to insert table of contents and similar lists
/// at present, supports only \tableofcontents. Other /// at present, supports only \tableofcontents and \listoflistings.
/// such commands, such as \listoffigures, are supported /// Other such commands, such as \listoffigures, are supported
/// by InsetFloatList. /// by InsetFloatList.
class InsetTOC : public InsetCommand { class InsetTOC : public InsetCommand {
public: public:
@ -32,8 +32,12 @@ public:
/// ///
InsetCode lyxCode() const { return TOC_CODE; } InsetCode lyxCode() const { return TOC_CODE; }
/// ///
docstring layoutName() const;
///
DisplayType display() const { return AlignCenter; } DisplayType display() const { return AlignCenter; }
/// ///
virtual void validate(LaTeXFeatures &) const;
///
int plaintext(odocstream &, OutputParams const &) const; int plaintext(odocstream &, OutputParams const &) const;
/// ///
int docbook(odocstream &, OutputParams const &) const; int docbook(odocstream &, OutputParams const &) const;
@ -52,8 +56,7 @@ public:
/// ///
static std::string defaultCommand() { return "tableofcontents"; } static std::string defaultCommand() { return "tableofcontents"; }
/// ///
static bool isCompatibleCommand(std::string const & cmd) static bool isCompatibleCommand(std::string const & cmd);
{ return cmd == defaultCommand(); }
//@} //@}
private: private:

View File

@ -43,6 +43,7 @@
\begin{document} \begin{document}
\tableofcontents \tableofcontents
\lstlistoflistings
\noindent This paragraph is not indented. \noindent This paragraph is not indented.

View File

@ -2815,11 +2815,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
handle_ert(os, t.asInput(), context); handle_ert(os, t.asInput(), context);
} }
else if (t.cs() == "tableofcontents") { else if (t.cs() == "tableofcontents" || t.cs() == "lstlistoflistings") {
context.check_layout(os); context.check_layout(os);
begin_command_inset(os, "toc", "tableofcontents"); begin_command_inset(os, "toc", t.cs());
end_inset(os); end_inset(os);
skip_spaces_braces(p); skip_spaces_braces(p);
if (t.cs() == "lstlistoflistings")
preamble.registerAutomaticallyLoadedPackage("listings");
} }
else if (t.cs() == "listoffigures") { else if (t.cs() == "listoffigures") {

View File

@ -30,8 +30,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in // Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own. // independent branches. Instead add your own.
#define LYX_FORMAT_LYX 429 // uwestoehr: rotated tables #define LYX_FORMAT_LYX 430 // gb: listoflistings
#define LYX_FORMAT_TEX2LYX 429 // uwestoehr: rotated tables #define LYX_FORMAT_TEX2LYX 430 // gb: listoflistings
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER #ifndef _MSC_VER