mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
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. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34591 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
8bbd8bc44c
commit
b0097bcddb
@ -94,6 +94,9 @@ import os, re, string, sys
|
||||
# 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 @@ import os, re, string, sys
|
||||
# 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 @@ def convert(lines):
|
||||
continue
|
||||
|
||||
# Only new features
|
||||
if format >= 24 and format <= 25:
|
||||
if format >= 24 and format <= 26:
|
||||
i += 1
|
||||
continue
|
||||
|
||||
|
@ -106,6 +106,7 @@ enum LayoutTags {
|
||||
LT_HTMLTITLE,
|
||||
LT_SPELLCHECK,
|
||||
LT_REFPREFIX,
|
||||
LT_REQARGS,
|
||||
LT_INTITLE // keep this last!
|
||||
};
|
||||
|
||||
@ -118,7 +119,6 @@ Layout::Layout()
|
||||
latextype = LATEX_PARAGRAPH;
|
||||
intitle = false;
|
||||
inpreamble = false;
|
||||
optionalargs = 0;
|
||||
needprotect = false;
|
||||
keepempty = false;
|
||||
font = inherit_font;
|
||||
@ -214,6 +214,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
|
||||
{ "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 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
|
||||
break;
|
||||
|
||||
case LT_OPTARGS:
|
||||
lex >> optionalargs ;
|
||||
lex >> optargs;
|
||||
break;
|
||||
|
||||
case LT_REQARGS:
|
||||
lex >> reqargs;
|
||||
break;
|
||||
|
||||
case LT_NEED_PROTECT:
|
||||
|
11
src/Layout.h
11
src/Layout.h
@ -241,8 +241,15 @@ public:
|
||||
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
|
||||
|
@ -2341,11 +2341,13 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
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;
|
||||
|
@ -65,7 +65,7 @@ private:
|
||||
};
|
||||
|
||||
// Keep the changes documented in the Customization manual.
|
||||
int const FORMAT = 26;
|
||||
int const FORMAT = 27;
|
||||
|
||||
|
||||
bool layout2layout(FileName const & filename, FileName const & tempfile)
|
||||
|
@ -229,7 +229,7 @@ int InsetCaption::latex(odocstream & os,
|
||||
// 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::getArgument(odocstream & os,
|
||||
int InsetCaption::getOptArg(odocstream & os,
|
||||
OutputParams const & runparams) const
|
||||
{
|
||||
return latexOptArgInsets(paragraphs()[0], os, runparams, 1);
|
||||
return latexArgInsets(paragraphs()[0], os, runparams, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,15 +56,16 @@ docstring InsetOptArg::xhtml(XHTMLStream &, OutputParams const &) const
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,9 @@ public:
|
||||
///
|
||||
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; }
|
||||
|
||||
|
@ -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 @@ TeXEnvironment(Buffer const & buf,
|
||||
|
||||
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 @@ TeXEnvironment(Buffer const & buf,
|
||||
} // 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 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
|
||||
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;
|
||||
|
@ -25,15 +25,19 @@ namespace lyx {
|
||||
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
|
||||
|
@ -454,7 +454,8 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
|
||||
}
|
||||
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 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
|
||||
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 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
|
||||
if (t.character() == ']' && (flags & FLAG_BRACK_LAST))
|
||||
return;
|
||||
if (t.character() == '}' && (flags & FLAG_BRACE_LAST))
|
||||
return;
|
||||
|
||||
//
|
||||
// cat codes
|
||||
|
Loading…
Reference in New Issue
Block a user