I had a closer look at bug 20 and the context stuff in tex2lyx. The 
outcome is the attached patch, which ensures that we don't create 
invalid .lyx files anymore. The Contexts were not always used correctly 
until now (I am guilty of that, too). This is now fixed, and I added some 
comments in order to prevent that in the future.
The patch does also fix the environment bug reported by João: The new 
member variable Context::new_layout_allowed suppresses layout changes and 
new paragraphs if we are inside an environment in a non-standard 
paragraph. LyX would otherwise create invalid .tex files.
Apart from some parboxes I get now _identical_ .ps files on the userguide 
roundtrip.
Lars, can I apply this?

Georg
Index: lib/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ChangeLog,v
retrieving revision 1.725
diff -u -p -r1.725 ChangeLog
--- lib/ChangeLog	19 Jul 2005 20:56:11 -0000	1.725
+++ lib/ChangeLog	22 Jul 2005 17:26:27 -0000
@@ -1,3 +1,7 @@
+2005-07-24  Georg Baum  <[EMAIL PROTECTED]>
+
+	* syntax.default: add \fancyhead and \href
+
 2005-07-19  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
 	* configure.m4: fi invocation of tex2lyx.
Index: lib/syntax.default
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/syntax.default,v
retrieving revision 1.1
diff -u -p -r1.1 syntax.default
--- lib/syntax.default	16 Jul 2005 15:15:17 -0000	1.1
+++ lib/syntax.default	22 Jul 2005 17:26:29 -0000
@@ -125,6 +125,7 @@ $$
 \epsfig{}
 \epsfxsize
 \epsfysize
+\fancyhead[]{}
 \footnote[]{}
 \footnotesize
 \H{}
@@ -445,6 +446,7 @@ $$
 \glossaryentry{}{}       %only in .glo file (JMarc)
 % \graphpaper[](,)(,)    %picture
 \headtoname
+\href{}{translate}       % from the hyperref package
 \hspace{}
 \hspace*{}
 \hyphenation{}
Index: src/tex2lyx/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/ChangeLog,v
retrieving revision 1.103
diff -u -p -r1.103 ChangeLog
--- src/tex2lyx/ChangeLog	18 Jul 2005 16:23:53 -0000	1.103
+++ src/tex2lyx/ChangeLog	22 Jul 2005 17:26:54 -0000
@@ -1,3 +1,26 @@
+2005-07-24  Georg Baum  <[EMAIL PROTECTED]>
+
+	* context.[Ch] (~Context): new, warn about ignored extra stuff
+	* context.[Ch] (operator==, operator!=): new Font comparison operators
+	* context.C (check_layout): simplify logic
+	* context.C (dump): output all members
+	* context.h (new_layout_allowed): new member variable
+	* text.C (parse_text): remove string wrapper since it can lead to
+	invalid .lyx files (begin_layout/end_layout trouble)
+	* text.C (parse_text_snippet): Make sure that we don't create invalid
+	.lyx files
+	* text.C (parse_text_snippet): New string wrapper for simple text
+	* text.C (handle_ert): Always check layout
+	* text.C (parse_environment): Don't allow font changes in unknown
+	environments
+	* text.C (parse_unknown_environment): new, needed for the above
+	* text.C (parse_environment): Only swallo spaces when we know that it
+	does not harm
+	* text.C (parse_comment): Honor context.new_layout_allowed
+	* text.C (parse_text_attributes): Make sure that we have a valid
+	layout
+	* text.C (parse_text): Honor context.new_layout_allowed
+
 2005-07-18  Lars Gullik Bjønnes  <[EMAIL PROTECTED]>
 
 	* Makefile.am (EXTRA_DIST): add tex2lyx.man
Index: src/tex2lyx/context.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/context.C,v
retrieving revision 1.14
diff -u -p -r1.14 context.C
--- src/tex2lyx/context.C	13 Jul 2005 11:38:55 -0000	1.14
+++ src/tex2lyx/context.C	22 Jul 2005 17:26:54 -0000
@@ -51,6 +51,17 @@ void end_deeper(ostream & os)
 
 }
 
