]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/text.cpp
Cmake export tests: Ignore missing glyphs on some tests
[lyx.git] / src / tex2lyx / text.cpp
index 33c389ba5f4bdb3115cf3eda260bae44fd99e40c..2e7f08a596d6560ac738d78c3da072e36c1a4877 100644 (file)
@@ -124,6 +124,9 @@ string parse_text_snippet(Parser & p, unsigned flags, const bool outer,
        return os.str();
 }
 
+string fboxrule = "";
+string fboxsep = "";
+string shadow_size = "";
 
 char const * const known_ref_commands[] = { "ref", "pageref", "vref",
  "vpageref", "prettyref", "nameref", "eqref", 0 };
@@ -133,11 +136,11 @@ char const * const known_coded_ref_commands[] = { "ref", "pageref", "vref",
 
 char const * const known_refstyle_commands[] = { "algref", "chapref", "corref",
  "eqref", "enuref", "figref", "fnref", "lemref", "parref", "partref", "propref",
- "secref", "subref", "tabref", "thmref", 0 };
+ "secref", "subsecref", "tabref", "thmref", 0 };
 
 char const * const known_refstyle_prefixes[] = { "alg", "chap", "cor",
  "eq", "enu", "fig", "fn", "lem", "par", "part", "prop",
- "sec", "sub", "tab", "thm", 0 };
+ "sec", "subsec", "tab", "thm", 0 };
 
 
 /**
@@ -310,7 +313,7 @@ char const * const known_tipa_marks[] = {"textsubwedge", "textsubumlaut",
 "textovercross", "textsubarch", "textsuperimposetilde", "textraising",
 "textlowering", "textadvancing", "textretracting", "textdoublegrave",
 "texthighrise", "textlowrise", "textrisefall", "textsyllabic",
-"textsubring", 0};
+"textsubring", "textsubbar", 0};
 
 /// TIPA tones that need special handling
 char const * const known_tones[] = {"15", "51", "45", "12", "454", 0};
@@ -318,6 +321,15 @@ char const * const known_tones[] = {"15", "51", "45", "12", "454", 0};
 // string to store the float type to be able to determine the type of subfloats
 string float_type = "";
 
+// string to store the float status of minted listings
+string minted_float = "";
+
+// whether a caption has been parsed for a floating minted listing
+bool minted_float_has_caption = false;
+
+// The caption for non-floating minted listings
+string minted_nonfloat_caption = "";
+
 
 /// splits "x=z, y=b" into a map and an ordered keyword vector
 void split_map(string const & s, map<string, string> & res, vector<string> & keys)
@@ -410,6 +422,9 @@ bool translate_len(string const & length, string & valstring, string & unit)
        } else if (unit == "\\textheight") {
                valstring = percentval;
                unit = "theight%" + endlen;
+       } else if (unit == "\\baselineskip") {
+               valstring = percentval;
+               unit = "baselineskip%" + endlen;
        }
        return true;
 }
@@ -518,8 +533,8 @@ docstring convert_unicodesymbols(docstring s)
                bool termination;
                docstring rem;
                set<string> req;
-               docstring parsed = encodings.fromLaTeXCommand(s,
-                               Encodings::TEXT_CMD, termination, rem, &req);
+               docstring parsed = normalize_c(encodings.fromLaTeXCommand(s,
+                               Encodings::TEXT_CMD, termination, rem, &req));
                set<string>::const_iterator it = req.begin();
                set<string>::const_iterator en = req.end();
                for (; it != en; ++it)
@@ -577,6 +592,16 @@ void output_ert_inset(ostream & os, string const & s, Context & context)
 }
 
 
+void output_comment(Parser & p, ostream & os, string const & s,
+                    Context & context)
+{
+       if (p.next_token().cat() == catNewline)
+               output_ert_inset(os, '%' + s, context);
+       else
+               output_ert_inset(os, '%' + s + '\n', context);
+}
+
+
 Layout const * findLayout(TextClass const & textclass, string const & name, bool command)
 {
        Layout const * layout = findLayoutWithoutModule(textclass, name, command);
@@ -832,11 +857,12 @@ bool parse_command(string const & command, Parser & p, ostream & os,
 void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                unsigned inner_flags, bool outer, Context & parent_context,
                string const & outer_type, string const & special,
-               string const & inner_type)
+               string inner_type, string const & frame_color,
+               string const & background_color)
 {
        string position;
        string inner_pos;
-       string hor_pos = "c";
+       string hor_pos = "l";
        // We need to set the height to the LaTeX default of 1\\totalheight
        // for the case when no height argument is given
        string height_value = "1";
@@ -847,6 +873,63 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
        string width_unit;
        string latex_width;
        string width_special = "none";
+       string thickness = "0.4pt";
+       if (!fboxrule.empty())
+               thickness = fboxrule;
+       else
+               thickness = "0.4pt";
+       string separation;
+       if (!fboxsep.empty())
+               separation = fboxsep;
+       else
+               separation = "3pt";
+       string shadowsize;
+       if (!shadow_size.empty())
+               shadowsize = shadow_size;
+       else
+               shadowsize = "4pt";
+       string framecolor = "black";
+       string backgroundcolor = "none";
+       if (!frame_color.empty())
+               framecolor = frame_color;
+       if (!background_color.empty())
+               backgroundcolor = background_color;
+       // if there is a color box around the \begin statements have not yet been parsed
+       // so do this now
+       if (!frame_color.empty() || !background_color.empty()) {
+               eat_whitespace(p, os, parent_context, false);
+               p.get_token().asInput(); // the '{'
+               // parse minipage
+               if (p.next_token().asInput() == "\\begin") {
+                       p.get_token().asInput();
+                       p.getArg('{', '}');
+                       inner_type = "minipage";
+                       inner_flags = FLAG_END;
+                       active_environments.push_back("minipage");
+               }
+               // parse parbox
+               else if (p.next_token().asInput() == "\\parbox") {
+                       p.get_token().asInput();
+                       inner_type = "parbox";
+                       inner_flags = FLAG_ITEM;
+               }
+               // parse makebox
+               else if (p.next_token().asInput() == "\\makebox") {
+                       p.get_token().asInput();
+                       inner_type = "makebox";
+                       inner_flags = FLAG_ITEM;
+               }
+               // in case there is just \colorbox{color}{text}
+               else {
+                       latex_width = "";
+                       inner_type = "makebox";
+                       inner_flags = FLAG_BRACE_LAST;
+                       position = "t";
+                       inner_pos = "t";
+               }
+       }
+       if (!p.hasOpt() && (inner_type == "makebox" || outer_type == "mbox"))
+               hor_pos = "c";
        if (!inner_type.empty() && p.hasOpt()) {
                if (inner_type != "makebox")
                        position = p.getArg('[', ']');
@@ -887,6 +970,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                                        inner_pos = position;
                                }
                        }
+               } else {
+                       if (inner_type == "makebox")
+                               hor_pos = "c";
                }
        }
        if (inner_type.empty()) {
@@ -904,6 +990,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                                             << " for " << outer_type << endl;
                                        hor_pos = "c";
                                }
+                       } else {
+                               if (outer_type == "framebox")
+                                       hor_pos = "c";
                        }
                }
        } else if (inner_type != "makebox")
@@ -934,9 +1023,8 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
        if (!outer_type.empty() && !inner_type.empty() &&
            (inner_flags & FLAG_END))
                active_environments.push_back(inner_type);
-       // LyX can't handle length variables
-       bool use_ert = contains(width_unit, '\\') || contains(height_unit, '\\');
-       if (!use_ert && !outer_type.empty() && !inner_type.empty()) {
+       bool use_ert = false;
+       if (!outer_type.empty() && !inner_type.empty()) {
                // Look whether there is some content after the end of the
                // inner box, but before the end of the outer box.
                // If yes, we need to output ERT.
@@ -955,18 +1043,7 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                }
                p.popPosition();
        }
-       // if only \makebox{content} was used we can set its width to 1\width
-       // because this identic and also identic to \mbox
-       // this doesn't work for \framebox{content}, thus we have to use ERT for this
-       if (latex_width.empty() && inner_type == "makebox") {
-               width_value = "1";
-               width_unit = "in";
-               width_special = "width";
-       } else if (latex_width.empty() && outer_type == "framebox") {
-               width_value.clear();
-               width_unit.clear();
-               width_special = "none";
-       }
+
        if (use_ert) {
                ostringstream ss;
                if (!outer_type.empty()) {
@@ -1036,7 +1113,7 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                begin_inset(os, "Box ");
                if (outer_type == "framed")
                        os << "Framed\n";
-               else if (outer_type == "framebox" || outer_type == "fbox")
+               else if (outer_type == "framebox" || outer_type == "fbox" || !frame_color.empty())
                        os << "Boxed\n";
                else if (outer_type == "shadowbox")
                        os << "Shadowbox\n";
@@ -1055,6 +1132,8 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                os << "hor_pos \"" << hor_pos << "\"\n";
                if (outer_type == "mbox")
                        os << "has_inner_box 1\n";
+               else if (!frame_color.empty() && inner_type == "makebox")
+                       os << "has_inner_box 0\n";
                else
                        os << "has_inner_box " << !inner_type.empty() << "\n";
                os << "inner_pos \"" << inner_pos << "\"\n";
@@ -1062,15 +1141,32 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                   << '\n';
                if (outer_type == "mbox")
                        os << "use_makebox 1\n";
+               else if (!frame_color.empty())
+                       os << "use_makebox 0\n";
                else
                        os << "use_makebox " << (inner_type == "makebox") << '\n';
-               if (outer_type == "fbox" || outer_type == "mbox")
+               if (outer_type == "mbox" || (outer_type == "fbox" && inner_type.empty()))
                        os << "width \"\"\n";
+               // for values like "1.5\width" LyX uses "1.5in" as width ad sets "width" as sepecial
+               else if (contains(width_unit, '\\'))
+                       os << "width \"" << width_value << "in" << "\"\n";
                else
                        os << "width \"" << width_value << width_unit << "\"\n";
-               os << "special \"" << width_special << "\"\n";
-               os << "height \"" << height_value << height_unit << "\"\n";
+               if (contains(width_unit, '\\')) {
+                       width_unit.erase (0,1); // remove the leading '\'
+                       os << "special \"" << width_unit << "\"\n";
+               } else
+                       os << "special \"" << width_special << "\"\n";
+               if (contains(height_unit, '\\'))
+                       os << "height \"" << height_value << "in" << "\"\n";
+               else
+                       os << "height \"" << height_value << height_unit << "\"\n";
                os << "height_special \"" << height_special << "\"\n";
+               os << "thickness \"" << thickness << "\"\n";
+               os << "separation \"" << separation << "\"\n";
+               os << "shadowsize \"" << shadowsize << "\"\n";
+               os << "framecolor \"" << framecolor << "\"\n";
+               os << "backgroundcolor \"" << backgroundcolor << "\"\n";
                os << "status open\n\n";
 
                // Unfortunately we can't use parse_text_in_inset:
@@ -1115,13 +1211,13 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                // LyX puts a % after the end of the minipage
                if (p.next_token().cat() == catNewline && p.next_token().cs().size() > 1) {
                        // new paragraph
-                       //output_ert_inset(os, "%dummy", parent_context);
+                       //output_comment(p, os, "dummy", parent_context);
                        p.get_token();
                        p.skip_spaces();
                        parent_context.new_paragraph(os);
                }
                else if (p.next_token().cat() == catSpace || p.next_token().cat() == catNewline) {
-                       //output_ert_inset(os, "%dummy", parent_context);
+                       //output_comment(p, os, "dummy", parent_context);
                        p.get_token();
                        p.skip_spaces();
                        // We add a protected space if something real follows
@@ -1132,6 +1228,26 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                }
 #endif
        }
+       if (inner_type == "minipage" && (!frame_color.empty() || !background_color.empty()))
+               active_environments.pop_back();
+       if (inner_flags != FLAG_BRACE_LAST && (!frame_color.empty() || !background_color.empty())) {
+               // in this case we have to eat the the closing brace of the color box
+               p.get_token().asInput(); // the '}'
+       }
+       if (p.next_token().asInput() == "}") {
+               // in this case we assume that the closing brace is from the box settings
+               // therefore reset these values for the next box
+               fboxrule = "";
+               fboxsep = "";
+               shadow_size = "";
+       }
+
+       // all boxes except of Frameless and Shaded require calc
+       if (!(outer_type.empty() || outer_type == "mbox") &&
+               !((outer_type == "shaded" && inner_type.empty()) ||
+                            (outer_type == "minipage" && inner_type == "shaded") ||
+                            (outer_type == "parbox" && inner_type == "shaded")))
+               preamble.registerAutomaticallyLoadedPackage("calc");
 }
 
 
@@ -1167,8 +1283,7 @@ void parse_outer_box(Parser & p, ostream & os, unsigned flags, bool outer,
                        p.skip_spaces(true);
                }
        }
-       if (outer_type == "shaded" || outer_type == "fbox"
-               || outer_type == "mbox") {
+       if (outer_type == "shaded" || outer_type == "mbox") {
                // These boxes never have an inner box
                ;
        } else if (p.next_token().asInput() == "\\parbox") {
@@ -1194,24 +1309,39 @@ void parse_outer_box(Parser & p, ostream & os, unsigned flags, bool outer,
                        eat_whitespace(p, os, parent_context, false);
                }
                parse_box(p, os, flags, FLAG_END, outer, parent_context,
-                         outer_type, special, inner);
+                         outer_type, special, inner, "", "");
        } else {
                if (inner_flags == FLAG_ITEM) {
                        p.get_token();
                        eat_whitespace(p, os, parent_context, false);
                }
                parse_box(p, os, flags, inner_flags, outer, parent_context,
-                         outer_type, special, inner);
+                         outer_type, special, inner, "", "");
        }
 }
 
 
-void parse_listings(Parser & p, ostream & os, Context & parent_context, bool in_line)
+void parse_listings(Parser & p, ostream & os, Context & parent_context,
+                   bool in_line, bool use_minted)
 {
        parent_context.check_layout(os);
        begin_inset(os, "listings\n");
-       if (p.hasOpt()) {
-               string arg = p.verbatimOption();
+       string arg = p.hasOpt() ? subst(p.verbatimOption(), "\n", "") : string();
+       size_t i;
+       while ((i = arg.find(", ")) != string::npos
+                       || (i = arg.find(",\t")) != string::npos)
+               arg.erase(i + 1, 1);
+
+       if (use_minted) {
+               string const language = p.getArg('{', '}');
+               p.skip_spaces(true);
+               arg += string(arg.empty() ? "" : ",") + "language=" + language;
+               if (!minted_float.empty()) {
+                       arg += string(arg.empty() ? "" : ",") + minted_float;
+                       minted_nonfloat_caption.clear();
+               }
+       }
+       if (!arg.empty()) {
                os << "lstparams " << '"' << arg << '"' << '\n';
                if (arg.find("\\color") != string::npos)
                        preamble.registerAutomaticallyLoadedPackage("color");
@@ -1223,6 +1353,19 @@ void parse_listings(Parser & p, ostream & os, Context & parent_context, bool in_
        os << "status collapsed\n";
        Context context(true, parent_context.textclass);
        context.layout = &parent_context.textclass.plainLayout();
+       if (use_minted && prefixIs(minted_nonfloat_caption, "[t]")) {
+               minted_nonfloat_caption.erase(0,3);
+               os << "\n\\begin_layout Plain Layout\n";
+               begin_inset(os, "Caption Standard\n");
+               Context newcontext(true, context.textclass,
+                                  context.layout, 0, context.font);
+               newcontext.check_layout(os);
+               os << minted_nonfloat_caption << "\n";
+               newcontext.check_end_layout(os);
+               end_inset(os);
+               os << "\n\\end_layout\n";
+               minted_nonfloat_caption.clear();
+       }
        string s;
        if (in_line) {
                // set catcodes to verbatim early, just in case.
@@ -1231,10 +1374,41 @@ void parse_listings(Parser & p, ostream & os, Context & parent_context, bool in_
                //FIXME: handler error condition
                s = p.verbatimStuff(delim).second;
 //             context.new_paragraph(os);
-       } else
+       } else if (use_minted) {
+               s = p.verbatimEnvironment("minted");
+       } else {
                s = p.verbatimEnvironment("lstlisting");
+       }
        output_ert(os, s, context);
-       end_inset(os);
+       if (use_minted && prefixIs(minted_nonfloat_caption, "[b]")) {
+               minted_nonfloat_caption.erase(0,3);
+               os << "\n\\begin_layout Plain Layout\n";
+               begin_inset(os, "Caption Standard\n");
+               Context newcontext(true, context.textclass,
+                                  context.layout, 0, context.font);
+               newcontext.check_layout(os);
+               os << minted_nonfloat_caption << "\n";
+               newcontext.check_end_layout(os);
+               end_inset(os);
+               os << "\n\\end_layout\n";
+               minted_nonfloat_caption.clear();
+       }
+       // Don't close the inset here for floating minted listings.
+       // It will be closed at the end of the listing environment.
+       if (!use_minted || minted_float.empty())
+               end_inset(os);
+       else {
+               eat_whitespace(p, os, parent_context, true);
+               Token t = p.get_token();
+               if (t.asInput() != "\\end") {
+                       // If anything follows, collect it into a caption.
+                       minted_float_has_caption = true;
+                       os << "\n\\begin_layout Plain Layout\n"; // outer layout
+                       begin_inset(os, "Caption Standard\n");
+                       os << "\n\\begin_layout Plain Layout\n"; // inner layout
+               }
+               p.putback();
+       }
 }
 
 
@@ -1338,12 +1512,12 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                if (!opt.empty())
                        os << "placement " << opt << '\n';
                if (contains(opt, "H"))
-                       preamble.registerAutomaticallyLoadedPackage("float");
+                       preamble.registerAutomaticallyLoadedPackage("float");
                else {
                        Floating const & fl = parent_context.textclass.floats()
-                               .getType(unstarred_name);
-                       if (!fl.floattype().empty() && fl.usesFloatPkg())
-                               preamble.registerAutomaticallyLoadedPackage("float");
+                                             .getType(unstarred_name);
+                       if (!fl.floattype().empty() && fl.usesFloatPkg())
+                               preamble.registerAutomaticallyLoadedPackage("float");
                }
 
                os << "wide " << convert<string>(is_starred)
@@ -1360,13 +1534,21 @@ void parse_environment(Parser & p, ostream & os, bool outer,
        }
 
        else if (unstarred_name == "sidewaysfigure"
-               || unstarred_name == "sidewaystable") {
+               || unstarred_name == "sidewaystable"
+               || unstarred_name == "sidewaysalgorithm") {
+               string const opt = p.hasOpt() ? p.getArg('[', ']') : string();
                eat_whitespace(p, os, parent_context, false);
                parent_context.check_layout(os);
                if (unstarred_name == "sidewaysfigure")
                        begin_inset(os, "Float figure\n");
-               else
+               else if (unstarred_name == "sidewaystable")
                        begin_inset(os, "Float table\n");
+               else if (unstarred_name == "sidewaysalgorithm")
+                       begin_inset(os, "Float algorithm\n");
+               if (!opt.empty())
+                       os << "placement " << opt << '\n';
+               if (contains(opt, "H"))
+                       preamble.registerAutomaticallyLoadedPackage("float");
                os << "wide " << convert<string>(is_starred)
                   << "\nsideways true"
                   << "\nstatus open\n\n";
@@ -1436,7 +1618,7 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                                        parent_context, name, "shaded");
                else
                        parse_box(p, os, 0, FLAG_END, outer, parent_context,
-                                 "", "", name);
+                                 "", "", name, "", "");
                p.skip_spaces();
        }
 
@@ -1452,15 +1634,17 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                preamble.registerAutomaticallyLoadedPackage("verbatim");
        }
 
-       else if (name == "verbatim") {
+       else if (unstarred_name == "verbatim") {
                // FIXME: this should go in the generic code that
                // handles environments defined in layout file that
                // have "PassThru 1". However, the code over there is
                // already too complicated for my taste.
+               string const ascii_name =
+                       (name == "verbatim*") ? "Verbatim*" : "Verbatim";
                parent_context.new_paragraph(os);
                Context context(true, parent_context.textclass,
-                               &parent_context.textclass[from_ascii("Verbatim")]);
-               string s = p.verbatimEnvironment("verbatim");
+                               &parent_context.textclass[from_ascii(ascii_name)]);
+               string s = p.verbatimEnvironment(name);
                output_ert(os, s, context);
                p.skip_spaces();
        }
@@ -1577,8 +1761,8 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                        p.skip_spaces(true);
                        os << "btprint " << '"' << "btPrintAll" << '"' << "\n";
                }
-               os << "bibfiles " << '"' << bibfile << '"' << "\n";
-               os << "options " << '"' << bibstyle << '"' <<  "\n";
+               os << "bibfiles " << '"' << bibfile << "\"\n"
+                  << "options " << '"' << bibstyle << "\"\n";
                parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
                end_inset(os);
                p.skip_spaces();
@@ -1588,11 +1772,107 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                eat_whitespace(p, os, parent_context, false);
                parse_outer_box(p, os, FLAG_END, outer, parent_context, name, "");
                p.skip_spaces();
+               preamble.registerAutomaticallyLoadedPackage("framed");
+       }
+
+       else if (name == "listing") {
+               minted_float = "float";
+               eat_whitespace(p, os, parent_context, false);
+               string const opt = p.hasOpt() ? p.getArg('[', ']') : string();
+               if (!opt.empty())
+                       minted_float += "=" + opt;
+               // If something precedes \begin{minted}, we output it at the end
+               // as a caption, in order to keep it inside the listings inset.
+               eat_whitespace(p, os, parent_context, true);
+               p.pushPosition();
+               Token const & t = p.get_token();
+               p.skip_spaces(true);
+               string const envname = p.next_token().cat() == catBegin
+                                               ? p.getArg('{', '}') : string();
+               bool prologue = t.asInput() != "\\begin" || envname != "minted";
+               p.popPosition();
+               minted_float_has_caption = false;
+               string content = parse_text_snippet(p, FLAG_END, outer,
+                                                   parent_context);
+               size_t i = content.find("\\begin_inset listings");
+               bool minted_env = i != string::npos;
+               string caption;
+               if (prologue) {
+                       caption = content.substr(0, i);
+                       content.erase(0, i);
+               }
+               parent_context.check_layout(os);
+               if (minted_env && minted_float_has_caption) {
+                       eat_whitespace(p, os, parent_context, true);
+                       os << content << "\n";
+                       if (!caption.empty())
+                               os << caption << "\n";
+                       os << "\n\\end_layout\n"; // close inner layout
+                       end_inset(os);            // close caption inset
+                       os << "\n\\end_layout\n"; // close outer layout
+               } else if (!caption.empty()) {
+                       if (!minted_env) {
+                               begin_inset(os, "listings\n");
+                               os << "lstparams " << '"' << minted_float << '"' << '\n';
+                               os << "inline false\n";
+                               os << "status collapsed\n";
+                       }
+                       os << "\n\\begin_layout Plain Layout\n";
+                       begin_inset(os, "Caption Standard\n");
+                       Context newcontext(true, parent_context.textclass,
+                                          0, 0, parent_context.font);
+                       newcontext.check_layout(os);
+                       os << caption << "\n";
+                       newcontext.check_end_layout(os);
+                       end_inset(os);
+                       os << "\n\\end_layout\n";
+               } else if (content.empty()) {
+                       begin_inset(os, "listings\n");
+                       os << "lstparams " << '"' << minted_float << '"' << '\n';
+                       os << "inline false\n";
+                       os << "status collapsed\n";
+               } else {
+                       os << content << "\n";
+               }
+               end_inset(os); // close listings inset
+               parent_context.check_end_layout(os);
+               parent_context.new_paragraph(os);
+               p.skip_spaces();
+               minted_float.clear();
+               minted_float_has_caption = false;
        }
 
-       else if (name == "lstlisting") {
+       else if (name == "lstlisting" || name == "minted") {
+               bool use_minted = name == "minted";
                eat_whitespace(p, os, parent_context, false);
-               parse_listings(p, os, parent_context, false);
+               if (use_minted && minted_float.empty()) {
+                       // look ahead for a bottom caption
+                       p.pushPosition();
+                       bool found_end_minted = false;
+                       while (!found_end_minted && p.good()) {
+                               Token const & t = p.get_token();
+                               p.skip_spaces();
+                               string const envname =
+                                       p.next_token().cat() == catBegin
+                                               ? p.getArg('{', '}') : string();
+                               found_end_minted = t.asInput() == "\\end"
+                                                       && envname == "minted";
+                       }
+                       eat_whitespace(p, os, parent_context, true);
+                       Token const & t = p.get_token();
+                       p.skip_spaces(true);
+                       if (t.asInput() == "\\lyxmintcaption") {
+                               string const pos = p.getArg('[', ']');
+                               if (pos == "b") {
+                                       string const caption =
+                                               parse_text_snippet(p, FLAG_ITEM,
+                                                       false, parent_context);
+                                       minted_nonfloat_caption = "[b]" + caption;
+                               }
+                       }
+                       p.popPosition();
+               }
+               parse_listings(p, os, parent_context, false, use_minted);
                p.skip_spaces();
        }
 
@@ -1786,7 +2066,7 @@ void parse_comment(Parser & p, ostream & os, Token const & t, Context & context)
        LASSERT(t.cat() == catComment, return);
        if (!t.cs().empty()) {
                context.check_layout(os);
-               output_ert_inset(os, '%' + t.cs(), context);
+               output_comment(p, os, t.cs(), context);
                if (p.next_token().cat() == catNewline) {
                        // A newline after a comment line starts a new
                        // paragraph
@@ -1969,7 +2249,6 @@ void copy_file(FileName const & src, string dstname)
                dst = FileName(dstname);
        else
                dst = makeAbsPath(dstname, absParent);
-       string const absMaster = getMasterFilePath(false);
        FileName const srcpath = src.onlyPath();
        FileName const dstpath = dst.onlyPath();
        if (equivalent(srcpath, dstpath))
@@ -2387,10 +2666,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                }
 
                else if (p.isParagraph()) {
-                       if (context.new_layout_allowed)
-                               context.new_paragraph(os);
-                       else
-                               output_ert_inset(os, "\\par ", context);
+                       // In minted floating listings we will collect
+                       // everything into the caption, where multiple
+                       // paragraphs are forbidden.
+                       if (minted_float.empty()) {
+                               if (context.new_layout_allowed)
+                                       context.new_paragraph(os);
+                               else
+                                       output_ert_inset(os, "\\par ", context);
+                       } else
+                               os << ' ';
                        eat_whitespace(p, os, context, true);
                }
 
@@ -2655,7 +2940,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        } else {
                                begin_command_inset(os, "bibitem", "bibitem");
                                os << "label \"" << label << "\"\n"
-                                     "key \"" << key << "\"\n";
+                                  << "key \"" << key << "\"\n"
+                                  << "literal \"true\"\n";
                                end_inset(os);
                        }
                }
@@ -2733,8 +3019,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        context.check_layout(os);
                        // FIXME: This is a hack to prevent paragraph
                        // deletion if it is empty. Handle this better!
-                       output_ert_inset(os,
-                               "%dummy comment inserted by tex2lyx to "
+                       output_comment(p, os,
+                               "dummy comment inserted by tex2lyx to "
                                "ensure that this paragraph is not empty",
                                context);
                        // Both measures above may generate an additional
@@ -2808,7 +3094,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // the syntax is \subfloat[list entry][sub caption]{content}
                        // if it is a table of figure depends on the surrounding float
                        // FIXME: second optional argument is not parsed
-                       bool has_caption = false;
                        p.skip_spaces();
                        // do nothing if there is no outer float
                        if (!float_type.empty()) {
@@ -2820,6 +3105,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                   << "\nstatus collapsed\n\n";
                                // test for caption
                                string caption;
+                               bool has_caption = false;
                                if (p.next_token().cat() != catEscape &&
                                                p.next_token().character() == '[') {
                                                        p.get_token(); // eat '['
@@ -3048,9 +3334,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        end_inset(os);
                }
 
-               else if (t.cs() == "lstinline") {
+               else if (t.cs() == "lstinline" || t.cs() == "mintinline") {
+                       bool const use_minted = t.cs() == "mintinline";
                        p.skip_spaces();
-                       parse_listings(p, os, context, true);
+                       parse_listings(p, os, context, true, use_minted);
                }
 
                else if (t.cs() == "ensuremath") {
@@ -3073,13 +3360,22 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                output_ert_inset(os, t.asInput(), context);
                }
 
-               else if (t.cs() == "tableofcontents" || t.cs() == "lstlistoflistings") {
+               else if (t.cs() == "tableofcontents"
+                               || t.cs() == "lstlistoflistings"
+                               || t.cs() == "listoflistings") {
+                       string name = t.cs();
+                       if (preamble.minted() && name == "listoflistings")
+                               name.insert(0, "lst");
                        context.check_layout(os);
-                       begin_command_inset(os, "toc", t.cs());
+                       begin_command_inset(os, "toc", name);
                        end_inset(os);
                        skip_spaces_braces(p);
-                       if (t.cs() == "lstlistoflistings")
-                               preamble.registerAutomaticallyLoadedPackage("listings");
+                       if (name == "lstlistoflistings") {
+                               if (preamble.minted())
+                                       preamble.registerAutomaticallyLoadedPackage("minted");
+                               else
+                                       preamble.registerAutomaticallyLoadedPackage("listings");
+                       }
                }
 
                else if (t.cs() == "listoffigures" || t.cs() == "listoftables") {
@@ -3139,7 +3435,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                else if (t.cs() == "textcolor") {
                        // scheme is \textcolor{color name}{text}
                        string const color = p.verbatim_item();
-                       // we only support the predefined colors of the color package
+                       // we support the predefined colors of the color  and the xcolor package
                        if (color == "black" || color == "blue" || color == "cyan"
                                || color == "green" || color == "magenta" || color == "red"
                                || color == "white" || color == "yellow") {
@@ -3149,6 +3445,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                        context.check_layout(os);
                                        os << "\n\\color inherit\n";
                                        preamble.registerAutomaticallyLoadedPackage("color");
+                       } else if (color == "brown" || color == "darkgray" || color == "gray"
+                               || color == "lightgray" || color == "lime" || color == "olive"
+                               || color == "orange" || color == "pink" || color == "purple"
+                               || color == "teal" || color == "violet") {
+                                       context.check_layout(os);
+                                       os << "\n\\color " << color << "\n";
+                                       parse_text_snippet(p, os, FLAG_ITEM, outer, context);
+                                       context.check_layout(os);
+                                       os << "\n\\color inherit\n";
+                                       preamble.registerAutomaticallyLoadedPackage("xcolor");
                        } else
                                // for custom defined colors
                                output_ert_inset(os, t.asInput() + "{" + color + "}", context);
@@ -3178,14 +3484,15 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        preamble.registerAutomaticallyLoadedPackage("ulem");
                }
 
-               else if (t.cs() == "uuline" || t.cs() == "uwave" ||
-                        t.cs() == "emph" || t.cs() == "noun") {
+               else if (t.cs() == "uuline" || t.cs() == "uwave"
+                       || t.cs() == "emph" || t.cs() == "noun"
+                       || t.cs() == "xout") {
                        context.check_layout(os);
                        os << "\n\\" << t.cs() << " on\n";
                        parse_text_snippet(p, os, FLAG_ITEM, outer, context);
                        context.check_layout(os);
                        os << "\n\\" << t.cs() << " default\n";
-                       if (t.cs() == "uuline" || t.cs() == "uwave")
+                       if (t.cs() == "uuline" || t.cs() == "uwave" || t.cs() == "xout")
                                preamble.registerAutomaticallyLoadedPackage("ulem");
                }
 
@@ -3324,6 +3631,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        os << "target \"" << target << "\"\n";
                        if (type == "mailto:" || type == "file:")
                                os << "type \"" << type << "\"\n";
+                       os << "literal \"true\"\n";
                        end_inset(os);
                        skip_spaces_braces(p);
                }
@@ -3381,6 +3689,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                           << ":";
                        os << convert_command_inset_arg(p.verbatim_item())
                           << "\"\n";
+                       os << "plural \"false\"\n";
+                       os << "caps \"false\"\n";
+                       os << "noprefix \"false\"\n";
                        end_inset(os);
                        preamble.registerAutomaticallyLoadedPackage("refstyle");
                }
@@ -3397,6 +3708,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                os << "reference \""
                                   << convert_command_inset_arg(p.verbatim_item())
                                   << "\"\n";
+                               os << "plural \"false\"\n";
+                               os << "caps \"false\"\n";
+                               os << "noprefix \"false\"\n";
                                end_inset(os);
                                if (t.cs() == "vref" || t.cs() == "vpageref")
                                        preamble.registerAutomaticallyLoadedPackage("varioref");
@@ -3464,7 +3778,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        os << "before " << '"' << before << '"' << "\n";
                        os << "key \""
                           << convert_command_inset_arg(p.verbatim_item())
-                          << "\"\n";
+                          << "\"\n"
+                          << "literal \"true\"\n";
                        end_inset(os);
                        // Need to set the cite engine if natbib is loaded by
                        // the document class directly
@@ -3516,9 +3831,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                before.erase(before.length() - 1, 1);
                        }
                        begin_command_inset(os, "citation", command);
-                       os << "after " << '"' << after << '"' << "\n";
-                       os << "before " << '"' << before << '"' << "\n";
-                       os << "key " << '"' << citation << '"' << "\n";
+                       os << "after " << '"' << after << "\"\n"
+                          << "before " << '"' << before << "\"\n"
+                          << "key " << '"' << citation << "\"\n"
+                          << "literal \"true\"\n";
                        end_inset(os);
                        // Need to set the cite engine if jurabib is loaded by
                        // the document class directly
@@ -3535,8 +3851,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // the BibTeX inset
                        if (key != "*") {
                                begin_command_inset(os, "citation", t.cs());
-                               os << "after " << '"' << after << '"' << "\n";
-                               os << "key " << '"' << key << '"' << "\n";
+                               os << "after " << '"' << after << "\"\n"
+                                  << "key " << '"' << key << "\"\n"
+                                  << "literal \"true\"\n";
                                end_inset(os);
                        } else if (t.cs() == "nocite")
                                btprint = key;
@@ -3566,7 +3883,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                           << convert_command_inset_arg(p.verbatim_item());
                        os << "\"\ndescription \""
                           << convert_command_inset_arg(p.verbatim_item())
-                          << "\"\n";
+                          << "\"\n"
+                          << "literal \"true\"\n";
                        end_inset(os);
                        preamble.registerAutomaticallyLoadedPackage("nomencl");
                }
@@ -3580,6 +3898,20 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        end_inset(os);
                }
 
+               else if (t.cs() == "lyxmintcaption") {
+                       string const pos = p.getArg('[', ']');
+                       if (pos == "t") {
+                               string const caption =
+                                       parse_text_snippet(p, FLAG_ITEM, false,
+                                                          context);
+                               minted_nonfloat_caption = "[t]" + caption;
+                       } else {
+                               // We already got the caption at the bottom,
+                               // so simply skip it.
+                               parse_text_snippet(p, FLAG_ITEM, false, context);
+                       }
+               }
+
                else if (t.cs() == "printindex" || t.cs() == "printsubindex") {
                        context.check_layout(os);
                        string commandname = t.cs();
@@ -3596,6 +3928,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                        os << "type \"idx\"\n";
                                else
                                        os << "type \"" << indexname << "\"\n";
+                               os << "literal \"true\"\n";
                        }
                        end_inset(os);
                        skip_spaces_braces(p);
@@ -4125,7 +4458,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                                context, "parbox", "shaded");
                        } else
                                parse_box(p, os, 0, FLAG_ITEM, outer, context,
-                                         "", "", t.cs());
+                                         "", "", t.cs(), "", "");
                }
 
                else if (t.cs() == "fbox" || t.cs() == "mbox" ||
@@ -4133,6 +4466,52 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                         t.cs() == "shadowbox" || t.cs() == "doublebox")
                        parse_outer_box(p, os, FLAG_ITEM, outer, context, t.cs(), "");
 
+               else if (t.cs() == "fcolorbox" || t.cs() == "colorbox") {
+                       string backgroundcolor;
+                       preamble.registerAutomaticallyLoadedPackage("xcolor");
+                       if (t.cs() == "fcolorbox") {
+                               string const framecolor = p.getArg('{', '}');
+                               backgroundcolor = p.getArg('{', '}');
+                               parse_box(p, os, 0, 0, outer, context, "", "", "", framecolor, backgroundcolor);
+                       } else {
+                               backgroundcolor = p.getArg('{', '}');
+                               parse_box(p, os, 0, 0, outer, context, "", "", "", "", backgroundcolor);
+                       }
+               }
+
+               // FIXME: due to the compiler limit of "if" nestings
+               // the code for the alignment was put here
+               // put them in their own if if this is fixed
+               else if (t.cs() == "fboxrule" || t.cs() == "fboxsep"
+                            || t.cs() == "shadowsize"
+                                || t.cs() == "raggedleft" || t.cs() == "centering"
+                        || t.cs() == "raggedright") {
+                       if (t.cs() == "fboxrule")
+                               fboxrule = "";
+                       if (t.cs() == "fboxsep")
+                               fboxsep = "";
+                       if (t.cs() == "shadowsize")
+                               shadow_size = "";
+                       if (t.cs() != "raggedleft" && t.cs() != "centering"
+                        && t.cs() != "raggedright") {
+                               p.skip_spaces(true);
+                               while (p.good() && p.next_token().cat() != catSpace
+                                      && p.next_token().cat() != catNewline
+                                      && p.next_token().cat() != catEscape) {
+                                       if (t.cs() == "fboxrule")
+                                               fboxrule = fboxrule + p.get_token().asInput();
+                                       if (t.cs() == "fboxsep")
+                                               fboxsep = fboxsep + p.get_token().asInput();
+                                       if (t.cs() == "shadowsize")
+                                               shadow_size = shadow_size + p.get_token().asInput();
+                               }
+                       } else {
+                               output_ert_inset(os, t.asInput(), context);
+                       }
+               }
+
+               //\framebox() is part of the picture environment and different from \framebox{}
+               //\framebox{} will be parsed by parse_outer_box
                else if (t.cs() == "framebox") {
                        if (p.next_token().character() == '(') {
                                //the syntax is: \framebox(x,y)[position]{content}
@@ -4167,7 +4546,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        } else
                                //the syntax is: \makebox[width][position]{content}
                                parse_box(p, os, 0, FLAG_ITEM, outer, context,
-                                         "", "", t.cs());
+                                         "", "", t.cs(), "", "");
                }
 
                else if (t.cs() == "smallskip" ||
@@ -4343,7 +4722,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                                // therefore handle them separately
                                                if (unit == "\\paperwidth" || unit == "\\columnwidth"
                                                        || unit == "\\textwidth" || unit == "\\linewidth"
-                                                       || unit == "\\textheight" || unit == "\\paperheight")
+                                                       || unit == "\\textheight" || unit == "\\paperheight"
+                                                       || unit == "\\baselineskip")
                                                        known_unit = true;
                                                break;
                                                         }
@@ -4426,14 +4806,19 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        docstring const name = newinsetlayout->name();
                        bool const caption = name.find(from_ascii("Caption:")) == 0;
                        if (caption) {
-                               begin_inset(os, "Caption ");
-                               os << to_utf8(name.substr(8)) << '\n';
+                               // Already done for floating minted listings.
+                               if (minted_float.empty()) {
+                                       begin_inset(os, "Caption ");
+                                       os << to_utf8(name.substr(8)) << '\n';
+                               }
                        } else {
                                begin_inset(os, "Flex ");
                                os << to_utf8(name) << '\n'
                                   << "status collapsed\n";
                        }
-                       if (newinsetlayout->isPassThru()) {
+                       if (!minted_float.empty()) {
+                               parse_text_snippet(p, os, FLAG_ITEM, false, context);
+                       } else if (newinsetlayout->isPassThru()) {
                                // set catcodes to verbatim early, just in case.
                                p.setCatcodes(VERBATIM_CATCODES);
                                string delim = p.get_token().asInput();
@@ -4449,7 +4834,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                parse_text_in_inset(p, os, FLAG_ITEM, false, context, newinsetlayout);
                        if (caption)
                                p.skip_spaces();
-                       end_inset(os);
+                       // Minted caption insets are not closed here because
+                       // we collect everything into the caption.
+                       if (minted_float.empty())
+                               end_inset(os);
                }
 
                else if (t.cs() == "includepdf") {
@@ -4584,10 +4972,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        }
                        // handle some TIPA special characters
                        else if (preamble.isPackageUsed("tipa")) {
-                               if (name == "\\textglobfall") {
-                                       name = "End";
-                                       skip_braces(p);
-                               } else if (name == "\\s") {
+                               if (name == "\\s") {
                                        // fromLaTeXCommand() does not yet
                                        // recognize tipa short cuts
                                        name = "\\textsyllabic";
@@ -4596,7 +4981,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                        // fromLaTeXCommand() does not yet
                                        // recognize tipa short cuts
                                        p.get_token();
-                                       name = "\\b";
+                                       name = "\\textsubbar";
                                } else if (name == "\\textdoublevertline") {
                                        // FIXME: This is not correct,
                                        // \textvertline is higher than \textbardbl
@@ -4663,8 +5048,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        bool termination;
                        docstring rem;
                        set<string> req;
-                       docstring s = encodings.fromLaTeXCommand(from_utf8(name),
-                                       Encodings::TEXT_CMD, termination, rem, &req);
+                       docstring s = normalize_c(encodings.fromLaTeXCommand(from_utf8(name),
+                                       Encodings::TEXT_CMD, termination, rem, &req));
                        if (!s.empty()) {
                                context.check_layout(os);
                                os << to_utf8(s);