The attached patch makes tex2lyx output file format 227 with minipages and 
parboxes converted to frameless box insets. The conversion was 
starightforward, although I had to change the length functions again. We 
could simplify the code if LyX would use the LaTeX names for length 
variables and not "col%" etc.

Jürgen, tex2lyx produces a valid LyX file again with this patch, so I have 
nothing aginst removing minipages from LyX anymore ;-)


Georg
Index: src/tex2lyx/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/ChangeLog,v
retrieving revision 1.43
diff -u -p -r1.43 ChangeLog
--- src/tex2lyx/ChangeLog	2003/12/10 08:33:11	1.43
+++ src/tex2lyx/ChangeLog	2003/12/11 20:55:41
@@ -1,3 +1,9 @@
+2003-12-11  Georg Baum  <[EMAIL PROTECTED]>
+
+	* preamble.C: Change file format to 227
+	* text.C: Convert minipages and parboxes to box insets
+	* context.[Ch]: New function Context::add_extra_stuff()
+
 2003-12-08  Georg Baum  <[EMAIL PROTECTED]>
 
 	* text.C: Use the new VSpace inset (fixes a bug with added_space top)
Index: src/tex2lyx/context.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/context.C,v
retrieving revision 1.8
diff -u -p -r1.8 context.C
--- src/tex2lyx/context.C	2003/11/05 10:14:12	1.8
+++ src/tex2lyx/context.C	2003/12/11 20:55:41
@@ -12,6 +12,7 @@
 
 #include <iostream>
 
+#include "support/lstrings.h"
 #include "context.h"
 
 using std::ostream;
