]> git.lyx.org Git - features.git/commitdiff
tex2lyx: add support for LaTeXParam
authorJuergen Spitzmueller <spitz@lyx.org>
Fri, 16 Mar 2018 11:56:17 +0000 (12:56 +0100)
committerJuergen Spitzmueller <spitz@lyx.org>
Fri, 16 Mar 2018 11:58:01 +0000 (12:58 +0100)
Part of #11068

src/tex2lyx/Context.h
src/tex2lyx/Parser.cpp
src/tex2lyx/Parser.h
src/tex2lyx/TODO.txt
src/tex2lyx/tex2lyx.cpp
src/tex2lyx/tex2lyx.h
src/tex2lyx/text.cpp

index 47b39fc37c1f8d43e89f9b5d63cdef0da85ddd11..e48bdf35d67b4bf118ef9fb71f1bfce7a0e8f85d 100644 (file)
@@ -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;
+       /// A LaTeXParam to be ignored in parsing.
+       std::string latexparam;
        /// If there has been an \\begin_deeper, we'll need a matching
        /// \\end_deeper
        bool need_end_deeper;
index cf8586b7135d70da799c325839275fa88df04592..5b12dddb9e4854a0683c67f4cfddee1e47f9ba93 100644 (file)
@@ -650,6 +650,27 @@ string const Parser::plainCommand(char left, char right, string const & name)
 }
 
 
