From 27733452f78af8bf172ee55eba12e1fe5c6eccae Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Mon, 16 Apr 2012 21:40:59 +0200 Subject: [PATCH] Native support for \lstlistoflistings --- lib/doc/EmbeddedObjects.lyx | 21 ++++++++++++++ lib/layouts/stdinsets.inc | 20 +++++++++---- lib/lyx2lyx/lyx2lyx_tools.py | 35 +++++++++++++++++++++-- lib/lyx2lyx/lyx_2_1.py | 48 ++++++++++++++++++++++++++++++-- lib/ui/stdmenus.inc | 1 + src/frontends/qt4/TocWidget.cpp | 6 ++-- src/insets/InsetTOC.cpp | 44 ++++++++++++++++++++++++++--- src/insets/InsetTOC.h | 11 +++++--- src/tex2lyx/test/test-insets.tex | 1 + src/tex2lyx/text.cpp | 6 ++-- src/version.h | 4 +-- 11 files changed, 173 insertions(+), 24 deletions(-) diff --git a/lib/doc/EmbeddedObjects.lyx b/lib/doc/EmbeddedObjects.lyx index 89c3636dd8..d8c5a430f0 100644 --- a/lib/doc/EmbeddedObjects.lyx +++ b/lib/doc/EmbeddedObjects.lyx @@ -39685,6 +39685,27 @@ reference "lst:Example-Listing" \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 \begin_layout Standard diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc index faa6d1c9d0..2000172f23 100644 --- a/lib/layouts/stdinsets.inc +++ b/lib/layouts/stdinsets.inc @@ -170,25 +170,35 @@ InsetLayout Phantom ForcePlain true End -InsetLayout IncludeListings +InsetLayout ListOfListings # We need the [[List of Listings]] context, since "Listings" is also # the name of the inset and translated differently. # "Listings[[List of Listings]]" is the name of the "List of listings" # ("Listings" is the predefined english name) in listings.sty, so it # must be used here as well. BabelPreamble - \addto\captions$$lang{\renewcommand{\lstlistingname}{_(Listing)}} \addto\captions$$lang{\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}} EndBabelPreamble - # The commands do not need to be defined in LangPreamble, since - # listings.sty does that already. However they need to be redefined + # 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. LangPreamble - \renewcommand{\lstlistingname}{_(Listing)} \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. + LangPreamble + \renewcommand{\lstlistingname}{_(Listing)} + EndLangPreamble +End + InsetLayout Listings CopyStyle IncludeListings LabelString Listings[[inset]] diff --git a/lib/lyx2lyx/lyx2lyx_tools.py b/lib/lyx2lyx/lyx2lyx_tools.py index ac0b0a6c9e..75006baab5 100644 --- a/lib/lyx2lyx/lyx2lyx_tools.py +++ b/lib/lyx2lyx/lyx2lyx_tools.py @@ -60,7 +60,7 @@ latex_length(slen): ''' import string -from parser_tools import find_token +from parser_tools import find_token, find_end_of_inset from unicode_symbols import unicode_reps @@ -131,7 +131,38 @@ def put_cmd_in_ert(arg): ret += ["\\end_layout", "\\end_inset"] 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): 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.' diff --git a/lib/lyx2lyx/lyx_2_1.py b/lib/lyx2lyx/lyx_2_1.py index 704fef2021..c76cf1baac 100644 --- a/lib/lyx2lyx/lyx_2_1.py +++ b/lib/lyx2lyx/lyx_2_1.py @@ -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, \ #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, \ -# put_cmd_in_ert, lyx2latex, latex_length, revert_flex_inset, \ +# lyx2latex, latex_length, revert_flex_inset, \ # revert_font_attrs, hex2ratio, str2bool #################################################################### @@ -690,6 +690,46 @@ def convert_table_rotation(document): 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 # @@ -711,10 +751,12 @@ convert = [ [426, []], [427, []], [428, [convert_cell_rotation]], - [429, [convert_table_rotation]] + [429, [convert_table_rotation]], + [430, [convert_listoflistings]], ] revert = [ + [429, [revert_listoflistings]], [428, [revert_table_rotation]], [427, [revert_cell_rotation]], [426, [revert_tipa]], diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc index 6ab91f3a18..9a88185dde 100644 --- a/lib/ui/stdmenus.inc +++ b/lib/ui/stdmenus.inc @@ -451,6 +451,7 @@ Menuset Item "Table of Contents|C" "inset-insert toc" FloatListInsert IndicesLists + Item "List of Listings|L" "inset-insert toc CommandInset toc LatexCommand lstlistoflistings \end_inset" Item "Nomenclature|N" "nomencl-print" Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex" End diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index 80c9db97d9..345b40ea21 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -496,9 +496,11 @@ void TocWidget::filterContents() static QString decodeType(QString const & str) { QString type = str; - if (type.contains("tableofcontents")) { + if (type.contains("tableofcontents")) type = "tableofcontents"; - } else if (type.contains("floatlist")) { + else if (type.contains("lstlistoflistings")) + type = "listing"; + else if (type.contains("floatlist")) { if (type.contains("\"figure")) type = "figure"; else if (type.contains("\"table")) diff --git a/src/insets/InsetTOC.cpp b/src/insets/InsetTOC.cpp index 0ab4b65816..3b407b7eb4 100644 --- a/src/insets/InsetTOC.cpp +++ b/src/insets/InsetTOC.cpp @@ -37,6 +37,15 @@ using namespace std; namespace lyx { +namespace { +string cmd2type(string const & cmd) +{ + if (cmd == "lstlistoflistings") + return "listing"; + return cmd; +} +} + InsetTOC::InsetTOC(Buffer * buf, InsetCommandParams const & 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 { if (getCmdName() == "tableofcontents") return buffer().B_("Table of Contents"); + if (getCmdName() == "lstlistoflistings") + return buffer().B_("List of Listings"); 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 { os << screenLabel() << "\n\n"; - buffer().tocBackend().writePlaintextTocList(getCmdName(), os); + buffer().tocBackend().writePlaintextTocList(cmd2type(getCmdName()), os); return PLAINTEXT_NEWLINE; } @@ -94,6 +128,9 @@ int InsetTOC::docbook(odocstream & os, OutputParams const &) const docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const { + if (getCmdName() != "tableofcontents") + return docstring(); + Layout const & lay = buffer().params().documentClass().htmlTOCLayout(); string const & tocclass = lay.defaultCSSClass(); string const tocattr = "class='tochead " + tocclass + "'"; @@ -104,15 +141,14 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const odocstringstream ods; XHTMLStream xs(ods); - Toc const & toc = buffer().tocBackend().toc("tableofcontents"); + Toc const & toc = buffer().tocBackend().toc(cmd2type(getCmdName())); if (toc.empty()) return docstring(); xs << html::StartTag("div", "class='toc'"); // Title of TOC - static string toctitle = N_("Table of Contents"); - docstring title = buffer().B_(toctitle); + docstring title = screenLabel(); xs << html::StartTag("div", tocattr) << title << html::EndTag("div"); diff --git a/src/insets/InsetTOC.h b/src/insets/InsetTOC.h index 9ba7cf06f3..e6e932b3f1 100644 --- a/src/insets/InsetTOC.h +++ b/src/insets/InsetTOC.h @@ -19,8 +19,8 @@ namespace lyx { /// Used to insert table of contents and similar lists -/// at present, supports only \tableofcontents. Other -/// such commands, such as \listoffigures, are supported +/// at present, supports only \tableofcontents and \listoflistings. +/// Other such commands, such as \listoffigures, are supported /// by InsetFloatList. class InsetTOC : public InsetCommand { public: @@ -32,8 +32,12 @@ public: /// InsetCode lyxCode() const { return TOC_CODE; } /// + docstring layoutName() const; + /// DisplayType display() const { return AlignCenter; } /// + virtual void validate(LaTeXFeatures &) const; + /// int plaintext(odocstream &, OutputParams const &) const; /// int docbook(odocstream &, OutputParams const &) const; @@ -52,8 +56,7 @@ public: /// static std::string defaultCommand() { return "tableofcontents"; } /// - static bool isCompatibleCommand(std::string const & cmd) - { return cmd == defaultCommand(); } + static bool isCompatibleCommand(std::string const & cmd); //@} private: diff --git a/src/tex2lyx/test/test-insets.tex b/src/tex2lyx/test/test-insets.tex index 9d9be0dbfb..71a1680253 100644 --- a/src/tex2lyx/test/test-insets.tex +++ b/src/tex2lyx/test/test-insets.tex @@ -43,6 +43,7 @@ \begin{document} \tableofcontents +\lstlistoflistings \noindent This paragraph is not indented. diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 2f59222ed7..db7e7c6d35 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -2815,11 +2815,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, handle_ert(os, t.asInput(), context); } - else if (t.cs() == "tableofcontents") { + else if (t.cs() == "tableofcontents" || t.cs() == "lstlistoflistings") { context.check_layout(os); - begin_command_inset(os, "toc", "tableofcontents"); + begin_command_inset(os, "toc", t.cs()); end_inset(os); skip_spaces_braces(p); + if (t.cs() == "lstlistoflistings") + preamble.registerAutomaticallyLoadedPackage("listings"); } else if (t.cs() == "listoffigures") { diff --git a/src/version.h b/src/version.h index 02bc516c63..8329f8a287 100644 --- a/src/version.h +++ b/src/version.h @@ -30,8 +30,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 429 // uwestoehr: rotated tables -#define LYX_FORMAT_TEX2LYX 429 // uwestoehr: rotated tables +#define LYX_FORMAT_LYX 430 // gb: listoflistings +#define LYX_FORMAT_TEX2LYX 430 // gb: listoflistings #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER -- 2.39.2