Am Samstag, 17. Juli 2004 15:48 schrieb Juergen Spitzmueller:
> I don't care for that. BTW we also have
> \begin_inset LatexCommand \bibtex[bibtotoc,diss]{diss}
> or
> \begin_inset LatexCommand \bibtex[diss][btPrintCited]{diss}
> which does not even exist as a LaTeX command
> or
> \begin_inset LatexCommand \url[LyX home page]{http://www.lyx.org}
> and
> \begin_inset LatexCommand \htmlurl[LyX home page]{http://www.lyx.org}

I did not know that.

> So maybe the thing should rather be called LyXCommand.

Indeed.

BTW, the "Full author list" and "Force uppercase" checkboxes should be 
greyed out for \citeyear and \citeyearpar (both frontends).

> In general, I don't care, as long as it works. But note that you have to 
> change other things besides insetcite. E.g. the frontends read before and 
> after as getOptions and getSecOptions. Perhaps something like this (in 
> several places or in its own function) would do:
> 
> if (params.getSecOptions().empty())
>       after = params.getOptions()
> else {
>       before = params.getOptions()
>       after = params.getSecOptions()
> }
> 
> provided that \citet[see][]{foo} returns getSecOptions().empty().

I expected that I would only need to change one place. I see no easy 
solution without duplicating the code above (what I want to avoid). 
Therefore (and because LatexCommand is no LatexCommand at other places, 
too), I gave up and put the conversion logic in tex2lyx.

In order to handle \cite correctly, I need to know wether natbib is used in 
parse_text(). I simply made h_use_natbib in preamble.C public. I know that 
this is ugly, but I did not want to create some fancy machinery just for 
one package.

OK to apply?


Georg
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/tex2lyx/ChangeLog lyx-1.4-cvs/src/tex2lyx/ChangeLog
--- lyx-1.4-clean/src/tex2lyx/ChangeLog	2004-07-10 20:00:49.000000000 +0200
+++ lyx-1.4-cvs/src/tex2lyx/ChangeLog	2004-07-18 18:24:24.000000000 +0200
@@ -1,3 +1,11 @@
+2004-07-18  Georg Baum  <[EMAIL PROTECTED]>
+
+	* preamble.C, tex2lyx.h: make h_use_natbib public
+	* preamble.C (handle_package): handle natbib package
+	* preamble.C (handle_package): output packages that have options
+	even if they are handled by lyx to preserve the options
+	* text.C (parse_text): handle natbib citation commands
+
 2004-06-28  Georg Baum  <[EMAIL PROTECTED]>
 
 	* math.C, preamble.C, tex2lyx.[Ch], text.C: const fixes
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/tex2lyx/preamble.C lyx-1.4-cvs/src/tex2lyx/preamble.C
--- lyx-1.4-clean/src/tex2lyx/preamble.C	2004-07-10 20:00:49.000000000 +0200
+++ lyx-1.4-cvs/src/tex2lyx/preamble.C	2004-07-18 18:07:27.000000000 +0200
@@ -71,7 +71,11 @@ string h_papersize               = "Defa
 string h_paperpackage            = "default";
 string h_use_geometry            = "0";
 string h_use_amsmath             = "0";
+} // anonymous namespace
+
 string h_use_natbib              = "0";
+
+namespace {
 string h_use_numerical_citations = "0";
 string h_paperorientation        = "portrait";
 string h_secnumdepth             = "3";
@@ -105,6 +109,7 @@ void handle_opt(vector<string> & opts, c
 
 void handle_package(string const & name, string const & options)
 {
+	bool options_handled = false;
 	//cerr << "handle_package: '" << name << "'\n";
 	if (name == "a4wide") {
 		h_papersize = "a4paper";
@@ -121,21 +126,32 @@ void handle_package(string const & name,
 		; // ignore this
 	else if (name == "fontenc")
 		; // ignore this
-	else if (name == "inputenc")
+	else if (name == "inputenc") {
 		h_inputencoding = options;
-	else if (name == "makeidx")
+		options_handled = true;
+	} else if (name == "makeidx")
 		; // ignore this
 	else if (name == "verbatim")
 		; // ignore this
 	else if (is_known(name, known_languages)) {
 		h_language = name;
 		h_quotes_language = name;
-	} else {
-		if (!options.empty())
-			h_preamble << "\\usepackage[" << options << "]{" << name << "}\n";
-		else
-			h_preamble << "\\usepackage{" << name << "}\n";
-	}
+	} else if (name == "natbib") {
+		h_use_natbib = "1";
+		if (options == "authoryear") {
+			h_use_numerical_citations = "0";
+			options_handled = true;
+		} else if (options == "numbers") {
+			h_use_numerical_citations = "1";
+			options_handled = true;
+		}
+	} else if (options.empty())
+		h_preamble << "\\usepackage{" << name << "}\n";
+
+	// We need to output this package even if lyx knows it to preserve
+	// the options
+	if (!options_handled && !options.empty())
+		h_preamble << "\\usepackage[" << options << "]{" << name << "}\n";
 }
 
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/tex2lyx/tex2lyx.h lyx-1.4-cvs/src/tex2lyx/tex2lyx.h
--- lyx-1.4-clean/src/tex2lyx/tex2lyx.h	2004-07-10 20:00:49.000000000 +0200
+++ lyx-1.4-cvs/src/tex2lyx/tex2lyx.h	2004-07-18 18:07:30.000000000 +0200
@@ -25,6 +25,7 @@ class Context;
 
 /// in preamble.C
 LyXTextClass const parse_preamble(Parser & p, std::ostream & os, std::string const & forceclass);
+extern std::string h_use_natbib;
 
 
 /// in text.C
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/tex2lyx/text.C lyx-1.4-cvs/src/tex2lyx/text.C
--- lyx-1.4-clean/src/tex2lyx/text.C	2004-07-10 20:00:49.000000000 +0200
+++ lyx-1.4-cvs/src/tex2lyx/text.C	2004-07-18 18:20:45.000000000 +0200
@@ -76,9 +76,18 @@ void parse_text_snippet(Parser & p, ostr
 
 namespace {
 
-char const * const known_latex_commands[] = { "ref", "cite", "label", "index",
+char const * const known_latex_commands[] = { "ref", "label", "index",
 "printindex", "pageref", "url", "vref", "vpageref", "prettyref", "eqref", 0 };
 
+/*!
+ * natbib commands.
+ * We can't put these into known_latex_commands because the argument order
+ * is reversed in lyx if there are 2 arguments.
+ */
+char const * const known_natbib_commands[] = { "cite", "citet", "citep",
+"citealt", "citealp", "citeauthor", "citeyear", "citeyearpar",
+"citefullauthor", "Citet", "Citep", "Citealt", "Citealp", "Citeauthor", 0 };
+
 /// LaTeX names for quotes
 char const * const known_quotes[] = { "glqq", "grqq", "quotedblbase",
 "textquotedblleft", "quotesinglbase", "guilsinglleft", "guilsinglright", 0};
@@ -1323,7 +1332,8 @@ void parse_text(Parser & p, ostream & os
 			os << "\n\\" << t.cs() << " default \n";
 		}
 
-		else if (is_known(t.cs(), known_latex_commands)) {
+		else if (is_known(t.cs(), known_latex_commands) ||
+		         t.cs() == "cite" && h_use_natbib == "0") {
 			context.check_layout(os);
 			begin_inset(os, "LatexCommand ");
 			os << '\\' << t.cs();
@@ -1333,6 +1343,62 @@ void parse_text(Parser & p, ostream & os
 			end_inset(os);
 		}
 
+		else if (h_use_natbib == "1" &&
+		         is_known(t.cs(), known_natbib_commands) &&
+		         ((t.cs() != "citefullauthor" &&
+			   t.cs() != "citeyear" &&
+			   t.cs() != "citeyearpar") ||
+		          p.next_token().asInput() != "*")) {
+			context.check_layout(os);
+			// tex                       lyx
+			// \citet[before][after]{a}  \citet[after][before]{a}
+			// \citet[before][]{a}       \citet[][before]{a}
+			// \citet[after]{a}          \citet[after]{a}
+			// \citet{a}                 \citet{a}
+			string command = '\\' + t.cs();
+			if (p.next_token().asInput() == "*") {
+				command += '*';
+				p.get_token();
+			}
+			// We need to distinguish "" and "[]", so we can't
+			// use p.getOpt().
+			string before;
+			string after;
+			eat_whitespace(p, os, context, false);
+			if (p.next_token().asInput() == "[") {
+				after = '[' + p.getArg('[', ']') + ']';
+				eat_whitespace(p, os, context, false);
+				if (p.next_token().asInput() == "[") {
+					before = after;
+					after = '[' + p.getArg('[', ']') + ']';
+				}
+			}
+			if (command == "\\citefullauthor")
+				// alternative name for "\\citeauthor*"
+				command = "\\citeauthor*";
+			else if (command == "\\cite") {
+				// \cite without optional argument means
+				// \citet, \cite with at least one optional
+				// argument means \citep.
+				if (before.empty() && after.empty())
+					command = "\\citet";
+				else
+					command = "\\citep";
+			}
+			if (before.empty() && after == "[]")
+				// avoid \citet[]{a}
+				after.erase();
+			else if (before == "[]" && after == "[]") {
+				// avoid \citet[][]{a}
+				before.erase();
+				after.erase();
+			}
+			begin_inset(os, "LatexCommand ");
+			os << command << after << before
+			   << '{' << p.verbatim_item() << "}\n";
+			end_inset(os);
+		}
+
 		else if (is_known(t.cs(), known_quotes)) {
 			char const * const * where = is_known(t.cs(), known_quotes);
 			context.check_layout(os);

Reply via email to