@@ -152,6 +162,13 @@ void Context::new_paragraph(ostream & os
 {
 	check_end_layout(os);
 	need_layout = true;
+}
+
+
+void Context::add_extra_stuff(std::string const & stuff)
+{
+	if (!lyx::support::contains(extra_stuff, stuff))
+		extra_stuff += stuff;
 }
 
 
Index: src/tex2lyx/preamble.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/preamble.C,v
retrieving revision 1.18
diff -u -p -r1.18 preamble.C
--- src/tex2lyx/preamble.C	2003/11/19 10:35:50	1.18
+++ src/tex2lyx/preamble.C	2003/12/11 20:55:43
@@ -143,7 +145,7 @@ void handle_package(string const & name,
 void end_preamble(ostream & os, LyXTextClass const & /*textclass*/)
 {
 	os << "#LyX file created by  tex2lyx 0.1.2 \n"
-	   << "\\lyxformat 225\n"
+	   << "\\lyxformat 227\n"
 	   << "\\textclass " << h_textclass << "\n"
 	   << "\\begin_preamble\n" << h_preamble.str() << "\n\\end_preamble\n";
 	if (!h_options.empty())
Index: src/tex2lyx/context.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/context.h,v
retrieving revision 1.8
diff -u -p -r1.8 context.h
--- src/tex2lyx/context.h	2003/11/05 10:14:12	1.8
+++ src/tex2lyx/context.h	2003/12/11 20:55:41
@@ -45,6 +52,9 @@ struct Context {
 
 	/// Start a new paragraph
 	void new_paragraph(std::ostream & os);
+
+	/// Add extra stuff if not already there
+	void add_extra_stuff(std::string const &);
 
 	// Do we need to output some \begin_layout command before the
 	// next characters?
Index: src/tex2lyx/text.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/text.C,v
retrieving revision 1.29
diff -u -p -r1.29 text.C
--- src/tex2lyx/text.C	2003/12/10 08:33:11	1.29
+++ src/tex2lyx/text.C	2003/12/11 20:55:52
@@ -38,6 +38,7 @@ using std::vector;
 
 using lyx::support::rtrim;
 using lyx::support::suffixIs;
+using lyx::support::contains;
 
 
 // thin wrapper around parse_text using a string
@@ -134,7 +135,7 @@ bool splitLatexLength(string const & len
 	if (value == "-")
 		value = "-1.0";
 	// 'cM' is a valid LaTeX length unit. Change it to 'cm'
-	if (lyx::support::contains(len, '\\'))
+	if (contains(len, '\\'))
 		unit = trim(string(len, i));
 	else
 		unit = lyx::support::lowercase(trim(string(len, i)));
@@ -144,13 +145,10 @@ bool splitLatexLength(string const & len
 
 // A simple function to translate a latex length to something lyx can
 // understand. Not perfect, but rather best-effort.
-string translate_len(string const & length)
+bool translate_len(string const & length, string & valstring, string & unit)
 {
-	string unit;
-	string valstring;
-	// If the input is invalid, return what we have.
 	if (!splitLatexLength(length, valstring, unit))
-		return length;
+		return false;
 	// LyX uses percent values
 	double value;
 	istringstream iss(valstring);
@@ -161,23 +159,64 @@ string translate_len(string const & leng
 	string const percentval = oss.str();
 	// a normal length
 	if (unit.empty() || unit[0] != '\\')
-		return valstring + unit;
+		return true;
 	const string::size_type i = unit.find(" ", i);
 	string const endlen = (i == string::npos) ? string() : string(unit, i);
-	if (unit == "\\textwidth")
-		return percentval + "text%" + endlen;
-	else if (unit == "\\columnwidth")
-		return percentval + "col%" + endlen;
-	else if (unit == "\\paperwidth")
-		return percentval + "page%" + endlen;
-	else if (unit == "\\linewidth")
-		return percentval + "line%" + endlen;
-	else if (unit == "\\paperheight")
-		return percentval + "pheight%" + endlen;
-	else if (unit == "\\textheight")
-		return percentval + "theight%" + endlen;
-	else
-		return valstring + unit;
+	if (unit == "\\textwidth") {
+		valstring = percentval;
+		unit = "text%" + endlen;
+	} else if (unit == "\\columnwidth") {
+		valstring = percentval;
+		unit = "col%" + endlen;
+	} else if (unit == "\\paperwidth") {
+		valstring = percentval;
+		unit = "page%" + endlen;
+	} else if (unit == "\\linewidth") {
+		valstring = percentval;
+		unit = "line%" + endlen;
+	} else if (unit == "\\paperheight") {
+		valstring = percentval;
+		unit = "pheight%" + endlen;
+	} else if (unit == "\\textheight") {
+		valstring = percentval;
+		unit = "theight%" + endlen;
+	}
+	return true;
+}
+
+
+string translate_len(string const & length)
+{
+	string unit;
+	string value;
+	if (translate_len(length, value, unit))
+		return value + unit;
+	// If the input is invalid, return what we have.
+	return length;
+}
+
+
+/*!
+ * Translates a LaTeX length into \param value, \param unit and \param special parts
+ * suitable for a box inset.
+ * The difference from translate_len() is that a box inset knows about some special
+ * "units" that are stored in \param special.
+ */
+void translate_box_len(string const & length, string & value, string & unit, string & special)
+{
+	if (translate_len(length, value, unit)) {
+		if (unit == "\\height" || unit == "\\depth" ||
+		    unit == "\\totalheight" || unit == "\\width") {
+			special = unit.substr(1);
+			// The unit is not used, but LyX requires a dummy setting
+			unit = "in";
+		} else
+			special = "none";
+	} else {
+		value.clear();
+		unit = length;
+		special = "none";
+	}
 }
 
 
@@ -367,6 +422,90 @@ bool parse_command(string const & comman
 }
 
 
+/// Parses a minipage or parbox
+void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
+               Context & parent_context, bool use_parbox)
+{
+	string position;
+	string inner_pos;
+	string height_value = "0";
+	string height_unit = "pt";
+	string height_special = "none";
+	string latex_height;
+	if (p.next_token().asInput() == "[") {
+		position = p.getArg('[', ']');
+		if (position != "t" && position != "c" && position != "b") {
+			position = "c";
+			cerr << "invalid position for minipage/parbox" << endl;
+		}
+		if (p.next_token().asInput() == "[") {
+			latex_height = p.getArg('[', ']');
+			translate_box_len(latex_height, height_value, height_unit, height_special);
+
+			if (p.next_token().asInput() == "[") {
+				inner_pos = p.getArg('[', ']');
+				if (inner_pos != "c" && inner_pos != "t" &&
+				    inner_pos != "b" && inner_pos != "s") {
+					inner_pos = position;
+					cerr << "invalid inner_pos for minipage/parbox"
+					     << endl;
+				}
+			}
+		}
+	}
+	string width_value;
+	string width_unit;
+	string width_special;
+	string const latex_width = p.verbatim_item();
+	translate_box_len(latex_width, width_value, width_unit, width_special);
+	if (contains(width_unit, "\\") || contains(height_unit, "\\")) {
+		// LyX can't handle length variables
+		ostringstream ss;
+		if (use_parbox)
+			ss << "\\parbox";
+		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 << '{';
+		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);
+	} else {
+		// LyX does not like empty positions, so we have
+		// to set them to the LaTeX default values here.
+		if (position.empty())
+			position = "c";
+		if (inner_pos.empty())
+			inner_pos = position;
+		parent_context.check_layout(os);
+		begin_inset(os, "Box Frameless\n");
+		os << "position \"" << position << "\"\n";
+		os << "hor_pos \"c\"\n";
+		os << "has_inner_box 1\n";
+		os << "inner_pos \"" << inner_pos << "\"\n";
+		os << "use_parbox " << use_parbox << "\n";
+		os << "width \"" << width_value << width_unit << "\"\n";
+		os << "special \"" << width_special << "\"\n";
+		os << "height \"" << height_value << height_unit << "\"\n";
+		os << "height_special \"" << height_special << "\"\n";
+		os << "collapsed false\n\n";
+		parse_text_in_inset(p, os, flags, outer, parent_context);
+		end_inset(os);
+	}
+}
+
+
 void parse_environment(Parser & p, ostream & os, bool outer,
 		       Context & parent_context)
 {
@@ -408,72 +568,9 @@ void parse_environment(Parser & p, ostre
 		parent_context.new_paragraph(os);
 	}
 
-	else if (name == "minipage") {
-		string position = "1";
-		string inner_pos = "0";
-		string height = "0pt";
-		string latex_position;
-		string latex_inner_pos;
-		string latex_height;
-		if (p.next_token().asInput() == "[") {
-			latex_position = p.getArg('[', ']');
-			switch(latex_position[0]) {
-			case 't': position = "0"; break;
-			case 'c': position = "1"; break;
-			case 'b': position = "2"; break;
-			default:
-				cerr << "invalid position for minipage"
-				     << endl;
-				break;
-			}
-			if (p.next_token().asInput() == "[") {
-				latex_height = p.getArg('[', ']');
-				height = translate_len(latex_height);
+	else if (name == "minipage")
+		parse_box(p, os, FLAG_END, outer, parent_context, false);
 
-				if (p.next_token().asInput() == "[") {
-					latex_inner_pos = p.getArg('[', ']');
-					switch(latex_inner_pos[0]) {
-					case 'c': inner_pos = "0"; break;
-					case 't': inner_pos = "1"; break;
-					case 'b': inner_pos = "2"; break;
-					case 's': inner_pos = "3"; break;
-					default:
-						cerr << "invalid inner_pos for minipage"
-						     << endl;
-						break;
-					}
-				}
-			}
-		}
-		string width = translate_len(p.verbatim_item());
-		if (width[0] == '\\') {
-			// lyx can't handle length variables
-			ostringstream ss;
-			ss << "\\begin{minipage}";
-			if (!latex_position.empty())
-				ss << '[' << latex_position << ']';
-			if (!latex_height.empty())
-				ss << '[' << latex_height << ']';
-			if (!latex_inner_pos.empty())
-				ss << '[' << latex_inner_pos << ']';
-			ss << "{" << width << "}";
-			handle_ert(os, ss.str(), parent_context);
-			parent_context.new_paragraph(os);
-			parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
-			handle_ert(os, "\\end{minipage}", parent_context);
-		} else {
-			parent_context.check_layout(os);
-			begin_inset(os, "Minipage\n");
-			os << "position " << position << '\n';
-			os << "inner_position " << inner_pos << '\n';
-			os << "height \"" << height << "\"\n";
-			os << "width \"" << width << "\"\n";
-			os << "collapsed false\n\n";
-			parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
-			end_inset(os);
-		}
-	}
-
 	// Alignment settings
 	else if (name == "center" || name == "flushleft" || name == "flushright" ||
 	         name == "centering" || name == "raggedright" || name == "raggedleft") {
@@ -483,11 +580,11 @@ void parse_environment(Parser & p, ostre
 			parent_context.new_paragraph(os);
 		}
 		if (name == "flushleft" || name == "raggedright")
-			parent_context.extra_stuff += "\\align left ";
+			parent_context.add_extra_stuff("\\align left ");
 		else if (name == "flushright" || name == "raggedleft")
-			parent_context.extra_stuff += "\\align right ";
+			parent_context.add_extra_stuff("\\align right ");
 		else
-			parent_context.extra_stuff += "\\align center ";
+			parent_context.add_extra_stuff("\\align center ");
 		parse_text(p, os, FLAG_END, outer, parent_context);
 		// Just in case the environment is empty ..
 		parent_context.extra_stuff.erase();
@@ -796,12 +916,12 @@ void parse_text(Parser & p, ostream & os
 
 		else if (t.cs() == "noindent") {
 			p.skip_spaces();
-			context.extra_stuff += "\\noindent ";
+			context.add_extra_stuff("\\noindent ");
 		}
 
 		else if (t.cs() == "appendix") {
 			p.skip_spaces();
-			context.extra_stuff += "\\start_of_appendix ";
+			context.add_extra_stuff("\\start_of_appendix ");
 		}
 
 		// Must attempt to parse "Section*" before "Section".
@@ -1269,6 +1389,9 @@ void parse_text(Parser & p, ostream & os
 			os << '{' << p.verbatim_item() << "}\n";
 			end_inset(os);
 		}
+
+		else if (t.cs() == "parbox")
+			parse_box(p, os, FLAG_ITEM, outer, context, true);
 
 		else if (t.cs() == "smallskip" ||
 		         t.cs() == "medskip" ||

Reply via email to