Author: rgheck
Date: Fri Jun  4 23:50:08 2010
New Revision: 34591
URL: http://www.lyx.org/trac/changeset/34591

Log:
Introduce a new "RequiredArgs" tag for layouts. This functions much as
the OptionalArgs tag does and is implemented by the now misnamed
InsetOptArgs, except that its content gets wrapped in "{}" rather than
"[]". Required arguments do not actually have to be provided, but they
are always output. 

This will allow e.g. beamer's Block environment to be implemented
without ERT.

Documentation to follow.

Modified:
   lyx-devel/trunk/lib/scripts/layout2layout.py
   lyx-devel/trunk/src/Layout.cpp
   lyx-devel/trunk/src/Layout.h
   lyx-devel/trunk/src/Text3.cpp
   lyx-devel/trunk/src/TextClass.cpp
   lyx-devel/trunk/src/insets/InsetCaption.cpp
   lyx-devel/trunk/src/insets/InsetOptArg.cpp
   lyx-devel/trunk/src/insets/InsetOptArg.h
   lyx-devel/trunk/src/output_latex.cpp
   lyx-devel/trunk/src/output_latex.h
   lyx-devel/trunk/src/tex2lyx/text.cpp

Modified: lyx-devel/trunk/lib/scripts/layout2layout.py
==============================================================================
--- lyx-devel/trunk/lib/scripts/layout2layout.py        Fri Jun  4 15:24:03 
2010        (r34590)
+++ lyx-devel/trunk/lib/scripts/layout2layout.py        Fri Jun  4 23:50:08 
2010        (r34591)
@@ -94,6 +94,9 @@
 # Incremented to format 26, 29 March 2010 by rgh
 # Added CiteFormat.
 
+# Incremented to format 27, 4 June 2010 by rgh
+# Added RequiredArgs tag.
+
 # Do not forget to document format change in Customization
 # Manual (section "Declaring a new text class").
 
@@ -101,7 +104,7 @@
 # development/tools/updatelayouts.sh script to update all
 # layout files to the new format.
 
-currentFormat = 26
+currentFormat = 27
 
 
 def usage(prog_name):
@@ -274,7 +277,7 @@
             continue
         
         # Only new features
-        if format >= 24 and format <= 25:
+        if format >= 24 and format <= 26:
             i += 1
             continue
 

Modified: lyx-devel/trunk/src/Layout.cpp
==============================================================================
--- lyx-devel/trunk/src/Layout.cpp      Fri Jun  4 15:24:03 2010        (r34590)
+++ lyx-devel/trunk/src/Layout.cpp      Fri Jun  4 23:50:08 2010        (r34591)
@@ -106,6 +106,7 @@
        LT_HTMLTITLE,
        LT_SPELLCHECK,
        LT_REFPREFIX,
+       LT_REQARGS,
        LT_INTITLE // keep this last!
 };
 
@@ -118,7 +119,6 @@
        latextype = LATEX_PARAGRAPH;
        intitle = false;
        inpreamble = false;
-       optionalargs = 0;
        needprotect = false;
        keepempty = false;
        font = inherit_font;
@@ -214,6 +214,7 @@
                { "passthru",       LT_PASS_THRU },
                { "preamble",       LT_PREAMBLE },
                { "refprefix",      LT_REFPREFIX },
+               { "requiredargs",   LT_REQARGS },
                { "requires",       LT_REQUIRES },
                { "rightmargin",    LT_RIGHTMARGIN },
                { "spacing",        LT_SPACING },
@@ -320,7 +321,11 @@
                        break;
 
                case LT_OPTARGS:
-                       lex >> optionalargs ;
+                       lex >> optargs;
+                       break;
+
+               case LT_REQARGS:
+                       lex >> reqargs;
                        break;
 
                case LT_NEED_PROTECT:

Modified: lyx-devel/trunk/src/Layout.h
==============================================================================
--- lyx-devel/trunk/src/Layout.h        Fri Jun  4 15:24:03 2010        (r34590)
+++ lyx-devel/trunk/src/Layout.h        Fri Jun  4 23:50:08 2010        (r34591)
@@ -241,8 +241,15 @@
        bool intitle;
        /// Is the content to go in the preamble rather than the body?
        bool inpreamble;