+string const Parser::getCommandLatexParam()
+{
+       if (!good())
+               return string();
+       string res;
+       size_t offset = 0;
+       while (true) {
+               if (pos_ + offset >= tokens_.size())
+                       tokenize_one();
+               if (pos_ + offset >= tokens_.size())
+                       break;
+               Token t = tokens_[pos_ + offset];
+               if (t.cat() == catBegin)
+                       break;
+               res += t.asInput();
+               ++offset;
+       }
+       return res;
+}
+
+
 Parser::Arg Parser::verbatimStuff(string const & end_string, bool const allow_linebreak)
 {
        if (!good())
index 83fa1c745a2ae59c3905314295926bf2d6c07c10..b15f95aa4160f9152ee4269de6e01311bbd82b6f 100644 (file)
@@ -278,6 +278,11 @@ public:
         * This function is designed to parse verbatim commands.
         */
        std::string const plainCommand(char left, char right, std::string const & name);
+       /*
+        * Returns everything before the main command argument.
+        * This is where the LaTeXParam value of a layout is output.
+        */
+       std::string const getCommandLatexParam();
        /*
         * Basically the same as plainEnvironment() but the parsing is
         * stopped at string \p end_string. Contrary to the other
index 8ab67dfbd848f8c2855fdcbfa4c328793e92bdb1..0fe7d44e717988fe4816078055f7c740bc00abb1 100644 (file)
@@ -45,7 +45,6 @@ Format LaTeX feature                        LyX feature
 386    LyX version                          InsetInfo
 390    forward/reverse search               \forward_search, \forward_macro
 391    decimal alignment in tables          InsetTabular
-392    new beamer format                    InsetLayout
 399    automatic mathdots loading           \use_mathdots
 407    vertical offset for multirows        InsetTabular
 411    support for polyglossia              \language_package  (the cases of no package, of babel and of custom package is supported)
@@ -53,21 +52,7 @@ Format LaTeX feature                        LyX feature
 443    unicode-math.sty                     InsetMath*
 448
 453    automatic stmaryrd loading           \use_package stmaryrd
-454    beamer overprint environment         InsetArgument, layout Overprint
-       \begin{overprint}[maxlength]
-       \onslide<slide> text ...
-       \end{overprint}
-455    beamer frametitle command            \begin_layout FrameTitle
-       \frametitle<overlay>[short]{long}
 457    automatic stackrel loading           \use_package stackrel
-466    Powerdot updates:
-       \pause[]                              layout Pause
-       \onslide{}{}                          InsetFlex, InsetArgument
-       \onslide*{}{}                         InsetFlex, InsetArgument
-       \onslide+{}{}                         InsetFlex, InsetArgument
-       \twocolumn[]{}{}                      Layout Twocolumn, InsetArgument
-       \item[]<>                             InsetArgument
-       \begin{enumerate|itemize|...}[]       InsetArgument
 526   Plural and capitalized refstyles      InsetRef
 533   Multibib support
       \begin{btUnit}...\end{btUnit}        \multibib {none|part|chapter|section|subsection}
index 26f1f666d3094618cfea318c2021f1c2df0b6f6a..1079087a2c12c7cd985963327bfe86c006d3a311 100644 (file)
@@ -173,10 +173,13 @@ void add_known_theorem(string const & theorem, string const & o1,
 
 
 Layout const * findLayoutWithoutModule(TextClass const & tc,
-                                       string const & name, bool command)
+                                       string const & name, bool command,
+                                       string const & latexparam)
 {
        for (auto const & lay : tc) {
                if (lay.latexname() == name &&
+                   (latexparam.empty() ||
+                    (!lay.latexparam().empty() && suffixIs(latexparam, lay.latexparam()))) &&
                    ((command && lay.isCommand()) || (!command && lay.isEnvironment())))
                        return &lay;
        }
@@ -185,10 +188,13 @@ Layout const * findLayoutWithoutModule(TextClass const & tc,
 
 
 InsetLayout const * findInsetLayoutWithoutModule(TextClass const & tc,
-                                                 string const & name, bool command)
+                                                 string const & name, bool command,
+                                                 string const & latexparam)
 {
        for (auto const & ilay : tc.insetLayouts()) {
                if (ilay.second.latexname() == name &&
+                   (latexparam.empty() ||
+                    (!ilay.second.latexparam().empty() && suffixIs(latexparam, ilay.second.latexparam()))) &&
                    ((command && ilay.second.latextype() == InsetLayout::COMMAND) ||
                     (!command && ilay.second.latextype() == InsetLayout::ENVIRONMENT)))
                        return &(ilay.second);
index 224541f9ed318c0477e378ce18a4a88da59bf307..0ac2b3bfbcc4a22c2231be754e05fb1771f70643 100644 (file)
@@ -113,8 +113,9 @@ extern void add_known_environment(std::string const & environment,
 extern void add_known_theorem(std::string const & theorem,
        std::string const & o1, bool o2, docstring const & definition);
 extern Layout const * findLayoutWithoutModule(TextClass const & tc,
-       std::string const & name, bool command);
-extern InsetLayout const * findInsetLayoutWithoutModule(TextClass const & tc, std::string const & name, bool command);
+       std::string const & name, bool command, std::string const & latexparam = std::string());
+extern InsetLayout const * findInsetLayoutWithoutModule(TextClass const & tc, std::string const & name, bool command,
+       std::string const & latexparam = std::string());
 /*!
  * Check whether a module provides command (if \p command is true) or
  * environment (if \p command is false) \p name, and add the module to the
index 8d025f2f8a82ba4af4758d8d16e429dc56ada66a..53620380ddf139e9c6e5eae1ad65474e7555bd9e 100644 (file)
@@ -67,6 +67,13 @@ void parse_text_in_inset(Parser & p, ostream & os, unsigned flags, bool outer,
        if (layout)
                output_arguments(os, p, outer, false, string(), newcontext,
                                 layout->latexargs());
+       // If we have a latex param, we eat it here.
+       if (!context.latexparam.empty()) {
+               ostringstream oss;
+               Context dummy(true, context.textclass);
+               parse_text(p, oss, FLAG_RDELIM, outer, dummy,
+                          string(1, context.latexparam.back()));
+       }
        parse_text(p, os, flags, outer, newcontext, rdelim);
        if (layout)
                output_arguments(os, p, outer, false, "post", newcontext,
@@ -697,24 +704,27 @@ void output_comment(Parser & p, ostream & os, string const & s,
 }
 
 
-Layout const * findLayout(TextClass const & textclass, string const & name, bool command)
+Layout const * findLayout(TextClass const & textclass, string const & name, bool command,
+                         string const & latexparam = string())
 {
-       Layout const * layout = findLayoutWithoutModule(textclass, name, command);
+       Layout const * layout = findLayoutWithoutModule(textclass, name, command, latexparam);
        if (layout)
                return layout;
        if (checkModule(name, command))
-               return findLayoutWithoutModule(textclass, name, command);
+               return findLayoutWithoutModule(textclass, name, command, latexparam);
        return layout;
 }
 
 
-InsetLayout const * findInsetLayout(TextClass const & textclass, string const & name, bool command)
+InsetLayout const * findInsetLayout(TextClass const & textclass, string const & name, bool command,
+                                   string const & latexparam = string())
 {
-       InsetLayout const * insetlayout = findInsetLayoutWithoutModule(textclass, name, command);
+       InsetLayout const * insetlayout =
+               findInsetLayoutWithoutModule(textclass, name, command, latexparam);
        if (insetlayout)
                return insetlayout;
        if (checkModule(name, command))
-               return findInsetLayoutWithoutModule(textclass, name, command);
+               return findInsetLayoutWithoutModule(textclass, name, command, latexparam);
        return insetlayout;
 }
 
@@ -844,6 +854,13 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
        context.check_deeper(os);
        output_arguments(os, p, outer, true, string(), context,
                         context.layout->latexargs());
+       // If we have a latex param, we eat it here.
+       if (!parent_context.latexparam.empty()) {
+               ostringstream oss;
+               Context dummy(true, parent_context.textclass);
+               parse_text(p, oss, FLAG_RDELIM, outer, dummy,
+                          string(1, parent_context.latexparam.back()));
+       }
        parse_text(p, os, FLAG_ITEM, outer, context);
        output_arguments(os, p, outer, false, "post", context,
                         context.layout->postcommandargs());
@@ -3275,6 +3292,25 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        continue;
                }
 
+               // Before we look for the layout name with star and alone below, we check the layouts including
+               // the LateXParam, which might be one or several options or a star.
+               // The single '=' is meant here.
+               if (context.new_layout_allowed &&
+                  (newlayout = findLayout(context.textclass, t.cs(), true, p.getCommandLatexParam()))) {
+                       // store the latexparam here. This is eaten in output_command_layout
+                       context.latexparam = newlayout->latexparam();
+                       // write the layout
+                       output_command_layout(os, p, outer, context, newlayout);
+                       p.skip_spaces();
+                       if (!preamble.titleLayoutFound())
+                               preamble.titleLayoutFound(newlayout->intitle);
+                       set<string> const & req = newlayout->requires();
+                       for (set<string>::const_iterator it = req.begin(); it != req.end(); ++it)
+                               preamble.registerAutomaticallyLoadedPackage(*it);
+                       continue;
+               }
+
+
                // Starred section headings
                // Must attempt to parse "Section*" before "Section".
                if ((p.next_token().asInput() == "*") &&
@@ -5422,6 +5458,57 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        continue;
                }
 
+               // Before we look for the layout name alone below, we check the layouts including the LateXParam, which
+               // might be one or several options or a star.
+               // The single '=' is meant here.
+               if ((newinsetlayout = findInsetLayout(context.textclass, starredname, true, p.getCommandLatexParam()))) {
+                       if (starred)
+                               p.get_token();
+                       p.skip_spaces();
+                       context.check_layout(os);
+                       // store the latexparam here. This is eaten in parse_text_in_inset
+                       context.latexparam = newinsetlayout->latexparam();
+                       docstring name = newinsetlayout->name();
+                       bool const caption = name.find(from_ascii("Caption:")) == 0;
+                       if (caption) {
+                               // Already done for floating minted listings.
+                               if (minted_float.empty()) {
+                                       begin_inset(os, "Caption ");
+                                       os << to_utf8(name.substr(8)) << '\n';
+                               }
+                       } else {
+                               // FIXME: what do we do if the prefix is not Flex: ?
+                               if (prefixIs(name, from_ascii("Flex:")))
+                                       name.erase(0, 5);
+                               begin_inset(os, "Flex ");
+                               os << to_utf8(name) << '\n'
+                                  << "status collapsed\n";
+                       }
+                       if (!minted_float.empty()) {
+                               parse_text_snippet(p, os, FLAG_ITEM, false, context);
+                       } else if (newinsetlayout->isPassThru()) {
+                               // set catcodes to verbatim early, just in case.
+                               p.setCatcodes(VERBATIM_CATCODES);
+                               string delim = p.get_token().asInput();
+                               if (delim != "{")
+                                       cerr << "Warning: bad delimiter for command " << t.asInput() << endl;
+                               //FIXME: handle error condition
+                               string const arg = p.verbatimStuff("}").second;
+                               Context newcontext(true, context.textclass);
+                               if (newinsetlayout->forcePlainLayout())
+                                       newcontext.layout = &context.textclass.plainLayout();
+                               output_ert(os, arg, newcontext);
+                       } else
+                               parse_text_in_inset(p, os, FLAG_ITEM, false, context, newinsetlayout);
+                       if (caption)
+                               p.skip_spaces();
+                       // Minted caption insets are not closed here because
+                       // we collect everything into the caption.
+                       if (minted_float.empty())
+                               end_inset(os);
+                       continue;
+               }
+
                // The single '=' is meant here.
                if ((newinsetlayout = findInsetLayout(context.textclass, starredname, true))) {
                        if (starred)