From: Jean-Marc Lasgouttes Date: Mon, 4 Aug 2003 10:26:10 +0000 (+0000) Subject: architectural changes to tex2lyx X-Git-Tag: 1.6.10~16340 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=c544107e324090c6eafb4c56749da2624b9b1122;p=features.git architectural changes to tex2lyx git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7494 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/tex2lyx/ChangeLog b/src/tex2lyx/ChangeLog index 54d77c7ac5..0775b5c695 100644 --- a/src/tex2lyx/ChangeLog +++ b/src/tex2lyx/ChangeLog @@ -1,3 +1,26 @@ +2003-08-03 Jean-Marc Lasgouttes + + * text.C: update to use Context struct, and more notably: + (cap, check_layout, check_end_layout): remove + (parse_text_snippet): new thin wrapper around parse_text, used for + things like \textrm{...} + (parse_environment): remove existing depth handling code, which is + handled transparently by the Context struct; make unknown + environments work (again?) through ERT + + * test-structure.tex: new test file, used to try out various + layouts combinations + + * tex2lyx.C: + * tex2lyx.h: + * table.C: update to use Context struct + + * context.[Ch]: new helper struct which is passed to parse_* + functions and handles *_layout and *_deeper tags output + + * Makefile.am (EXTRA_DIST): new file test-structure.tex + (tex2lyx_SOURCES): add context.[Ch] + 2003-07-30 Angus Leeming * Makefile.am: Hide the fact that we re-generate those symbolic links diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am index f773de6186..2a2e1adceb 100644 --- a/src/tex2lyx/Makefile.am +++ b/src/tex2lyx/Makefile.am @@ -1,6 +1,7 @@ include $(top_srcdir)/config/common.am INCLUDES = -I$(srcdir)/../ $(BOOST_INCLUDES) +EXTRA_DIST = test-structure.tex #noinst_LTLIBRARIES = libtexparser.la # @@ -27,6 +28,8 @@ linked_files = \ tex2lyx_SOURCES = \ $(linked_files) \ Spacing.h \ + context.C \ + context.h \ gettext.C \ gettext.h \ lyxfont.C \ diff --git a/src/tex2lyx/context.C b/src/tex2lyx/context.C new file mode 100644 index 0000000000..93431edda8 --- /dev/null +++ b/src/tex2lyx/context.C @@ -0,0 +1,79 @@ +/** A small helper function + \author Jean-Marc Lasgouttes (2003) + */ + +#include + +#include "context.h" + +using std::ostream; +using std::endl; + +Context::Context(bool need_layout_, + LyXTextClass const & textclass_, + LyXLayout_ptr layout_, LyXLayout_ptr parent_layout_) + : need_layout(need_layout_), + need_end_layout(false), need_end_deeper(false), + textclass(textclass_), + layout(layout_), parent_layout(parent_layout_) +{ + if (!layout.get()) + layout = textclass.defaultLayout(); + if (!parent_layout.get()) + parent_layout = textclass.defaultLayout(); +} + + +void Context::check_end_layout(ostream & os) +{ + if (need_end_layout) { + os << "\n\\end_layout\n"; + need_end_layout = false; + } + if (need_end_deeper) { + os << "\n\\end_deeper\n"; + need_end_deeper = false; + } +} + + +void Context::check_layout(ostream & os) +{ + if (need_layout) { + if (parent_layout->isEnvironment()) { + if (need_end_deeper) { + // no need to have \end_deeper \begin_deeper +// FIXME: This does not work because \par already calls check_end_layout + need_end_deeper = false; + check_end_layout(os); + } else { + check_end_layout(os); + os << "\n\\begin_deeper\n"; + need_end_deeper = true; + } + } else + check_end_layout(os); + + os << "\n\\begin_layout " << layout->name() << "\n\n"; + need_end_layout = true; + need_layout=false; + if (!extra_stuff.empty()) { + os << extra_stuff; + extra_stuff.erase(); + } + } +} + + +void Context::dump(ostream & os, string const & desc) const +{ + os << desc <<" ["; + if (need_layout) + os << "need_layout "; + if (need_end_layout) + os << "need_end_layout "; + if (!extra_stuff.empty()) + os << "extrastuff=[" << extra_stuff << "] "; + os << "layout=" << layout->name(); + os << " parent_layout=" << parent_layout->name() << "]" << endl; +} diff --git a/src/tex2lyx/context.h b/src/tex2lyx/context.h new file mode 100644 index 0000000000..2b5faa88aa --- /dev/null +++ b/src/tex2lyx/context.h @@ -0,0 +1,43 @@ +// -*- C++ -*- +#ifndef CONTEXT_H +#define CONTEXT_H + +#include "lyxtextclass.h" + +// A helper struct +struct Context { + Context(bool need_layout_, + LyXTextClass const & textclass_, + LyXLayout_ptr layout_ = LyXLayout_ptr(), + LyXLayout_ptr parent_layout_= LyXLayout_ptr()); + + // Output a \begin_layout is requested + void check_layout(std::ostream & os); + + // Output a \end_layout if needed + void check_end_layout(std::ostream & os); + + // dump content on standard error (for debugging purpose) + void dump(std::ostream &, std::string const & desc = "context") const; + + // Do we need to output some \begin_layout command before the + // next characters? + bool need_layout; + // Do we need to output some \end_layout command + bool need_end_layout; + // We may need to add something after this \begin_layout command + std::string extra_stuff; + // If there has been an \begin_deeper, we'll need a matching + // \end_deeper + bool need_end_deeper; + + // The textclass of the document. Could actually be a global variable + LyXTextClass const & textclass; + // The layout of the current paragraph + LyXLayout_ptr layout; + // The layout of the outer paragraph (for environment layouts) + LyXLayout_ptr parent_layout; +}; + + +#endif diff --git a/src/tex2lyx/table.C b/src/tex2lyx/table.C index da29b6b3ea..ac1b44eddf 100644 --- a/src/tex2lyx/table.C +++ b/src/tex2lyx/table.C @@ -26,8 +26,6 @@ using std::map; #include "mathed/math_gridinfo.h" -extern bool need_layout; - // filled in preamble.C std::map special_columns; @@ -284,7 +282,7 @@ void handle_hline_below(RowInfo & ri, vector & ci) void handle_tabular(Parser & p, ostream & os, - LyXTextClass const & textclass) + Context & context) { string posopts = p.getOpt(); if (posopts.size()) @@ -400,7 +398,7 @@ void handle_tabular(Parser & p, ostream & os, cellinfo[row][col].multi = 1; cellinfo[row][col].align = t.front().align; ostringstream os; - parse_text_in_inset(p, os, FLAG_ITEM, false, textclass); + parse_text_in_inset(p, os, FLAG_ITEM, false, context); cellinfo[row][col].content = os.str(); cellinfo[row][col].leftline |= t.front().leftline; cellinfo[row][col].rightline |= t.front().rightline; @@ -422,7 +420,7 @@ void handle_tabular(Parser & p, ostream & os, cellinfo[row][col].rightline = colinfo[col].rightline; cellinfo[row][col].align = colinfo[col].align; ostringstream os; - parse_text_in_inset(p, os, FLAG_ITEM, false, textclass); + parse_text_in_inset(p, os, FLAG_CELL, false, context); cellinfo[row][col].content = os.str(); } } diff --git a/src/tex2lyx/test-structure.tex b/src/tex2lyx/test-structure.tex new file mode 100644 index 0000000000..5d6e0fc879 --- /dev/null +++ b/src/tex2lyx/test-structure.tex @@ -0,0 +1,87 @@ +\documentclass{article} + +\begin{document} + +This document contains all sorts of layouts we are supposed to +support, along with weird nestings. + + +A normal paragraph + +Another one +\begin{equation} +x = \sin y +\end{equation} +with maths inside + +\begin{quote} +An environment... + +... with two paragraphs +\end{quote} + +\begin{foo} +an unknown environment +\end{foo} + + +\section{A section} + +\section[Hello!]{A section with optional argument} + +\begin{quote} +An environment +\end{quote} + +\section*{A starred section} + +\begin{figure} +\caption{A figure} +\end{figure} + +A paragraph\footnote{hello} with a footnote and another +one\footnote{hello + +there} with several paragraphs + +some ERT \vspace{1cm} aa + +and another paragraph + +\begin{center} +Some centered stuff (does not work) +\end{center} + +\begin{quotation} +An environment + +\section*{with a command inside it} +\end{quotation} + +\begin{quotation} +An environment + +\begin{quotation} +and the one inside it + +actually with several paragraphs +\end{quotation} + +\end{quotation} + +We can also nest enumerations (does not work quite yet) + +\begin{enumerate} +\item Item1 +\begin{enumerate} +\item Item1.a +\item Item1.b +\end{enumerate} +\begin{itemize} +\item Item1.* +\item Item1.* +\end{itemize} +\item Item2 +\end{enumerate} + +\end{document} diff --git a/src/tex2lyx/tex2lyx.C b/src/tex2lyx/tex2lyx.C index ed941fc739..a2a60e2370 100644 --- a/src/tex2lyx/tex2lyx.C +++ b/src/tex2lyx/tex2lyx.C @@ -5,6 +5,7 @@ // {[( #include "tex2lyx.h" +#include "context.h" #include "debug.h" #include "lyx_main.h" @@ -130,8 +131,9 @@ int main(int argc, char * argv[]) stringstream ss; LyXTextClass textclass = parse_preamble(p, ss); active_environments.push_back("document"); - parse_text(p, ss, FLAG_END, true, textclass); - check_end_layout(ss); + Context context(true, textclass); + parse_text(p, ss, FLAG_END, true, context); + context.check_end_layout(ss); ss << "\n\\end_document\n"; ss.seekg(0); diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h index d2b296d471..74b21e2907 100644 --- a/src/tex2lyx/tex2lyx.h +++ b/src/tex2lyx/tex2lyx.h @@ -1,3 +1,4 @@ +// -*- C++ -*- #ifndef TEX2LYX_H #define TEX2LYX_H @@ -8,31 +9,32 @@ #include #include -class LyXTextClass; +class Context; +/// in preamble.C LyXTextClass const parse_preamble(Parser & p, std::ostream & os); + +/// in text.C void parse_text(Parser & p, std::ostream & os, unsigned flags, bool outer, - LyXTextClass const & textclass, - LyXLayout_ptr layout_ptr = LyXLayout_ptr()); + Context & context); + +//std::string parse_text(Parser & p, unsigned flags, const bool outer, +// Context & context); void parse_text_in_inset(Parser & p, std::ostream & os, unsigned flags, - bool outer, LyXTextClass const & textclass, - LyXLayout_ptr layout = LyXLayout_ptr()); + bool outer, Context & context); -void parse_table(Parser & p, std::ostream & os, unsigned flags); +/// in math.C void parse_math(Parser & p, std::ostream & os, unsigned flags, mode_type mode); -void handle_tabular(Parser & p, std::ostream & os, - LyXTextClass const & textclass); -// Helper -std::string parse_text(Parser & p, unsigned flags, const bool outer, - LyXTextClass const & textclass, - LyXLayout_ptr layout_ptr = LyXLayout_ptr()); +/// in table.C +void handle_tabular(Parser & p, std::ostream & os, Context & context); + -void check_end_layout(std::ostream & os); +/// in tex2lyx.C void handle_comment(Parser & p); std::string const trim(std::string const & a, char const * p = " \t\n\r"); diff --git a/src/tex2lyx/text.C b/src/tex2lyx/text.C index 06da035ca5..28e53c184c 100644 --- a/src/tex2lyx/text.C +++ b/src/tex2lyx/text.C @@ -7,8 +7,8 @@ #include #include "tex2lyx.h" +#include "context.h" #include "FloatList.h" -#include "lyxtextclass.h" #include "support/lstrings.h" #include "support/tostr.h" @@ -28,19 +28,34 @@ using std::vector; using lyx::support::rtrim; using lyx::support::suffixIs; -// Do we need to output some \begin_layout command before the next characters? -bool need_layout = true; -// We may need to add something after this \begin_layout command -string extra_stuff; -// Do we need to output some \end_layout command -bool need_end_layout = false; -void check_end_layout(ostream & os) +// thin wrapper around parse_text using a string +string parse_text(Parser & p, unsigned flags, const bool outer, + Context & context) { - if (need_end_layout) { - os << "\n\\end_layout\n"; - need_end_layout = false; - } + ostringstream os; + parse_text(p, os, flags, outer, context); + return os.str(); +} + +// parses a subdocument, usually useful in insets (whence the name) +void parse_text_in_inset(Parser & p, ostream & os, unsigned flags, bool outer, + Context & context) +{ + Context newcontext(true, context.textclass); + parse_text(p, os, flags, outer, newcontext); + newcontext.check_end_layout(os); +} + + +// 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); + parse_text(p, os, flags, outer, newcontext); + // should not be needed + newcontext.check_end_layout(os); } @@ -63,14 +78,6 @@ char const * known_sizes[] = { "tiny", "scriptsize", "footnotesize", char const * known_coded_sizes[] = { "tiny", "scriptsize", "footnotesize", "small", "normal", "large", "larger", "largest", "huge", "giant", 0}; -string cap(string s) -{ - if (s.size()) - s[0] = toupper(s[0]); - return s; -} - - // splits "x=z, y=b" into a map map split_map(string const & s) { @@ -87,21 +94,6 @@ map split_map(string const & s) } -void check_layout(ostream & os, LyXLayout_ptr layout) -{ - if (need_layout) { - check_end_layout(os); - os << "\n\\begin_layout " << layout->name() << "\n\n"; - need_end_layout = true; - need_layout=false; - if (!extra_stuff.empty()) { - os << extra_stuff; - extra_stuff.erase(); - } - } -} - - void begin_inset(ostream & os, string const & name) { os << "\n\\begin_inset " << name; @@ -127,18 +119,19 @@ void skip_braces(Parser & p) } -void handle_ert(ostream & os, string const & s) +void handle_ert(ostream & os, string const & s, Context const & context) { + Context newcontext(true, context.textclass); begin_inset(os, "ERT"); - os << "\nstatus Collapsed\n\n\\begin_layout Standard\n\n"; + os << "\nstatus Collapsed\n"; + newcontext.check_layout(os); for (string::const_iterator it = s.begin(), et = s.end(); it != et; ++it) { if (*it == '\\') os << "\n\\backslash \n"; else os << *it; } - need_end_layout = true; - check_end_layout(os); + newcontext.check_end_layout(os); end_inset(os); } @@ -163,73 +156,75 @@ LyXLayout_ptr findLayout(LyXTextClass const & textclass, } -void output_command_layout(ostream & os, LyXLayout_ptr const & layout, - Parser & p, bool outer, LyXTextClass const & textclass) +void output_command_layout(ostream & os, Parser & p, bool outer, + Context & parent_context, + LyXLayout_ptr newlayout) { - need_layout = true; - check_layout(os, layout); - if (layout->optionalargs > 0) { +// parent_context.dump(os, "#parent_context before output_command_layout"); + parent_context.check_end_layout(os); + Context context(true, parent_context.textclass, newlayout, + parent_context.layout); + context.check_layout(os); + if (context.layout->optionalargs > 0) { string s; if (p.next_token().character() == '[') { p.get_token(); // eat '[' begin_inset(os, "OptArg\n"); os << "collapsed true\n"; - parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, textclass); + parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context); end_inset(os); } } - parse_text(p, os, FLAG_ITEM, outer, textclass, layout); - need_layout = true; + parse_text_snippet(p, os, FLAG_ITEM, outer, context); + context.check_end_layout(os); +// context.dump(os, "#context after output_command_layout"); +// parent_context.dump(os, "#parent_context after output_command_layout"); } -} // anonymous namespace - - void parse_environment(Parser & p, ostream & os, bool outer, - LyXTextClass const & textclass, LyXLayout_ptr layout) + Context & parent_context) { +// parent_context.dump(os, "#parent_context before parse_environment"); LyXLayout_ptr newlayout; string const name = p.getArg('{', '}'); const bool is_starred = suffixIs(name, '*'); string const unstarred_name = rtrim(name, "*"); active_environments.push_back(name); if (is_math_env(name)) { - check_layout(os, layout); + parent_context.check_layout(os); begin_inset(os, "Formula "); os << "\\begin{" << name << "}"; parse_math(p, os, FLAG_END, MATH_MODE); os << "\\end{" << name << "}"; end_inset(os); } else if (name == "tabular") { - check_layout(os, layout); + parent_context.check_layout(os); begin_inset(os, "Tabular "); - handle_tabular(p, os, textclass); + handle_tabular(p, os, parent_context); end_inset(os); - } else if (textclass.floats().typeExist(unstarred_name)) { - check_layout(os, layout); + } else if (parent_context.textclass.floats().typeExist(unstarred_name)) { + parent_context.check_layout(os); begin_inset(os, "Float " + unstarred_name + "\n"); if (p.next_token().asInput() == "[") { os << "placement " << p.getArg('[', ']') << '\n'; } os << "wide " << tostr(is_starred) << "\ncollapsed false\n"; - parse_text_in_inset(p, os, FLAG_END, outer, textclass); + parse_text_in_inset(p, os, FLAG_END, outer, parent_context); end_inset(os); } else if (name == "center") { - parse_text(p, os, FLAG_END, outer, textclass); + parse_text(p, os, FLAG_END, outer, parent_context); // The single '=' is meant here. - } else if ((newlayout = findLayout(textclass, name)).get() && + } else if ((newlayout = findLayout(parent_context.textclass, name)).get() && newlayout->isEnvironment()) { - size_t const n = active_environments.size(); - string const s = active_environments[n - 2]; - bool const deeper = s == "enumerate" || s == "itemize" - || s == "lyxlist"; - if (deeper) - os << "\n\\begin_deeper"; - switch (newlayout->latextype) { + Context context(true, parent_context.textclass, newlayout, + parent_context.layout); + parent_context.check_end_layout(os); +// context.dump(os, "#context in parse_environment"); + switch (context.layout->latextype) { case LATEX_LIST_ENVIRONMENT: - extra_stuff = "\\labelwidthstring " + context.extra_stuff = "\\labelwidthstring " + p.verbatim_item() + '\n'; break; case LATEX_BIB_ENVIRONMENT: @@ -238,24 +233,26 @@ void parse_environment(Parser & p, ostream & os, bool outer, default: break; } - need_layout = true; - parse_text(p, os, FLAG_END, outer, textclass, newlayout); - check_end_layout(os); - if (deeper) - os << "\n\\end_deeper\n"; - need_layout = true; + //context.check_layout(os); + parse_text(p, os, FLAG_END, outer, context); +// context.dump(os, "#context after parse_environment"); + context.check_end_layout(os); } else { - cerr << "why are we here?" << endl; - parse_text(p, os, FLAG_END, outer, textclass); + parent_context.check_layout(os); + handle_ert(os, "\\begin{" + name + "}", parent_context); + parse_text_snippet(p, os, FLAG_END, outer, parent_context); + handle_ert(os, "\\end{" + name + "}", parent_context); } } +} // anonymous namespace + + + void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, - LyXTextClass const & textclass, LyXLayout_ptr layout) + Context & context) { - if (!layout.get()) - layout = textclass.defaultLayout(); LyXLayout_ptr newlayout; while (p.good()) { Token const & t = p.get_token(); @@ -288,7 +285,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // if (t.cat() == catMath) { // we are inside some text mode thingy, so opening new math is allowed - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Formula "); Token const & n = p.get_token(); if (n.cat() == catMath && outer) { @@ -316,7 +313,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // quote...) else if (t.asInput() == "`" && p.next_token().asInput() == "`") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Quotes "); os << "eld"; end_inset(os); @@ -325,7 +322,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.asInput() == "'" && p.next_token().asInput() == "'") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Quotes "); os << "erd"; end_inset(os); @@ -339,23 +336,25 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, t.cat() == catOther || t.cat() == catAlign || t.cat() == catParameter) { - check_layout(os, layout); + context.check_layout(os); os << t.character(); } else if (t.cat() == catNewline) { if (p.next_token().cat() == catNewline) { p.get_token(); - need_layout = true; + context.need_layout = true; + // this should be done by the parser already + cerr << "what are we doing here?" << endl; } else { os << " "; // note the space } } else if (t.cat() == catActive) { - check_layout(os, layout); + context.check_layout(os); if (t.character() == '~') { - if (layout->free_spacing) + if (context.layout->free_spacing) os << ' '; else os << "\\InsetSpace ~\n"; @@ -366,29 +365,30 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cat() == catBegin) { // FIXME??? // special handling of size changes - check_layout(os, layout); + context.check_layout(os); bool const is_size = is_known(p.next_token().cs(), known_sizes); - need_end_layout = false; - string const s = parse_text(p, FLAG_BRACE_LAST, outer, textclass, layout); - need_end_layout = true; + Context newcontext(false, context.textclass); +// need_end_layout = false; + string const s = parse_text(p, FLAG_BRACE_LAST, outer, newcontext); +// need_end_layout = true; if (s.empty() && p.next_token().character() == '`') ; // ignore it in {}`` else if (is_size || s == "[" || s == "]" || s == "*") os << s; else { - handle_ert(os, "{"); + handle_ert(os, "{", context); os << s; - handle_ert(os, "}"); + handle_ert(os, "}", context); } } else if (t.cat() == catEnd) { if (flags & FLAG_BRACE_LAST) { - check_end_layout(os); + context.check_end_layout(os); return; } cerr << "stray '}' in text\n"; - handle_ert(os, "}"); + handle_ert(os, "}", context); } else if (t.cat() == catComment) @@ -399,7 +399,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // else if (t.cs() == "(") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Formula"); os << " \\("; parse_math(p, os, FLAG_SIMPLE2, MATH_MODE); @@ -408,7 +408,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.cs() == "[") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Formula"); os << " \\["; parse_math(p, os, FLAG_EQUATION, MATH_MODE); @@ -417,7 +417,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.cs() == "begin") - parse_environment(p, os, outer, textclass, layout); + parse_environment(p, os, outer, context); else if (t.cs() == "end") { if (flags & FLAG_END) { @@ -427,6 +427,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, cerr << "\\end{" + name + "} does not match \\begin{" + active_environment() + "}\n"; active_environments.pop_back(); + context.check_end_layout(os); return; } p.error("found 'end' unexpectedly"); @@ -438,10 +439,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, string s; if (p.next_token().character() == '[') { p.get_token(); // eat '[' - s = parse_text(p, FLAG_BRACK_LAST, outer, textclass, layout); + Context newcontext(false, context.textclass); + s = parse_text(p, FLAG_BRACK_LAST, outer, newcontext); } - need_layout = true; - check_layout(os, layout); + context.need_layout = true; + context.check_layout(os); if (s.size()) os << s << ' '; } @@ -450,12 +452,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, string name = p.get_token().cs(); while (p.next_token().cat() != catBegin) name += p.get_token().asString(); - handle_ert(os, "\\def\\" + name + '{' + p.verbatim_item() + '}'); + handle_ert(os, "\\def\\" + name + '{' + p.verbatim_item() + '}', context); } else if (t.cs() == "par") { p.skip_spaces(); - need_layout = true; + context.check_end_layout(os); + context.need_layout = true; // if (p.next_token().cs() != "\\begin") // handle_par(os); //cerr << "next token: '" << p.next_token().cs() << "'\n"; @@ -464,24 +467,24 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // Must attempt to parse "Section*" before "Section". else if ((p.next_token().asInput() == "*") && // The single '=' is meant here. - (newlayout = findLayout(textclass, + (newlayout = findLayout(context.textclass, t.cs() + '*')).get() && newlayout->isCommand()) { p.get_token(); - output_command_layout(os, newlayout, p, outer, textclass); + output_command_layout(os, p, outer, context, newlayout); } // The single '=' is meant here. - else if ((newlayout = findLayout(textclass, t.cs())).get() && + else if ((newlayout = findLayout(context.textclass, t.cs())).get() && newlayout->isCommand()) { - output_command_layout(os, newlayout, p, outer, textclass); + output_command_layout(os, p, outer, context, newlayout); } else if (t.cs() == "includegraphics") { map opts = split_map(p.getArg('[', ']')); string name = p.verbatim_item(); - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Graphics "); os << "\n\tfilename " << name << '\n'; if (opts.find("width") != opts.end()) @@ -492,34 +495,34 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else if (t.cs() == "footnote") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Foot\n"); os << "collapsed true\n"; - parse_text_in_inset(p, os, FLAG_ITEM, false, textclass); + parse_text_in_inset(p, os, FLAG_ITEM, false, context); end_inset(os); } - else if (t.cs() == "ensuremath") { - check_layout(os, layout); - string s = parse_text(p, FLAG_ITEM, false, textclass); - if (s == "±" || s == "³" || s == "²" || s == "µ") - os << s; - else - handle_ert(os, "\\ensuremath{" + s + "}"); - } - else if (t.cs() == "marginpar") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "Marginal\n"); os << "collapsed true\n"; - need_layout = true; - parse_text(p, os, FLAG_ITEM, false, textclass); + parse_text_in_inset(p, os, FLAG_ITEM, false, context); end_inset(os); - need_end_layout = true; + } + + else if (t.cs() == "ensuremath") { + context.check_layout(os); + Context newcontext(false, context.textclass); + string s = parse_text(p, FLAG_ITEM, false, newcontext); + if (s == "±" || s == "³" || s == "²" || s == "µ") + os << s; + else + handle_ert(os, "\\ensuremath{" + s + "}", + context); } else if (t.cs() == "hfill") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\hfill\n"; skip_braces(p); } @@ -528,7 +531,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, skip_braces(p); // swallow this else if (t.cs() == "tableofcontents") { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "LatexCommand "); os << '\\' << t.cs() << "{}\n"; end_inset(os); @@ -537,70 +540,70 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "textrm") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\family roman \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\family default \n"; } else if (t.cs() == "textsf") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\family sans \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\family default \n"; } else if (t.cs() == "texttt") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\family typewriter \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\family default \n"; } else if (t.cs() == "textit") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\shape italic \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\shape default \n"; } else if (t.cs() == "textsc") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\noun on \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\noun default \n"; } else if (t.cs() == "textbf") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\series bold \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\series default \n"; } else if (t.cs() == "underbar") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\bar under \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\bar default \n"; } else if (t.cs() == "emph" || t.cs() == "noun") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\" << t.cs() << " on \n"; - parse_text(p, os, FLAG_ITEM, outer, textclass); + parse_text_snippet(p, os, FLAG_ITEM, outer, context); os << "\n\\" << t.cs() << " default \n"; } else if (t.cs() == "bibitem") { - check_layout(os, layout); + context.check_layout(os); os << "\\bibitem "; os << p.getOpt(); os << '{' << p.verbatim_item() << '}' << "\n"; } else if (is_known(t.cs(), known_latex_commands)) { - check_layout(os, layout); + context.check_layout(os); begin_inset(os, "LatexCommand "); os << '\\' << t.cs(); os << p.getOpt(); @@ -619,66 +622,66 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (is_known(t.cs(), known_sizes)) { char const ** where = is_known(t.cs(), known_sizes); - check_layout(os, layout); + context.check_layout(os); os << "\n\\size " << known_coded_sizes[where - known_sizes] << "\n"; } else if (t.cs() == "LyX" || t.cs() == "TeX" || t.cs() == "LaTeX") { - check_layout(os, layout); + context.check_layout(os); os << t.cs(); skip_braces(p); // eat {} } else if (t.cs() == "LaTeXe") { - check_layout(os, layout); + context.check_layout(os); os << "LaTeX2e"; skip_braces(p); // eat {} } else if (t.cs() == "ldots") { - check_layout(os, layout); + context.check_layout(os); skip_braces(p); os << "\\SpecialChar \\ldots{}\n"; } else if (t.cs() == "lyxarrow") { - check_layout(os, layout); + context.check_layout(os); os << "\\SpecialChar \\menuseparator\n"; skip_braces(p); } else if (t.cs() == "ldots") { - check_layout(os, layout); + context.check_layout(os); os << "\\SpecialChar \\ldots{}\n"; skip_braces(p); } else if (t.cs() == "@" && p.next_token().asInput() == ".") { - check_layout(os, layout); + context.check_layout(os); os << "\\SpecialChar \\@.\n"; p.get_token(); } else if (t.cs() == "-") { - check_layout(os, layout); + context.check_layout(os); os << "\\SpecialChar \\-\n"; } else if (t.cs() == "textasciitilde") { - check_layout(os, layout); + context.check_layout(os); os << '~'; skip_braces(p); } else if (t.cs() == "textasciicircum") { - check_layout(os, layout); + context.check_layout(os); os << '^'; skip_braces(p); } else if (t.cs() == "textbackslash") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\backslash \n"; skip_braces(p); } @@ -686,12 +689,12 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (t.cs() == "_" || t.cs() == "&" || t.cs() == "#" || t.cs() == "$" || t.cs() == "{" || t.cs() == "}" || t.cs() == "%") { - check_layout(os, layout); + context.check_layout(os); os << t.cs(); } else if (t.cs() == "char") { - check_layout(os, layout); + context.check_layout(os); if (p.next_token().character() == '`') { p.get_token(); if (p.next_token().cs() == "\"") { @@ -699,15 +702,15 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << '"'; skip_braces(p); } else { - handle_ert(os, "\\char`"); + handle_ert(os, "\\char`", context); } } else { - handle_ert(os, "\\char"); + handle_ert(os, "\\char", context); } } else if (t.cs() == "\"") { - check_layout(os, layout); + context.check_layout(os); string const name = p.verbatim_item(); if (name == "a") os << 'ä'; else if (name == "o") os << 'ö'; @@ -715,43 +718,44 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, else if (name == "A") os << 'Ä'; else if (name == "O") os << 'Ö'; else if (name == "U") os << 'Ü'; - else handle_ert(os, "\"{" + name + "}"); + else handle_ert(os, "\"{" + name + "}", context); } else if (t.cs() == "=" || t.cs() == "H" || t.cs() == "c" || t.cs() == "^" || t.cs() == "'" || t.cs() == "~") { // we need the trim as the LyX parser chokes on such spaces - check_layout(os, layout); + context.check_layout(os); os << "\n\\i \\" << t.cs() << "{" - << trim(parse_text(p, FLAG_ITEM, outer, textclass), " ") << "}\n"; + << trim(parse_text(p, FLAG_ITEM, outer, context), " ") << "}\n"; } else if (t.cs() == "ss") { - check_layout(os, layout); + context.check_layout(os); os << "ß"; } else if (t.cs() == "i" || t.cs() == "j") { - check_layout(os, layout); + context.check_layout(os); os << "\\" << t.cs() << ' '; } else if (t.cs() == "\\") { - check_layout(os, layout); + context.check_layout(os); os << "\n\\newline \n"; } else if (t.cs() == "input") { - check_layout(os, layout); - handle_ert(os, "\\input{" + p.verbatim_item() + "}\n"); + context.check_layout(os); + handle_ert(os, "\\input{" + p.verbatim_item() + "}\n", + context); } else if (t.cs() == "fancyhead") { - check_layout(os, layout); + context.check_layout(os); ostringstream ss; ss << "\\fancyhead"; ss << p.getOpt(); ss << '{' << p.verbatim_item() << "}\n"; - handle_ert(os, ss.str()); + handle_ert(os, ss.str(), context); } else { @@ -766,10 +770,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, z = p.verbatim_item(); } cerr << "found ERT: " << s << endl; - handle_ert(os, s + ' '); + handle_ert(os, s + ' ', context); */ - check_layout(os, layout); - handle_ert(os, t.asInput() + ' '); + context.check_layout(os); + handle_ert(os, t.asInput() + ' ', context); } if (flags & FLAG_LEAVE) { @@ -780,22 +784,4 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } -string parse_text(Parser & p, unsigned flags, const bool outer, - LyXTextClass const & textclass, - LyXLayout_ptr layout) -{ - ostringstream os; - parse_text(p, os, flags, outer, textclass, layout); - return os.str(); -} - -void parse_text_in_inset(Parser & p, ostream & os, unsigned flags, bool outer, - LyXTextClass const & textclass, LyXLayout_ptr layout) -{ - need_layout = true; - need_end_layout = false; - parse_text(p, os, flags, outer, textclass, layout); - check_end_layout(os); - need_end_layout = true; -} // }])