]> git.lyx.org Git - features.git/commitdiff
Translate all known box insets. This is needed since the super-clever preamble
authorGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Fri, 21 Jan 2011 18:29:10 +0000 (18:29 +0000)
committerGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Fri, 21 Jan 2011 18:29:10 +0000 (18:29 +0000)
parser discards all needed packages like calc.sty or framed.sty, so the
resulting document would be uncompilable with those boxes as ERT.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37287 a592a061-630c-0410-9148-cb99ea01b6c8

src/tex2lyx/Parser.cpp
src/tex2lyx/TODO.txt
src/tex2lyx/test/box-color-size-space-align.tex
src/tex2lyx/text.cpp

index 4cdb9a0d8d06ffcc75ab2e6e05295817960a8331..d2998bf9e2a74b24bfa9368d729e19a4fb5ebbfa 100644 (file)
@@ -266,9 +266,13 @@ bool Parser::skip_spaces(bool skip_comments)
                }
                if ((curr_token().cat() == catComment && curr_token().cs().empty()))
                        continue;
-               if (skip_comments && curr_token().cat() == catComment)
-                       cerr << "  Ignoring comment: " << curr_token().asInput();
-               else {
+               if (skip_comments && curr_token().cat() == catComment) {
+                       // If positions_ is not empty we are doing some kind
+                       // of look ahead
+                       if (!positions_.empty())
+                               cerr << "  Ignoring comment: "
+                                    << curr_token().asInput();
+               } else {
                        putback();
                        break;
                }
@@ -285,7 +289,11 @@ void Parser::unskip_spaces(bool skip_comments)
                        putback();
                else if (skip_comments && curr_token().cat() == catComment) {
                        // TODO: Get rid of this
-                       cerr << "Unignoring comment: " << curr_token().asInput();
+                       // If positions_ is not empty we are doing some kind
+                       // of look ahead
+                       if (!positions_.empty())
+                               cerr << "Unignoring comment: "
+                                    << curr_token().asInput();
                        putback();
                }
                else
index b38c1734429019521511dfcb9f3298a98083c3ce..97586f361a94d3529c11ed63906d11ef0fdb7192 100644 (file)
@@ -15,13 +15,10 @@ Format LaTeX feature                        LyX feature
        lib/external_templates. This is
        quite difficult to recognize.
 226    nothing (impossible to import)       InsetBranch, \branch...\end_branch
-226    ?                                    InsetBox (Boxed/ovalbox/Ovalbox/
-                                                      Shadowbox/Doublebox)
 226    transformations                      InsetExternal
 228    draft                                InsetExternal
 231    sidewaysfigure/sidewaystable         InsetFloat
 232    bibtopic                             InsetBibTeX
-246    framed.sty                           InsetBox
 247    utopia.sty, ccfonts.sty,             font settings (header)
        chancery.sty, beraserif.sty
 248    booktabs.sty                         InsetTabular
index 019b2461c6442984d97a3e61558f8e0655c32b6d..6c529326b9574cf481e59d36fd753da664fe43d0 100644 (file)
@@ -13,6 +13,8 @@
 \definecolor{note_fontcolor}{rgb}{0, 0, 1}
 \definecolor{shadecolor}{rgb}{1, 0, 0}
 \usepackage{framed}
+\usepackage{calc}
+\usepackage{fancybox}
 
 \setlength{\parskip}{3mm}
 \setlength{\parindent}{0sp}
@@ -86,6 +88,10 @@ blabla \makebox[3cm][l]{makebox 3} blabla
 
 \subsection{Framed Boxes}
 
+blabla \begin{framed}framed\end{framed} blabla
+
+blabla \begin{framed}\begin{framed}nested framed\end{framed}\end{framed} blabla
+
 blabla \fbox{fbox} blabla
 
 blabla \framebox{framebox 1} blabla
@@ -115,6 +121,14 @@ Dies ist ein Beispieltext. %
 \end{minipage}}
 Dies ist ein Beispieltext.
 
