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