diff --git a/src/tex2lyx/Context.cpp b/src/tex2lyx/Context.cpp index 283846e7cf..f214f770ee 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 64d69e3561..2d5315b5df 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 5b12dddb9e..37f7deedc1 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 b15f95aa41..0912523674 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. * \begin{name} must be parsed already, \end{name} diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt index d813c064fe..840aac91c8 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 4dd5fa7589..51b5e931e2 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();