+blabla \ovalbox{ovalbox} blabla
+
+blabla \Ovalbox{Ovalbox} blabla
+
+blabla \shadowbox{shadowbox} blabla
+
+blabla \doublebox{doublebox} blabla
+
 $\boxed{\int A=B}$
 
 \subsection{LyX Boxes}
index 556b839cf6120ff850101eecc830613b92e20785..166d49992ca838246f1062f1bca3940b7563b0e0 100644 (file)
@@ -653,22 +653,26 @@ bool parse_command(string const & command, Parser & p, ostream & os,
 
 
 /// Parses a minipage or parbox
-void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
-              Context & parent_context, bool use_parbox)
+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 position;
        string inner_pos;
+       string hor_pos = "c";
        // 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";
        string height_unit = "in";
        string height_special = "totalheight";
        string latex_height;
-       if (p.hasOpt()) {
+       if (!inner_type.empty() && p.hasOpt()) {
                position = p.getArg('[', ']');
                if (position != "t" && position != "c" && position != "b") {
+                       cerr << "invalid position " << position << " for "
+                            << inner_type << endl;
                        position = "c";
-                       cerr << "invalid position for minipage/parbox" << endl;
                }
                if (p.hasOpt()) {
                        latex_height = p.getArg('[', ']');
@@ -678,40 +682,100 @@ void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
                                inner_pos = p.getArg('[', ']');
                                if (inner_pos != "c" && inner_pos != "t" &&
                                    inner_pos != "b" && inner_pos != "s") {
+                                       cerr << "invalid inner_pos "
+                                            << inner_pos << " for "
+                                            << inner_type << endl;
                                        inner_pos = position;
-                                       cerr << "invalid inner_pos for minipage/parbox"
-                                            << endl;
                                }
                        }
                }
        }
        string width_value;
        string width_unit;
-       string const latex_width = p.verbatim_item();
+       string latex_width;
+       if (inner_type.empty()) {
+               if (special.empty())
+                       latex_width = "\\columnwidth";
+               else {
+                       Parser p2(special);
+                       latex_width = p2.getOptContent();
+                       string const opt = p2.getOptContent();
+                       if (!opt.empty()) {
+                               hor_pos = opt;
+                               if (hor_pos != "l" && hor_pos != "c" &&
+                                   hor_pos != "r") {
+                                       cerr << "invalid hor_pos " << hor_pos
+                                            << " for " << outer_type << endl;
+                                       hor_pos = "c";
+                               }
+                       }
+               }
+       } else
+               latex_width = p.verbatim_item();
        translate_len(latex_width, width_value, width_unit);
