]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/text.cpp
Fix #10778 (issue with CJK and language nesting)
[lyx.git] / src / tex2lyx / text.cpp
index 1178f3a01b27c686da06382aacf5df1714345d39..ce330a2b9ffe97a21a1c0da1ac0093632469fdd6 100644 (file)
@@ -136,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 };
 
 
 /**
@@ -313,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};
@@ -521,8 +521,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)
@@ -580,6 +580,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);
@@ -852,29 +862,29 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
        string latex_width;
        string width_special = "none";
        string thickness = "0.4pt";
-       if (fboxrule != "")
+       if (!fboxrule.empty())
                thickness = fboxrule;
        else
                thickness = "0.4pt";
        string separation;
-       if (fboxsep != "")
+       if (!fboxsep.empty())
                separation = fboxsep;
        else
                separation = "3pt";
        string shadowsize;
-       if (shadow_size != "")
+       if (!shadow_size.empty())
                shadowsize = shadow_size;
        else
                shadowsize = "4pt";
        string framecolor = "black";
        string backgroundcolor = "none";
-       if (frame_color != "")
+       if (!frame_color.empty())
                framecolor = frame_color;
-       if (background_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 != "" || background_color != "") {
+       if (!frame_color.empty() || !background_color.empty()) {
                eat_whitespace(p, os, parent_context, false);
                p.get_token().asInput(); // the '{'
                // parse minipage
@@ -883,6 +893,7 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                        p.getArg('{', '}');
                        inner_type = "minipage";
                        inner_flags = FLAG_END;
+                       active_environments.push_back("minipage");
                }
                // parse parbox
                else if (p.next_token().asInput() == "\\parbox") {
@@ -905,6 +916,8 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                        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('[', ']');
@@ -946,9 +959,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                                }
                        }
                } else {
-                               if (inner_type == "makebox")
-                                       hor_pos = "c";
-                       }
+                       if (inner_type == "makebox")
+                               hor_pos = "c";
+               }
        }
        if (inner_type.empty()) {
                if (special.empty() && outer_type != "framebox")
@@ -1018,18 +1031,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" && background_color == "") {
-               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()) {
@@ -1099,7 +1101,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";
@@ -1118,6 +1120,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";
@@ -1125,9 +1129,11 @@ 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, '\\'))
@@ -1193,13 +1199,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
@@ -1210,21 +1216,26 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                }
 #endif
        }
-       if (background_color != "") {
+       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() == "}"
-           && (fboxrule != "" || fboxsep != "" || shadow_size != "")) {
+       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
-               if (fboxrule != "")
-                       fboxrule = "";
-               if (fboxsep != "")
-                       fboxsep = "";
-               if (shadow_size != "")
-                       shadow_size = "";
+               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");
 }
 
 
@@ -1260,8 +1271,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") {
@@ -1545,15 +1555,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();
        }
@@ -1681,6 +1693,7 @@ 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 == "lstlisting") {
@@ -1879,7 +1892,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
@@ -2062,7 +2075,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))
@@ -2826,8 +2838,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
@@ -2901,7 +2913,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()) {
@@ -2913,6 +2924,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 '['
@@ -4236,30 +4248,48 @@ 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() == "colorbox") {
-                       string const backgroundcolor = p.getArg('{', '}');
-                       parse_box(p, os, 0, 0, outer, context, "", "", "", "", backgroundcolor);
+               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") {
-                       p.skip_spaces(true);
+                            || 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 = "";
-                       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();
+                       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{}
@@ -4727,7 +4757,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
@@ -4794,8 +4824,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);