better environment handling in tex2lyx

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10185 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2005-07-14 15:19:01 +00:00
parent de70b1ce26
commit b38d210152
7 changed files with 180 additions and 56 deletions

View File

@ -1,3 +1,8 @@
2005-07-13 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* reLyX/syntax.default: new "environments" environments and
mathenvironments for tex2lyx
2005-07-12 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* layouts/scrclass.inc: fix bad comment.

View File

@ -676,3 +676,41 @@ titlepage
\sp {^}
\ensuremath {} % If it's in math mode, \ensuremath is unnec.
\end{reLyXmt}
% LaTeX environments.
% They have always one extra "argument":
% It contains "translate" if the contents of the environment contains normal
% LaTeX code that can be translated to LyX.
\begin{environments}
bibunit[]{translate}
psmatrix[]{}
\end{environments}
% Environments that start math mode.
% $...$, $$...$$, \(...\) and \[...\] are hardcoded in tex2lyx.
% The arguments are currently ignored.
\begin{mathenvironments}
equation
equation*
eqnarray
eqnarray*
align
align*
gather
gather*
multline
multline*
math
displaymath
flalign
flalign
% These require extra args
alignat
alignat*
xalignat
xalignat*
xxalignat
% These are not known by LyX but work nevertheless:
empheq
\end{mathenvironments}

View File

@ -1,3 +1,12 @@
2005-07-13 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* math.C (is_math_env): Don't hardcode known math environments anymore
* tex2lyx.[Ch] (known_environments, known_math_environments): new
* tex2lyx.C (read_command): new, split off from read_syntaxfile
* tex2lyx.C (read_environment): new
* text.C (parse_arguments): new, split off from parse_command
* text.C (parse_environment): handle known environments
2005-07-12 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* text.C (parse_text): output font changes only if needed

View File

@ -25,18 +25,7 @@ using std::string;
bool is_math_env(string const & name)
{
static char const * const known_math_envs[] = { "equation",
"equation*", "eqnarray", "eqnarray*", "align", "align*", "gather",
"gather*", "multline", "multline*", "math", "displaymath", "flalign",
"flalign*",
// These require extra args
"alignat", "alignat*", "xalignat", "xalignat*", "xxalignat",
0};
for (char const * const * what = known_math_envs; *what; ++what)
if (*what == name)
return true;
return false;
return known_math_environments.find(name) != known_math_environments.end();
}

View File