-       if (contains(width_unit, '\\') || contains(height_unit, '\\')) {
-               // LyX can't handle length variables
-               ostringstream ss;
-               if (use_parbox)
-                       ss << "\\parbox";
+       // LyX can't handle length variables
+       bool use_ert = contains(width_unit, '\\') || contains(height_unit, '\\');
+       if (!use_ert && !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.
+               p.pushPosition();
+               if (inner_flags & FLAG_END)
+                       p.verbatimEnvironment(inner_type);
                else
-                       ss << "\\begin{minipage}";
-               if (!position.empty())
-                       ss << '[' << position << ']';
-               if (!latex_height.empty())
-                       ss << '[' << latex_height << ']';
-               if (!inner_pos.empty())
-                       ss << '[' << inner_pos << ']';
-               ss << "{" << latex_width << "}";
-               if (use_parbox)
-                       ss << '{';
+                       p.verbatim_item();
+               p.skip_spaces(true);
+               if ((outer_type == "framed" && p.next_token().asInput() != "\\end") ||
+                   (outer_type != "framed" && p.next_token().cat() != catEnd)) {
+                       // something is between the end of the inner box and
+                       // the end of the outer box, so we need to use ERT.
+                       use_ert = true;
+               }
+               p.popPosition();
+       }
+       if (use_ert) {
+               ostringstream ss;
+               if (!outer_type.empty()) {
+                       if (outer_flags & FLAG_END)
+                               ss << "\\begin{" << outer_type << '}';
+                       else {
+                               ss << '\\' << outer_type << '{';
+                               if (!special.empty())
+                                       ss << special;
+                       }
+               }
+               if (!inner_type.empty()) {
+                       if (inner_flags & FLAG_END)
+                               ss << "\\begin{" << inner_type << '}';
+                       else
+                               ss << '\\' << inner_type;
+                       if (!position.empty())
+                               ss << '[' << position << ']';
+                       if (!latex_height.empty())
+                               ss << '[' << latex_height << ']';
+                       if (!inner_pos.empty())
+                               ss << '[' << inner_pos << ']';
+                       ss << '{' << latex_width << '}';
+                       if (!(inner_flags & FLAG_END))
+                               ss << '{';
+               }
                handle_ert(os, ss.str(), parent_context);
-               parent_context.new_paragraph(os);
-               parse_text_in_inset(p, os, flags, outer, parent_context);
-               if (use_parbox)
-                       handle_ert(os, "}", parent_context);
-               else
-                       handle_ert(os, "\\end{minipage}", parent_context);
+               if (!inner_type.empty()) {
+                       parse_text(p, os, inner_flags, outer, parent_context);
+                       if (inner_flags & FLAG_END)
+                               handle_ert(os, "\\end{" + inner_type + '}',
+                                          parent_context);
+                       else
+                               handle_ert(os, "}", parent_context);
+               }
+               if (!outer_type.empty()) {
+                       parse_text(p, os, outer_flags, outer, parent_context);
+                       if (outer_flags & FLAG_END)
+                               handle_ert(os, "\\end{" + outer_type + '}',
+                                          parent_context);
+                       else
+                               handle_ert(os, "}", parent_context);
+               }
        } else {
                // LyX does not like empty positions, so we have
                // to set them to the LaTeX default values here.
@@ -720,18 +784,54 @@ void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
                if (inner_pos.empty())
                        inner_pos = position;
                parent_context.check_layout(os);
-               begin_inset(os, "Box Frameless\n");
+               begin_inset(os, "Box ");
+               if (outer_type == "framed")
+                       os << "Framed\n";
+               else if (outer_type == "framebox")
+                       os << "Boxed\n";
+               else if (outer_type == "shadowbox")
+                       os << "Shadowbox\n";
+               else if (outer_type == "shaded")
+                       os << "Shaded\n";
+               else if (outer_type == "doublebox")
+                       os << "Doublebox\n";
+               else if (outer_type.empty())
+                       os << "Frameless\n";
+               else
+                       os << outer_type << '\n';
                os << "position \"" << position << "\"\n";
-               os << "hor_pos \"c\"\n";
-               os << "has_inner_box 1\n";
+               os << "hor_pos \"" << hor_pos << "\"\n";
+               os << "has_inner_box " << !inner_type.empty() << "\n";
                os << "inner_pos \"" << inner_pos << "\"\n";
-               os << "use_parbox " << use_parbox << "\n";
+               os << "use_parbox " << (inner_type == "parbox") << '\n';
                os << "width \"" << width_value << width_unit << "\"\n";
                os << "special \"none\"\n";
                os << "height \"" << height_value << height_unit << "\"\n";
                os << "height_special \"" << height_special << "\"\n";
                os << "status open\n\n";
-               parse_text_in_inset(p, os, flags, outer, parent_context);
+               Context context(true, parent_context.textclass);
+               context.font = parent_context.font;
+
+               // If we have no inner box the contens will be read with the outer box
+               if (!inner_type.empty())
+                       parse_text(p, os, inner_flags, outer, context);
+
+               // 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;
+               }
+
+               // Find end of outer box, output contents if inner_type is
+               // empty and output possible comments
+               if (!outer_type.empty()) {
+                       // This does not output anything but comments if
+                       // inner_type is not empty (see use_ert)
+                       parse_text(p, os, outer_flags, outer, context);
+               }
+
+               context.check_end_layout(os);
                end_inset(os);
 #ifdef PRESERVE_LAYOUT
                // LyX puts a % after the end of the minipage
@@ -757,6 +857,54 @@ void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
 }
 
 
