]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/text.cpp
Fix bug #7895: Do not output lines with only a single space.
[lyx.git] / src / tex2lyx / text.cpp
index f9b14c6821e68bf912e1ce23a0fdc7813151ea13..bf3ea8c2bd4c0e032473cca8ff84d4a42ba62833 100644 (file)
@@ -674,10 +674,14 @@ void parse_arguments(string const & command,
        for (size_t i = 0; i < no_arguments; ++i) {
                switch (template_arguments[i]) {
                case required:
+               case req_group:
                        // This argument contains regular LaTeX
                        handle_ert(os, ert + '{', context);
                        eat_whitespace(p, os, context, false);
-                       parse_text(p, os, FLAG_ITEM, outer, context);
+                       if (template_arguments[i] == required)
+                               parse_text(p, os, FLAG_ITEM, outer, context);
+                       else
+                               parse_text_snippet(p, os, FLAG_ITEM, outer, context);
                        ert = "}";
                        break;
                case item:
@@ -689,11 +693,13 @@ void parse_arguments(string const & command,
                        else
                                ert += p.verbatim_item();
                        break;
+               case displaymath:
                case verbatim:
                        // This argument may contain special characters
                        ert += '{' + p.verbatim_item() + '}';
                        break;
                case optional:
+               case opt_group:
                        // true because we must not eat whitespace
                        // if an optional arg follows we must not strip the
                        // brackets from this one
@@ -741,16 +747,29 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
        string height_unit = "in";
        string height_special = "totalheight";
        string latex_height;
+       string width_value;
+       string width_unit;
+       string latex_width;
+       string width_special = "none";
        if (!inner_type.empty() && p.hasOpt()) {
-               position = p.getArg('[', ']');
+               if (inner_type != "makebox")
+                       position = p.getArg('[', ']');
+               else {
+                       latex_width = p.getArg('[', ']');
+                       translate_box_len(latex_width, width_value, width_unit, width_special);
+                       position = "t";
+               }
                if (position != "t" && position != "c" && position != "b") {
                        cerr << "invalid position " << position << " for "
                             << inner_type << endl;
                        position = "c";
                }
                if (p.hasOpt()) {
-                       latex_height = p.getArg('[', ']');
-                       translate_box_len(latex_height, height_value, height_unit, height_special);
+                       if (inner_type != "makebox") {
+                               latex_height = p.getArg('[', ']');
+                               translate_box_len(latex_height, height_value, height_unit, height_special);
+                       } else
+                               hor_pos = p.getArg('[', ']');
 
                        if (p.hasOpt()) {
                                inner_pos = p.getArg('[', ']');
@@ -764,12 +783,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                        }
                }
        }
-       string width_value;
-       string width_unit;
-       string latex_width;
        if (inner_type.empty()) {
-               if (special.empty())
-                       latex_width = "\\columnwidth";
+               if (special.empty() && outer_type != "framebox")
+                       latex_width = "1\\columnwidth";
                else {
                        Parser p2(special);
                        latex_width = p2.getArg('[', ']');
@@ -784,9 +800,17 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                                }
                        }
                }
-       } else
+       } else if (inner_type != "makebox")
                latex_width = p.verbatim_item();
+       // if e.g. only \ovalbox{content} was used, set the width to 1\columnwidth
+       // as this is LyX's standard for such cases (except for makebox)
+       // \framebox is more special and handled below
+       if (latex_width.empty() && inner_type != "makebox"
+               && outer_type != "framebox")
+               latex_width = "1\\columnwidth";
+
        translate_len(latex_width, width_value, width_unit);
+
        bool shadedparbox = false;
        if (inner_type == "shaded") {
                eat_whitespace(p, os, parent_context, false);
@@ -825,6 +849,16 @@ 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") {
+               use_ert = true;
+       }
        if (use_ert) {
                ostringstream ss;
                if (!outer_type.empty()) {
@@ -869,10 +903,20 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                        // the inner env
                        if (!inner_type.empty() && (inner_flags & FLAG_END))
                                active_environments.pop_back();
+       
+                       // Ensure that the end of the outer box is parsed correctly:
+                       // The opening brace has been eaten by parse_outer_box()
+                       if (!outer_type.empty() && (outer_flags & FLAG_ITEM)) {
+                               outer_flags &= ~FLAG_ITEM;
+                               outer_flags |= FLAG_BRACE_LAST;
+                       }
                        parse_text(p, os, outer_flags, outer, parent_context);
                        if (outer_flags & FLAG_END)
                                handle_ert(os, "\\end{" + outer_type + '}',
                                           parent_context);
+                       else if (inner_type.empty() && outer_type == "framebox")
+                               // in this case it is already closed later
+                               ;
                        else
                                handle_ert(os, "}", parent_context);
                }
@@ -883,8 +927,6 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                        position = "c";
                if (inner_pos.empty())
                        inner_pos = position;
-               // FIXME: Support makebox
-               bool const use_makebox = false;
                parent_context.check_layout(os);
                begin_inset(os, "Box ");
                if (outer_type == "framed")
@@ -909,10 +951,10 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                os << "has_inner_box " << !inner_type.empty() << "\n";
                os << "inner_pos \"" << inner_pos << "\"\n";
                os << "use_parbox " << (inner_type == "parbox" || shadedparbox)
-                       << '\n';
-               os << "use_makebox " << use_makebox << '\n';
+                  << '\n';
+               os << "use_makebox " << (inner_type == "makebox") << '\n';
                os << "width \"" << width_value << width_unit << "\"\n";
-               os << "special \"none\"\n";
+               os << "special \"" << width_special << "\"\n";
                os << "height \"" << height_value << height_unit << "\"\n";
                os << "height_special \"" << height_special << "\"\n";
                os << "status open\n\n";
@@ -921,9 +963,8 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags,
                // InsetBox::forcePlainLayout() is hard coded and does not
                // use the inset layout. Apart from that do we call parse_text
                // up to two times, but need only one check_end_layout.
-
                bool const forcePlainLayout =
-                       (!inner_type.empty() || use_makebox) &&
+                       (!inner_type.empty() || inner_type == "makebox") &&
                        outer_type != "shaded" && outer_type != "framed";
                Context context(true, parent_context.textclass);
                if (forcePlainLayout)
@@ -1122,18 +1163,31 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                parse_math(p, os, FLAG_END, MATH_MODE);
                os << "\\end{" << name << "}";
                end_inset(os);
+               if (is_display_math_env(name)) {
+                       // Prevent the conversion of a line break to a space
+                       // (bug 7668). This does not change the output, but
+                       // looks ugly in LyX.
+                       eat_whitespace(p, os, parent_context, false);
+               }
        }
 
-       else if (name == "tabular" || name == "longtable") {
+       else if (unstarred_name == "tabular" || name == "longtable") {
                eat_whitespace(p, os, parent_context, false);
+               string width = "0pt";
+               if (name == "tabular*") {
+                       width = lyx::translate_len(p.getArg('{', '}'));
+                       eat_whitespace(p, os, parent_context, false);
+               }
                parent_context.check_layout(os);
                begin_inset(os, "Tabular ");
-               handle_tabular(p, os, name == "longtable", parent_context);
+               handle_tabular(p, os, name, width, parent_context);
                end_inset(os);
                p.skip_spaces();
        }
 
        else if (parent_context.textclass.floats().typeExist(unstarred_name)) {
+               eat_whitespace(p, os, parent_context, false);
+               string const opt = p.hasOpt() ? p.getArg('[', ']') : string();
                eat_whitespace(p, os, parent_context, false);
                parent_context.check_layout(os);
                begin_inset(os, "Float " + unstarred_name + "\n");
@@ -1145,8 +1199,8 @@ void parse_environment(Parser & p, ostream & os, bool outer,
                        float_type = unstarred_name;
                else
                        float_type = "";
-               if (p.hasOpt())
-                       os << "placement " << p.getArg('[', ']') << '\n';
+               if (!opt.empty())
+                       os << "placement " << opt << '\n';
                os << "wide " << convert<string>(is_starred)
                   << "\nsideways false"
                   << "\nstatus open\n\n";
@@ -1860,7 +1914,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        context.check_layout(os);
                        begin_inset(os, "Formula ");
                        Token const & n = p.get_token();
-                       if (n.cat() == catMath && outer) {
+                       bool const display(n.cat() == catMath && outer);
+                       if (display) {
                                // TeX's $$...$$ syntax for displayed math
                                os << "\\[";
                                parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
@@ -1874,6 +1929,12 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                os << '$';
                        }
                        end_inset(os);
+                       if (display) {
+                               // Prevent the conversion of a line break to a
+                               // space (bug 7668). This does not change the
+                               // output, but looks ugly in LyX.
+                               eat_whitespace(p, os, context, false);
+                       }
                }
 
                else if (t.cat() == catSuper || t.cat() == catSub)
@@ -2120,6 +2181,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        parse_math(p, os, FLAG_EQUATION, MATH_MODE);
                        os << "\\]";
                        end_inset(os);
+                       // Prevent the conversion of a line break to a space
+                       // (bug 7668). This does not change the output, but
+                       // looks ugly in LyX.
+                       eat_whitespace(p, os, context, false);
                }
 
                else if (t.cs() == "begin")
@@ -2139,16 +2204,15 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                }
 
                else if (t.cs() == "item") {
-                       p.skip_spaces();
                        string s;
-                       bool optarg = false;
-                       if (p.next_token().cat() != catEscape &&
-                           p.next_token().character() == '[') {
-                               p.get_token(); // eat '['
-                               s = parse_text_snippet(p, FLAG_BRACK_LAST,
-                                                      outer, context);
-                               optarg = true;
-                       }
+                       bool const optarg = p.hasOpt();
+                       if (optarg) {
+                               // FIXME: This swallows comments, but we cannot use
+                               //        eat_whitespace() since we must not output
+                               //        anything before the item.
+                               s = p.getArg('[', ']');
+                       } else
+                               p.skip_spaces(false);
                        context.set_item();
                        context.check_layout(os);
                        if (context.has_item) {
@@ -2164,13 +2228,30 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                if (context.layout->labeltype != LABEL_MANUAL) {
                                        // LyX does not support \item[\mybullet]
                                        // in itemize environments
-                                       handle_ert(os, "[", context);
-                                       os << s;
-                                       handle_ert(os, "]", context);
+                                       Parser p2(s + ']');
+                                       os << parse_text_snippet(p2,
+                                               FLAG_BRACK_LAST, outer, context);
                                } else if (!s.empty()) {
+                                       // LyX adds braces around the argument,
+                                       // so we need to remove them here.
+                                       if (s.size() > 2 && s[0] == '{' &&
+                                           s[s.size()-1] == '}')
+                                               s = s.substr(1, s.size()-2);
+                                       // If the argument contains a space we
+                                       // must put it into ERT: Otherwise LyX
+                                       // would misinterpret the space as
+                                       // item delimiter (bug 7663)
+                                       if (contains(s, ' ')) {
+                                               handle_ert(os, s, context);
+                                       } else {
+                                               Parser p2(s + ']');
+                                               os << parse_text_snippet(p2,
+                                                       FLAG_BRACK_LAST,
+                                                       outer, context);
+                                       }
                                        // The space is needed to separate the
                                        // item from the rest of the sentence.
-                                       os << s << ' ';
+                                       os << ' ';
                                        eat_whitespace(p, os, context, false);
                                }
                        }
@@ -3525,16 +3606,22 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                }
 
                //\makebox() is part of the picture environment and different from \makebox{}
-               //\makebox{} will be parsed by parse_box when bug 2956 is fixed
+               //\makebox{} will be parsed by parse_box
                else if (t.cs() == "makebox") {
                        string arg = t.asInput();
-                       if (p.next_token().character() == '(')
+                       if (p.next_token().character() == '(') {
                                //the syntax is: \makebox(x,y)[position]{content}
                                arg += p.getFullParentheseArg();
-                       else
-                               //the syntax is: \makebox[width][position]{content}
                                arg += p.getFullOpt();
-                       handle_ert(os, arg + p.getFullOpt(), context);
+                               eat_whitespace(p, os, context, false);
+                               handle_ert(os, arg + '{', context);
+                               eat_whitespace(p, os, context, false);
+                               parse_text(p, os, FLAG_ITEM, outer, context);
+                               handle_ert(os, "}", context);
+                       } else
+                               //the syntax is: \makebox[width][position]{content}
+                               parse_box(p, os, 0, FLAG_ITEM, outer, context,
+                                         "", "", t.cs());
                }
 
                else if (t.cs() == "smallskip" ||