When using hyperref with the option colorlinks (that we support), hyperref 
loads the color package
\AtBeginDocument. But babel loads it too \AtBeginDocument, so that is not 
loaded when babel defined
shorthand characters.
Thus document with the languages Esperanto, Slovak, and some others are not 
compilable, see
http://bugzilla.lyx.org/show_bug.cgi?id=5291 (I attached there a testfile.)

Heiko Oberdiek, the hyperref developer, pointed me to the solution that color 
is loaded before babel
when hyperref is used with colorlinks.

The attached patch implements this. To be able to do that, I needed to handle 
the color packages
[x]color and pdfcolmk in a separate routine in LaTeXParams.cpp.

OK to go in?

regards Uwe
Index: BufferParams.cpp
===================================================================
--- BufferParams.cpp	(revision 26594)
+++ BufferParams.cpp	(working copy)
@@ -917,8 +917,14 @@
 		}
 	}
 
-	if (pdfoptions().use_hyperref)
+	if (pdfoptions().use_hyperref) {
 		features.require("hyperref");
+		// due to interferences with babel and hyperref, the color package has to
+		// be loaded after hyperref when hyperref is used with the colorlinks
+		// option, see http://bugzilla.lyx.org/show_bug.cgi?id=5291
+		if (pdfoptions().colorlinks)
+			features.require("color");
+	}
 
 	if (language->lang() == "vietnamese")
 		features.require("vietnamese");
@@ -1249,7 +1255,16 @@
 		texrow.newline();
 	}
 
-	// If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel here.
+	// due to interferences with babel and hyperref, the color package has to
+	// be loaded (when it is not already loaded) before babel when hyperref
+	// is used with the colorlinks option, see
+	// http://bugzilla.lyx.org/show_bug.cgi?id=5291
+	if (use_babel && features.isRequired("hyperref") && pdfoptions().colorlinks) {
+		os << from_utf8(features.getColorOptions());
+		texrow.newline();
+	}
+
+	// If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
 	if (use_babel
 		&& (features.isRequired("jurabib")
 			|| features.isRequired("hyperref")
@@ -1263,9 +1278,15 @@
 	}
 
 	// Now insert the LyX specific LaTeX commands...
+	docstring lyxpreamble;
 
+	// The color packages (when not loaded before babel)
+	// (have to be loaded before the optional packages)
+	if (!(use_babel && features.isRequired("hyperref") && pdfoptions().colorlinks))
+		lyxpreamble += from_utf8(features.getColorOptions());
+
 	// The optional packages;
-	docstring lyxpreamble(from_ascii(features.getPackages()));
+	lyxpreamble += from_utf8(features.getPackages());
 
 	// Line spacing
 	lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
@@ -1284,12 +1305,12 @@
 		pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
 		lyxpreamble += oss.str();
 	}
-
+	
 	// Will be surrounded by \makeatletter and \makeatother when needed
 	docstring atlyxpreamble;
 
 	// Some macros LyX will need
-	docstring tmppreamble(from_ascii(features.getMacros()));
+	docstring tmppreamble(from_utf8(features.getMacros()));
 
 	if (!tmppreamble.empty())
 		atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
@@ -1367,8 +1388,7 @@
 	else
 		lyxpreamble += '\n' + atlyxpreamble;
 
-	// We try to load babel late, in case it interferes
-	// with other packages.
+	// We try to load babel late, in case it interferes with other packages.
 	// Jurabib and Hyperref have to be called after babel, though.
 	if (use_babel && !features.isRequired("jurabib")
 	    && !features.isRequired("hyperref")
Index: LaTeXFeatures.cpp
===================================================================
--- LaTeXFeatures.cpp	(revision 26594)
+++ LaTeXFeatures.cpp	(working copy)
@@ -520,6 +520,34 @@
 }
 
 
+string const LaTeXFeatures::getColorOptions() const
+{
+	ostringstream colors;
+
+	// Handling the color packages separately is needed to be able to load them
+	// before babel when hyperref is loaded with the colorlinks option
+	// for more info see Bufferparams.cpp
+
+	// [x]color.sty
+	if (mustProvide("color") || mustProvide("xcolor")) {
+		string const package =
+			(mustProvide("xcolor") ? "xcolor" : "color");
+		if (params_.graphicsDriver == "default")
+			colors << "\\usepackage{" << package << "}\n";
+		else
+			colors << "\\usepackage["
+				 << params_.graphicsDriver
+				 << "]{" << package << "}\n";
+	}
+
+	// pdfcolmk must be loaded after color
+	if (mustProvide("pdfcolmk"))
+		colors << "\\usepackage{pdfcolmk}\n";
+
+	return colors.str();
+}
+
+
 string const LaTeXFeatures::getPackages() const
 {
 	ostringstream packages;
@@ -573,22 +601,8 @@
 	if (mustProvide("accents"))
 		packages << "\\usepackage{accents}\n";
 
-	// [x]color.sty
-	if (mustProvide("color") || mustProvide("xcolor")) {
-		string const package =
-			(mustProvide("xcolor") ? "xcolor" : "color");
-		if (params_.graphicsDriver == "default")
-			packages << "\\usepackage{" << package << "}\n";
-		else
-			packages << "\\usepackage["
-				 << params_.graphicsDriver
-				 << "]{" << package << "}\n";
-	}
+	// [x]color and pdfcolmk are handled in getColorOptions() above
 
-	// pdfcolmk must be loaded after color
-	if (mustProvide("pdfcolmk"))
-		packages << "\\usepackage{pdfcolmk}\n";
-
 	// makeidx.sty
 	if (isRequired("makeidx")) {
 		if (!tclass.provides("makeidx"))
Index: LaTeXFeatures.h
===================================================================
--- LaTeXFeatures.h	(revision 26594)
+++ LaTeXFeatures.h	(working copy)
@@ -46,6 +46,8 @@
 	///
 	LaTeXFeatures(Buffer const &, BufferParams const &,
 		      OutputParams const &);
+	/// The color packages
+	std::string const getColorOptions() const;
 	/// The packages needed by the document
 	std::string const getPackages() const;
 	/// The macros definitions needed by the document

Reply via email to