diff --git a/src/tex2lyx/Changelog.txt b/src/tex2lyx/Changelog.txt new file mode 100644 index 0000000000..19f1561916 --- /dev/null +++ b/src/tex2lyx/Changelog.txt @@ -0,0 +1,37 @@ +Changelog tex2lyx + +Version 0.1.5 + +Commands + +- support for \lyxline +- fix for bug 27: + - support for \selectlanguage + - support for \foreignlanguage + - support for \inputencoding +- updated support for \printindex +- support for \printnomenclature +- updated support for \listof +- updated support for \tableofcontents + +Environments + +- support for hyperlink +- support for shaded note +- support for framed note + +Preamble + +- support for font settings +- updated preamble format to lyxformat 303 + (tex2lyx will still use lyxformat 245 for a while) +- updated language support +- support for multi-language documents that use babel + (CJK follows later) +- fix bug 2310: + - support for document encoding + +Packages + +- support for esint +- updated support for amsmath \ No newline at end of file diff --git a/src/tex2lyx/Context.h b/src/tex2lyx/Context.h index 1af6433023..564b332713 100644 --- a/src/tex2lyx/Context.h +++ b/src/tex2lyx/Context.h @@ -36,7 +36,7 @@ public: } void init() { - size = "normal"; + size = "default"; family = "default"; series = "default"; shape = "default"; diff --git a/src/tex2lyx/preamble.cpp b/src/tex2lyx/preamble.cpp index b39c8c123f..77f72cdb31 100644 --- a/src/tex2lyx/preamble.cpp +++ b/src/tex2lyx/preamble.cpp @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author André Pönitz + * \author Uwe Stöhr * * Full author contact details are available in file CREDITS. */ @@ -30,6 +31,7 @@ namespace lyx { +using std::find; using std::istringstream; using std::ostream; using std::ostringstream; @@ -49,50 +51,71 @@ std::map > used_packages; namespace { -const char * const known_languages[] = { "austrian", "babel", "bahasa", -"basque", "breton", "british", "bulgarian", "catalan", "croatian", "czech", -"danish", "dutch", "english", "esperanto", "estonian", "finnish", -"francais", "french", "frenchb", "frenchle", "frenchpro", -"galician", "german", "germanb", "greek", "hebcal", "hebfont", -"hebrew", "hebrew_newcode", "hebrew_oldcode", "hebrew_p", "hyphen", -"icelandic", "irish", "italian", "latin", "lgrcmr", "lgrcmro", "lgrcmss", -"lgrcmtt", "lgrenc", "lgrlcmss", "lgrlcmtt", "lheclas", "lhecmr", -"lhecmss", "lhecmtt", "lhecrml", "lheenc", "lhefr", "lheredis", "lheshold", -"lheshscr", "lheshstk", "lsorbian", "magyar", "naustrian", "ngermanb", -"ngerman", "norsk", "polish", "portuges", "rlbabel", "romanian", -"russianb", "samin", "scottish", "serbian", "slovak", "slovene", "spanish", -"swedish", "turkish", "ukraineb", "usorbian", "welsh", 0}; +const char * const known_languages[] = { "afrikaans", "albanian", "american", +"arabic_arabtex", "arabic_arabi", "armenian", "austrian", "bahasa", "basque", +"brazilian", "breton", "british", "bulgarian", "canadian", "canadien", +"catalan", "chinese-simplified", "chinese-traditional", "croatian", "czech", +"danish", "dutch", "english", "esperanto", "estonian", "farsi", "finnish", +"francais", "french", "galician", "german", "greek", "hebrew", "icelandic", +"irish", "italian", "japanese", "japanese-plain", "kazakh", "korean", "latin", +"latvian", "lithuanian", "lowersorbian", "magyar", "naustrian", "ngerman", +"norsk", "nynorsk ", "polish", "portuges", "romanian", "russian", "samin", +"scottish", "serbian", "slovak", "slovene", "spanish", "swedish", "thai", +"turkish", "ukrainian", "uppersorbian", "vietnamese", "welsh", 0}; -const char * const known_french_languages[] = {"french", "frenchb", "francais", - "frenchle", "frenchpro", 0}; -char const * const known_fontsizes[] = { "10pt", "11pt", "12pt", 0 }; +const char * const known_fontsizes[] = { "10pt", "11pt", "12pt", 0 }; + +const char * const known_encodings[] = { "auto", "latin1", "latin2", "latin3", +"latin4", "latin5", "latin9", "latin10", "iso88595", "8859-6", "iso-8859-7", +"8859-8", "l7xen", "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", +"cp862", "cp865", "cp866", "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", +"cp1257", "koi8-r", "koi8-u", "pt154", "pt254", "utf8", 0}; + +const char * const known_roman_fonts[] = { "ae", "bookman", "charter", +"cmr", "fourier", "lmodern", "mathpazo", "mathptmx", "newcent", 0}; + +const char * const known_sans_fonts[] = { "avant", "berasans", "cmbr", "cmss", +"helvet", "lmss", 0}; + +const char * const known_typewriter_fonts[] = { "beramono", "cmtl", "cmtt", +"courier", "lmtt", "luximono", "fourier", "lmodern", "mathpazo", "mathptmx", +"newcent", 0}; // some ugly stuff ostringstream h_preamble; -string h_textclass = "article"; -string h_options = string(); -string h_language = "english"; -string h_inputencoding = "latin1"; -string h_fontscheme = "default"; -string h_graphics = "default"; -string h_paperfontsize = "default"; -string h_spacing = "single"; -string h_papersize = "default"; -string h_use_geometry = "false"; -string h_use_amsmath = "0"; -string h_cite_engine = "basic"; -string h_use_bibtopic = "false"; -string h_paperorientation = "portrait"; -string h_secnumdepth = "3"; -string h_tocdepth = "3"; -string h_paragraph_separation = "indent"; -string h_defskip = "medskip"; -string h_quotes_language = "english"; -string h_papercolumns = "1"; -string h_papersides = string(); -string h_paperpagestyle = "default"; -string h_tracking_changes = "false"; -string h_output_changes = "false"; +string h_textclass = "article"; +string h_options = string(); +string h_language = "english"; +string h_inputencoding = "auto"; +string h_font_roman = "default"; +string h_font_sans = "default"; +string h_font_typewriter = "default"; +string h_font_default_family = "default"; +string h_font_sc = "false"; +string h_font_osf = "false"; +string h_font_sf_scale = "100"; +string h_font_tt_scale = "100"; +string h_graphics = "default"; +string h_paperfontsize = "default"; +string h_spacing = "single"; +string h_papersize = "default"; +string h_use_geometry = "false"; +string h_use_amsmath = "1"; +string h_use_esint = "1"; +string h_cite_engine = "basic"; +string h_use_bibtopic = "false"; +string h_paperorientation = "portrait"; +string h_secnumdepth = "3"; +string h_tocdepth = "3"; +string h_paragraph_separation = "indent"; +string h_defskip = "medskip"; +string h_quotes_language = "english"; +string h_papercolumns = "1"; +string h_papersides = string(); +string h_paperpagestyle = "default"; +string h_tracking_changes = "false"; +string h_output_changes = "false"; +string h_use_hyperref = "false"; void handle_opt(vector & opts, char const * const * what, string & target) @@ -102,16 +125,17 @@ void handle_opt(vector & opts, char const * const * what, string & targe for (; *what; ++what) { vector::iterator it = find(opts.begin(), opts.end(), *what); + // the last language option is the document language if (it != opts.end()) { //cerr << "### found option '" << *what << "'\n"; target = *what; opts.erase(it); - return; } } } + /*! * Split a package options string (keyval format) into a vector. * Example input: @@ -173,22 +197,52 @@ void handle_package(string const & name, string const & opts) { vector options = split_options(opts); add_package(name, options); + size_t pos; + string scale; + + // cerr << "handle_package: '" << name << "'\n"; + + // roman fonts + if (is_known(name, known_roman_fonts)) + h_font_roman = name; + if (name == "fourier") + h_font_roman = "utopia"; + if (name == "mathpazo") + h_font_roman = "palatino"; + if (name == "mathptmx") + h_font_roman = "times"; + // sansserif fonts + if (is_known(name, known_sans_fonts)) { + h_font_sans = name; + if (!opts.empty()) { + scale = opts; + pos = scale.find(".", 0); + h_font_sf_scale = scale.erase(0, pos + 1); + } + } + // typewriter fonts + if (is_known(name, known_typewriter_fonts)) { + h_font_typewriter = name; + if (!opts.empty()) { + scale = opts; + pos = scale.find(".", 0); + h_font_tt_scale = scale.erase(0, pos + 1); + } + } - //cerr << "handle_package: '" << name << "'\n"; - if (name == "ae") - h_fontscheme = "ae"; - else if (name == "aecompl") - h_fontscheme = "ae"; - else if (name == "amsmath") - h_use_amsmath = "1"; else if (name == "amssymb") - h_use_amsmath = "1"; + h_use_amsmath = "2"; + else if (name == "esint") + h_use_esint = "2"; else if (name == "babel") ; // ignore this else if (name == "fontenc") ; // ignore this else if (name == "inputenc") { - h_inputencoding = opts; + // only set when there are not more than one inputenc option + // therefore check for the "," character + if ((pos = opts.find(",", 0)) == string::npos) + h_inputencoding = opts; options.clear(); } else if (name == "makeidx") ; // ignore this @@ -197,14 +251,8 @@ void handle_package(string const & name, string const & opts) else if (name == "graphicx") ; // ignore this else if (is_known(name, known_languages)) { - if (is_known(name, known_french_languages)) { - h_language = "french"; - h_quotes_language = "french"; - } else { - h_language = name; - h_quotes_language = name; - } - + h_language = name; + h_quotes_language = name; } else if (name == "natbib") { h_cite_engine = "natbib_authoryear"; vector::iterator it = @@ -234,26 +282,35 @@ void handle_package(string const & name, string const & opts) } - void end_preamble(ostream & os, TextClass const & /*textclass*/) { - os << "#LyX file created by tex2lyx 0.1.2\n" + os << "#LyX file created by tex2lyx 0.1.5\n" << "\\lyxformat 245\n" << "\\begin_document\n" << "\\begin_header\n" - << "\\textclass " << h_textclass << "\n" - << "\\begin_preamble\n" << h_preamble.str() << "\n\\end_preamble\n"; + << "\\textclass " << h_textclass << "\n"; + if (!h_preamble.str().empty()) + os << "\\begin_preamble\n" << h_preamble.str() << "\n\\end_preamble\n"; if (!h_options.empty()) - os << "\\options " << h_options << "\n"; + os << "\\options " << h_options << "\n"; os << "\\language " << h_language << "\n" << "\\inputencoding " << h_inputencoding << "\n" - << "\\fontscheme " << h_fontscheme << "\n" + << "\\font_roman " << h_font_roman << "\n" + << "\\font_sans " << h_font_sans << "\n" + << "\\font_typewriter " << h_font_typewriter << "\n" + << "\\font_default_family " << h_font_default_family << "\n" + << "\\font_sc " << h_font_sc << "\n" + << "\\font_osf " << h_font_osf << "\n" + << "\\font_sf_scale " << h_font_sf_scale << "\n" + << "\\font_tt_scale " << h_font_tt_scale << "\n" << "\\graphics " << h_graphics << "\n" << "\\paperfontsize " << h_paperfontsize << "\n" << "\\spacing " << h_spacing << "\n" + << "\\use_hyperref " << h_use_hyperref << "\n" << "\\papersize " << h_papersize << "\n" << "\\use_geometry " << h_use_geometry << "\n" << "\\use_amsmath " << h_use_amsmath << "\n" + << "\\use_esint " << h_use_esint << "\n" << "\\cite_engine " << h_cite_engine << "\n" << "\\use_bibtopic " << h_use_bibtopic << "\n" << "\\paperorientation " << h_paperorientation << "\n" @@ -275,6 +332,7 @@ void end_preamble(ostream & os, TextClass const & /*textclass*/) } // anonymous namespace + TextClass const parse_preamble(Parser & p, ostream & os, string const & forceclass) { // initialize fixed types @@ -312,26 +370,22 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla t.cat() == catEnd || t.cat() == catAlign || t.cat() == catParameter) - h_preamble << t.character(); + ;//h_preamble << t.character(); else if (t.cat() == catSpace || t.cat() == catNewline) - h_preamble << t.asInput(); + ;//h_preamble << t.asInput(); else if (t.cat() == catComment) - h_preamble << t.asInput(); + ;//h_preamble << t.asInput(); else if (t.cs() == "pagestyle") h_paperpagestyle = p.verbatim_item(); - else if (t.cs() == "makeatletter") { + else if (t.cs() == "makeatletter") p.setCatCode('@', catLetter); - h_preamble << "\\makeatletter"; - } - else if (t.cs() == "makeatother") { + else if (t.cs() == "makeatother") p.setCatCode('@', catOther); - h_preamble << "\\makeatother"; - } else if (t.cs() == "newcommand" || t.cs() == "renewcommand" || t.cs() == "providecommand") { @@ -344,16 +398,38 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla string const opt1 = p.getOpt(); string const opt2 = p.getFullOpt(); string const body = p.verbatim_item(); + // font settings + if (name == "\\rmdefault") + if (is_known(body, known_roman_fonts)) + h_font_roman = body; + + if (name == "\\sfdefault") + if (is_known(body, known_sans_fonts)) + h_font_sans = body; + + if (name == "\\ttdefault") + if (is_known(body, known_typewriter_fonts)) + h_font_typewriter = body; + + if (name == "\\familydefault") { + string family = body; + // remove leading "\" + h_font_default_family = family.erase(0,1); + } // only non-lyxspecific stuff if ( name != "\\noun" && name != "\\tabularnewline" && name != "\\LyX" - && name != "\\lyxline" + && name != "\\lyxline" && name != "\\lyxaddress" && name != "\\lyxrightaddress" && name != "\\lyxdot" && name != "\\boldsymbol" - && name != "\\lyxarrow") { + && name != "\\lyxarrow" + && name != "\\rmdefault" + && name != "\\sfdefault" + && name != "\\ttdefault" + && name != "\\familydefault") { ostringstream ss; ss << '\\' << t.cs(); if (star) @@ -370,15 +446,14 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla << opts << "{" << body << "}"; */ } + } else if (t.cs() == "documentclass") { vector opts; split(p.getArg('[', ']'), opts, ','); - handle_opt(opts, known_languages, h_language); - if (is_known(h_language, known_french_languages)) - h_language = "french"; handle_opt(opts, known_fontsizes, h_paperfontsize); + handle_opt(opts, known_languages, h_language); // delete "pt" at the end string::size_type i = h_paperfontsize.find("pt"); if (i != string::npos) @@ -509,6 +584,7 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla return textclass; } + // }]) diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index c6af718433..423992dc89 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -5,6 +5,7 @@ * * \author André Pönitz * \author Jean-Marc Lasgouttes + * \author Uwe Stöhr * * Full author contact details are available in file CREDITS. */ @@ -105,7 +106,7 @@ string parse_text_snippet(Parser & p, unsigned flags, const bool outer, char const * const known_latex_commands[] = { "ref", "cite", "label", - "index", "printindex", "pageref", "url", "vref", "vpageref", "prettyref", + "index", "pageref", "url", "vref", "vpageref", "prettyref", "eqref", 0 }; /*! @@ -145,7 +146,7 @@ char const * const known_sizes[] = { "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large", "Large", "LARGE", "huge", "Huge", 0}; /// the same as known_sizes with .lyx names -char const * const known_coded_sizes[] = { "tiny", "scriptsize", "footnotesize", +char const * const known_coded_sizes[] = { "default", "tiny", "scriptsize", "footnotesize", "small", "normal", "large", "larger", "largest", "huge", "giant", 0}; /// LaTeX 2.09 names for font families @@ -775,6 +776,8 @@ void parse_environment(Parser & p, ostream & os, bool outer, parse_text_in_inset(p, os, FLAG_END, outer, parent_context); end_inset(os); p.skip_spaces(); + // FIXME the comment note inset has a trailing "{}" pair + //p.skip_braces(p); } else if (name == "lyxgreyedout") { @@ -1126,6 +1129,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, Context & context) { LayoutPtr newlayout; + // store the current selectlanguage to be used after \foreignlanguage + string selectlang; // Store the latest bibliographystyle (needed for bibtex inset) string bibliographystyle; bool const use_natbib = used_packages.find("natbib") != used_packages.end(); @@ -1738,7 +1743,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "tableofcontents") { p.skip_spaces(); context.check_layout(os); - begin_inset(os, "LatexCommand \\tableofcontents\n"); + begin_inset(os, "CommandInset toc\n"); + os << "LatexCommand tableofcontents\n"; end_inset(os); skip_braces(p); // swallow this } @@ -1761,15 +1767,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "listof") { p.skip_spaces(true); - string const name = p.get_token().asString(); + string const name = p.verbatim_item(); + string const name2 = subst(p.verbatim_item(), "\n", " "); if (context.textclass.floats().typeExist(name)) { context.check_layout(os); begin_inset(os, "FloatList "); os << name << "\n"; end_inset(os); - p.get_token(); // swallow second arg + // the second argument is not needed } else - handle_ert(os, "\\listof{" + name + "}", context); + handle_ert(os, "\\listof{" + name + "}{" + name2 + "}", context); } else if (t.cs() == "textrm") @@ -2053,6 +2060,27 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, eat_whitespace(p, os, context, false); } + else if (t.cs() == "selectlanguage") { + context.check_layout(os); + // save the language for the case that a \foreignlanguage is used + selectlang = subst(p.verbatim_item(), "\n", " "); + os << "\\lang " << selectlang << "\n"; + + } + + else if (t.cs() == "foreignlanguage") { + context.check_layout(os); + os << "\n\\lang " << subst(p.verbatim_item(), "\n", " ") << "\n"; + os << subst(p.verbatim_item(), "\n", " "); + // set back to last selectlanguage + os << "\n\\lang " << selectlang << "\n"; + } + + else if (t.cs() == "inputencoding") + // write nothing because this is done by LyX using the "\lang" + // information given by selectlanguage and foreignlanguage + subst(p.verbatim_item(), "\n", " "); + else if (t.cs() == "LyX" || t.cs() == "TeX" || t.cs() == "LaTeX") { context.check_layout(os); @@ -2078,6 +2106,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, skip_braces(p); } + else if (t.cs() == "lyxline") { + context.check_layout(os); + // the argument can be omitted, is handled by LyX + subst(p.verbatim_item(), "\n", " "); + os << "\\lyxline\n "; + + } + else if (t.cs() == "textcompwordmark") { context.check_layout(os); os << "\\SpecialChar \\textcompwordmark{}\n"; @@ -2299,16 +2335,31 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "bibliography") { context.check_layout(os); - begin_inset(os, "LatexCommand "); - os << "\\bibtex"; + begin_inset(os, "CommandInset bibtex"); + os << "\nLatexCommand bibtex"; // Do we have a bibliographystyle set? - if (!bibliographystyle.empty()) { - os << '[' << bibliographystyle << ']'; - } - os << '{' << p.verbatim_item() << "}\n"; + if (!bibliographystyle.empty()) + os << "\noptions " << '"' << bibliographystyle << '"'; + os << "\nbibfiles " << '"' << p.verbatim_item() << '"'; end_inset(os); } + else if (t.cs() == "printindex") { + context.check_layout(os); + begin_inset(os, "CommandInset index_print\n"); + os << "LatexCommand printindex"; + end_inset(os); + skip_braces(p); + } + + else if (t.cs() == "printnomenclature") { + context.check_layout(os); + begin_inset(os, "CommandInset nomencl_print\n"); + os << "LatexCommand printnomenclature"; + end_inset(os); + skip_braces(p); + } + else if (t.cs() == "parbox") parse_box(p, os, FLAG_ITEM, outer, context, true);