X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2FPreamble.cpp;h=622c7df1435a61a5a6963ca5f6e7085173a2ee27;hb=02b2cd50ed925323ad0a1ae6905c424e36da6b6d;hp=7e902c6c7ea962cd76922bef3b1c83a0b49e434c;hpb=43bcf4c9c21227820031519937ffd77fe9e26673;p=lyx.git diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp index 7e902c6c7e..622c7df143 100644 --- a/src/tex2lyx/Preamble.cpp +++ b/src/tex2lyx/Preamble.cpp @@ -21,6 +21,7 @@ #include "Layout.h" #include "Lexer.h" #include "TextClass.h" +#include "version.h" #include "support/convert.h" #include "support/FileName.h" @@ -61,11 +62,12 @@ const char * const known_languages[] = {"acadian", "afrikaans", "albanian", "greek", "hebrew", "hungarian", "icelandic", "indon", "indonesian", "interlingua", "irish", "italian", "japanese", "kazakh", "kurmanji", "latin", "latvian", "lithuanian", "lowersorbian", "lsorbian", "magyar", "malay", "meyalu", "mongolian", "naustrian", -"newzealand", "ngerman", "ngermanb", "norsk", "nynorsk", "polutonikogreek", "polish", -"portuges", "portuguese", "romanian", "russian", "russianb", "samin", -"scottish", "serbian", "serbian-latin", "slovak", "slovene", "spanish", -"swedish", "thai", "turkish", "turkmen", "ukraineb", "ukrainian", -"uppersorbian", "UKenglish", "USenglish", "usorbian", "vietnam", "welsh", +"newzealand", "ngerman", "ngermanb", "norsk", "nswissgerman", "nynorsk", +"polutonikogreek", "polish", "portuges", "portuguese", "romanian", "russian", +"russianb", "samin", "scottish", "serbian", "serbian-latin", "slovak", +"slovene", "spanish", "swedish", "swissgerman", "thai", "turkish", "turkmen", +"ukraineb", "ukrainian", "uppersorbian", "UKenglish", "USenglish", "usorbian", +"vietnam", "welsh", 0}; /** @@ -81,11 +83,12 @@ const char * const known_coded_languages[] = {"french", "afrikaans", "albanian", "greek", "hebrew", "magyar", "icelandic", "bahasa", "bahasa", "interlingua", "irish", "italian", "japanese", "kazakh", "kurmanji", "latin", "latvian", "lithuanian", "lowersorbian", "lowersorbian", "magyar", "bahasam", "bahasam", "mongolian", "naustrian", -"newzealand", "ngerman", "ngerman", "norsk", "nynorsk", "polutonikogreek", "polish", -"portuguese", "portuguese", "romanian", "russian", "russian", "samin", -"scottish", "serbian", "serbian-latin", "slovak", "slovene", "spanish", -"swedish", "thai", "turkish", "turkmen", "ukrainian", "ukrainian", -"uppersorbian", "uppersorbian", "english", "english", "vietnamese", "welsh", +"newzealand", "ngerman", "ngerman", "norsk", "german-ch", "nynorsk", +"polutonikogreek", "polish", "portuguese", "portuguese", "romanian", "russian", +"russian", "samin", "scottish", "serbian", "serbian-latin", "slovak", +"slovene", "spanish", "swedish", "german-ch-old", "thai", "turkish", "turkmen", +"ukrainian", "ukrainian", "uppersorbian", "english", "english", "uppersorbian", +"vietnamese", "welsh", 0}; /// languages with danish quotes (.lyx names) @@ -129,14 +132,12 @@ const char * const known_roman_fonts[] = { "ae", "beraserif", "bookman", "tgbonum", "tgchorus", "tgpagella", "tgschola", "tgtermes", "utopia", 0}; const char * const known_sans_fonts[] = { "avant", "berasans", "biolinum-type1", -"cmbr", "cmss", "helvet", "kurier", "kurierl", "lmss", "tgadventor", "tgheros", 0}; - -const char * const known_kurier_fonts[] = { "kurier", "kurierl", -"kurier-condensed", "kurier-light-condensed", 0}; +"cmbr", "cmss", "helvet", "iwona", "iwonac", "iwonal", "iwonalc", "kurier", +"kurierc", "kurierl", "kurierlc", "lmss", "tgadventor", "tgheros", 0}; const char * const known_typewriter_fonts[] = { "beramono", "cmtl", "cmtt", -"courier", "lmtt", "luximono", "fourier", "lmodern", "mathpazo", "mathptmx", -"newcent", "tgcursor", "txtt", 0}; +"courier", "lmtt", "luximono", "fourier", "libertineMono-type1", "lmodern", +"mathpazo", "mathptmx", "newcent", "tgcursor", "txtt", 0}; const char * const known_math_fonts[] = { "eulervm", "newtxmath", 0}; @@ -181,9 +182,12 @@ const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian", const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb", "amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color", "float", "fontspec", "graphicx", "hhline", "ifthen", "longtable", "makeidx", -"multirow", "nomencl", "pdfpages", "refstyle", "rotating", "rotfloat", "splitidx", -"setspace", "subscript", "textcomp", "tipa", "tipx", "ulem", "url", "varioref", -"verbatim", "wrapfig", "xunicode", 0}; +"multirow", "nomencl", "pdfpages", "prettyref", "refstyle", "rotating", +"rotfloat", "splitidx", "setspace", "subscript", "textcomp", "tipa", "tipx", +"tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xunicode", 0}; + +// used for the handling of \newindex +int index_number = 0; // codes used to remove packages that are loaded automatically by LyX. // Syntax: package_beg_seppackage_mid_seppackage_end_sep @@ -293,6 +297,7 @@ string process_keyval_opt(vector & options, string name) /** * known polyglossia language names (including variants) + * FIXME: support spelling=old for german variants (german vs. ngerman LyX names etc) */ const char * const Preamble::polyglossia_languages[] = { "albanian", "croatian", "hebrew", "norsk", "swedish", "amharic", "czech", "hindi", @@ -300,11 +305,11 @@ const char * const Preamble::polyglossia_languages[] = { "armenian", "divehi", "interlingua", "polish", "telugu", "asturian", "dutch", "irish", "portuges", "thai", "bahasai", "english", "italian", "romanian", "turkish", "bahasam", "esperanto", "lao", "russian", "turkmen", "basque", "estonian", "latin", -"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "urdu", "brazil", -"brazilian", "finnish", "lithuanian", "scottish", "usorbian", "breton", "french", -"lsorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", "slovak", -"welsh", "catalan", "german", "malayalam", "slovenian", "coptic", "greek", -"marathi", "spanish", +"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "tibetan", "urdu", +"brazil", "brazilian", "finnish", "lithuanian", "scottish", "usorbian", "breton", +"french", "lsorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", +"slovak", "welsh", "catalan", "german", "malayalam", "slovenian", "coptic", "greek", +"marathi", "spanish", "austrian", "american", "ancient", "australian", "british", "monotonic", "newzealand", "polytonic", 0}; @@ -318,11 +323,11 @@ const char * const Preamble::coded_polyglossia_languages[] = { "armenian", "divehi", "interlingua", "polish", "telugu", "asturian", "dutch", "irish", "portuges", "thai", "bahasa", "english", "italian", "romanian", "turkish", "bahasam", "esperanto", "lao", "russian", "turkmen", "basque", "estonian", "latin", -"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "urdu", "brazilian", -"brazilian", "finnish", "lithuanian", "scottish", "uppersorbian", "breton", "french", -"lowersorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", "slovak", -"welsh", "catalan", "ngerman", "malayalam", "slovene", "coptic", "greek", -"marathi", "spanish", +"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "tibetan", "urdu", +"brazilian", "brazilian", "finnish", "lithuanian", "scottish", "uppersorbian", "breton", +"french", "lowersorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", +"slovak", "welsh", "catalan", "ngerman", "malayalam", "slovene", "coptic", "greek", +"marathi", "spanish", "naustrian", "american", "ancientgreek", "australian", "british", "greek", "newzealand", "polutonikogreek", 0}; @@ -419,7 +424,8 @@ bool scale_as_percentage(string const & scale, string & percentage) if (pos != string::npos) { string value = scale.substr(pos + 1); if (isStrDbl(value)) { - percentage = convert(100 * convert(value)); + percentage = convert( + static_cast(100 * convert(value))); return true; } } @@ -439,15 +445,15 @@ string remove_braces(string const & value) } // anonymous namespace -Preamble::Preamble() : one_language(true), title_layout_found(false), - h_font_cjk_set(false) +Preamble::Preamble() : one_language(true), explicit_babel(false), + title_layout_found(false), h_font_cjk_set(false) { //h_backgroundcolor; //h_boxbgcolor; h_biblio_style = "plain"; h_bibtex_command = "default"; h_cite_engine = "basic"; - h_cite_engine_type = "numerical"; + h_cite_engine_type = "default"; h_color = "#008000"; h_defskip = "medskip"; //h_float_placement; @@ -469,7 +475,7 @@ Preamble::Preamble() : one_language(true), title_layout_found(false), h_html_be_strict = "false"; h_html_css_as_file = "0"; h_html_math_output = "0"; - h_index = "Index"; + h_index[0] = "Index"; h_index_command = "default"; h_inputencoding = "auto"; h_justification = "true"; @@ -495,7 +501,7 @@ Preamble::Preamble() : one_language(true), title_layout_found(false), //h_pdf_author; //h_pdf_subject; //h_pdf_keywords; - h_pdf_bookmarks = "1"; + h_pdf_bookmarks = "0"; h_pdf_bookmarksnumbered = "0"; h_pdf_bookmarksopen = "0"; h_pdf_bookmarksopenlevel = "1"; @@ -503,12 +509,12 @@ Preamble::Preamble() : one_language(true), title_layout_found(false), h_pdf_pdfborder = "0"; h_pdf_colorlinks = "0"; h_pdf_backref = "section"; - h_pdf_pdfusetitle = "1"; + h_pdf_pdfusetitle = "0"; //h_pdf_pagemode; //h_pdf_quoted_options; h_quotes_language = "english"; h_secnumdepth = "3"; - h_shortcut = "idx"; + h_shortcut[0] = "idx"; h_spacing = "single"; h_suppress_date = "false"; h_textclass = "article"; @@ -519,9 +525,10 @@ Preamble::Preamble() : one_language(true), title_layout_found(false), h_use_geometry = "false"; h_use_default_options = "false"; h_use_hyperref = "false"; - h_use_refstyle = "0"; + h_use_refstyle = false; h_use_packages["amsmath"] = "1"; h_use_packages["amssymb"] = "0"; + h_use_packages["cancel"] = "0"; h_use_packages["esint"] = "1"; h_use_packages["mhchem"] = "0"; h_use_packages["mathdots"] = "0"; @@ -720,14 +727,19 @@ void Preamble::handle_package(Parser &p, string const & name, // sansserif fonts if (is_known(name, known_sans_fonts)) { h_font_sans = name; - if (options.size() == 1) { + if (options.size() >= 1) { if (scale_as_percentage(opts, h_font_sf_scale)) options.clear(); } } - if (name == "biolinum-type1") + if (name == "biolinum-type1") { h_font_sans = "biolinum"; + // biolinum can have several options, e.g. [osf,scaled=0.97] + string::size_type pos = opts.find("osf"); + if (pos != string::npos) + h_font_osf = "true"; + } // typewriter fonts if (is_known(name, known_typewriter_fonts)) { @@ -735,13 +747,17 @@ void Preamble::handle_package(Parser &p, string const & name, // fourier as typewriter is handled in handling of \ttdefault if (name != "fourier") { h_font_typewriter = name; - if (options.size() == 1) { + if (options.size() >= 1) { if (scale_as_percentage(opts, h_font_tt_scale)) options.clear(); } } } + if (name == "libertineMono-type1") { + h_font_typewriter = "libertine-mono"; + } + // font uses old-style figure if (name == "eco") h_font_osf = "true"; @@ -761,8 +777,13 @@ void Preamble::handle_package(Parser &p, string const & name, h_font_math = "minion-ntxm"; } - if (name == "refstyle") - h_use_refstyle = "1"; + if (name == "iwona") + if (opts == "math") + h_font_math = "iwona-math"; + + if (name == "kurier") + if (opts == "math") + h_font_math = "kurier-math"; // after the detection and handling of special cases, we can remove the // fonts, otherwise they would appear in the preamble, see bug #7856 @@ -770,7 +791,7 @@ void Preamble::handle_package(Parser &p, string const & name, || is_known(name, known_typewriter_fonts) || is_known(name, known_math_fonts)) ; - else if (name == "amsmath" || name == "amssymb" || + else if (name == "amsmath" || name == "amssymb" || name == "cancel" || name == "esint" || name == "mhchem" || name == "mathdots" || name == "mathtools" || name == "stackrel" || name == "stmaryrd" || name == "undertilde") @@ -819,9 +840,10 @@ void Preamble::handle_package(Parser &p, string const & name, h_preamble << "\\usepackage[" << opts << "]{babel}\n"; } delete_opt(options, known_languages); - } - else + } else { h_preamble << "\\usepackage{babel}\n"; + explicit_babel = true; + } } else if (name == "polyglossia") { @@ -843,7 +865,7 @@ void Preamble::handle_package(Parser &p, string const & name, } else if (name == "CJKutf8") { - h_inputencoding = "UTF8"; + h_inputencoding = "utf8-cjk"; p.setEncoding("UTF-8"); registerAutomaticallyLoadedPackage("CJKutf8"); } @@ -862,14 +884,22 @@ void Preamble::handle_package(Parser &p, string const & name, // h_inputencoding is only set when there is not more than one // inputenc option because otherwise h_inputencoding must be // set to "auto" (the default encoding of the document language) - // Therefore check for the "," character. + // Therefore check that exactly one option is passed to inputenc. // It is also only set when there is not more than one babel // language option. - if (opts.find(",") == string::npos && one_language == true) - h_inputencoding = opts; - if (!options.empty()) - p.setEncoding(options.back(), Encoding::inputenc); - options.clear(); + if (!options.empty()) { + string const encoding = options.back(); + Encoding const * const enc = encodings.fromLaTeXName( + encoding, Encoding::inputenc, true); + if (!enc) + cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl; + else { + if (!enc->unsafe() && options.size() == 1 && one_language == true) + h_inputencoding = enc->name(); + p.setEncoding(enc->iconvName()); + } + options.clear(); + } } else if (name == "srcltx") { @@ -888,9 +918,6 @@ void Preamble::handle_package(Parser &p, string const & name, h_language_package = "\\usepackage{" + name + "}"; } - else if (name == "prettyref") - ; // ignore this FIXME: Use the package separator mechanism instead - else if (name == "lyxskak") { // ignore this and its options const char * const o[] = {"ps", "mover", 0}; @@ -900,6 +927,10 @@ void Preamble::handle_package(Parser &p, string const & name, else if (is_known(name, known_lyx_packages) && options.empty()) { if (name == "splitidx") h_use_indices = "true"; + if (name == "refstyle") + h_use_refstyle = true; + else if (name == "prettyref") + h_use_refstyle = false; if (!in_lyx_preamble) { h_preamble << package_beg_sep << name << package_mid_sep << "\\usepackage{" @@ -944,9 +975,24 @@ void Preamble::handle_package(Parser &p, string const & name, h_cite_engine_type = "authoryear"; } + else if (name == "bibtopic") + h_use_bibtopic = "true"; + else if (name == "hyperref") handle_hyperref(options); + else if (name == "algorithm2e") { + // Load "algorithm2e" module + addModule("algorithm2e"); + // Add the package options to the global document options + if (!options.empty()) { + if (h_options.empty()) + h_options = join(options, ","); + else + h_options += ',' + join(options, ","); + } + } + else if (!in_lyx_preamble) { if (options.empty()) h_preamble << "\\usepackage{" << name << '}'; @@ -1028,7 +1074,10 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc) } // output the LyX file settings - os << "#LyX file created by tex2lyx " << PACKAGE_VERSION << "\n" + // Important: Keep the version formatting in sync with LyX and + // lyx2lyx (bug 7951) + os << "#LyX file created by tex2lyx " << lyx_version_major << '.' + << lyx_version_minor << '\n' << "\\lyxformat " << LYX_FORMAT << '\n' << "\\begin_document\n" << "\\begin_header\n" @@ -1142,10 +1191,19 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc) os << "\\backgroundcolor " << h_backgroundcolor << '\n'; if (!h_boxbgcolor.empty()) os << "\\boxbgcolor " << h_boxbgcolor << '\n'; - os << "\\index " << h_index << '\n' - << "\\shortcut " << h_shortcut << '\n' - << "\\color " << h_color << '\n' - << "\\end_index\n"; + if (index_number != 0) + for (int i = 0; i < index_number; i++) { + os << "\\index " << h_index[i] << '\n' + << "\\shortcut " << h_shortcut[i] << '\n' + << "\\color " << h_color << '\n' + << "\\end_index\n"; + } + else { + os << "\\index " << h_index[0] << '\n' + << "\\shortcut " << h_shortcut[0] << '\n' + << "\\color " << h_color << '\n' + << "\\end_index\n"; + } os << h_margins << "\\secnumdepth " << h_secnumdepth << "\n" << "\\tocdepth " << h_tocdepth << "\n" @@ -1370,6 +1428,69 @@ void Preamble::parse(Parser & p, string const & forceclass, p.setCatcode('@', catOther); } + else if (t.cs() == "makeindex") { + // LyX will re-add this if a print index command is found + p.skip_spaces(); + } + + else if (t.cs() == "newindex") { + string const indexname = p.getArg('[', ']'); + string const shortcut = p.verbatim_item(); + if (!indexname.empty()) + h_index[index_number] = indexname; + else + h_index[index_number] = shortcut; + h_shortcut[index_number] = shortcut; + index_number += 1; + p.skip_spaces(); + } + + else if (t.cs() == "RS@ifundefined") { + string const name = p.verbatim_item(); + string const body1 = p.verbatim_item(); + string const body2 = p.verbatim_item(); + // only non-lyxspecific stuff + if (in_lyx_preamble && + (name == "subref" || name == "thmref" || name == "lemref")) + p.skip_spaces(); + else { + ostringstream ss; + ss << '\\' << t.cs(); + ss << '{' << name << '}' + << '{' << body1 << '}' + << '{' << body2 << '}'; + h_preamble << ss.str(); + } + } + + else if (t.cs() == "AtBeginDocument") { + string const name = p.verbatim_item(); + // only non-lyxspecific stuff + if (in_lyx_preamble && + (name == "\\providecommand\\partref[1]{\\ref{part:#1}}" + || name == "\\providecommand\\chapref[1]{\\ref{chap:#1}}" + || name == "\\providecommand\\secref[1]{\\ref{sec:#1}}" + || name == "\\providecommand\\subref[1]{\\ref{sub:#1}}" + || name == "\\providecommand\\parref[1]{\\ref{par:#1}}" + || name == "\\providecommand\\figref[1]{\\ref{fig:#1}}" + || name == "\\providecommand\\tabref[1]{\\ref{tab:#1}}" + || name == "\\providecommand\\algref[1]{\\ref{alg:#1}}" + || name == "\\providecommand\\fnref[1]{\\ref{fn:#1}}" + || name == "\\providecommand\\enuref[1]{\\ref{enu:#1}}" + || name == "\\providecommand\\eqref[1]{\\ref{eq:#1}}" + || name == "\\providecommand\\lemref[1]{\\ref{lem:#1}}" + || name == "\\providecommand\\thmref[1]{\\ref{thm:#1}}" + || name == "\\providecommand\\corref[1]{\\ref{cor:#1}}" + || name == "\\providecommand\\propref[1]{\\ref{prop:#1}}")) + p.skip_spaces(); + else { + ostringstream ss; + ss << '\\' << t.cs(); + ss << '{' << name << '}'; + h_preamble << ss.str(); + } + } + else if (t.cs() == "newcommand" || t.cs() == "newcommandx" || t.cs() == "renewcommand" || t.cs() == "renewcommandx" || t.cs() == "providecommand" || t.cs() == "providecommandx" @@ -1415,13 +1536,6 @@ void Preamble::parse(Parser & p, string const & forceclass, in_lyx_preamble = true; } - if (name == "\\bfdefault") - // LyX re-adds this if a kurier font is used - if (is_known(h_font_sans, known_kurier_fonts) && body == "b") { - p.skip_spaces(); - in_lyx_preamble = true; - } - // remove the lyxdot definition that is re-added by LyX // if necessary if (name == "\\lyxdot") { @@ -1451,22 +1565,6 @@ void Preamble::parse(Parser & p, string const & forceclass, in_lyx_preamble = was_in_lyx_preamble; } - else if (t.cs() == "edef"){ - // we only support this for kurier fonts - string const command = p.next_token().asInput(); - p.get_token(); - if (command == "\\sfdefault") { - p.getArg('{', '}'); - if (h_font_sans == "kurier") - h_font_sans = "kurier-condensed"; - if (h_font_sans == "kurierl") - h_font_sans = "kurier-light-condensed"; - p.skip_spaces(); - } - else - h_preamble << "\\edef" << command << "{" << p.getArg('{', '}') << "}\n"; - } - else if (t.cs() == "documentclass") { vector::iterator it; vector opts = split_options(p.getArg('[', ']')); @@ -1536,8 +1634,15 @@ void Preamble::parse(Parser & p, string const & forceclass, else if (t.cs() == "inputencoding") { string const encoding = p.getArg('{','}'); - h_inputencoding = encoding; - p.setEncoding(encoding, Encoding::inputenc); + Encoding const * const enc = encodings.fromLaTeXName( + encoding, Encoding::inputenc, true); + if (!enc) + cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl; + else { + if (!enc->unsafe()) + h_inputencoding = enc->name(); + p.setEncoding(enc->iconvName()); + } } else if (t.cs() == "newenvironment") { @@ -1797,6 +1902,21 @@ void Preamble::parse(Parser & p, string const & forceclass, p.pushPosition(); h_language = guessLanguage(p, default_language); p.popPosition(); + if (explicit_babel && h_language != default_language) { + // We set the document language to a CJK language, + // but babel is explicitly called in the user preamble + // without options. LyX will not add the default + // language to the document options if it is either + // english, or no text is set as default language. + // Therefore we need to add a language option explicitly. + // FIXME: It would be better to remove all babel calls + // from the user preamble, but this is difficult + // without re-introducing bug 7861. + if (h_options.empty()) + h_options = lyx2babel(default_language); + else + h_options += ',' + lyx2babel(default_language); + } } } @@ -1810,6 +1930,15 @@ string babel2lyx(string const & language) } +string lyx2babel(string const & language) +{ + char const * const * where = is_known(language, known_coded_languages); + if (where) + return known_languages[where - known_coded_languages]; + return language; +} + + string Preamble::polyglossia2lyx(string const & language) { char const * const * where = is_known(language, polyglossia_languages);