-       /// Does this layout allow for an optional parameter?
-       int optionalargs;
+       /// Number of requried arguments for this command or environment
+       unsigned int reqargs;
+       /// Number of optional arguments for this command or environment
+       /// These MUST come at the beginning, so:
+       ///  \cmd[opt1][opt2]{req1}{here is the text from LyX}
+       /// is fine. But:
+       ///  \cmd[opt1]{req1}[opt2]{here is the text from LyX}
+       /// is not.
+       unsigned int optargs;
        /// Which counter to step
        docstring counter;
        /// Prefix to use when creating labels

Modified: lyx-devel/trunk/src/Text3.cpp
==============================================================================
--- lyx-devel/trunk/src/Text3.cpp       Fri Jun  4 15:24:03 2010        (r34590)
+++ lyx-devel/trunk/src/Text3.cpp       Fri Jun  4 23:50:08 2010        (r34591)
@@ -2341,11 +2341,13 @@
        case LFUN_INFO_INSERT:
                code = INFO_CODE;
                break;
-       case LFUN_OPTIONAL_INSERT:
+       case LFUN_OPTIONAL_INSERT: {
                code = OPTARG_CODE;
-               enable = cur.paragraph().insetList().count(OPTARG_CODE)
-                       < cur.paragraph().layout().optionalargs;
+               Layout const & lay = cur.paragraph().layout();
+               int const numargs = lay.reqargs + lay.optargs;
+               enable = cur.paragraph().insetList().count(OPTARG_CODE) < 
numargs;
                break;
+       }
        case LFUN_INDEX_INSERT:
                code = INDEX_CODE;
                break;

Modified: lyx-devel/trunk/src/TextClass.cpp
==============================================================================
--- lyx-devel/trunk/src/TextClass.cpp   Fri Jun  4 15:24:03 2010        (r34590)
+++ lyx-devel/trunk/src/TextClass.cpp   Fri Jun  4 23:50:08 2010        (r34591)
@@ -65,7 +65,7 @@
 };
 
 // Keep the changes documented in the Customization manual. 
-int const FORMAT = 26;
+int const FORMAT = 27;
 
 
 bool layout2layout(FileName const & filename, FileName const & tempfile)

Modified: lyx-devel/trunk/src/insets/InsetCaption.cpp
==============================================================================
--- lyx-devel/trunk/src/insets/InsetCaption.cpp Fri Jun  4 15:24:03 2010        
(r34590)
+++ lyx-devel/trunk/src/insets/InsetCaption.cpp Fri Jun  4 23:50:08 2010        
(r34591)
@@ -229,7 +229,7 @@
        // optional argument.
        runparams.moving_arg = true;
        os << "\\caption";
-       int l = latexOptArgInsets(paragraphs()[0], os, runparams, 1);
+       int l = latexArgInsets(paragraphs()[0], os, runparams, 0, 1);
        os << '{';
        l += InsetText::latex(os, runparams);
        os << "}\n";
@@ -285,7 +285,7 @@
 int InsetCaption::getOptArg(odocstream & os,
                        OutputParams const & runparams) const
 {
-       return latexOptArgInsets(paragraphs()[0], os, runparams, 1);
+       return latexArgInsets(paragraphs()[0], os, runparams, 0, 1);
 }
 
 

Modified: lyx-devel/trunk/src/insets/InsetOptArg.cpp
==============================================================================
--- lyx-devel/trunk/src/insets/InsetOptArg.cpp  Fri Jun  4 15:24:03 2010        
(r34590)
+++ lyx-devel/trunk/src/insets/InsetOptArg.cpp  Fri Jun  4 23:50:08 2010        
(r34591)
@@ -56,15 +56,16 @@
        return docstring();
 }
 
