Increase tex2lyx output format to 298.

298: All math macros are exported with \\global to LaTeX now, so a \\global
     in front of a math macro has to be recognized. Since the math macros do
     no longer use the same syntax in .lyx and .tex (which is a mistake IMHO)
     an exact match is no longer possible except for \global\long\def.
Bugfix this time: \\providecommand was errornously recognized as math macro


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36946 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2010-12-19 19:21:53 +00:00
parent ec22820cbf
commit 2d5e1123d1
3 changed files with 135 additions and 50 deletions

View File

@ -118,6 +118,20 @@ There is also some basic support for graphics, in the form
\includegraphics{foo.eps}, or the slightly more elaborate
\includegraphics[bb=10bp 0bp 96bp 96bp,clip,height=1cm, width=1cm]{foo.eps}.
\section{Macros}
LyX supports several kinds of macros:
def \def\macroa#1{a #1 a}
global def \global\def\macrob#1{b #1 b}
long def \long\def\macroc#1{c #1 c}
global long def \global\long\def\macrod#1{d #1 d}
providecommand \providecommand{\macroe}[1]{e #1 e}
newcommand \newcommand{\macrof}[1]{f #1 f}
renewcommand \renewcommand{\macrof}[1]{g #1 g}
Now use them all:
\macroa{x} \macrob{x} \macroc{x} \macrod{x} \macroe{x} \macrof{x}
\section{Special formattings\index{Special formattings}}
\subsection{LyX line}

View File

@ -114,7 +114,7 @@ extern CommandMap known_math_environments;
///
extern bool noweb_mode;
/// LyX format that is created by tex2lyx
int const LYX_FORMAT = 297;
int const LYX_FORMAT = 298;
/// path of the master .tex file
extern std::string getMasterFilePath();

View File

@ -1188,6 +1188,114 @@ void parse_noweb(Parser & p, ostream & os, Context & context)
newcontext.check_end_layout(os);
}
/// detects \\def, \\long\\def and \\global\\long\\def with ws and comments
bool is_macro(Parser & p)
{
Token first = p.curr_token();
if (first.cat() != catEscape || !p.good())
return false;
if (first.cs() == "def")
return true;
if (first.cs() != "global" && first.cs() != "long")
return false;
Token second = p.get_token();
int pos = 1;
while (p.good() && !p.isParagraph() && (second.cat() == catSpace ||
second.cat() == catNewline || second.cat() == catComment)) {
second = p.get_token();
pos++;
}
bool secondvalid = second.cat() == catEscape;
Token third;
bool thirdvalid = false;
if (p.good() && first.cs() == "global" && secondvalid &&
second.cs() == "long") {
third = p.get_token();
pos++;
while (p.good() && !p.isParagraph() &&
(third.cat() == catSpace ||
third.cat() == catNewline ||
third.cat() == catComment)) {
third = p.get_token();
pos++;
}
thirdvalid = third.cat() == catEscape;
}
for (int i = 0; i < pos; ++i)
p.putback();
if (!secondvalid)
return false;
if (!thirdvalid)
return (first.cs() == "global" || first.cs() == "long") &&
second.cs() == "def";
return first.cs() == "global" && second.cs() == "long" &&
third.cs() == "def";
}
/// Parse a macro definition (assumes that is_macro() returned true)
void parse_macro(Parser & p, ostream & os, Context & context)
{
context.check_layout(os);
Token first = p.curr_token();
Token second;
Token third;
string command = first.asInput();
if (first.cs() != "def") {
p.get_token();
eat_whitespace(p, os, context, false);
second = p.curr_token();
command += second.asInput();
if (second.cs() != "def") {
p.get_token();
eat_whitespace(p, os, context, false);
third = p.curr_token();
command += third.asInput();
}
}
eat_whitespace(p, os, context, false);
string const name = p.get_token().cs();
eat_whitespace(p, os, context, false);
// parameter text
bool simple = true;
string paramtext;
int arity = 0;
while (p.next_token().cat() != catBegin) {
if (p.next_token().cat() == catParameter) {
// # found
p.get_token();
paramtext += "#";
// followed by number?
if (p.next_token().cat() == catOther) {
char c = p.getChar();
paramtext += c;
// number = current arity + 1?
if (c == arity + '0' + 1)
++arity;
else
simple = false;
} else
paramtext += p.get_token().cs();
} else {
paramtext += p.get_token().cs();
simple = false;
}
}
// only output simple (i.e. compatible) macro as FormulaMacros
string ert = '\\' + name + ' ' + paramtext + '{' + p.verbatim_item() + '}';
if (simple) {
context.check_layout(os);
begin_inset(os, "FormulaMacro");
os << "\n\\def" << ert;
end_inset(os);
} else
handle_ert(os, command + ert, context);
}
} // anonymous namespace
@ -1538,49 +1646,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
end_inset(os);
}
else if (t.cs() == "def") {
context.check_layout(os);
eat_whitespace(p, os, context, false);
string name = p.get_token().cs();
eat_whitespace(p, os, context, false);
// parameter text
bool simple = true;
string paramtext;
int arity = 0;
while (p.next_token().cat() != catBegin) {
if (p.next_token().cat() == catParameter) {
// # found
p.get_token();
paramtext += "#";
// followed by number?
if (p.next_token().cat() == catOther) {
char c = p.getChar();
paramtext += c;
// number = current arity + 1?
if (c == arity + '0' + 1)
++arity;
else
simple = false;
} else
paramtext += p.get_token().cs();
} else {
paramtext += p.get_token().cs();
simple = false;
}
}
// only output simple (i.e. compatible) macro as FormulaMacros
string ert = "\\def\\" + name + ' ' + paramtext + '{' + p.verbatim_item() + '}';
if (simple) {
context.check_layout(os);
begin_inset(os, "FormulaMacro");
os << "\n" << ert;
end_inset(os);
} else
handle_ert(os, ert, context);
}
else if (is_macro(p))
parse_macro(p, os, context);
else if (t.cs() == "noindent") {
p.skip_spaces();
@ -2636,8 +2703,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
else if (t.cs() == "newcommand" ||
t.cs() == "providecommand" ||
t.cs() == "renewcommand") {
// these could be handled by parse_command(), but
// we need to call add_known_command() here.
// providecommand could be handled by parse_command(),
// but we need to call add_known_command() here.
string name = t.asInput();
if (p.next_token().asInput() == "*") {
// Starred form. Eat '*'
@ -2652,10 +2719,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
opt1 + opt2 +
'{' + p.verbatim_item() + '}';
context.check_layout(os);
begin_inset(os, "FormulaMacro");
os << "\n" << ert;
end_inset(os);
if (t.cs() == "providecommand")
handle_ert(os, ert, context);
else {
context.check_layout(os);
begin_inset(os, "FormulaMacro");
os << "\n" << ert;
end_inset(os);
}
}
else if (t.cs() == "vspace") {