+void parse_outer_box(Parser & p, ostream & os, unsigned flags, bool outer,
+                     Context & parent_context, string const & outer_type,
+                     string const & special)
+{
+       eat_whitespace(p, os, parent_context, false);
+       if (flags & FLAG_ITEM) {
+               // Eat '{'
+               if (p.next_token().cat() == catBegin)
+                       p.get_token();
+               else
+                       cerr << "Warning: Ignoring missing '{' after \\"
+                            << outer_type << '.' << endl;
+               eat_whitespace(p, os, parent_context, false);
+       }
+       string inner;
+       unsigned int inner_flags = 0;
+       if (outer_type == "shaded") {
+               // These boxes never have an inner box
+               ;
+       } else if (p.next_token().asInput() == "\\parbox") {
+               inner = p.get_token().cs();
+               inner_flags = FLAG_ITEM;
+       } else if (p.next_token().asInput() == "\\begin") {
+               // Is this a minipage?
+               p.pushPosition();
+               p.get_token();
+               inner = p.getArg('{', '}');
+               p.popPosition();
+               if (inner == "minipage") {
+                       p.get_token();
+                       p.getArg('{', '}');
+                       eat_whitespace(p, os, parent_context, false);
+                       inner_flags = FLAG_END;
+               } else
+                       inner = "";
+       }
+       if (inner_flags == FLAG_END) {
+               active_environments.push_back(inner);
+               parse_box(p, os, flags, FLAG_END, outer, parent_context,
+                         outer_type, special, inner);
+               active_environments.pop_back();
+       } else {
+               parse_box(p, os, flags, inner_flags, outer, parent_context,
+                         outer_type, special, inner);
+       }
+}
+
+
 /// parse an unknown environment
 void parse_unknown_environment(Parser & p, string const & name, ostream & os,
                               unsigned flags, bool outer,
@@ -830,7 +978,7 @@ void parse_environment(Parser & p, ostream & os, bool outer,
 
        else if (name == "minipage") {
                eat_whitespace(p, os, parent_context, false);
-               parse_box(p, os, FLAG_END, outer, parent_context, false);
+               parse_box(p, os, 0, FLAG_END, outer, parent_context, "", "", name);
                p.skip_spaces();
        }
 
@@ -857,23 +1005,7 @@ void parse_environment(Parser & p, ostream & os, bool outer,
 
        else if (name == "framed" || name == "shaded") {
                eat_whitespace(p, os, parent_context, false);
-               parent_context.check_layout(os);
-               if (name == "framed")
-                       begin_inset(os, "Box Framed\n");
-               else
-                       begin_inset(os, "Box Shaded\n");
-               os << "position \"t\"\n"
-                     "hor_pos \"c\"\n"
-                     "has_inner_box 0\n"
-                     "inner_pos \"t\"\n"
-                     "use_parbox 0\n"
-                     "width \"100col%\"\n"
-                     "special \"none\"\n"
-                     "height \"1in\"\n"
-                     "height_special \"totalheight\"\n"
-                     "status open\n";
-               parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
-               end_inset(os);
+               parse_outer_box(p, os, FLAG_END, outer, parent_context, name, "");
                p.skip_spaces();
        }
 
@@ -2766,8 +2898,18 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                }
 
                else if (t.cs() == "parbox")
-                       parse_box(p, os, FLAG_ITEM, outer, context, true);
-               
+                       parse_box(p, os, 0, FLAG_ITEM, outer, context, "", "", t.cs());
+
+               else if (t.cs() == "ovalbox" || t.cs() == "Ovalbox" ||
+                        t.cs() == "shadowbox" || t.cs() == "doublebox")
+                       parse_outer_box(p, os, FLAG_ITEM, outer, context, t.cs(), "");
+
+               else if (t.cs() == "framebox") {
+                       string special = p.getOpt();
+                       special += p.getOpt();
+                       parse_outer_box(p, os, FLAG_ITEM, outer, context, t.cs(), special);
+               }
+
                //\makebox() is part of the picture environment and different from \makebox{}
                //\makebox{} will be parsed by parse_box when bug 2956 is fixed
                else if (t.cs() == "makebox") {