+
+bool operator==(Font const & f1, Font const & f2)
+{
+	return
+		f1.size == f2.size &&
+		f1.family == f2.family &&
+		f1.series == f2.series &&
+		f1.shape == f2.shape;
+}
+
+
 void output_font_change(ostream & os, Font const & oldfont,
                         Font const & newfont)
 {
@@ -75,7 +86,7 @@ Context::Context(bool need_layout_,
 	: need_layout(need_layout_),
 	  need_end_layout(false), need_end_deeper(false),
 	  has_item(false), deeper_paragraph(false),
-	  textclass(textclass_),
+	  new_layout_allowed(true), textclass(textclass_),
 	  layout(layout_), parent_layout(parent_layout_),
 	  font(font_)
 {
@@ -86,6 +97,14 @@ Context::Context(bool need_layout_,
 }
 
 
+Context::~Context()
+{
+	if (!extra_stuff.empty())
+		std::cerr << "Bug: Ignoring extra stuff '" << extra_stuff
+		          << '\'' << std::endl;
+}
+
+
 void Context::check_layout(ostream & os)
 {
 	if (need_layout) {
@@ -104,8 +122,6 @@ void Context::check_layout(ostream & os)
 				}
 				begin_layout(os, layout, font, normalfont);
 				has_item = false;
-				need_layout=false;
-				need_end_layout = true;
 			} else {
 				// a standard paragraph in an
 				// enumeration. We have to recognize
@@ -114,16 +130,15 @@ void Context::check_layout(ostream & os)
 					begin_deeper(os);
 				begin_layout(os, textclass.defaultLayout(),
 				             font, normalfont);
-				need_layout=false;
-				need_end_layout = true;
 				deeper_paragraph = true;
 			}
+			need_layout = false;
 		} else {
 			// No list-like environment
 			begin_layout(os, layout, font, normalfont);
 			need_layout=false;
-			need_end_layout = true;
 		}
+		need_end_layout = true;
 		if (!extra_stuff.empty()) {
 			os << extra_stuff;
 			extra_stuff.erase();
@@ -206,8 +229,13 @@ void Context::dump(ostream & os, string 
 		os << "has_item ";
 	if (deeper_paragraph)
 		os << "deeper_paragraph ";
+	if (new_layout_allowed)
+		os << "new_layout_allowed ";
 	if (!extra_stuff.empty())
 		os << "extrastuff=[" << extra_stuff << "] ";
-	os << "layout=" << layout->name();
-	os << " parent_layout=" << parent_layout->name() << "]" << endl;
+	os << "textclass=" << textclass.name()
+	   << " layout=" << layout->name()
+	   << " parent_layout=" << parent_layout->name() << "] font=["
+	   << font.size << ' ' << font.family << ' ' << font.series << ' '
+	   << font.shape << ']' << endl;
 }
Index: src/tex2lyx/context.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/context.h,v
retrieving revision 1.12
diff -u -p -r1.12 context.h
--- src/tex2lyx/context.h	13 Jul 2005 11:38:55 -0000	1.12
+++ src/tex2lyx/context.h	22 Jul 2005 17:26:54 -0000
@@ -45,12 +45,32 @@ public:
 };
 
 
+bool operator==(Font const &, Font const &);
+
+
+inline bool operator!=(Font const & f1, Font const & f2)
+{
+	return !operator==(f1, f2);
+}
+
+
 /// Output changed font parameters if \p oldfont and \p newfont differ
 void output_font_change(std::ostream & os, Font const & oldfont,
                         Font const & newfont);
 
 
-// A helper struct
+/*!
+ * A helper struct.
+ *
+ * Every bit of text has a corresponding context.
+ * Usage: Parsing begins with a global context. A new context is opened for
+ * every new LaTeX group, e.g. at the beginning of a new environment.
+ * The old context is used again after the group is closed.
+ *
+ * Since not all paragraph parameters in LyX have the same scoping as their
+ * LaTeX counterpart we may have to transfer context properties (e. g. the
+ * font) from and to the parent context.
+ */
 class Context {
 public:
 	Context(bool need_layout_,
@@ -58,6 +78,7 @@ public:
 		LyXLayout_ptr layout_ = LyXLayout_ptr(),
 		LyXLayout_ptr parent_layout_= LyXLayout_ptr(),
 	        Font font_ = Font());
+	~Context();
 
 	/// Output a \\begin_layout if requested
 	void check_layout(std::ostream & os);
@@ -97,13 +118,21 @@ public:
 	/// If there has been an \\begin_deeper, we'll need a matching
 	/// \\end_deeper
 	bool need_end_deeper;
-	/// If we are in an itemize-like environment, we need an \\item
+	/// If we are in an itemize-like environment, we need an \item
 	/// for each paragraph, otherwise this has to be a deeper
 	/// paragraph.
 	bool has_item;
 	/// we are handling a standard paragraph in an itemize-like
 	/// environment
 	bool deeper_paragraph;
+	/*!
+	 * Inside of unknown environments we may not allow font and layout
+	 * changes.
+	 * Otherwise things like
+	 * \\large\\begin{foo}\\huge bar\\end{foo}
+	 * would not work.
+	 */
+	bool new_layout_allowed;
 
 	/// The textclass of the document. Could actually be a global variable
 	LyXTextClass const & textclass;
Index: src/tex2lyx/tex2lyx.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/tex2lyx.h,v
retrieving revision 1.21
diff -u -p -r1.21 tex2lyx.h
--- src/tex2lyx/tex2lyx.h	14 Jul 2005 15:19:01 -0000	1.21
+++ src/tex2lyx/tex2lyx.h	22 Jul 2005 17:26:56 -0000
@@ -34,12 +34,15 @@ LyXTextClass const parse_preamble(Parser
 void parse_text(Parser & p, std::ostream & os, unsigned flags, bool outer,
 		Context & context);
 
-//std::string parse_text(Parser & p, unsigned flags, const bool outer,
-//		       Context & context);
-
-/// parses a subdocument, usually useful in insets (whence the name)
+/*!
+ * Parses a subdocument, usually useful in insets (whence the name).
+ *
+ * It ignores \c context.need_layout and \c context.need_end_layout and
+ * starts and ends always a new layout.
+ * Therefore this may only be used to parse text in insets or table cells.
+ */
 void parse_text_in_inset(Parser & p, std::ostream & os, unsigned flags,
-			 bool outer, Context & context);
+			 bool outer, Context const & context);
 
 
 /// in math.C
Index: src/tex2lyx/text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/text.C,v
retrieving revision 1.62
diff -u -p -r1.62 text.C
--- src/tex2lyx/text.C	15 Jul 2005 15:42:44 -0000	1.62
+++ src/tex2lyx/text.C	22 Jul 2005 17:26:56 -0000
@@ -50,18 +51,8 @@ using std::vector;
 namespace fs = boost::filesystem;
 
 
-/// thin wrapper around parse_text using a string
-string parse_text(Parser & p, unsigned flags, const bool outer,
-		  Context & context)
-{
-	ostringstream os;
-	parse_text(p, os, flags, outer, context);
-	return os.str();
-}
-
-
 void parse_text_in_inset(Parser & p, ostream & os, unsigned flags, bool outer,
-		Context & context)
+		Context const & context)
 {
 	Context newcontext(true, context.textclass);
 	newcontext.font = context.font;
@@ -70,19 +61,45 @@ void parse_text_in_inset(Parser & p, ost
 }
 
 
+namespace {
+
 /// parses a paragraph snippet, useful for example for \\emph{...}
 void parse_text_snippet(Parser & p, ostream & os, unsigned flags, bool outer,
 		Context & context)
 {
-	Context newcontext(false, context.textclass);
-	newcontext.font = context.font;
+	Context newcontext(context);
+	// Don't inherit the extra stuff
+	newcontext.extra_stuff.clear();
 	parse_text(p, os, flags, outer, newcontext);
-	// should not be needed
-	newcontext.check_end_layout(os);
+	// Make sure that we don't create invalid .lyx files
+	context.need_layout = newcontext.need_layout;
+	context.need_end_layout = newcontext.need_end_layout;
 }
 
 
-namespace {
+/*!
+ * Thin wrapper around parse_text_snippet() using a string.
+ *
+ * We completely ignore \c context.need_layout and \c context.need_end_layout,
+ * because our return value is not used directly (otherwise the stream version
+ * of parse_text_snippet() could be used). That means that the caller needs
+ * to do layout management manually.
+ * This is intended to parse text that does not create any layout changes.
+ */
+string parse_text_snippet(Parser & p, unsigned flags, const bool outer,
+		  Context & context)
+{
+	Context newcontext(context);
+	newcontext.need_layout = false;
+	newcontext.need_end_layout = false;
+	newcontext.new_layout_allowed = false;
+	// Avoid warning by Context::~Context()
+	newcontext.extra_stuff.clear();
+	ostringstream os;
+	parse_text_snippet(p, os, flags, outer, newcontext);
+	return os.str();
+}
+
 
 char const * const known_latex_commands[] = { "ref", "cite", "label", "index",
 "printindex", "pageref", "url", "vref", "vpageref", "prettyref", "eqref", 0 };
@@ -356,14 +387,10 @@ void skip_braces(Parser & p)
 }
 
 
-
-void handle_ert(ostream & os, string const & s, Context & context,
-                bool check_layout = true)
+void handle_ert(ostream & os, string const & s, Context & context)
 {
-	if (check_layout) {
-		// We must have a valid layout before outputting the ERT inset.
-		context.check_layout(os);
-	}
+	// We must have a valid layout before outputting the ERT inset.
+	context.check_layout(os);
 	Context newcontext(true, context.textclass);
 	begin_inset(os, "ERT");
 	os << "\nstatus collapsed\n";
@@ -655,14 +711,40 @@ void parse_box(Parser & p, ostream & os,
 }
 
 
+/// parse an unknown environment
+void parse_unknown_environment(Parser & p, string const & name, ostream & os,
+                               unsigned flags, bool outer,
+                               Context & parent_context)
+{
+	if (name == "tabbing")
+		// We need to remember that we have to handle '\=' specially
+		flags |= FLAG_TABBING;
+
+	// We need to translate font changes and paragraphs inside the
+	// environment to ERT if we have a non standard font.
+	// Otherwise things like
+	// \large\begin{foo}\huge bar\end{foo}
+	// will not work.
+	bool const specialfont =
+		(parent_context.font != parent_context.normalfont);
+	bool const new_layout_allowed = parent_context.new_layout_allowed;
+	if (specialfont)
+		parent_context.new_layout_allowed = false;
+	handle_ert(os, "\\begin{" + name + "}", parent_context);
+	parse_text_snippet(p, os, flags, outer, parent_context);
+	handle_ert(os, "\\end{" + name + "}", parent_context);
+	if (specialfont)
+		parent_context.new_layout_allowed = new_layout_allowed;
+}
+
+
 void parse_environment(Parser & p, ostream & os, bool outer,
-		       Context & parent_context)
+                       Context & parent_context)
 {
 	LyXLayout_ptr newlayout;
 	string const name = p.getArg('{', '}');
 	const bool is_starred = suffixIs(name, '*');
 	string const unstarred_name = rtrim(name, "*");
-	eat_whitespace(p, os, parent_context, false);
 	active_environments.push_back(name);
 
 	if (is_math_env(name)) {
@@ -675,13 +801,16 @@ void parse_environment(Parser & p, ostre
 	}
 
 	else if (name == "tabular" || name == "longtable") {
+		eat_whitespace(p, os, parent_context, false);
 		parent_context.check_layout(os);
 		begin_inset(os, "Tabular ");
 		handle_tabular(p, os, name == "longtable", parent_context);
 		end_inset(os);
+		p.skip_spaces();
 	}
 
 	else if (parent_context.textclass.floats().typeExist(unstarred_name)) {
+		eat_whitespace(p, os, parent_context, false);
 		parent_context.check_layout(os);
 		begin_inset(os, "Float " + unstarred_name + "\n");
 		if (p.next_token().asInput() == "[") {
@@ -695,14 +824,43 @@ void parse_environment(Parser & p, ostre
 		// We don't need really a new paragraph, but
 		// we must make sure that the next item gets a \begin_layout.
 		parent_context.new_paragraph(os);
+		p.skip_spaces();
 	}
 
-	else if (name == "minipage")
+	else if (name == "minipage") {
+		eat_whitespace(p, os, parent_context, false);
 		parse_box(p, os, FLAG_END, outer, parent_context, false);
+		p.skip_spaces();
+	}
+
+	else if (name == "comment") {
+		eat_whitespace(p, os, parent_context, false);
+		parent_context.check_layout(os);
+		begin_inset(os, "Note Comment\n");
+		os << "status open\n";
+		parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
+		end_inset(os);
+		p.skip_spaces();
+	}
+
+	else if (name == "lyxgreyedout") {
+		eat_whitespace(p, os, parent_context, false);
+		parent_context.check_layout(os);
+		begin_inset(os, "Note Greyedout\n");
+		os << "status open\n";
+		parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
+		end_inset(os);
+		p.skip_spaces();
+	}
+
+	else if (!parent_context.new_layout_allowed)
+		parse_unknown_environment(p, name, os, FLAG_END, outer,
+		                          parent_context);
 
 	// Alignment settings
 	else if (name == "center" || name == "flushleft" || name == "flushright" ||
 	         name == "centering" || name == "raggedright" || name == "raggedleft") {
+		eat_whitespace(p, os, parent_context, false);
 		// We must begin a new paragraph if not already done
 		if (! parent_context.atParagraphStart()) {
 			parent_context.check_end_layout(os);
@@ -719,11 +877,13 @@ void parse_environment(Parser & p, ostre
 		parent_context.extra_stuff.erase();
 		// We must begin a new paragraph to reset the alignment
 		parent_context.new_paragraph(os);
+		p.skip_spaces();
 	}
 
 	// The single '=' is meant here.
 	else if ((newlayout = findLayout(parent_context.textclass, name)).get() &&
 		  newlayout->isEnvironment()) {
+		eat_whitespace(p, os, parent_context, false);
 		Context context(true, parent_context.textclass, newlayout,
 				parent_context.layout, parent_context.font);
 		if (parent_context.deeper_paragraph) {
@@ -756,10 +966,12 @@ void parse_environment(Parser & p, ostre
 		}
 		context.check_end_deeper(os);
 		parent_context.new_paragraph(os);
+		p.skip_spaces();
 	}
 
 	else if (name == "appendix") {
 		// This is no good latex style, but it works and is used in some documents...
+		eat_whitespace(p, os, parent_context, false);
 		parent_context.check_end_layout(os);
 		Context context(true, parent_context.textclass, parent_context.layout,
 				parent_context.layout, parent_context.font);
@@ -767,34 +1007,7 @@ void parse_environment(Parser & p, ostre
 		os << "\\start_of_appendix\n";
 		parse_text(p, os, FLAG_END, outer, context);
 		context.check_end_layout(os);
-	}
-
-	else if (name == "comment") {
-		parent_context.check_layout(os);
-		begin_inset(os, "Note Comment\n");
-		os << "status open\n";
-		parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
-		end_inset(os);
-	}
-
-	else if (name == "lyxgreyedout") {
-		parent_context.check_layout(os);
-		begin_inset(os, "Note Greyedout\n");
-		os << "status open\n";
-		parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
-		end_inset(os);
-	}
-
-	else if (name == "tabbing") {
-		// We need to remember that we have to handle '\=' specially
-		handle_ert(os, "\\begin{" + name + "}", parent_context);
-		// FIXME: Try whether parse_text instead of parse_text_snippet
-		// works. Then no manual layout checking would be needed.
-		parent_context.check_end_layout(os);
-		parse_text_snippet(p, os, FLAG_END | FLAG_TABBING, outer,
-		                   parent_context);
-		parent_context.need_layout = true;
-		handle_ert(os, "\\end{" + name + "}", parent_context);
+		p.skip_spaces();
 	}
 
 	else if (known_environments.find(name) != known_environments.end()) {
@@ -808,36 +1021,31 @@ void parse_environment(Parser & p, ostre
 			arguments.back();
 		if (!arguments.empty())
 			arguments.pop_back();
+		// See comment in parse_unknown_environment()
+		bool const specialfont =
+			(parent_context.font != parent_context.normalfont);
+		bool const new_layout_allowed =
+			parent_context.new_layout_allowed;
+		if (specialfont)
+			parent_context.new_layout_allowed = false;
 		parse_arguments("\\begin{" + name + "}", arguments, p, os,
 		                outer, parent_context);
 		if (contents == verbatim)
 			handle_ert(os, p.verbatimEnvironment(name),
 			           parent_context);
-		else {
-			// FIXME: Try whether parse_text instead of
-			// parse_text_snippet works. Then no manual layout
-			// checking would be needed.
-			parent_context.check_end_layout(os);
+		else
 			parse_text_snippet(p, os, FLAG_END, outer,
 			                   parent_context);
-			parent_context.need_layout = true;
-		}
 		handle_ert(os, "\\end{" + name + "}", parent_context);
+		if (specialfont)
+			parent_context.new_layout_allowed = new_layout_allowed;
 	}
 
-	else {
-		handle_ert(os, "\\begin{" + name + "}", parent_context);
-		// FIXME: Try whether parse_text instead of parse_text_snippet
-		// works. Then no manual layout checking would be needed.
-		parent_context.check_end_layout(os);
-		parse_text_snippet(p, os, FLAG_END, outer, parent_context);
-		parent_context.need_layout = true;
-		handle_ert(os, "\\end{" + name + "}", parent_context);
-	}
+	else
+		parse_unknown_environment(p, name, os, FLAG_END, outer,
+		                          parent_context);
 
 	active_environments.pop_back();
-	if (name != "math")
-		p.skip_spaces();
 }
 
 
@@ -851,11 +1059,13 @@ void parse_comment(Parser & p, ostream &
 		if (p.next_token().cat() == catNewline) {
 			// A newline after a comment line starts a new
 			// paragraph
-			if(!context.atParagraphStart()) {
-				// Only start a new paragraph if not already
-				// done (we might get called recursively)
-				context.new_paragraph(os);
-			}
+			if (context.new_layout_allowed) {
+				if(!context.atParagraphStart())
+					// Only start a new paragraph if not already
+					// done (we might get called recursively)
+					context.new_paragraph(os);
+			} else
+				handle_ert(os, "\n", context);
 			eat_whitespace(p, os, context, true);
 		}
 	} else {
@@ -899,12 +1109,13 @@ void parse_text_attributes(Parser & p, o
 			   string & currentvalue, string const & newvalue)
 {
 	context.check_layout(os);
-	string oldvalue = currentvalue;
+	string const oldvalue = currentvalue;
 	currentvalue = newvalue;
 	os << '\n' << attribute << ' ' << newvalue << "\n";
 	parse_text_snippet(p, os, flags, outer, context);
-	currentvalue = oldvalue;
+	context.check_layout(os);
 	os << '\n' << attribute << ' ' << oldvalue << "\n";
+	currentvalue = oldvalue;
 }
 
 
@@ -1061,7 +1312,10 @@ void parse_text(Parser & p, ostream & os
 		}
 
 		else if (p.isParagraph()) {
-			context.new_paragraph(os);
+			if (context.new_layout_allowed)
+				context.new_paragraph(os);
+			else
+				handle_ert(os, "\\par ", context);
 			eat_whitespace(p, os, context, true);
 		}
 
@@ -1076,55 +1330,85 @@ void parse_text(Parser & p, ostream & os
 				os << t.character();
 		}
 
+		else if (t.cat() == catBegin &&
+		         p.next_token().cat() == catEnd) {
+			// {}
+			Token const prev = p.prev_token();
+			p.get_token();
+			if (p.next_token().character() == '`' ||
+			    (prev.character() == '-' &&
+			     p.next_token().character() == '-'))
+				; // ignore it in {}`` or -{}-
+			else
+				handle_ert(os, "{}", context);
+
+		}
+
 		else if (t.cat() == catBegin) {
 			context.check_layout(os);
 			// special handling of font attribute changes
 			Token const prev = p.prev_token();
 			Token const next = p.next_token();
 			Font const oldFont = context.font;
-			string const s = parse_text(p, FLAG_BRACE_LAST, outer,
-			                            context);
-			context.font = oldFont;
-			if (s.empty() && (p.next_token().character() == '`' ||
-			                  (prev.character() == '-' &&
-			                   p.next_token().character() == '-')))
-				; // ignore it in {}`` or -{}-
-			else if (s == "[" || s == "]" || s == "*")
-				os << s;
-			else if (is_known(next.cs(), known_sizes)) {
-				// s will change the size, so we must reset
-				// it here
-				os << s;
+			if (next.character() == '[' ||
+			    next.character() == ']' ||
+			    next.character() == '*') {
+				p.get_token();
+				if (p.next_token().cat() == catEnd) {
+					os << next.character();
+					p.get_token();
+				} else {
+					p.putback();
+					handle_ert(os, "{", context);
+					parse_text_snippet(p, os,
+							FLAG_BRACE_LAST,
+							outer, context);
+					handle_ert(os, "}", context);
+				}
+			} else if (! context.new_layout_allowed) {
+				handle_ert(os, "{", context);
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
+				handle_ert(os, "}", context);
+			} else if (is_known(next.cs(), known_sizes)) {
+				// next will change the size, so we must
+				// reset it here
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				if (!context.atParagraphStart())
 					os << "\n\\size "
 					   << context.font.size << "\n";
 			} else if (is_known(next.cs(), known_font_families)) {
-				// s will change the font family, so we must
-				// reset it here
-				os << s;
+				// next will change the font family, so we
+				// must reset it here
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				if (!context.atParagraphStart())
 					os << "\n\\family "
 					   << context.font.family << "\n";
 			} else if (is_known(next.cs(), known_font_series)) {
-				// s will change the font series, so we must
-				// reset it here
-				os << s;
+				// next will change the font series, so we
+				// must reset it here
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				if (!context.atParagraphStart())
 					os << "\n\\series "
 					   << context.font.series << "\n";
 			} else if (is_known(next.cs(), known_font_shapes)) {
-				// s will change the font shape, so we must
-				// reset it here
-				os << s;
+				// next will change the font shape, so we
+				// must reset it here
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				if (!context.atParagraphStart())
 					os << "\n\\shape "
 					   << context.font.shape << "\n";
 			} else if (is_known(next.cs(), known_old_font_families) ||
 			           is_known(next.cs(), known_old_font_series) ||
 			           is_known(next.cs(), known_old_font_shapes)) {
-				// s will change the font family, series
+				// next will change the font family, series
 				// and shape, so we must reset it here
-				os << s;
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				if (!context.atParagraphStart())
 					os <<  "\n\\family "
 					   << context.font.family
@@ -1133,10 +1417,9 @@ void parse_text(Parser & p, ostream & os
 					   << "\n\\shape "
 					   << context.font.shape << "\n";
 			} else {
-				handle_ert(os, "{", context, false);
-				// s will end the current layout and begin a
-				// new one if necessary
-				os << s;
+				handle_ert(os, "{", context);
+				parse_text_snippet(p, os, FLAG_BRACE_LAST,
+				                   outer, context);
 				handle_ert(os, "}", context);
 			}
 		}
@@ -1195,9 +1481,8 @@ void parse_text(Parser & p, ostream & os
 			bool optarg = false;
 			if (p.next_token().character() == '[') {
 				p.get_token(); // eat '['
-				Context newcontext(false, context.textclass);
-				newcontext.font = context.font;
-				s = parse_text(p, FLAG_BRACK_LAST, outer, newcontext);
+				s = parse_text_snippet(p, FLAG_BRACK_LAST,
+				                       outer, context);
 				optarg = true;
 			}
 			context.set_item();
@@ -1265,6 +1550,7 @@ void parse_text(Parser & p, ostream & os
 
 		// Must attempt to parse "Section*" before "Section".
 		else if ((p.next_token().asInput() == "*") &&
+		         context.new_layout_allowed && 
 			 // The single '=' is meant here.
 			 (newlayout = findLayout(context.textclass,
 						 t.cs() + '*')).get() &&
@@ -1275,7 +1561,8 @@ void parse_text(Parser & p, ostream & os
 		}
 
 		// The single '=' is meant here.
-		else if ((newlayout = findLayout(context.textclass, t.cs())).get() &&
+		else if (context.new_layout_allowed &&
+		         (newlayout = findLayout(context.textclass, t.cs())).get() &&
 			 newlayout->isCommand()) {
 			output_command_layout(os, p, outer, context, newlayout);
 			p.skip_spaces();
@@ -1446,9 +1748,7 @@ void parse_text(Parser & p, ostream & os
 		else if (t.cs() == "ensuremath") {
 			p.skip_spaces();
 			context.check_layout(os);
-			Context newcontext(false, context.textclass);
-			newcontext.font = context.font;
-			string s = parse_text(p, FLAG_ITEM, false, newcontext);
+			string const s = p.verbatim_item();
 			if (s == "±" || s == "³" || s == "²" || s == "µ")
 				os << s;
 			else
@@ -1575,6 +1875,7 @@ void parse_text(Parser & p, ostream & os
 			context.check_layout(os);
 			os << "\n\\bar under\n";
 			parse_text_snippet(p, os, FLAG_ITEM, outer, context);
+			context.check_layout(os);
 			os << "\n\\bar default\n";
 		}
 
@@ -1582,6 +1883,7 @@ void parse_text(Parser & p, ostream & os
 			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";
 		}
 
@@ -1699,7 +2039,8 @@ void parse_text(Parser & p, ostream & os
 			skip_braces(p);
 		}
 
-		else if (is_known(t.cs(), known_sizes)) {
+		else if (is_known(t.cs(), known_sizes) &&
+		         context.new_layout_allowed) {
 			char const * const * where = is_known(t.cs(), known_sizes);
 			context.check_layout(os);
 			Font const oldFont = context.font;
@@ -1708,7 +2049,8 @@ void parse_text(Parser & p, ostream & os
 			eat_whitespace(p, os, context, false);
 		}
 
-		else if (is_known(t.cs(), known_font_families)) {
+		else if (is_known(t.cs(), known_font_families) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_font_families);
 			context.check_layout(os);
@@ -1719,7 +2061,8 @@ void parse_text(Parser & p, ostream & os
 			eat_whitespace(p, os, context, false);
 		}
 
-		else if (is_known(t.cs(), known_font_series)) {
+		else if (is_known(t.cs(), known_font_series) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_font_series);
 			context.check_layout(os);
@@ -1730,7 +2073,8 @@ void parse_text(Parser & p, ostream & os
 			eat_whitespace(p, os, context, false);
 		}
 
-		else if (is_known(t.cs(), known_font_shapes)) {
+		else if (is_known(t.cs(), known_font_shapes) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_font_shapes);
 			context.check_layout(os);
@@ -1740,7 +2084,8 @@ void parse_text(Parser & p, ostream & os
 			output_font_change(os, oldFont, context.font);
 			eat_whitespace(p, os, context, false);
 		}
-		else if (is_known(t.cs(), known_old_font_families)) {
+		else if (is_known(t.cs(), known_old_font_families) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_old_font_families);
 			context.check_layout(os);
@@ -1753,7 +2098,8 @@ void parse_text(Parser & p, ostream & os
 			eat_whitespace(p, os, context, false);
 		}
 
-		else if (is_known(t.cs(), known_old_font_series)) {
+		else if (is_known(t.cs(), known_old_font_series) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_old_font_series);
 			context.check_layout(os);
@@ -1766,7 +2112,8 @@ void parse_text(Parser & p, ostream & os
 			eat_whitespace(p, os, context, false);
 		}
 
-		else if (is_known(t.cs(), known_old_font_shapes)) {
+		else if (is_known(t.cs(), known_old_font_shapes) &&
+		         context.new_layout_allowed) {
 			char const * const * where =
 				is_known(t.cs(), known_old_font_shapes);
 			context.check_layout(os);
@@ -1885,7 +2249,8 @@ void parse_text(Parser & p, ostream & os
 			// we need the trim as the LyX parser chokes on such spaces
 			context.check_layout(os);
 			os << "\n\\i \\" << t.cs() << "{"
-			   << trim(parse_text(p, FLAG_ITEM, outer, context), " ") << "}\n";
+			   << trim(parse_text_snippet(p, FLAG_ITEM, outer, context), " ")
+			   << "}\n";
 		}
 
 		else if (t.cs() == "ss") {
@@ -1959,15 +2324,6 @@ void parse_text(Parser & p, ostream & os
 			end_inset(os);
 		}
 
-		else if (t.cs() == "fancyhead") {
-			context.check_layout(os);
-			ostringstream ss;
-			ss << "\\fancyhead";
-			ss << p.getOpt();
-			ss << '{' << p.verbatim_item() << "}\n";
-			handle_ert(os, ss.str(), context);
-		}
-
 		else if (t.cs() == "bibliographystyle") {
 			// store new bibliographystyle
 			bibliographystyle = p.verbatim_item();
@@ -2002,6 +2365,13 @@ void parse_text(Parser & p, ostream & os
 			skip_braces(p);
 		}
 
+		else if (t.cs() == "newpage") {
+			context.check_layout(os);
+			// FIXME: what about \\clearpage and \\pagebreak?
+			os << "\n\\newpage\n";
+			skip_braces(p); // eat {}
+		}
+
 		else if (t.cs() == "newcommand" ||
 		         t.cs() == "providecommand" ||
 		         t.cs() == "renewcommand") {
@@ -2133,6 +2503,5 @@ void parse_text(Parser & p, ostream & os
 		}
 	}
 }
-
 
 // }])

Reply via email to