commit 57157d2e4d156812f574eff54ef0c5a7ed64bb18
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Sun Mar 31 14:27:56 2019 +0200

    tex2lyx: support for list preambles
---
 src/tex2lyx/Context.cpp |    2 +-
 src/tex2lyx/Context.h   |    6 ++++++
 src/tex2lyx/Parser.cpp  |   20 ++++++++++++++++++++
 src/tex2lyx/Parser.h    |    2 ++
 src/tex2lyx/TODO.txt    |    1 -
 src/tex2lyx/text.cpp    |   29 +++++++++++++++++++++++++++++
 6 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/src/tex2lyx/Context.cpp b/src/tex2lyx/Context.cpp
index 283846e..f214f77 100644
--- a/src/tex2lyx/Context.cpp
+++ b/src/tex2lyx/Context.cpp
@@ -81,7 +81,7 @@ Context::Context(bool need_layout_,
                 TeXFont const & font_)
        : need_layout(need_layout_),
          need_end_layout(false), need_end_deeper(false),
-         has_item(false), deeper_paragraph(false),
+         has_item(false), in_list_preamble(false), deeper_paragraph(false),
          new_layout_allowed(true), merging_hyphens_allowed(true),
          textclass(textclass_),
          layout(layout_), parent_layout(parent_layout_),
diff --git a/src/tex2lyx/Context.h b/src/tex2lyx/Context.h
index 64d69e3..2d5315b 100644
--- a/src/tex2lyx/Context.h
+++ b/src/tex2lyx/Context.h
@@ -130,6 +130,8 @@ public:
        std::string par_extra_stuff;
        /// We may need to add something at the beginning of a list.
        std::string list_extra_stuff;
+       /// Stuff between list begin and first item
+       std::string list_preamble;
        /// A LaTeXParam to be ignored in parsing.
        std::string latexparam;
        /// If there has been an \\begin_deeper, we'll need a matching
@@ -139,6 +141,10 @@ public:
        /// for each paragraph, otherwise this has to be a deeper
        /// paragraph.
        bool has_item;
+       /// If we are in an itemize-like environment, this marks
+       /// the text before the first \item. Typically, list
+       /// parameters (such as lengths) are adjusted here.
+       bool in_list_preamble;
        /// we are handling a standard paragraph in an itemize-like
        /// environment
        bool deeper_paragraph;
diff --git a/src/tex2lyx/Parser.cpp b/src/tex2lyx/Parser.cpp
index 5b12ddd..37f7dee 100644
--- a/src/tex2lyx/Parser.cpp
+++ b/src/tex2lyx/Parser.cpp
@@ -577,6 +577,26 @@ string Parser::getFullParentheseArg()
 }
 
 