@ -127,7 +127,9 @@ string active_environment()
}
map<string, vector<ArgumentType> > known_commands;
CommandMap known_commands;
CommandMap known_environments;
CommandMap known_math_environments;
void add_known_command(string const & command, string const & o1,
@ -161,6 +163,57 @@ void add_known_command(string const & command, string const & o1,
namespace {
/*!
* Read one command definition from the syntax file
*/
void read_command(Parser & p, string command, CommandMap & commands) {
if (p.next_token().asInput() == "*") {
p.get_token();
command += '*';
}
vector<ArgumentType> arguments;
while (p.next_token().cat() == catBegin ||
p.next_token().asInput() == "[") {
if (p.next_token().cat() == catBegin) {
string const arg = p.getArg('{', '}');
if (arg == "translate")
arguments.push_back(required);
else
arguments.push_back(verbatim);
} else {
p.getArg('[', ']');
arguments.push_back(optional);
}
}
commands[command] = arguments;
}
/*!
* Read a class of environments from the syntax file
*/
void read_environment(Parser & p, string const & begin,
CommandMap & environments)
{
string environment;
while (p.good()) {
Token const & t = p.get_token();
if (t.cat() == catLetter)
environment += t.asInput();
else if (!environment.empty()) {
p.putback();
read_command(p, environment, environments);
environment.erase();
}
if (t.cat() == catEscape && t.asInput() == "\\end") {
string const end = p.getArg('{', '}');
if (end == begin)
return;
}
}
}
/*!
* Read a list of TeX commands from a reLyX compatible syntax file.
* Since this list is used after all commands that have a LyX counterpart
@ -184,27 +237,20 @@ void read_syntaxfile(string const & file_name)
while (p.good()) {
Token const & t = p.get_token();
if (t.cat() == catEscape) {
string command = t.asInput();
if (p.next_token().asInput() == "*") {
p.get_token();
command += '*';
string const command = t.asInput();
if (command == "\\begin") {
string const name = p.getArg('{', '}');
if (name == "environments" || name == "reLyXre")
// We understand "reLyXre", but it is
// not as powerful as "environments".
read_environment(p, name,
known_environments);
else if (name == "mathenvironments")
read_environment(p, name,
known_math_environments);
} else {
read_command(p, command, known_commands);
}
p.skip_spaces();
vector<ArgumentType> arguments;
while (p.next_token().cat() == catBegin ||
p.next_token().asInput() == "[") {
if (p.next_token().cat() == catBegin) {
string const arg = p.getArg('{', '}');
if (arg == "translate")
arguments.push_back(required);
else
arguments.push_back(verbatim);
} else {
p.getArg('[', ']');
arguments.push_back(optional);
}
}
known_commands[command] = arguments;
}
}
}

View File

@ -81,9 +81,14 @@ enum ArgumentType {
optional
};
/// Known TeX commands with arguments that get parsed into ERT.
extern std::map<std::string, std::vector<ArgumentType> > known_commands;
typedef std::map<std::string, std::vector<ArgumentType> > CommandMap;
/// Known TeX commands with arguments that get parsed into ERT.
extern CommandMap known_commands;
/// Known TeX environments with arguments that get parsed into ERT.
extern CommandMap known_environments;
/// Known TeX math environments with arguments that get parsed into LyX mathed.
extern CommandMap known_math_environments;
/// path of the master .tex file
extern std::string getMasterFilePath();

View File

@ -506,6 +506,36 @@ void check_space(Parser const & p, ostream & os, Context & context)
}
/*!
* Parse all arguments of \p command
*/
void parse_arguments(string const & command,
vector<ArgumentType> const & template_arguments,
Parser & p, ostream & os, bool outer, Context & context)
{
string ert = command;
size_t no_arguments = template_arguments.size();
for (size_t i = 0; i < no_arguments; ++i) {
switch (template_arguments[i]) {
case required:
// This argument contains regular LaTeX
handle_ert(os, ert + '{', context);
parse_text(p, os, FLAG_ITEM, outer, context);
ert = "}";
break;
case verbatim:
// This argument may contain special characters
ert += '{' + p.verbatim_item() + '}';
break;
case optional:
ert += p.getOpt();
break;
}
}
handle_ert(os, ert, context);
}
/*!
* Check whether \p command is a known command. If yes,
* handle the command with all arguments.
@ -515,27 +545,8 @@ bool parse_command(string const & command, Parser & p, ostream & os,
bool outer, Context & context)
{
if (known_commands.find(command) != known_commands.end()) {
vector<ArgumentType> const & template_arguments = known_commands[command];
string ert = command;
size_t no_arguments = template_arguments.size();
for (size_t i = 0; i < no_arguments; ++i) {
switch (template_arguments[i]) {
case required:
// This argument contains regular LaTeX
handle_ert(os, ert + '{', context);
parse_text(p, os, FLAG_ITEM, outer, context);
ert = "}";
break;
case verbatim:
// This argument may contain special characters
ert += '{' + p.verbatim_item() + '}';
break;
case optional:
ert += p.getOpt();
break;
}
}
handle_ert(os, ert, context);
parse_arguments(command, known_commands[command], p, os,
outer, context);
return true;
}
return false;
@ -781,6 +792,27 @@ void parse_environment(Parser & p, ostream & os, bool outer,
handle_ert(os, "\\end{" + name + "}", parent_context);
}
else if (known_environments.find(name) != known_environments.end()) {
vector<ArgumentType> arguments = known_environments[name];
// The last "argument" denotes wether we may translate the
// environment contents to LyX
// The default required if no argument is given makes us
// compatible with the reLyXre environment.
ArgumentType contents = arguments.empty() ?
required :
arguments.back();
if (!arguments.empty())
arguments.pop_back();
parse_arguments("\\begin{" + name + "}", arguments, p, os,
outer, parent_context);
if (contents == verbatim)
handle_ert(os, p.verbatimEnvironment(name),
parent_context);
else
parse_text_snippet(p, os, FLAG_END, outer,
parent_context);
}
else {
handle_ert(os, "\\begin{" + name + "}", parent_context);
parse_text_snippet(p, os, FLAG_END, outer, parent_context);