From: Stefan Schimanski Date: Sun, 23 Dec 2007 16:32:00 +0000 (+0000) Subject: * newlyxcommand support as LaTeX feature X-Git-Tag: 1.6.10~6825 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=f85fccef65ef514da8480262087990f3af1f9310;p=features.git * newlyxcommand support as LaTeX feature git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22281 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index fdf353dba3..6718a2ff8e 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -150,7 +150,7 @@ static string const mathcircumflex_def = static string const tabularnewline_def = "%% Because html converters don't know tabularnewline\n" "\\providecommand{\\tabularnewline}{\\\\}\n"; - + static string const lyxgreyedout_def = "%% The greyedout annotation environment\n" "\\newenvironment{lyxgreyedout}{\\textcolor[gray]{0.8}\\bgroup}{\\egroup}\n"; @@ -191,7 +191,101 @@ static string const textcyr_def = "\\DeclareRobustCommand{\\textcyr}[1]{\\leavevmode{\\cyrtext #1}}\n" "\\DeclareFontEncoding{T2A}{}{}\n"; - +static string const newlyxcommand_def = + "%% Math macros with multiple optional parameters\n" + "% #1<-\\foo\n" + "\\def\\newlyxcommand#1{\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@arity{#1}}\n" + " {\\newlyxcommand@arity{#1}[0]}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-arity\n" + "\\def\\newlyxcommand@arity#1[#2]{\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@firstopt{#1}{}{#2}}\n" + " {\\newlyxcommand@def#1{#2}}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@firstopt#1#2#3[#4]{\n" + " % ##1<-\\foo@\n" + " \\def\\@defclause##1{\n" + " \\def#1{\n" + " \\@ifnextchar[%]\n" + " {##1{}{#4}}\n" + " {##1{}{#4}[#4]}}\n" + " }\n" + " \\expandafter\\@defclause\\csname\\expandafter\\@gobble\\string#1@\\endcsname\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@opt{#1}{#2}{#3}}\n" + " {\\newlyxcommand@last{#1}{#2}{#3}[#4]}\n" + "}\n" + "\n" + "\\begingroup\n" + "\\catcode`\\Q=3\n" + "\\gdef\\@myempty{Q}\n" + "\\endgroup\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@opt#1#2#3[#4]{\n" + " % ##1<-\\foo@iii ##2<-\\foo@iiii \n" + " % ####1<-{a}{b}{c} ####2<-default value ####3<- default arg\n" + " \\def\\@defclause##1##2{\n" + " \\def##1####1####2[####3]{\n" + " \\ifx\\@myempty####3\\@myempty%\n" + " \\def\\@callnext{\n" + " \\@ifnextchar[%]\n" + " {##2{####1{####2}}{#4}}\n" + " {##2{####1{####2}}{#4}[#4]}\n" + " }\n" + " \\else\n" + " \\def\\@callnext{\n" + " \\@ifnextchar[%]\n" + " {##2{####1{####3}}{#4}}\n" + " {##2{####1{####3}}{#4}[#4]}\n" + " }\n" + " \\fi\n" + " \\@callnext\n" + " }\n" + " }\n" + " \\expandafter\\def\\expandafter\\@clausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2\\endcsname}\n" + " \\expandafter\\def\\expandafter\\@nextclausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname}\n" + " \\expandafter\\expandafter\\expandafter \n" + " \\@defclause\\expandafter\\@clausename\\@nextclausename\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@opt{#1}{#2i}{#3}}\n" + " {\\newlyxcommand@last{#1}{#2i}{#3}[#4]}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@last#1#2#3[#4]{\n" + " \\def\\@defclause##1##2{\n" + " \\def##1####1####2[####3]{\n" + " \\ifx\\@myempty####3\\@myempty%\n" + " \\def\\@callnext{##2####1{####2}}\n" + " \\else\n" + " \\def\\@callnext{##2####1{####3}}\n" + " \\fi\n" + " \\@callnext\n" + " }\n" + " }\n" + " \\expandafter\\def\\expandafter\\@clausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2\\endcsname}\n" + " \\expandafter\\def\\expandafter\\@nextclausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname}\n" + " \\expandafter\\expandafter\\expandafter\n" + " \\@defclause\\expandafter\\@clausename\\@nextclausename\n" + " \\expandafter\\newlyxcommand@def\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname{#3}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-arity #3<-definition\n" + "\\def\\newlyxcommand@def#1#2#3{\n" + " \\ifx#20\n" + " \\def#1{#3}\n" + " \\else\n" + " \\def\\@splitargs##1#2##2.{\\def#1##1#2}\\@splitargs##1##2##3##4##5##6##7##8##9.{#3}\n" + " \\fi\n" + "}\n"; + ///////////////////////////////////////////////////////////////////// // // LaTeXFeatures @@ -653,6 +747,8 @@ string const LaTeXFeatures::getMacros() const macros << binom_def << '\n'; if (mustProvide("mathcircumflex")) macros << mathcircumflex_def << '\n'; + if (mustProvide("newlyxcommand")) + macros << newlyxcommand_def << '\n'; // other if (mustProvide("ParagraphLeftIndent")) diff --git a/src/Text3.cpp b/src/Text3.cpp index b90c6c8482..01a2fd671f 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -149,6 +149,7 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display) // somewhere, and an ordinary formula // otherwise if (sel.find(from_ascii("\\newcommand")) == string::npos + && sel.find(from_ascii("\\newlyxcommand")) == string::npos && sel.find(from_ascii("\\def")) == string::npos) { InsetMathHull * formula = new InsetMathHull; diff --git a/src/mathed/MathMacroTemplate.cpp b/src/mathed/MathMacroTemplate.cpp index 231633b947..135ada9473 100644 --- a/src/mathed/MathMacroTemplate.cpp +++ b/src/mathed/MathMacroTemplate.cpp @@ -13,6 +13,7 @@ #include "MathMacroTemplate.h" #include "DocIterator.h" +#include "LaTeXFeatures.h" #include "InsetMathBrace.h" #include "InsetMathChar.h" #include "InsetMathSqrt.h" @@ -1070,6 +1071,13 @@ bool MathMacroTemplate::fixNameAndCheckIfValid() return data.size() > 0; } + +void MathMacroTemplate::validate(LaTeXFeatures & features) const +{ + if (optionals_ > 1) { + features.require("newlyxcommand"); + } +} void MathMacroTemplate::getDefaults(vector & defaults) const { diff --git a/src/mathed/MathMacroTemplate.h b/src/mathed/MathMacroTemplate.h index 22f22e84d5..3c247e33ea 100644 --- a/src/mathed/MathMacroTemplate.h +++ b/src/mathed/MathMacroTemplate.h @@ -80,6 +80,9 @@ public: /// Remove everything from the name which makes it invalid /// and return true iff it is valid. bool fixNameAndCheckIfValid(); + + /// request "external features" + virtual void validate(LaTeXFeatures &) const; /// decide whether its a redefinition void updateToContext(MacroContext const & mc) const; diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index ebeebd3652..c5927cc03f 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -894,7 +894,8 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.cs() == "def" || t.cs() == "newcommand" || - t.cs() == "renewcommand") + t.cs() == "renewcommand" || + t.cs() == "newlyxcommand") { MacroType type = MacroTypeNewcommand; if (t.cs() == "def") diff --git a/src/tex2lyx/preamble.cpp b/src/tex2lyx/preamble.cpp index 3fa21d87b3..90c97d03a3 100644 --- a/src/tex2lyx/preamble.cpp +++ b/src/tex2lyx/preamble.cpp @@ -461,8 +461,10 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla p.setCatCode('@', catOther); } - else if (t.cs() == "newcommand" || t.cs() == "renewcommand" - || t.cs() == "providecommand") { + else if (t.cs() == "newcommand" + || t.cs() == "renewcommand" + || t.cs() == "providecommand" + || t.cs() == "newlyxcommand") { bool star = false; if (p.next_token().character() == '*') { p.get_token(); diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp index 5e4a55b888..790cf4a3a7 100644 --- a/src/tex2lyx/tex2lyx.cpp +++ b/src/tex2lyx/tex2lyx.cpp @@ -120,6 +120,7 @@ void add_known_command(string const & command, string const & o1, // \newcommand{\foo}[1][]{bar #1} "[1]" true \foo bar // \newcommand{\foo}[1][]{bar #1} "[1]" true \foo[x] bar x // \newcommand{\foo}[1][x]{bar #1} "[1]" true \foo[x] bar x + // and the same with \newlyxcommand unsigned int nargs = 0; vector arguments; string const opt1 = rtrim(ltrim(o1, "["), "]"); diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index c73c051cd3..8cadc5f841 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -2380,8 +2380,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.cs() == "newcommand" || - t.cs() == "providecommand" || - t.cs() == "renewcommand") { + t.cs() == "providecommand" || + t.cs() == "renewcommand" || + t.cs() == "newlyxcommand") { // these could be handled by parse_command(), but // we need to call add_known_command() here. string name = t.asInput();