-int InsetOptArg::latexOptional(odocstream & os,
-                              OutputParams const & runparams) const
+int InsetOptArg::latexArgument(odocstream & os,
+               OutputParams const & runparams, bool optional) const
 {
        odocstringstream ss;
        int ret = InsetText::latex(ss, runparams);
        docstring str = ss.str();
-       if (str.find(']') != docstring::npos)
+       if (optional && str.find(']') != docstring::npos)
                str = '{' + str + '}';
-       os << '[' << str << ']';
+       os << (optional ? '[' : '{') << str
+          << (optional ? ']' : '}');
        return ret;
 }
 

Modified: lyx-devel/trunk/src/insets/InsetOptArg.h
==============================================================================
--- lyx-devel/trunk/src/insets/InsetOptArg.h    Fri Jun  4 15:24:03 2010        
(r34590)
+++ lyx-devel/trunk/src/insets/InsetOptArg.h    Fri Jun  4 23:50:08 2010        
(r34591)
@@ -29,8 +29,9 @@
        ///
        InsetOptArg(Buffer *);
 
-       /// Outputting the optional parameter of a LaTeX command
-       int latexOptional(odocstream &, OutputParams const &) const;
+       /// Outputting the parameter of a LaTeX command
+       int latexArgument(odocstream &, OutputParams const &,
+                       bool optional) const;
        ///
        bool hasSettings() const { return false; }
 

Modified: lyx-devel/trunk/src/output_latex.cpp
==============================================================================
--- lyx-devel/trunk/src/output_latex.cpp        Fri Jun  4 15:24:03 2010        
(r34590)
+++ lyx-devel/trunk/src/output_latex.cpp        Fri Jun  4 23:50:08 2010        
(r34591)
@@ -34,6 +34,7 @@
 #include "support/lstrings.h"
 
 #include <boost/next_prior.hpp>
+#include <list>
 
 using namespace std;
 using namespace lyx::support;
