X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2Ftext.cpp;h=50eee93a3d2291596ee63140d7afac665298232f;hb=8e7b5eebf0ef9742e5f6983d8f55f563c12a31ab;hp=2b5d0acb0bcce21293a0d124c28f565ea8ae7167;hpb=bb0432d74a7ca6b8e1c1f98d71405dc04eb6257a;p=lyx.git diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 2b5d0acb0b..50eee93a3d 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -24,6 +24,8 @@ #include "Length.h" #include "Preamble.h" +#include "insets/ExternalTemplate.h" + #include "support/lassert.h" #include "support/convert.h" #include "support/FileName.h" @@ -115,6 +117,62 @@ char const * const known_ref_commands[] = { "ref", "pageref", "vref", char const * const known_coded_ref_commands[] = { "ref", "pageref", "vref", "vpageref", "formatted", "eqref", 0 }; +/** + * known polyglossia language names (including variants) + */ +const char * const polyglossia_languages[] = { +"albanian", "croatian", "hebrew", "norsk", "swedish", "amharic", "czech", "hindi", +"nynorsk", "syriac", "arabic", "danish", "icelandic", "occitan", "tamil", +"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", +"american", "ancient", "australian", "british", "monotonic", "newzealand", +"polytonic", 0}; + +/** + * the same as polyglossia_languages with .lyx names + * please keep this in sync with polyglossia_languages line by line! + */ +const char * const coded_polyglossia_languages[] = { +"albanian", "croatian", "hebrew", "norsk", "swedish", "amharic", "czech", "hindi", +"nynorsk", "syriac", "arabic_arabi", "danish", "icelandic", "occitan", "tamil", +"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", +"american", "ancientgreek", "australian", "british", "greek", "newzealand", +"polutonikogreek", 0}; + +/** + * supported CJK encodings + */ +const char * const supported_CJK_encodings[] = { +"EUC-JP", "KS", "GB", "UTF8", 0}; + +/** + * the same as supported_CJK_encodings with their corresponding LyX language name + * please keep this in sync with supported_CJK_encodings line by line! + */ +const char * const coded_supported_CJK_encodings[] = { +"japanese-cjk", "korean", "chinese-simplified", "chinese-traditional", 0}; + +string CJK2lyx(string const & encoding) +{ + char const * const * where = is_known(encoding, supported_CJK_encodings); + if (where) + return coded_supported_CJK_encodings[where - supported_CJK_encodings]; + return encoding; +} + /*! * natbib commands. * The starred forms are also known except for "citefullauthor", @@ -454,11 +512,14 @@ docstring convert_unicodesymbols(docstring s) continue; } s = s.substr(i); + bool termination; docstring rem; set req; docstring parsed = encodings.fromLaTeXCommand(s, - Encodings::TEXT_CMD, rem, &req); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + Encodings::TEXT_CMD, termination, rem, &req); + set::const_iterator it = req.begin(); + set::const_iterator en = req.end(); + for (; it != en; ++it) preamble.registerAutomaticallyLoadedPackage(*it); os << parsed; s = rem; @@ -567,7 +628,7 @@ void skip_spaces_braces(Parser & p, bool keepws = false) should be handled by this function: - abc \j{} xyz - abc \j {} xyz - - abc \j + - abc \j {} xyz - abc \j %comment {} xyz @@ -611,7 +672,7 @@ void output_command_layout(ostream & os, Parser & p, bool outer, while (optargs < context.layout->optargs) { eat_whitespace(p, os, context, false); if (p.next_token().cat() == catEscape || - p.next_token().character() != '[') + p.next_token().character() != '[') break; p.get_token(); // eat '[' begin_inset(os, "Argument\n"); @@ -928,7 +989,7 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags, // the inner env if (!inner_type.empty() && (inner_flags & FLAG_END)) active_environments.pop_back(); - + // Ensure that the end of the outer box is parsed correctly: // The opening brace has been eaten by parse_outer_box() if (!outer_type.empty() && (outer_flags & FLAG_ITEM)) { @@ -1116,16 +1177,28 @@ void parse_outer_box(Parser & p, ostream & os, unsigned flags, bool outer, } -void parse_listings(Parser & p, ostream & os, Context & parent_context) +void parse_listings(Parser & p, ostream & os, Context & parent_context, bool in_line) { parent_context.check_layout(os); begin_inset(os, "listings\n"); - os << "inline false\n" - << "status collapsed\n"; + if (p.hasOpt()) { + string arg = p.verbatimOption(); + os << "lstparams " << '"' << arg << '"' << '\n'; + } + if (in_line) + os << "inline true\n"; + else + os << "inline false\n"; + os << "status collapsed\n"; Context context(true, parent_context.textclass); context.layout = &parent_context.textclass.plainLayout(); - context.check_layout(os); - string const s = p.verbatimEnvironment("lstlisting"); + string s; + if (in_line) { + s = p.plainCommand('!', '!', "lstinline"); + context.new_paragraph(os); + context.check_layout(os); + } else + s = p.plainEnvironment("lstlisting"); for (string::const_iterator it = s.begin(), et = s.end(); it != et; ++it) { if (*it == '\\') os << "\n\\backslash\n"; @@ -1171,8 +1244,7 @@ void parse_unknown_environment(Parser & p, string const & name, ostream & os, void parse_environment(Parser & p, ostream & os, bool outer, - string & last_env, bool & title_layout_found, - Context & parent_context) + string & last_env, Context & parent_context) { Layout const * newlayout; InsetLayout const * newinsetlayout = 0; @@ -1196,6 +1268,23 @@ void parse_environment(Parser & p, ostream & os, bool outer, } } + else if (is_known(name, polyglossia_languages)) { + // We must begin a new paragraph if not already done + if (! parent_context.atParagraphStart()) { + parent_context.check_end_layout(os); + parent_context.new_paragraph(os); + } + // save the language in the context so that it is + // handled by parse_text + parent_context.font.language = polyglossia2lyx(name); + parse_text(p, os, FLAG_END, outer, parent_context); + // Just in case the environment is empty + parent_context.extra_stuff.erase(); + // We must begin a new paragraph to reset the language + parent_context.new_paragraph(os); + p.skip_spaces(); + } + else if (unstarred_name == "tabular" || name == "longtable") { eat_whitespace(p, os, parent_context, false); string width = "0pt"; @@ -1265,7 +1354,7 @@ void parse_environment(Parser & p, ostream & os, bool outer, // we must make sure that the next item gets a \begin_layout. parent_context.new_paragraph(os); p.skip_spaces(); - preamble.registerAutomaticallyLoadedPackage("rotfloat"); + preamble.registerAutomaticallyLoadedPackage("rotfloat"); } else if (name == "wrapfigure" || name == "wraptable") { @@ -1298,7 +1387,7 @@ void parse_environment(Parser & p, ostream & os, bool outer, // we must make sure that the next item gets a \begin_layout. parent_context.new_paragraph(os); p.skip_spaces(); - preamble.registerAutomaticallyLoadedPackage("wrapfig"); + preamble.registerAutomaticallyLoadedPackage("wrapfig"); } else if (name == "minipage") { @@ -1341,6 +1430,81 @@ void parse_environment(Parser & p, ostream & os, bool outer, preamble.registerAutomaticallyLoadedPackage("verbatim"); } + else if (name == "verbatim") { + os << "\n\\end_layout\n\n\\begin_layout Verbatim\n"; + string const s = p.plainEnvironment("verbatim"); + string::const_iterator it2 = s.begin(); + for (string::const_iterator it = s.begin(), et = s.end(); it != et; ++it) { + if (*it == '\\') + os << "\\backslash "; + else if (*it == '\n') { + it2 = it + 1; + // avoid adding an empty paragraph at the end + // FIXME: if there are 2 consecutive spaces at the end ignore it + // because LyX will re-add a \n + // This hack must be removed once bug 8049 is fixed! + if ((it + 1 != et) && (it + 2 != et || *it2 != '\n')) + os << "\n\\end_layout\n\\begin_layout Verbatim\n"; + } else + os << *it; + } + os << "\n\\end_layout\n\n"; + p.skip_spaces(); + // reset to Standard layout + os << "\n\\begin_layout Standard\n"; + } + + else if (name == "CJK") { + // the scheme is \begin{CJK}{encoding}{mapping}{text} + // It is impossible to decide if a CJK environment was in its own paragraph or within + // a line. We therefore always assume a paragraph since the latter is a rare case. + eat_whitespace(p, os, parent_context, false); + parent_context.check_end_layout(os); + // store the encoding to be able to reset it + string const encoding_old = p.encoding_latex_; + string const encoding = p.getArg('{', '}'); + // SJIS and BIG5 don't work with LaTeX according to the comment in unicode.cpp + // JIS does not work with LyX's encoding conversion + if (encoding != "SJIS" && encoding != "BIG5" && encoding != "JIS") + p.setEncoding(encoding); + else + p.setEncoding("utf8"); + // LyX doesn't support the second argument so if + // this is used we need to output everything as ERT + string const mapping = p.getArg('{', '}'); + if ( (!mapping.empty() && mapping != " ") + || (!is_known(encoding, supported_CJK_encodings))) { + parent_context.check_layout(os); + handle_ert(os, "\\begin{" + name + "}{" + encoding + "}{" + mapping + "}", + parent_context); + // we must parse the content as verbatim because e.g. SJIS can contain + // normally invalid characters + string const s = p.plainEnvironment("CJK"); + string::const_iterator it2 = s.begin(); + for (string::const_iterator it = s.begin(), et = s.end(); it != et; ++it) { + if (*it == '\\') + handle_ert(os, "\\", parent_context); + else if (*it == '$') + handle_ert(os, "$", parent_context); + else + os << *it; + } + p.skip_spaces(); + handle_ert(os, "\\end{" + name + "}", + parent_context); + } else { + string const lang = CJK2lyx(encoding); + // store the language because we must reset it at the end + string const lang_old = parent_context.font.language; + parent_context.font.language = lang; + parse_text_in_inset(p, os, FLAG_END, outer, parent_context); + parent_context.font.language = lang_old; + parent_context.new_paragraph(os); + } + p.encoding_latex_ = encoding_old; + p.skip_spaces(); + } + else if (name == "lyxgreyedout") { eat_whitespace(p, os, parent_context, false); parent_context.check_layout(os); @@ -1361,14 +1525,9 @@ void parse_environment(Parser & p, ostream & os, bool outer, else if (name == "lstlisting") { eat_whitespace(p, os, parent_context, false); - // FIXME handle listings with parameters - // If this is added, don't forgot to handle the - // automatic color package loading - if (p.hasOpt()) - parse_unknown_environment(p, name, os, FLAG_END, - outer, parent_context); - else - parse_listings(p, os, parent_context); + // FIXME handle the automatic color package loading + // uwestoehr asks: In what case color is loaded? + parse_listings(p, os, parent_context, false); p.skip_spaces(); } @@ -1478,7 +1637,7 @@ void parse_environment(Parser & p, ostream & os, bool outer, while (optargs < context.layout->optargs) { eat_whitespace(p, os, context, false); if (p.next_token().cat() == catEscape || - p.next_token().character() != '[') + p.next_token().character() != '[') break; p.get_token(); // eat '[' if (need_layout) { @@ -1520,10 +1679,12 @@ void parse_environment(Parser & p, ostream & os, bool outer, context.check_end_deeper(os); parent_context.new_paragraph(os); p.skip_spaces(); - if (!title_layout_found) - title_layout_found = newlayout->intitle; + if (!preamble.titleLayoutFound()) + preamble.titleLayoutFound(newlayout->intitle); set const & req = newlayout->requires(); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + set::const_iterator it = req.begin(); + set::const_iterator en = req.end(); + for (; it != en; ++it) preamble.registerAutomaticallyLoadedPackage(*it); } @@ -1899,6 +2060,28 @@ void parse_macro(Parser & p, ostream & os, Context & context) handle_ert(os, command + ert, context); } + +void registerExternalTemplatePackages(string const & name) +{ + external::TemplateManager const & etm = external::TemplateManager::get(); + external::Template const * const et = etm.getTemplateByName(name); + if (!et) + return; + external::Template::Formats::const_iterator cit = et->formats.end(); + if (pdflatex) + cit = et->formats.find("PDFLaTeX"); + if (cit == et->formats.end()) + // If the template has not specified a PDFLaTeX output, + // we try the LaTeX format. + cit = et->formats.find("LaTeX"); + if (cit == et->formats.end()) + return; + vector::const_iterator qit = cit->second.requirements.begin(); + vector::const_iterator qend = cit->second.requirements.end(); + for (; qit != qend; ++qit) + preamble.registerAutomaticallyLoadedPackage(*qit); +} + } // anonymous namespace @@ -1911,14 +2094,50 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // Store the latest bibliographystyle and nocite{*} option // (needed for bibtex inset) string btprint; - string bibliographystyle; + string bibliographystyle = "default"; bool const use_natbib = preamble.isPackageUsed("natbib"); bool const use_jurabib = preamble.isPackageUsed("jurabib"); string last_env; - bool title_layout_found = false; while (p.good()) { Token const & t = p.get_token(); + // it is impossible to determine the correct document language if CJK is used. + // Therefore write a note at the beginning of the document + if (have_CJK) { + context.check_layout(os); + begin_inset(os, "Note Note\n"); + os << "status open\n\\begin_layout Plain Layout\n" + << "\\series bold\n" + << "Important information:\n" + << "\\end_layout\n\n" + << "\\begin_layout Plain Layout\n" + << "This document contains text in Chinese, Japanese or Korean.\n" + << " It was therefore impossible for tex2lyx to set the correct document langue for your document." + << " Please set in the document settings by yourself!\n" + << "\\end_layout\n"; + end_inset(os); + have_CJK = false; + } + + // it is impossible to determine the correct encoding for non-CJK Japanese. + // Therefore write a note at the beginning of the document + if (is_nonCJKJapanese) { + context.check_layout(os); + begin_inset(os, "Note Note\n"); + os << "status open\n\\begin_layout Plain Layout\n" + << "\\series bold\n" + << "Important information:\n" + << "\\end_layout\n\n" + << "\\begin_layout Plain Layout\n" + << "This document is in Japanese (non-CJK).\n" + << " It was therefore impossible for tex2lyx to determine the correct encoding." + << " The encoding EUC-JP was assumed. If this is incorrect, please set the correct" + << " encoding in the document settings.\n" + << "\\end_layout\n"; + end_inset(os); + is_nonCJKJapanese = false; + } + #ifdef FILEDEBUG debugToken(cerr, t, flags); #endif @@ -2242,7 +2461,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "begin") parse_environment(p, os, outer, last_env, - title_layout_found, context); + context); else if (t.cs() == "end") { if (flags & FLAG_END) { @@ -2352,9 +2571,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // The file extension is in every case ".tex". // So we need to remove this extension and check for // the original one. - name.erase(name.length() - 4, name.length()); + name = removeExtension(name); if (!makeAbsPath(name, path).exists()) { - char const * const Gnumeric_formats[] = {"gnumeric" + char const * const Gnumeric_formats[] = {"gnumeric", "ods", "xls", 0}; string const Gnumeric_name = find_file(name, path, Gnumeric_formats); @@ -2375,14 +2594,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, macro = false; // register the packages that are automatically reloaded // by the Gnumeric template - // Fixme: InsetExternal.cpp should give us that list - preamble.registerAutomaticallyLoadedPackage("array"); - preamble.registerAutomaticallyLoadedPackage("calc"); - preamble.registerAutomaticallyLoadedPackage("color"); - preamble.registerAutomaticallyLoadedPackage("hhline"); - preamble.registerAutomaticallyLoadedPackage("ifthen"); - preamble.registerAutomaticallyLoadedPackage("longtable"); - preamble.registerAutomaticallyLoadedPackage("multirow"); + registerExternalTemplatePackages("GnumericSpreadsheet"); } } } @@ -2420,10 +2632,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // Must catch empty dates before findLayout is called below else if (t.cs() == "date") { + eat_whitespace(p, os, context, false); + p.pushPosition(); string const date = p.verbatim_item(); - if (date.empty()) + p.popPosition(); + if (date.empty()) { preamble.suppressDate(true); - else { + p.verbatim_item(); + } else { preamble.suppressDate(false); if (context.new_layout_allowed && (newlayout = findLayout(context.textclass, @@ -2431,16 +2647,18 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // write the layout output_command_layout(os, p, outer, context, newlayout); - p.skip_spaces(); - if (!title_layout_found) - title_layout_found = newlayout->intitle; + parse_text_snippet(p, os, FLAG_ITEM, outer, context); + if (!preamble.titleLayoutFound()) + preamble.titleLayoutFound(newlayout->intitle); set const & req = newlayout->requires(); - for (set::const_iterator it = req.begin(); - it != req.end(); it++) + set::const_iterator it = req.begin(); + set::const_iterator en = req.end(); + for (; it != en; ++it) preamble.registerAutomaticallyLoadedPackage(*it); } else - handle_ert(os, "\\date{" + date + '}', - context); + handle_ert(os, + "\\date{" + p.verbatim_item() + '}', + context); } } @@ -2453,10 +2671,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, p.get_token(); output_command_layout(os, p, outer, context, newlayout); p.skip_spaces(); - if (!title_layout_found) - title_layout_found = newlayout->intitle; + if (!preamble.titleLayoutFound()) + preamble.titleLayoutFound(newlayout->intitle); set const & req = newlayout->requires(); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); } @@ -2466,10 +2684,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // write the layout output_command_layout(os, p, outer, context, newlayout); p.skip_spaces(); - if (!title_layout_found) - title_layout_found = newlayout->intitle; + if (!preamble.titleLayoutFound()) + preamble.titleLayoutFound(newlayout->intitle); set const & req = newlayout->requires(); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); } @@ -2719,6 +2937,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // Warn about invalid options. // Check whether some option was given twice. end_inset(os); + preamble.registerAutomaticallyLoadedPackage("graphicx"); } else if (t.cs() == "footnote" || @@ -2740,6 +2959,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, end_inset(os); } + else if (t.cs() == "lstinline") { + p.skip_spaces(); + parse_listings(p, os, context, true); + } + else if (t.cs() == "ensuremath") { p.skip_spaces(); context.check_layout(os); @@ -2753,18 +2977,20 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.cs() == "makeindex" || t.cs() == "maketitle") { - if (title_layout_found) { + if (preamble.titleLayoutFound()) { // swallow this skip_spaces_braces(p); } else handle_ert(os, t.asInput(), context); } - else if (t.cs() == "tableofcontents") { + else if (t.cs() == "tableofcontents" || t.cs() == "lstlistoflistings") { context.check_layout(os); - begin_command_inset(os, "toc", "tableofcontents"); + begin_command_inset(os, "toc", t.cs()); end_inset(os); skip_spaces_braces(p); + if (t.cs() == "lstlistoflistings") + preamble.registerAutomaticallyLoadedPackage("listings"); } else if (t.cs() == "listoffigures") { @@ -2960,7 +3186,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, end_inset(os); skip_spaces_braces(p); } - + else if (t.cs() == "lyxline") { // swallow size argument (it is not used anyway) p.getArg('{', '}'); @@ -3160,12 +3386,18 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, btprint = key; } - else if (t.cs() == "index") { + else if (t.cs() == "index" || + (t.cs() == "sindex" && preamble.use_indices() == "true")) { context.check_layout(os); - begin_inset(os, "Index idx\n"); - os << "status collapsed\n"; + string const arg = (t.cs() == "sindex" && p.hasOpt()) ? + p.getArg('[', ']') : ""; + string const kind = arg.empty() ? "idx" : arg; + begin_inset(os, "Index "); + os << kind << "\nstatus collapsed\n"; parse_text_in_inset(p, os, FLAG_ITEM, false, context, "Index"); end_inset(os); + if (kind != "idx") + preamble.registerAutomaticallyLoadedPackage("splitidx"); } else if (t.cs() == "nomenclature") { @@ -3182,7 +3414,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, end_inset(os); preamble.registerAutomaticallyLoadedPackage("nomencl"); } - + else if (t.cs() == "label") { context.check_layout(os); begin_command_inset(os, "label", "label"); @@ -3329,8 +3561,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "selectlanguage") { context.check_layout(os); // save the language for the case that a - // \foreignlanguage is used - + // \foreignlanguage is used context.font.language = babel2lyx(p.verbatim_item()); os << "\n\\lang " << context.font.language << "\n"; } @@ -3341,6 +3572,38 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, context, "\\lang", context.font.language, lang); } + + else if (is_known(t.cs().substr(4, string::npos), polyglossia_languages)) { + // scheme is \textLANGUAGE{text} where LANGUAGE is in polyglossia_languages[] + string lang; + // We have to output the whole command if it has an option + // because LyX doesn't support this yet, see bug #8214, + // only if there is a single option specifying a variant, we can handle it. + if (p.hasOpt()) { + string langopts = p.getOpt(); + // check if the option contains a variant, if yes, extract it + string::size_type pos_var = langopts.find("variant"); + string::size_type i = langopts.find(','); + if (pos_var != string::npos){ + string variant; + if (i == string::npos) { + variant = langopts.substr(pos_var + 8, langopts.length() - pos_var - 9); + lang = polyglossia2lyx(variant); + parse_text_attributes(p, os, FLAG_ITEM, outer, + context, "\\lang", + context.font.language, lang); + } + else + handle_ert(os, t.asInput() + langopts, context); + } else + handle_ert(os, t.asInput() + langopts, context); + } else { + lang = polyglossia2lyx(t.cs().substr(4, string::npos)); + parse_text_attributes(p, os, FLAG_ITEM, outer, + context, "\\lang", + context.font.language, lang); + } + } else if (t.cs() == "inputencoding") { // nothing to write here @@ -3436,24 +3699,26 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, handle_ert(os, t.asInput(), context); // accents (see Table 6 in Comprehensive LaTeX Symbol List) - else if (t.cs().size() == 1 + else if (t.cs().size() == 1 && contains("\"'.=^`bcdHkrtuv~", t.cs())) { context.check_layout(os); // try to see whether the string is in unicodesymbols + bool termination; docstring rem; - string command = t.asInput() + "{" + string command = t.asInput() + "{" + trimSpaceAndEol(p.verbatim_item()) + "}"; set req; docstring s = encodings.fromLaTeXCommand(from_utf8(command), - Encodings::TEXT_CMD | Encodings::MATH_CMD, rem, &req); + Encodings::TEXT_CMD | Encodings::MATH_CMD, + termination, rem, &req); if (!s.empty()) { if (!rem.empty()) - cerr << "When parsing " << command + cerr << "When parsing " << command << ", result is " << to_utf8(s) << "+" << to_utf8(rem) << endl; os << to_utf8(s); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); } else // we did not find a non-ert version @@ -3584,6 +3849,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, begin_inset(os, "External\n"); os << "\ttemplate XFig\n" << "\tfilename " << outname << '\n'; + registerExternalTemplatePackages("XFig"); } else { begin_command_inset(os, "include", name); os << "preview false\n" @@ -4006,6 +4272,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << "\tkeepAspectRatio\n"; end_inset(os); context.check_layout(os); + registerExternalTemplatePackages("PDFPages"); } else if (t.cs() == "loadgame") { @@ -4037,25 +4304,28 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // after a \loadgame follows a \showboard if (p.get_token().asInput() == "showboard") p.get_token(); + registerExternalTemplatePackages("ChessDiagram"); } else { // try to see whether the string is in unicodesymbols // Only use text mode commands, since we are in text mode here, // and math commands may be invalid (bug 6797) + bool termination; docstring rem; set req; docstring s = encodings.fromLaTeXCommand(from_utf8(t.asInput()), - Encodings::TEXT_CMD, rem, &req); + Encodings::TEXT_CMD, termination, rem, &req); if (!s.empty()) { if (!rem.empty()) - cerr << "When parsing " << t.cs() + cerr << "When parsing " << t.cs() << ", result is " << to_utf8(s) << "+" << to_utf8(rem) << endl; context.check_layout(os); os << to_utf8(s); - skip_spaces_braces(p); - for (set::const_iterator it = req.begin(); it != req.end(); it++) + if (termination) + skip_spaces_braces(p); + for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); } //cerr << "#: " << t << " mode: " << mode << endl;