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