+bool Parser::hasListPreamble(string const itemcmd)
+{
+       // remember current position
+       unsigned int oldpos = pos_;
+       // jump over arguments
+       if (hasOpt())
+               getOpt();
+       if (hasOpt("{"))
+               getArg('{', '}');
+       // and swallow spaces and comments
+       skip_spaces(true);
+       // we have a preamvle if the next thing that follows is not
+       // the \item command
+       bool res =  next_token().cs() != itemcmd;
+       // back to orig position
+       pos_ = oldpos;
+       return res;
+}
+
+
 string const Parser::ertEnvironment(string const & name)
 {
        if (!good())
diff --git a/src/tex2lyx/Parser.h b/src/tex2lyx/Parser.h
index b15f95a..0912523 100644
--- a/src/tex2lyx/Parser.h
+++ b/src/tex2lyx/Parser.h
@@ -259,6 +259,8 @@ public:
         * empty string if there is no such argument.
         */
        std::string getFullParentheseArg();
+       /// Check if we have a list preamble
+       bool hasListPreamble(std::string const itemcmd);
        /*!
         * \returns the contents of the environment \p name.
         * <tt>\begin{name}</tt> must be parsed already, <tt>\end{name}</tt>
diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt
index d813c06..840aac9 100644
--- a/src/tex2lyx/TODO.txt
+++ b/src/tex2lyx/TODO.txt
@@ -34,7 +34,6 @@ Format LaTeX feature                        LyX feature
 443    unicode-math.sty                     InsetMath*
 453    automatic stmaryrd loading           \use_package stmaryrd
 457    automatic stackrel loading           \use_package stackrel
-563    InsetArgument listpreamble:1         All content between \begin{env} 
and first \item of a list
 568    Soul package                         soul.module
        \caps{...}                           \begin_inset Flex Capitalize
        \hl{...}                             \begin_inset Flex Highlight
diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp
index 4dd5fa7..51b5e93 100644
--- a/src/tex2lyx/text.cpp
+++ b/src/tex2lyx/text.cpp
@@ -2300,6 +2300,9 @@ void parse_environment(Parser & p, ostream & os, bool 
outer,
                        }
                        switch (context.layout->latextype) {
                        case  LATEX_LIST_ENVIRONMENT:
+                               context.in_list_preamble =
+                                       !context.layout->listpreamble().empty()
+                                       && 
p.hasListPreamble(context.layout->itemcommand());
                                context.add_par_extra_stuff("\\labelwidthstring 
"
                                                            + p.verbatim_item() 
+ '\n');
                                p.skip_spaces();
@@ -2323,11 +2326,20 @@ void parse_environment(Parser & p, ostream & os, bool 
outer,
                                output_arguments(os, p, outer, false, string(), 
context,
                                                 context.layout->latexargs());
                        else if (context.layout->latextype == 
LATEX_ITEM_ENVIRONMENT) {
+                               context.in_list_preamble =
+                                       !context.layout->listpreamble().empty()
+                                       && 
p.hasListPreamble(context.layout->itemcommand());
                                ostringstream oss;
                                output_arguments(oss, p, outer, false, 
string(), context,
                                                 context.layout->latexargs());
                                context.list_extra_stuff = oss.str();
                        }
+                       if (context.in_list_preamble) {
+                               // Collect the stuff between \begin and first 
\item
+                               context.list_preamble =
+                                       parse_text_snippet(p, FLAG_END, outer, 
context);
+                               context.in_list_preamble = false;
+                       }
                        parse_text(p, os, FLAG_END, outer, context);
                        if (context.layout->latextype == LATEX_ENVIRONMENT)
                                output_arguments(os, p, outer, false, "post", 
context,
@@ -2907,6 +2919,13 @@ void parse_text(Parser & p, ostream & os, unsigned 
flags, bool outer,
                debugToken(cerr, t, flags);
 #endif
 
+               if (context.in_list_preamble
+                   && p.next_token().cs() == context.layout->itemcommand()) {
+                       // We are parsing a list preamble. End before first 
\item.
+                       flags |= FLAG_LEAVE;
+                       context.in_list_preamble = false;
+               }
+
                if (flags & FLAG_ITEM) {
                        if (t.cat() == catSpace)
                                continue;
@@ -3351,6 +3370,16 @@ void parse_text(Parser & p, ostream & os, unsigned 
flags, bool outer,
                        if (context.layout->labeltype != LABEL_MANUAL)
                                output_arguments(os, p, outer, false, "item", 
context,
                                                 context.layout->itemargs());
+                       if (!context.list_preamble.empty()) {
+                               // We have a list preamble. Output it here.
+                               begin_inset(os, "Argument listpreamble:1");
+                               os << "\nstatus collapsed\n\n"
+                                  << "\\begin_layout Plain Layout\n\n"
+                                  << rtrim(context.list_preamble)
+                                  << "\n\\end_layout";
+                               end_inset(os);
+                               context.list_preamble.clear();
+                       }
                        if (!context.list_extra_stuff.empty()) {
                                os << context.list_extra_stuff;
                                context.list_extra_stuff.clear();

Reply via email to