@@ -167,9 +168,8 @@
 
        if (style.isEnvironment()) {
                os << "\\begin{" << from_ascii(style.latexname()) << '}';
-               if (style.optionalargs > 0) {
-                       int ret = latexOptArgInsets(*pit, os, runparams,
-                                                   style.optionalargs);
+               if (style.optargs != 0 || style.reqargs != 0) {
+                       int ret = latexArgInsets(*pit, os, runparams, 
style.reqargs, style.optargs);
                        while (ret > 0) {
                                texrow.newline();
                                --ret;
@@ -279,24 +279,61 @@
 } // namespace anon
 
 
-int latexOptArgInsets(Paragraph const & par, odocstream & os,
-       OutputParams const & runparams, int number)
+int latexArgInsets(Paragraph const & par, odocstream & os,
+       OutputParams const & runparams, unsigned int reqargs,
+       unsigned int optargs)
 {
-       int lines = 0;
+       unsigned int totalargs = reqargs + optargs;
+       list<InsetOptArg const *> ilist;
 
        InsetList::const_iterator it = par.insetList().begin();
        InsetList::const_iterator end = par.insetList().end();
-       for (; it != end && number > 0 ; ++it) {
+       for (; it != end; ++it) {
                if (it->inset->lyxCode() == OPTARG_CODE) {
-                       InsetOptArg * ins =
-                               static_cast<InsetOptArg *>(it->inset);
-                       lines += ins->latexOptional(os, runparams);
-                       --number;
+                       if (ilist.size() >= totalargs) {
+                               LYXERR0("WARNING: Found extra argument inset.");
+                               continue;
+                       }
+                       InsetOptArg const * ins =
+                               static_cast<InsetOptArg const *>(it->inset);
+                       ilist.push_back(ins);
+               }
+       }
+
+       if (!reqargs && ilist.size() == 0)
+               return 0;
+
+       int lines = 0;
+       bool const have_optional_args = ilist.size() > reqargs;
+       if (have_optional_args) {
+               unsigned int todo = ilist.size() - reqargs;
+               for (unsigned int i = 0; i < todo; ++i) {
+                       InsetOptArg const * ins = ilist.front();
+                       ilist.pop_front();
+                       lines += ins->latexArgument(os, runparams, true);
+               }
+       }
+
+       // we should now have no more insets than there are required
+       // arguments.
+       LASSERT(ilist.size() <= reqargs, /* */);
+       if (!reqargs)
+               return lines;
+
+       for (unsigned int i = 0; i < reqargs; ++i) {
+               if (ilist.empty())
+                       // a required argument wasn't given, so we output {}
+                       os << "{}";
+               else {
+                       InsetOptArg const * ins = ilist.front();
+                       ilist.pop_front();
+                       lines += ins->latexArgument(os, runparams, false);
                }
        }
        return lines;
 }
 
+
 // FIXME: this should be anonymous
 ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
          Text const & text,
@@ -543,9 +580,8 @@
                os << '\\' << from_ascii(style.latexname());
 
                // Separate handling of optional argument inset.
-               if (style.optionalargs > 0) {
-                       int ret = latexOptArgInsets(*pit, os, runparams,
-                                                   style.optionalargs);
+               if (style.optargs != 0 || style.reqargs != 0) {
+                       int ret = latexArgInsets(*pit, os, runparams, 
style.reqargs, style.optargs);
                        while (ret > 0) {
                                texrow.newline();
                                --ret;

Modified: lyx-devel/trunk/src/output_latex.h
==============================================================================
--- lyx-devel/trunk/src/output_latex.h  Fri Jun  4 15:24:03 2010        (r34590)
+++ lyx-devel/trunk/src/output_latex.h  Fri Jun  4 23:50:08 2010        (r34591)
@@ -25,15 +25,19 @@
 class Buffer;
 class BufferParams;
 class Encoding;
+class Layout;
 class Paragraph;
 class OutputParams;
 class TexRow;
 class Text;
 
-/// Export up to \p number optarg insets
-int latexOptArgInsets(Paragraph const & par,
-                     odocstream & os, OutputParams const & runparams,
-                     int number);
+/// Export up to \p reqargs required arguments and
+/// \p optargs optional ones. If not enough required
+/// ones are given, we'll output: {}. The optional ones
+/// must all come first.
+int latexArgInsets(Paragraph const & par,
+               odocstream & os, OutputParams const & runparams,
+               unsigned int reqargs, unsigned int optargs);
 
 /** Export \p paragraphs of buffer \p buf to LaTeX.
     Don't use a temporary stringstream for \p os if the final output is

Modified: lyx-devel/trunk/src/tex2lyx/text.cpp
==============================================================================
--- lyx-devel/trunk/src/tex2lyx/text.cpp        Fri Jun  4 15:24:03 2010        
(r34590)
+++ lyx-devel/trunk/src/tex2lyx/text.cpp        Fri Jun  4 23:50:08 2010        
(r34591)
@@ -454,7 +454,8 @@
        }
        context.check_deeper(os);
        context.check_layout(os);
-       if (context.layout->optionalargs > 0) {
+       unsigned int optargs = 0;
+       while (optargs < context.layout->optargs) {
                eat_whitespace(p, os, context, false);
                if (p.next_token().character() == '[') {
                        p.get_token(); // eat '['
@@ -463,6 +464,20 @@
                        parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, 
context);
                        end_inset(os);
                        eat_whitespace(p, os, context, false);
+                       optargs++;
+               }
+       }
+       unsigned int reqargs = 0;
+       while (reqargs < context.layout->reqargs) {
+               eat_whitespace(p, os, context, false);
+               if (p.next_token().character() == '{') {
+                       p.get_token(); // eat '['
+                       begin_inset(os, "OptArg\n");
+                       os << "status collapsed\n\n";
+                       parse_text_in_inset(p, os, FLAG_BRACE_LAST, outer, 
context);
+                       end_inset(os);
+                       eat_whitespace(p, os, context, false);
+                       reqargs++;
                }
        }
        parse_text(p, os, FLAG_ITEM, outer, context);
@@ -1150,6 +1165,8 @@
 
                if (t.character() == ']' && (flags & FLAG_BRACK_LAST))
                        return;
+               if (t.character() == '}' && (flags & FLAG_BRACE_LAST))
+                       return;
 
                //
                // cat codes

Reply via email to