X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2Ftext.cpp;h=f9201cd1a26f73f307979729869a3f243d5d0683;hb=a2b21e3cd4bbfd42e59161143eba6e7681aaa93f;hp=919f454c66a6c652d9e082527747eb7fdefbd234;hpb=ab32a8319d1d983f10970ac7ee974f40949cb0fd;p=lyx.git diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 919f454c66..f9201cd1a2 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -528,6 +528,35 @@ string guessQuoteStyle(string in, bool const opening) } +string const fromPolyglossiaEnvironment(string const s) +{ + // Since \arabic is taken by the LaTeX kernel, + // the Arabic polyglossia environment is upcased + if (s == "Arabic") + return "arabic"; + else + return s; +} + + +string uncapitalize(string const s) +{ + docstring in = from_ascii(s); + char_type t = lowercase(s[0]); + in[0] = t; + return to_ascii(in); +} + + +bool isCapitalized(string const s) +{ + docstring in = from_ascii(s); + char_type t = uppercase(s[0]); + in[0] = t; + return to_ascii(in) == s; +} + + } // namespace @@ -1566,6 +1595,14 @@ void parse_unknown_environment(Parser & p, string const & name, ostream & os, if (specialfont) parent_context.new_layout_allowed = false; output_ert_inset(os, "\\begin{" + name + "}", parent_context); + // Try to handle options: Look if we have optional arguments, + // and if so, put the brackets in ERT. + while (p.hasOpt()) { + p.get_token(); // eat '[' + output_ert_inset(os, "[", parent_context); + os << parse_text_snippet(p, FLAG_BRACK_LAST, outer, parent_context); + output_ert_inset(os, "]", parent_context); + } parse_text_snippet(p, os, flags, outer, parent_context); output_ert_inset(os, "\\end{" + name + "}", parent_context); if (specialfont) @@ -1602,7 +1639,8 @@ void parse_environment(Parser & p, ostream & os, bool outer, break; } - if (is_known(name, preamble.polyglossia_languages)) { + // We need to use fromPolyglossiaEnvironment die to Arabic > arabic + if (is_known(fromPolyglossiaEnvironment(name), preamble.polyglossia_languages)) { // We must begin a new paragraph if not already done if (! parent_context.atParagraphStart()) { parent_context.check_end_layout(os); @@ -1610,7 +1648,8 @@ void parse_environment(Parser & p, ostream & os, bool outer, } // save the language in the context so that it is // handled by parse_text - parent_context.font.language = preamble.polyglossia2lyx(name); + parent_context.font.language = + preamble.polyglossia2lyx(fromPolyglossiaEnvironment(name)); parse_text(p, os, FLAG_END, outer, parent_context); // Just in case the environment is empty parent_context.extra_stuff.erase(); @@ -2261,6 +2300,9 @@ void parse_environment(Parser & p, ostream & os, bool outer, } switch (context.layout->latextype) { case LATEX_LIST_ENVIRONMENT: + context.in_list_preamble = + !context.layout->listpreamble().empty() + && p.hasListPreamble(context.layout->itemcommand()); context.add_par_extra_stuff("\\labelwidthstring " + p.verbatim_item() + '\n'); p.skip_spaces(); @@ -2284,11 +2326,20 @@ void parse_environment(Parser & p, ostream & os, bool outer, output_arguments(os, p, outer, false, string(), context, context.layout->latexargs()); else if (context.layout->latextype == LATEX_ITEM_ENVIRONMENT) { + context.in_list_preamble = + !context.layout->listpreamble().empty() + && p.hasListPreamble(context.layout->itemcommand()); ostringstream oss; output_arguments(oss, p, outer, false, string(), context, context.layout->latexargs()); context.list_extra_stuff = oss.str(); } + if (context.in_list_preamble) { + // Collect the stuff between \begin and first \item + context.list_preamble = + parse_text_snippet(p, FLAG_END, outer, context); + context.in_list_preamble = false; + } parse_text(p, os, FLAG_END, outer, context); if (context.layout->latextype == LATEX_ENVIRONMENT) output_arguments(os, p, outer, false, "post", context, @@ -2304,7 +2355,7 @@ void parse_environment(Parser & p, ostream & os, bool outer, p.skip_spaces(); if (!preamble.titleLayoutFound()) preamble.titleLayoutFound(newlayout->intitle); - set const & req = newlayout->requires(); + set const & req = newlayout->required(); set::const_iterator it = req.begin(); set::const_iterator en = req.end(); for (; it != en; ++it) @@ -2868,6 +2919,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, debugToken(cerr, t, flags); #endif + if (context.in_list_preamble + && p.next_token().cs() == context.layout->itemcommand()) { + // We are parsing a list preamble. End before first \item. + flags |= FLAG_LEAVE; + context.in_list_preamble = false; + } + if (flags & FLAG_ITEM) { if (t.cat() == catSpace) continue; @@ -3312,6 +3370,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, if (context.layout->labeltype != LABEL_MANUAL) output_arguments(os, p, outer, false, "item", context, context.layout->itemargs()); + if (!context.list_preamble.empty()) { + // We have a list preamble. Output it here. + begin_inset(os, "Argument listpreamble:1"); + os << "\nstatus collapsed\n\n" + << "\\begin_layout Plain Layout\n\n" + << rtrim(context.list_preamble) + << "\n\\end_layout"; + end_inset(os); + context.list_preamble.clear(); + } if (!context.list_extra_stuff.empty()) { os << context.list_extra_stuff; context.list_extra_stuff.clear(); @@ -3465,7 +3533,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, parse_text_snippet(p, os, FLAG_ITEM, outer, context); if (!preamble.titleLayoutFound()) preamble.titleLayoutFound(newlayout->intitle); - set const & req = newlayout->requires(); + set const & req = newlayout->required(); set::const_iterator it = req.begin(); set::const_iterator en = req.end(); for (; it != en; ++it) @@ -3491,13 +3559,12 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, p.skip_spaces(); if (!preamble.titleLayoutFound()) preamble.titleLayoutFound(newlayout->intitle); - set const & req = newlayout->requires(); + set const & req = newlayout->required(); for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); continue; } - // Starred section headings // Must attempt to parse "Section*" before "Section". if ((p.next_token().asInput() == "*") && @@ -3509,7 +3576,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, p.skip_spaces(); if (!preamble.titleLayoutFound()) preamble.titleLayoutFound(newlayout->intitle); - set const & req = newlayout->requires(); + set const & req = newlayout->required(); for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); continue; @@ -3523,7 +3590,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, p.skip_spaces(); if (!preamble.titleLayoutFound()) preamble.titleLayoutFound(newlayout->intitle); - set const & req = newlayout->requires(); + set const & req = newlayout->required(); for (set::const_iterator it = req.begin(); it != req.end(); ++it) preamble.registerAutomaticallyLoadedPackage(*it); continue; @@ -3666,9 +3733,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, if (opts.find("width") != opts.end()) os << "\twidth " << translate_len(opts["width"]) << '\n'; - if (opts.find("height") != opts.end()) + if (opts.find("totalheight") != opts.end()) os << "\theight " - << translate_len(opts["height"]) << '\n'; + << translate_len(opts["totalheight"]) << '\n'; if (opts.find("scale") != opts.end()) { istringstream iss(opts["scale"]); double val; @@ -3684,7 +3751,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, vector::const_iterator s = find(keys.begin(), keys.end(), "width"); if (s == keys.end()) - s = find(keys.begin(), keys.end(), "height"); + s = find(keys.begin(), keys.end(), "totalheight"); if (s == keys.end()) s = find(keys.begin(), keys.end(), "scale"); if (s != keys.end() && distance(s, a) > 0) @@ -3745,8 +3812,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, special << "trim,"; if (opts.find("viewport") != opts.end()) special << "viewport=" << opts["viewport"] << ','; - if (opts.find("totalheight") != opts.end()) - special << "totalheight=" << opts["totalheight"] << ','; + if (opts.find("height") != opts.end()) + special << "height=" << opts["height"] << ','; if (opts.find("type") != opts.end()) special << "type=" << opts["type"] << ','; if (opts.find("ext") != opts.end()) @@ -3852,18 +3919,29 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, if (t.cs() == "listof") { p.skip_spaces(true); - string const name = p.get_token().cs(); + string const name = p.verbatim_item(); 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 + p.verbatim_item(); // swallow second arg } else output_ert_inset(os, "\\listof{" + name + "}", context); continue; } + if (t.cs() == "theendnotes" + || (t.cs() == "printendnotes" + && p.next_token().asInput() != "*" + && !p.hasOpt())) { + context.check_layout(os); + begin_inset(os, "FloatList endnote\n"); + end_inset(os); + skip_spaces_braces(p); + continue; + } + if ((where = is_known(t.cs(), known_text_font_families))) { parse_text_attributes(p, os, FLAG_ITEM, outer, context, "\\family", context.font.family, @@ -3973,11 +4051,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, continue; } - if (t.cs() == "lyxadded" || t.cs() == "lyxdeleted") { + if (t.cs() == "lyxadded" || t.cs() == "lyxdeleted" || t.cs() == "lyxobjdeleted" + || t.cs() == "lyxdisplayobjdeleted" || t.cs() == "lyxudisplayobjdeleted") { context.check_layout(os); + string initials; + if (p.hasOpt()) { + initials = p.getArg('[', ']'); + } string name = p.getArg('{', '}'); string localtime = p.getArg('{', '}'); - preamble.registerAuthor(name); + preamble.registerAuthor(name, initials); Author const & author = preamble.getAuthor(name); // from_asctime_utc() will fail if LyX decides to output the // time in the text language. @@ -3993,7 +4076,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << "\n\\change_deleted "; os << author.bufferId() << ' ' << ptime << '\n'; parse_text_snippet(p, os, FLAG_ITEM, outer, context); - bool dvipost = LaTeXPackages::isAvailable("dvipost"); bool xcolorulem = LaTeXPackages::isAvailable("ulem") && LaTeXPackages::isAvailable("xcolor"); // No need to test for luatex, since luatex comes in @@ -4006,9 +4088,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, preamble.registerAutomaticallyLoadedPackage("pdfcolmk"); } } else { - if (dvipost) { - preamble.registerAutomaticallyLoadedPackage("dvipost"); - } else if (xcolorulem) { + if (xcolorulem) { preamble.registerAutomaticallyLoadedPackage("ulem"); preamble.registerAutomaticallyLoadedPackage("xcolor"); } @@ -4170,21 +4250,37 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, continue; } - // handle refstyle first to catch \eqref which can also occur - // without refstyle. Only recognize these commands if + // Handle refstyle first in order to to catch \eqref, because this + // can also occur without refstyle. Only recognize these commands if // refstyle.sty was found in the preamble (otherwise \eqref // and user defined ref commands could be misdetected). - if ((where = is_known(t.cs(), known_refstyle_commands)) + // We uncapitalize the input in order to catch capitalized commands + // such as \Eqref. + if ((where = is_known(uncapitalize(t.cs()), known_refstyle_commands)) && preamble.refstyle()) { + string const cap = isCapitalized(t.cs()) ? "true" : "false"; + string plural = "false"; + // Catch the plural option [s] + if (p.hasOpt()) { + string const opt = p.getOpt(); + if (opt == "[s]") + plural = "true"; + else { + // LyX does not yet support other optional arguments of ref commands + output_ert_inset(os, t.asInput() + opt + "{" + + p.verbatim_item() + '}', context); + continue; + } + } context.check_layout(os); begin_command_inset(os, "ref", "formatted"); os << "reference \""; os << known_refstyle_prefixes[where - known_refstyle_commands] << ":"; - os << convert_literate_command_inset_arg(p.verbatim_item()) + os << convert_literate_command_inset_arg(p.getArg('{', '}')) << "\"\n"; - os << "plural \"false\"\n"; - os << "caps \"false\"\n"; + os << "plural \"" << plural << "\"\n"; + os << "caps \"" << cap << "\"\n"; os << "noprefix \"false\"\n"; end_inset(os); preamble.registerAutomaticallyLoadedPackage("refstyle"); @@ -4213,8 +4309,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, preamble.registerAutomaticallyLoadedPackage("prettyref"); } else { // LyX does not yet support optional arguments of ref commands - output_ert_inset(os, t.asInput() + '[' + opt + "]{" + - p.verbatim_item() + '}', context); + output_ert_inset(os, t.asInput() + opt + "{" + + p.verbatim_item() + '}', context); } continue; } @@ -4378,13 +4474,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } string keys, pretextlist, posttextlist; if (qualified) { - map pres, posts, preslit, postslit; + vector> pres, posts, preslit, postslit; vector lkeys; // text before the citation string lbefore, lbeforelit; // text after the citation string lafter, lafterlit; - string lkey; + string lkey; pair laft, lbef; while (true) { get_cite_arguments(p, true, lbefore, lafter); @@ -4395,7 +4491,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, laft = convert_latexed_command_inset_arg(lafter); literal |= !laft.first; lafter = laft.second; - lafterlit = subst(lbefore, "\n", " "); + lafterlit = subst(lafter, "\n", " "); } if (!lbefore.empty()) { lbefore.erase(0, 1); @@ -4420,14 +4516,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, lkey = p.getArg('{', '}'); if (lkey.empty()) break; - if (!lbefore.empty()) { - pres.insert(make_pair(lkey, lbefore)); - preslit.insert(make_pair(lkey, lbeforelit)); - } - if (!lafter.empty()) { - posts.insert(make_pair(lkey, lafter)); - postslit.insert(make_pair(lkey, lafterlit)); - } + pres.push_back(make_pair(lkey, lbefore)); + preslit.push_back(make_pair(lkey, lbeforelit)); + posts.push_back(make_pair(lkey, lafter)); + postslit.push_back(make_pair(lkey, lafterlit)); lkeys.push_back(lkey); } keys = convert_literate_command_inset_arg(getStringFromVector(lkeys)); @@ -4438,12 +4530,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, for (auto const & ptl : pres) { if (!pretextlist.empty()) pretextlist += '\t'; - pretextlist += ptl.first + " " + ptl.second; + pretextlist += ptl.first; + if (!ptl.second.empty()) + pretextlist += " " + ptl.second; } for (auto const & potl : posts) { if (!posttextlist.empty()) posttextlist += '\t'; - posttextlist += potl.first + " " + potl.second; + posttextlist += potl.first; + if (!potl.second.empty()) + posttextlist += " " + potl.second; } } else keys = convert_literate_command_inset_arg(p.verbatim_item()); @@ -5290,6 +5386,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else os << "encoding " << '"' << enc->name() << '"' << "\n"; } + string bibfileencs; + for (auto const & bf : preamble.biblatex_encodings) { + if (!bibfileencs.empty()) + bibfileencs += "\t"; + bibfileencs += bf; + } + if (!bibfileencs.empty()) + os << "file_encodings " << '"' << bibfileencs << '"' << "\n"; end_inset(os); need_commentbib = false; continue; @@ -6046,8 +6150,18 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, p.get_token(); // Eat '*' name += '*'; } - if (!parse_command(name, p, os, outer, context)) + if (!parse_command(name, p, os, outer, context)) { output_ert_inset(os, name, context); + // Try to handle options of unknown commands: + // Look if we have optional arguments, + // and if so, put the brackets in ERT. + while (p.hasOpt()) { + p.get_token(); // eat '[' + output_ert_inset(os, "[", context); + os << parse_text_snippet(p, FLAG_BRACK_LAST, outer, context); + output_ert_inset(os, "]", context); + } + } } } } @@ -6145,6 +6259,14 @@ void check_comment_bib(ostream & os, Context & context) } if (!bibfiles.empty()) os << "bibfiles " << '"' << bibfiles << '"' << "\n"; + string bibfileencs; + for (auto const & bf : preamble.biblatex_encodings) { + if (!bibfileencs.empty()) + bibfileencs += "\t"; + bibfileencs += bf; + } + if (!bibfileencs.empty()) + os << "file_encodings " << '"' << bibfileencs << '"' << "\n"; end_inset(os);// Bibtex os << "\\end_layout\n"; end_inset(os);// Note