From b38d210152d3297af0e152d1ee432f71d7797abb Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Thu, 14 Jul 2005 15:19:01 +0000 Subject: [PATCH] better environment handling in tex2lyx git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10185 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/ChangeLog | 5 +++ lib/reLyX/syntax.default | 38 +++++++++++++++++ src/tex2lyx/ChangeLog | 9 ++++ src/tex2lyx/math.C | 13 +----- src/tex2lyx/tex2lyx.C | 88 ++++++++++++++++++++++++++++++---------- src/tex2lyx/tex2lyx.h | 9 +++- src/tex2lyx/text.C | 74 +++++++++++++++++++++++---------- 7 files changed, 180 insertions(+), 56 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 89acfd16eb..897a3bc534 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2005-07-13 Georg Baum + + * reLyX/syntax.default: new "environments" environments and + mathenvironments for tex2lyx + 2005-07-12 Jean-Marc Lasgouttes * layouts/scrclass.inc: fix bad comment. diff --git a/lib/reLyX/syntax.default b/lib/reLyX/syntax.default index d395582e7d..4d5e35d36b 100644 --- a/lib/reLyX/syntax.default +++ b/lib/reLyX/syntax.default @@ -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} diff --git a/src/tex2lyx/ChangeLog b/src/tex2lyx/ChangeLog index bb4ac78d29..8dda46adbd 100644 --- a/src/tex2lyx/ChangeLog +++ b/src/tex2lyx/ChangeLog @@ -1,3 +1,12 @@ +2005-07-13 Georg Baum + + * 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 * text.C (parse_text): output font changes only if needed diff --git a/src/tex2lyx/math.C b/src/tex2lyx/math.C index eb57b1b822..7a883d928b 100644 --- a/src/tex2lyx/math.C +++ b/src/tex2lyx/math.C @@ -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(); } diff --git a/src/tex2lyx/tex2lyx.C b/src/tex2lyx/tex2lyx.C index a4045a32ff..7ffb4fcb5c 100644 --- a/src/tex2lyx/tex2lyx.C +++ b/src/tex2lyx/tex2lyx.C @@ -127,7 +127,9 @@ string active_environment() } -map > 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 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 += '*'; - } - p.skip_spaces(); - vector 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); - } + 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); } - known_commands[command] = arguments; } } } diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h index d1ea626aed..b6ff734132 100644 --- a/src/tex2lyx/tex2lyx.h +++ b/src/tex2lyx/tex2lyx.h @@ -81,9 +81,14 @@ enum ArgumentType { optional }; -/// Known TeX commands with arguments that get parsed into ERT. -extern std::map > known_commands; +typedef std::map > 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(); diff --git a/src/tex2lyx/text.C b/src/tex2lyx/text.C index 2dc7e81b31..65e901ee6b 100644 --- a/src/tex2lyx/text.C +++ b/src/tex2lyx/text.C @@ -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 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 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 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); -- 2.39.2