I have modified the parser to not drop any spaces anymore. The result is
that the Userguide roundtrip works better. Apart from the preamble, a
diff -u Userguide.tex Userguide-new.tex
shows now almost only real problems. Another benefit is that it is possible
to add support for verbatim and similar environments. A few bugfixes and
enhancements are added, too. The drawback is that we have more calls of
Parser::skip_spaces() now, but some of them will go with the implementation
of Jean-Marcs suggestion to handle \command and
\begin{command}...\end{command} by the same code. Also some comments are
still dropped, but we issue a warning now.
See the Changelog and comments in the source for more details.
For whose who want to test: The attached Userguide.diff removes some
occurences of bug # 1428 from the Userguide.
Comments?
Georg
--- UserGuide.lyx 2003-07-30 13:42:44.000000000 +0200
+++ UserGuide-corrected.lyx 2003-11-01 22:16:51.000000000 +0100
@@ -986,11 +986,7 @@
\emph on
Single click
\emph default
-the
-\emph on
-
-\emph default
-left mouse button to open or close any of these.
+the left mouse button to open or close any of these.
Also check the appropriate section of this manual for more details.
\end_deeper
\layout Enumerate
@@ -1003,11 +999,7 @@
\emph on
Single click
\emph default
- the right mouse button
-\emph on
-
-\emph default
-to open a dialog that will allow you to manipulate the table.
+ the right mouse button to open a dialog that will allow you to manipulate the table.
\end_deeper
\layout Subsection
@@ -2115,7 +2107,7 @@
PostScript® is a registered trademark of Adobe Systems Incorporated, and
is the main page description language in the UN*X world.
-
+
\end_inset
format.
@@ -6324,7 +6316,7 @@
the body of the item text.
The body of the text has a larger left margin, which is equal to the default
label width plus a little extra space.
-
+
\layout List
\labelwidthstring MMMMMM
@@ -7720,7 +7712,7 @@
\family sans
Section
\family default
-
+
\layout Itemize
@@ -7737,7 +7729,7 @@
\family sans
Paragraph
\family default
-
+
\layout Itemize
@@ -8646,7 +8638,7 @@
\labelwidthstring MMM
#2-b Back to level #2.
-
+
\end_deeper
\layout List
\labelwidthstring MMM
@@ -9163,7 +9155,7 @@
Verse
\family default
environment.
-
+
\layout Quotation
We're now ending the
@@ -9901,10 +9893,8 @@
Caps
\family default
-\shape smallcaps
-This is the Small caps font shape
-\shape default
\noun on
+This is the Small caps font shape
.
\end_deeper
\layout List
@@ -10383,11 +10373,7 @@
No\SpecialChar ~
color
\family default
-, which
-\family sans
-
-\family default
-is the standard
+, which is the standard
\begin_inset Quotes eld
\end_inset
@@ -10577,7 +10563,7 @@
\end_inset
.
-
+
\layout Enumerate
Next, LaTeX uses the commands in the
@@ -12954,7 +12940,7 @@
\family default
manually.
But this is annoying.
-
+
\end_inset
This way you have the full PostScript® and LaTeX power combined except
@@ -15509,8 +15495,6 @@
\family default
example file to see how this works.
-\emph on
-
\layout Standard
The check box in the long table options can be used to specify specific
@@ -15787,7 +15771,7 @@
\end_inset
-
+
\layout Section
Table of Contents and other Listings
@@ -17432,9 +17416,7 @@
\begin_inset Formula $\alpha$
\end_inset
- by typing the following keys: First type
-\family typewriter
-
+ by typing the following keys: First type
\family sans
M-c\SpecialChar ~
m
@@ -17471,7 +17453,7 @@
\end_inset
was right there on the screen.
-
+
\layout Standard
The
@@ -19578,10 +19560,7 @@
\layout Standard
So in general there is no need to use the option described below, and we
- recommend not using it until the text is
-\emph on
-
-\emph default
+ recommend not using it until the text is
finished, and until you have checked in the preview to see if you
\emph on
really
@@ -19643,7 +19622,7 @@
A good documentation should weight no more than 1
\newline
kg.
-
+
\layout Standard
Obviously, it would be a good thing to put a protected blank between
@@ -24769,7 +24748,7 @@
\begin_deeper
\layout Itemize
-math mode
+math mode
\layout Itemize
tables
@@ -24900,7 +24879,7 @@
\begin_deeper
\layout Itemize
-manual fine-tuning
+manual fine-tuning
\layout Itemize
using LaTeX from within LyX
? tex2lyx-space.diff
? lib/lyx2lyx/green.lyx
? lib/lyx2lyx/lyx225to221.sh
? lib/lyx2lyx/lyx2lyx-g
? lib/lyx2lyx/lyxconvert_221-g.py
? lib/lyx2lyx/lyxconvert_222.py
? lib/lyx2lyx/lyxconvert_222to221.py
? lib/lyx2lyx/lyxconvert_223to222.py
? lib/lyx2lyx/lyxconvert_224to223.py
? lib/lyx2lyx/lyxconvert_225to224.py
? lib/lyx2lyx/t.fig
? lib/lyx2lyx/text-1.3.lyx
? lib/lyx2lyx/text-1.4.lyx
? lib/lyx2lyx/text-224.lyx
? lib/lyx2lyx/text.lyx
? lib/lyx2lyx/textm-1.4.lyx
? lib/lyx2lyx/textm-221.lyx
? lib/lyx2lyx/textm-222.lyx
? lib/lyx2lyx/textm-223.lyx
? lib/lyx2lyx/textm-224.lyx
? lib/lyx2lyx/xx.lyx
? src/forms.h
? src/tex2lyx-new
? src/tex2lyx-orig
? src/frontends/xforms/forms.h
? src/tex2lyx/UserGuide-1.4-orig.lyx
? src/tex2lyx/UserGuide-1.4-orig.tex
? src/tex2lyx/UserGuide-1.4-orig.toc
? src/tex2lyx/UserGuide-1.4-t2l-lyx.lyx
? src/tex2lyx/UserGuide-1.4-t2l-lyx.tex
? src/tex2lyx/UserGuide-1.4-t2l.lyx
? src/tex2lyx/UserGuide-1.4-t2l.tex
? src/tex2lyx/UserGuide-1.4-t2l.toc
? src/tex2lyx/UserGuide-corrected-1.4-t2l.aux
? src/tex2lyx/UserGuide-corrected-1.4-t2l.dvi
? src/tex2lyx/UserGuide-corrected-1.4-t2l.log
? src/tex2lyx/UserGuide-corrected-1.4-t2l.lyx
? src/tex2lyx/UserGuide-corrected-1.4-t2l.ps
? src/tex2lyx/UserGuide-corrected-1.4-t2l.tex
? src/tex2lyx/UserGuide-corrected-1.4-t2l.toc
? src/tex2lyx/UserGuide-corrected-1.4.aux
? src/tex2lyx/UserGuide-corrected-1.4.dvi
? src/tex2lyx/UserGuide-corrected-1.4.log
? src/tex2lyx/UserGuide-corrected-1.4.lyx
? src/tex2lyx/UserGuide-corrected-1.4.ps
? src/tex2lyx/UserGuide-corrected-1.4.tex
? src/tex2lyx/UserGuide-corrected-1.4.toc
? src/tex2lyx/UserGuide-corrected.lyx
? src/tex2lyx/UserGuide.diff
? src/tex2lyx/UserGuide.lyx
? src/tex2lyx/UserGuide.tex
? src/tex2lyx/convert.sh
? src/tex2lyx/escher-lsd.eps
? src/tex2lyx/lyx
? src/tex2lyx/mobius.eps
? src/tex2lyx/newfile1.lyx
? src/tex2lyx/platypus.eps
? src/tex2lyx/t.diff
Index: lib/symbols
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/symbols,v
retrieving revision 1.44
diff -u -r1.44 symbols
--- lib/symbols 2003/10/13 09:50:08 1.44
+++ lib/symbols 2003/11/03 09:31:29
@@ -120,6 +120,8 @@
parbox parbox none
protect protect none
mbox mbox forcetext
+# this is not perfect, a real inset would be better
+intertext mbox forcetext
newcommand newcommand none
label label none
left left none
Index: lib/reLyX/syntax.default
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/reLyX/syntax.default,v
retrieving revision 1.7
diff -u -r1.7 syntax.default
--- lib/reLyX/syntax.default 2003/02/11 13:32:13 1.7
+++ lib/reLyX/syntax.default 2003/11/03 09:31:34
@@ -661,6 +661,7 @@
% the whole document will be copied in TeX mode!
slide
titlepage
+psfrags
\end{reLyXre}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Index: po/POTFILES.in
===================================================================
RCS file: /cvs/lyx/lyx-devel/po/POTFILES.in,v
retrieving revision 1.364
diff -u -r1.364 POTFILES.in
--- po/POTFILES.in 2003/10/29 13:24:53 1.364
+++ po/POTFILES.in 2003/11/03 09:31:34
@@ -195,6 +195,7 @@
src/paragraph_funcs.C
src/rowpainter.C
src/support/path_defines.C
+src/tex2lyx-new/lengthcommon.C
src/text.C
src/text2.C
src/text3.C
Index: src/lyxfunc.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/lyxfunc.C,v
retrieving revision 1.530
diff -u -r1.530 lyxfunc.C
--- src/lyxfunc.C 2003/11/01 15:45:14 1.530
+++ src/lyxfunc.C 2003/11/03 09:31:39
@@ -1521,10 +1521,15 @@
setMessage(N_("Opening child document ") +
MakeDisplayPath(filename) + "...");
view()->savePosition(0);
+ string const parentfilename = owner->buffer()->fileName();
if (bufferlist.exists(filename))
view()->buffer(bufferlist.getBuffer(filename));
else
view()->loadLyXFile(filename);
+ // Set the parent name of the child document.
+ // This makes insertion of citations and references in the child work,
+ // when the target is in the parent or another child document.
+ owner->buffer()->setParentName(parentfilename);
break;
}
Index: src/insets/insetminipage.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/insetminipage.C,v
retrieving revision 1.102
diff -u -r1.102 insetminipage.C
--- src/insets/insetminipage.C 2003/11/01 15:45:16 1.102
+++ src/insets/insetminipage.C 2003/11/03 09:31:44
@@ -107,6 +107,8 @@
params_.pos = params.pos;
params_.width = params.width;
+ params_.inner_pos = params.inner_pos;
+ params_.height = params.height;
/* FIXME: I refuse to believe we have to live
* with ugliness like this ... */
@@ -256,8 +258,30 @@
s_pos += 'b';
break;
}
- os << "\\begin{minipage}[" << s_pos << "]{"
- << params_.width.asLatexString() << "}%\n";
+ string s_inner_pos;
+ switch (params_.inner_pos) {
+ case inner_top:
+ s_inner_pos += 't';
+ break;
+ case inner_center:
+ s_inner_pos += 'c';
+ break;
+ case inner_bottom:
+ s_inner_pos += 'b';
+ break;
+ case inner_stretch:
+ s_inner_pos += 's';
+ break;
+ }
+ os << "\\begin{minipage}[" << s_pos << "]";
+ if(params_.height.value() != 0) {
+ // 0 was the default value before the height was accessible
+ os << '[' << params_.height.asLatexString() << ']';
+ if(params_.inner_pos != inner_center)
+ // inner_center was the default value before inner_pos was
accessible
+ os << '[' << s_inner_pos << ']';
+ }
+ os << '{' << params_.width.asLatexString() << "}%\n";
int i = inset.latex(buf, os, runparams);
Index: src/mathed/math_gridinset.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/mathed/math_gridinset.C,v
retrieving revision 1.131
diff -u -r1.131 math_gridinset.C
--- src/mathed/math_gridinset.C 2003/11/01 15:45:19 1.131
+++ src/mathed/math_gridinset.C 2003/11/03 09:31:47
@@ -217,6 +217,24 @@
colinfo_[col].align_ = c;
++col;
colinfo_[col].lines_ = 0;
+ } else if (c == '@' && it + 1 != hh.end() && *(it + 1) == '{') {
+ lyxerr << "unknown column separator: '" << c;
+ int brace_open = 0, brace_close = 0;
+ for (++it; it != hh.end(); ++it) {
+ c = *it;
+ if(c == '{') {
+ ++brace_open;
+ } else if(c == '}') {
+ ++brace_close;
+ }
+ lyxerr << c;
+ if(brace_open > 0 && brace_open == brace_close) {
+ ++it;
+ break;
+ }
+ }
+ --it;
+ lyxerr << "'\n";
} else {
lyxerr << "unknown column separator: '" << c << "'" << endl;
}
Index: src/tex2lyx/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/ChangeLog,v
retrieving revision 1.40
diff -u -r1.40 ChangeLog
--- src/tex2lyx/ChangeLog 2003/10/23 11:46:33 1.40
+++ src/tex2lyx/ChangeLog 2003/11/03 09:31:49
@@ -1,3 +1,27 @@
+2003-11-03 Georg Baum <[EMAIL PROTECTED]>
+
+ * math.C:
+ * table.C:
+ * text.C:
+ * context.[Ch]: New functions Context::set_item(),
+ Context::new_paragraph(ostream & os) and Context::atParagraphStart()
+ to make Context usage more explicit
+ * texparser.[Ch]: Rework Parser::tokenize (see comment in texparser.h)
+ * table.C:
+ * math.C:
+ * texparser.C: Don't silently drop comments
+ * texparser.C: Token::asInput() does not append a space anymore
+ * texparser.[Ch]: Renamed Parser::prev_token() to Parser::curr_token().
+ New function Parser::prev_token() returns now really the previous token
+ * Context.[Ch]:
+ * text.C: Convert known vspaces at paragraph start to \\added_space_top
+ * preamble.C: Don't put out newlines twice.
+ * text.C: Fix minipage position bug
+ * text.C: Fix \labelwidthstring bug
+ * text.C: Recognize alignment environments
+ * text.C: Fix a few cases of incorrect context usage, resulting
+ in missing or superflous \begin_layout / \end_laout lines.
+
2003-10-23 Georg Baum <[EMAIL PROTECTED]>
* math.C:
Index: src/tex2lyx/context.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/context.C,v
retrieving revision 1.7
diff -u -r1.7 context.C
--- src/tex2lyx/context.C 2003/10/06 15:43:21 1.7
+++ src/tex2lyx/context.C 2003/11/03 09:31:49
@@ -23,7 +23,7 @@
void begin_layout(ostream & os, LyXLayout_ptr layout)
{
- os << "\n\\begin_layout " << layout->name() << "\n\n";
+ os << "\n\\begin_layout " << layout->name() << "\n";
}
@@ -94,11 +94,12 @@
begin_layout(os, layout);
need_layout=false;
need_end_layout = true;
- if (!extra_stuff.empty()) {
- os << extra_stuff;
- extra_stuff.erase();
- }
}
+ if (!extra_stuff.empty()) {
+ os << extra_stuff;
+ extra_stuff.erase();
+ }
+ os << "\n";
}
}
@@ -140,6 +141,20 @@
}
+void Context::set_item()
+{
+ need_layout = true;
+ has_item = true;
+}
+
+
+void Context::new_paragraph(ostream & os)
+{
+ check_end_layout(os);
+ need_layout = true;
+}
+
+
void Context::dump(ostream & os, string const & desc) const
{
os << "\n" << desc <<" [";
@@ -147,6 +162,12 @@
os << "need_layout ";
if (need_end_layout)
os << "need_end_layout ";
+ if (need_end_deeper)
+ os << "need_end_deeper ";
+ if (has_item)
+ os << "has_item ";
+ if (deeper_paragraph)
+ os << "deeper_paragraph ";
if (!extra_stuff.empty())
os << "extrastuff=[" << extra_stuff << "] ";
os << "layout=" << layout->name();
Index: src/tex2lyx/context.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/context.h,v
retrieving revision 1.7
diff -u -r1.7 context.h
--- src/tex2lyx/context.h 2003/09/09 18:27:24 1.7
+++ src/tex2lyx/context.h 2003/11/03 09:31:49
@@ -37,6 +37,15 @@
// description \c desc.
void dump(std::ostream &, std::string const & desc = "context") const;
+ /// Are we just beginning a new paragraph?
+ bool atParagraphStart() const { return need_layout; }
+
+ /// Begin an item in a list environment
+ void set_item();
+
+ /// Start a new paragraph
+ void new_paragraph(std::ostream & os);
+
// Do we need to output some \begin_layout command before the
// next characters?
bool need_layout;
Index: src/tex2lyx/math.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/math.C,v
retrieving revision 1.11
diff -u -r1.11 math.C
--- src/tex2lyx/math.C 2003/10/23 11:46:33 1.11
+++ src/tex2lyx/math.C 2003/11/03 09:31:50
@@ -99,8 +99,10 @@
}
}
+ else if (t.cat() == catSpace)
+ os << ' ';
+
else if (t.cat() == catLetter ||
- t.cat() == catSpace ||
t.cat() == catSuper ||
t.cat() == catSub ||
t.cat() == catOther ||
@@ -110,8 +112,7 @@
os << t.character();
else if (t.cat() == catNewline) {
- //if (p.next_token().cat() == catNewline) {
- // p.get_token();
+ //if (t.cs.size() > 1) {
// handle_par(os);
//} else {
os << "\n "; // note the space
@@ -130,8 +131,13 @@
os << "unexpected '}' in math\n";
}
- else if (t.cat() == catComment)
- handle_comment(p);
+ else if (t.cat() == catComment) {
+ if (t.cs().size())
+ cerr << "Ignoring comment: " << t.asInput();
+ else
+ // "%\n" combination
+ p.skip_spaces();
+ }
//
// control sequences
Index: src/tex2lyx/preamble.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/preamble.C,v
retrieving revision 1.16
diff -u -r1.16 preamble.C
--- src/tex2lyx/preamble.C 2003/10/23 11:46:33 1.16
+++ src/tex2lyx/preamble.C 2003/11/03 09:31:50
@@ -176,6 +176,21 @@
h_preamble.str("");
}
+/*!
+ * Swallows up to \param number newlines.
+ * Swallows all newlines if \param number is 0.
+ */
+void swallow_newlines(Parser & p, ostream & os, size_t number)
+{
+ if (p.next_token().cat() != catNewline)
+ return;
+ Token const & t = p.get_token();
+ if (number == 0)
+ return;
+ for(size_t i = number; i < t.cs().size(); ++i)
+ os << '\n';
+}
+
} // anonymous namespace
LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & forceclass)
@@ -188,7 +203,7 @@
while (p.good()) {
Token const & t = p.get_token();
- if (t.cs() == "documentclass") {
+ if (t.cat() == catEscape && t.cs() == "documentclass") {
is_full_document = true;
break;
}
@@ -206,7 +221,6 @@
// cat codes
//
if (t.cat() == catLetter ||
- t.cat() == catSpace ||
t.cat() == catSuper ||
t.cat() == catSub ||
t.cat() == catOther ||
@@ -215,24 +229,28 @@
t.cat() == catBegin ||
t.cat() == catEnd ||
t.cat() == catAlign ||
- t.cat() == catNewline ||
t.cat() == catParameter)
h_preamble << t.character();
+ else if (t.cat() == catSpace || t.cat() == catNewline)
+ h_preamble << t.asInput();
+
else if (t.cat() == catComment)
- handle_comment(p);
+ h_preamble << t.asInput();
- else if (t.cs() == "pagestyle")
+ else if (t.cs() == "pagestyle") {
h_paperpagestyle = p.verbatim_item();
+ swallow_newlines(p, h_preamble, 1);
+ }
else if (t.cs() == "makeatletter") {
p.setCatCode('@', catLetter);
- h_preamble << "\\makeatletter\n";
+ h_preamble << "\\makeatletter";
}
else if (t.cs() == "makeatother") {
p.setCatCode('@', catOther);
- h_preamble << "\\makeatother\n";
+ h_preamble << "\\makeatother";
}
else if (t.cs() == "newcommand" || t.cs() == "renewcommand"
@@ -246,25 +264,27 @@
string const opts = p.getOpt();
string const body = p.verbatim_item();
// only non-lyxspecific stuff
- if (name != "\\noun "
- && name != "\\tabularnewline "
- && name != "\\LyX "
- && name != "\\lyxline "
- && name != "\\lyxaddress "
- && name != "\\lyxrightaddress "
- && name != "\\boldsymbol "
- && name != "\\lyxarrow ") {
+ if ( name != "\\noun"
+ && name != "\\tabularnewline"
+ && name != "\\LyX"
+ && name != "\\lyxline"
+ && name != "\\lyxaddress"
+ && name != "\\lyxrightaddress"
+ && name != "\\boldsymbol"
+ && name != "\\lyxarrow") {
ostringstream ss;
ss << '\\' << t.cs();
if (star)
ss << '*';
- ss << '{' << name << '}' << opts << '{' << body <<
"}\n";
+ ss << '{' << name << '}' << opts << '{' << body << "}";
h_preamble << ss.str();
/*
ostream & out = in_preamble ? h_preamble : os;
out << "\\" << t.cs() << "{" << name << "}"
- << opts << "{" << body << "}\n";
+ << opts << "{" << body << "}";
*/
+ } else {
+ swallow_newlines(p, h_preamble, 0);
}
}
@@ -276,6 +296,7 @@
h_quotes_language = h_language;
h_options = join(opts, ",");
h_textclass = p.getArg('{', '}');
+ swallow_newlines(p, h_preamble, 1);
}
else if (t.cs() == "usepackage") {
@@ -291,6 +312,7 @@
} else {
handle_package(name, options);
}
+ swallow_newlines(p, h_preamble, 1);
}
else if (t.cs() == "newenvironment") {
@@ -301,17 +323,18 @@
ss << p.getOpt();
ss << '{' << p.verbatim_item() << '}';
ss << '{' << p.verbatim_item() << '}';
- ss << '\n';
if (name != "lyxcode" && name != "lyxlist"
&& name != "lyxrightadress" && name !=
"lyxaddress")
h_preamble << ss.str();
+ else
+ swallow_newlines(p, h_preamble, 0);
}
else if (t.cs() == "def") {
string name = p.get_token().cs();
while (p.next_token().cat() != catBegin)
name += p.get_token().asString();
- h_preamble << "\\def\\" << name << '{' << p.verbatim_item() <<
"}\n";
+ h_preamble << "\\def\\" << name << '{' << p.verbatim_item() <<
"}";
}
else if (t.cs() == "newcolumntype") {
@@ -328,34 +351,36 @@
h_preamble << "\\newcolumntype{" << name << "}";
if (nargs)
h_preamble << "[" << nargs << "]";
- h_preamble << "{" << p.verbatim_item() << "}\n";
+ h_preamble << "{" << p.verbatim_item() << "}";
}
else if (t.cs() == "setcounter") {
string const name = p.getArg('{', '}');
string const content = p.getArg('{', '}');
- if (name == "secnumdepth")
+ if (name == "secnumdepth") {
h_secnumdepth = content;
- else if (name == "tocdepth")
+ swallow_newlines(p, h_preamble, 1);
+ } else if (name == "tocdepth") {
h_tocdepth = content;
- else
- h_preamble << "\\setcounter{" << name << "}{" <<
content << "}\n";
+ swallow_newlines(p, h_preamble, 1);
+ } else
+ h_preamble << "\\setcounter{" << name << "}{" <<
content << "}";
}
else if (t.cs() == "setlength") {
string const name = p.verbatim_item();
string const content = p.verbatim_item();
- if (name == "parskip")
+ // Is this correct?
+ if (name == "parskip") {
h_paragraph_separation = "skip";
- else if (name == "parindent")
+ swallow_newlines(p, h_preamble, 1);
+ } else if (name == "parindent") {
h_paragraph_separation = "skip";
- else
- h_preamble << "\\setlength{" << name << "}{" <<
content << "}\n";
+ swallow_newlines(p, h_preamble, 1);
+ } else
+ h_preamble << "\\setlength{" << name << "}{" <<
content << "}";
}
- else if (t.cs() == "par")
- h_preamble << '\n';
-
else if (t.cs() == "begin") {
string const name = p.getArg('{', '}');
if (name == "document")
@@ -364,8 +389,9 @@
}
else if (t.cs().size())
- h_preamble << '\\' << t.cs() << ' ';
+ h_preamble << '\\' << t.cs();
}
+ p.skip_spaces();
// Force textclass if the user wanted it
if (forceclass.size()) {
Index: src/tex2lyx/table.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/table.C,v
retrieving revision 1.22
diff -u -r1.22 table.C
--- src/tex2lyx/table.C 2003/10/29 19:19:27 1.22
+++ src/tex2lyx/table.C 2003/11/03 09:31:52
@@ -192,13 +192,14 @@
}
}
+ else if (t.cat() == catSpace || t.cat() == catNewline)
+ os << t.cs();
+
else if (t.cat() == catLetter ||
- t.cat() == catSpace ||
t.cat() == catSuper ||
t.cat() == catSub ||
t.cat() == catOther ||
t.cat() == catActive ||
- t.cat() == catNewline ||
t.cat() == catParameter)
os << t.character();
@@ -216,6 +217,7 @@
else if (t.cat() == catAlign) {
os << TAB;
+ p.skip_spaces();
}
else if (t.cs() == "tabularnewline" || t.cs() == "\\") {
@@ -232,7 +234,7 @@
hlines += "\\cline{" + p.verbatim_item() + '}';
else if (t.cat() == catComment)
- handle_comment(p);
+ os << t.asInput();
else if (t.cs() == "(") {
os << "\\(";
Index: src/tex2lyx/tex2lyx.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/tex2lyx.C,v
retrieving revision 1.52
diff -u -r1.52 tex2lyx.C
--- src/tex2lyx/tex2lyx.C 2003/10/23 11:46:33 1.52
+++ src/tex2lyx/tex2lyx.C 2003/11/03 09:31:52
@@ -52,19 +52,6 @@
// Hacks to allow the thing to link in the lyxlayout stuff
LyXErr lyxerr(std::cerr.rdbuf());
-void handle_comment(Parser & p)
-{
- string s;
- while (p.good()) {
- Token const & t = p.get_token();
- if (t.cat() == catNewline)
- break;
- s += t.asString();
- }
- //cerr << "comment: " << s << "\n";
- p.skip_spaces();
-}
-
string const trim(string const & a, char const * p)
{
@@ -238,6 +225,13 @@
active_environments.pop_back();
ss.seekg(0);
os << ss.str();
+#ifdef TEST_PARSER
+ p.reset();
+ ofstream parsertest("parsertest.tex");
+ while (p.good())
+ parsertest << p.get_token().asInput();
+ // <origfile> and parsertest.tex should now have identical content
+#endif
}
Index: src/tex2lyx/tex2lyx.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/tex2lyx.h,v
retrieving revision 1.11
diff -u -r1.11 tex2lyx.h
--- src/tex2lyx/tex2lyx.h 2003/10/23 11:46:33 1.11
+++ src/tex2lyx/tex2lyx.h 2003/11/03 09:31:52
@@ -46,7 +46,6 @@
/// in tex2lyx.C
-void handle_comment(Parser & p);
std::string const trim(std::string const & a, char const * p = " \t\n\r");
void split(std::string const & s, std::vector<std::string> & result,
Index: src/tex2lyx/texparser.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/texparser.C,v
retrieving revision 1.22
diff -u -r1.22 texparser.C
--- src/tex2lyx/texparser.C 2003/10/23 11:46:33 1.22
+++ src/tex2lyx/texparser.C 2003/11/03 09:31:53
@@ -28,17 +28,6 @@
CatCode theCatcode[256];
-void skipSpaceTokens(istream & is, char c)
-{
- // skip trailing spaces
- while (catcode(c) == catSpace || catcode(c) == catNewline)
- if (!is.get(c))
- break;
- //cerr << "putting back: " << c << "\n";
- is.putback(c);
-}
-
-
void catInit()
{
fill(theCatcode, theCatcode + 256, catOther);
@@ -95,12 +84,16 @@
ostream & operator<<(ostream & os, Token const & t)
{
- if (t.cs().size())
+ if (t.cat() == catComment)
+ os << '%' << t.cs() << '\n';
+ else if (t.cat() == catSpace)
+ os << t.cs();
+ else if (t.cat() == catEscape)
os << '\\' << t.cs() << ' ';
else if (t.cat() == catLetter)
os << t.character();
else if (t.cat() == catNewline)
- os << "[\\n," << t.cat() << "]\n";
+ os << "[" << t.cs().size() << "\\n," << t.cat() << "]\n";
else
os << '[' << t.character() << ',' << t.cat() << ']';
return os;
@@ -115,7 +108,11 @@
string Token::asInput() const
{
- return char_ ? string(1, char_) : '\\' + cs_ + ' ';
+ if (cat_ == catComment)
+ return '%' + cs_ + '\n';
+ if (cat_ == catSpace || cat_ == catNewline)
+ return cs_;
+ return char_ ? string(1, char_) : '\\' + cs_;
}
@@ -154,6 +151,13 @@
Token const & Parser::prev_token() const
{
static const Token dummy;
+ return pos_ > 1 ? tokens_[pos_ - 2] : dummy;
+}
+
+
+Token const & Parser::curr_token() const
+{
+ static const Token dummy;
return pos_ > 0 ? tokens_[pos_ - 1] : dummy;
}
@@ -173,20 +177,41 @@
}
-void Parser::skip_spaces()
+void Parser::skip_spaces(bool skip_comments)
{
- while (1) {
- if (next_token().cat() == catSpace || next_token().cat() == catNewline)
+ // We just silently return if we have no more tokens.
+ // skip_spaces() should be callable at any time,
+ // the caller must check p::good() anyway.
+ while (good()) {
+ if ( next_token().cat() == catSpace ||
+ (next_token().cat() == catNewline && next_token().cs().size() ==
1) ||
+ next_token().cat() == catComment && next_token().cs().empty())
get_token();
- else if (next_token().cat() == catComment)
- while (next_token().cat() != catNewline)
- get_token();
+ else if (skip_comments && next_token().cat() == catComment)
+ cerr << " Ignoring comment: " << get_token().asInput();
else
break;
}
}
+void Parser::unskip_spaces(bool skip_comments)
+{
+ while (pos_ > 0) {
+ if ( curr_token().cat() == catSpace ||
+ (curr_token().cat() == catNewline && curr_token().cs().size() ==
1))
+ putback();
+ else if (skip_comments && curr_token().cat() == catComment) {
+ // TODO: Get rid of this
+ cerr << "Unignoring comment: " << curr_token().asInput();
+ putback();
+ }
+ else
+ break;
+ }
+}
+
+
void Parser::putback()
{
--pos_;
@@ -209,7 +234,12 @@
string Parser::getArg(char left, char right)
{
- skip_spaces();
+ skip_spaces(true);
+
+ // This is needed if a partial file ends with a command without arguments,
+ // e. g. \medskip
+ if (! good())
+ return string();
string result;
char c = getChar();
@@ -217,8 +247,17 @@
if (c != left)
putback();
else
- while ((c = getChar()) != right && good())
- result += c;
+ while ((c = getChar()) != right && good()) {
+ // Ignore comments
+ if (curr_token().cat() == catComment) {
+ if (curr_token().cs().size())
+ cerr << "Ignoring comment: " <<
curr_token().asInput();
+ }
+ else if (curr_token().cat() == catSpace || curr_token().cat()
== catNewline)
+ result += curr_token().cs();
+ else
+ result += c;
+ }
return result;
}
@@ -245,34 +284,39 @@
//cerr << "reading c: " << c << "\n";
switch (catcode(c)) {
+ case catSpace: {
+ string s(1, c);
+ while (is.get(c) && catcode(c) == catSpace)
+ s += c;
+ if (catcode(c) != catSpace)
+ is.putback(c);
+ push_back(Token(s, catSpace));
+ break;
+ }
+
case catNewline: {
++lineno_;
- is.get(c);
- if (catcode(c) == catNewline) {
- //do {
- is.get(c);
- //} while (catcode(c) == catNewline);
- push_back(Token("par"));
- } else {
- push_back(Token('\n', catNewline));
+ string s(1, c);
+ while (is.get(c) && catcode(c) == catNewline) {
+ ++lineno_;
+ s += c;
}
- is.putback(c);
+ if (catcode(c) != catNewline)
+ is.putback(c);
+ push_back(Token(s, catNewline));
break;
}
case catComment: {
- push_back(Token(c, catComment));
+ // We don't treat "%\n" combinations here specially
because
+ // we want to preserve them in the preamble
+ string s;
while (is.get(c) && catcode(c) != catNewline)
- push_back(Token(c, catLetter));
- push_back(Token(c, catNewline));
+ s += c;
+ // Note: The '%' at the beginning and the '\n' at the
end
+ // of the comment are not stored.
++lineno_;
- is.get(c);
- if (catcode(c) == catNewline) {
- push_back(Token("par"));
- ++lineno_;
- } else {
- is.putback(c);
- }
+ push_back(Token(s, catComment));
break;
}
@@ -286,18 +330,11 @@
// collect letters
while (is.get(c) && catcode(c) ==
catLetter)
s += c;
- skipSpaceTokens(is, c);
+ if (catcode(c) != catLetter)
+ is.putback(c);
}
- push_back(Token(s));
+ push_back(Token(s, catEscape));
}
- break;
- }
-
- case catSuper:
- case catSub: {
- push_back(Token(c, catcode(c)));
- is.get(c);
- skipSpaceTokens(is, c);
break;
}
Index: src/tex2lyx/texparser.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/texparser.h,v
retrieving revision 1.15
diff -u -r1.15 texparser.h
--- src/tex2lyx/texparser.h 2003/10/23 11:46:33 1.15
+++ src/tex2lyx/texparser.h 2003/11/03 09:31:53
@@ -75,7 +75,7 @@
///
Token(char c, CatCode cat) : cs_(), char_(c), cat_(cat) {}
///
- Token(std::string const & cs) : cs_(cs), char_(0), cat_(catIgnore) {}
+ Token(std::string const & cs, CatCode cat) : cs_(cs), char_(0), cat_(cat) {}
///
std::string const & cs() const { return cs_; }
@@ -100,9 +100,16 @@
std::ostream & operator<<(std::ostream & os, Token const & t);
-//
-// Actual parser class
-//
+/*!
+ * Actual parser class
+ *
+ * The parser parses every character of the inputstream into a token
+ * and classifies the token.
+ * The following transformations are done:
+ * - Consecutive spaces are combined into one single token with CatCode catSpace
+ * - Consecutive newlines are combined into one single token with CatCode catSpace
+ * - Comments and %\n combinations are parsed into one token with CatCode catComment
+ */
class Parser {
@@ -136,11 +143,15 @@
///
Token const & prev_token() const;
///
- Token const & next_token() const;
+ Token const & curr_token() const;
///
+ Token const & next_token() const;
+ /// Make the next token current and return that.
Token const & get_token();
- /// skips spaces if any
- void skip_spaces();
+ /// skips spaces (and comments if \param skip_comments is true)
+ void skip_spaces(bool skip_comments = false);
+ /// puts back spaces (and comments if \param skip_comments is true)
+ void unskip_spaces(bool skip_comments = false);
///
void lex(std::string const & s);
///
@@ -156,7 +167,7 @@
///
CatCode getCatCode(char c) const;
-//private:
+private:
///
int lineno_;
///
Index: src/tex2lyx/text.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/tex2lyx/text.C,v
retrieving revision 1.25
diff -u -r1.25 text.C
--- src/tex2lyx/text.C 2003/10/23 11:46:33 1.25
+++ src/tex2lyx/text.C 2003/11/03 09:31:58
@@ -170,8 +170,30 @@
}
-void handle_ert(ostream & os, string const & s, Context const & context)
+void handle_ert(ostream & os, string const & s, Context & context, bool check_layout
= true)
{
+ if (check_layout) {
+ // 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";
+ 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;
+ }
+ newcontext.check_end_layout(os);
+ end_inset(os);
+}
+
+
+void handle_comment(ostream & os, string const & s, Context & context)
+{
+ // TODO: Handle this better
Context newcontext(true, context.textclass);
begin_inset(os, "ERT");
os << "\nstatus Collapsed\n";
@@ -182,6 +204,8 @@
else
os << *it;
}
+ // make sure that our comment is the last thing on the line
+ os << "\n\\newline";
newcontext.check_end_layout(os);
end_inset(os);
}
@@ -217,10 +241,11 @@
context.check_deeper(os);
context.check_layout(os);
if (context.layout->optionalargs > 0) {
+ p.skip_spaces();
if (p.next_token().character() == '[') {
p.get_token(); // eat '['
begin_inset(os, "OptArg\n");
- os << "collapsed true\n";
+ os << "collapsed true\n\n";
parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
end_inset(os);
}
@@ -228,9 +253,57 @@
parse_text_snippet(p, os, FLAG_ITEM, outer, context);
context.check_end_layout(os);
context.check_end_deeper(os);
+ // 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);
}
+/*!
+ * Output a space if necessary.
+ * This function gets called for every whitespace token.
+ *
+ * We suppress as many spaces as possible. This has two effects:
+ * - Reimporting LyX generated LaTeX files changes almost no whitespace
+ * - Superflous whitespace from non LyX generated LaTeX files is removed.
+ *
+ * The consequence is that the logic inside the function is
+ * complicated, but that's the price...
+ *
+ * We have three cases here:
+ * - A space must be suppressed. Example: The lyxcode case below
+ * - A space may be suppressed. Example: Spaces before "\par"
+ * - A space must not be suppressed. Example: A space between two words
+ */
+void check_space(Parser const & p, ostream & os, Context & context)
+{
+ Token const next = p.next_token();
+ Token const curr = p.curr_token();
+ Token const prev = p.prev_token();
+ string const name = next.cs();
+ if (next.cat() == catSpace ||
+ next.cat() == catComment ||
+ (next.cat() == catNewline && next.cs().size() == 1) ||
+ next.cs() == "par" ||
+ next.cs() == "item" ||
+ (next.cs() == "end" && (context.layout->latextype ==
LATEX_ITEM_ENVIRONMENT ||
+ context.layout->latextype ==
LATEX_LIST_ENVIRONMENT ||
+ active_environment() == "quotation" ||
+ active_environment() == "quote" ||
+ active_environment() == "verse" ||
+ // LyX emits a newline before \end{lyxcode}.
+ // This newline must be ignored,
+ // otherwise LyX will add an additional protected
space.
+ (active_environment() == "lyxcode" && curr.cat()
== catNewline))) ||
+ // Or should we make a negative list? The alignment environments like
center would be included
+ prev.cs() == "]" ||
+ prev.cs() == "\\") {
+ return;
+ }
+ context.check_layout(os);
+ os << ' ';
+}
+
void parse_environment(Parser & p, ostream & os, bool outer,
Context & parent_context)
{
@@ -239,6 +312,8 @@
const bool is_starred = suffixIs(name, '*');
string const unstarred_name = rtrim(name, "*");
active_environments.push_back(name);
+ p.skip_spaces();
+
if (is_math_env(name)) {
parent_context.check_layout(os);
begin_inset(os, "Formula ");
@@ -262,13 +337,15 @@
os << "placement " << p.getArg('[', ']') << '\n';
}
os << "wide " << tostr(is_starred)
- << "\ncollapsed false\n";
+ << "\ncollapsed false\n\n";
parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
end_inset(os);
+ // 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);
}
else if (name == "minipage") {
- parent_context.check_layout(os);
string position = "1";
string inner_pos = "0";
string height = "0pt";
@@ -293,8 +370,8 @@
if (p.next_token().asInput() == "[") {
latex_inner_pos = p.getArg('[', ']');
switch(latex_inner_pos[0]) {
- case 't': inner_pos = "0"; break;
- case 'c': inner_pos = "1"; break;
+ 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:
@@ -318,11 +395,11 @@
ss << '[' << latex_inner_pos << ']';
ss << "{" << width << "}";
handle_ert(os, ss.str(), parent_context);
- parent_context.check_end_layout(os);
- parent_context.need_layout = true;
+ 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';
@@ -332,11 +409,27 @@
parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
end_inset(os);
}
-
}
- else if (name == "center") {
+ // Alignment settings
+ else if (name == "center" || name == "flushleft" || name == "flushright" ||
+ name == "centering" || name == "raggedright" || name == "raggedleft")
{
+ // We must begin a new paragraph if not already done
+ if (! parent_context.atParagraphStart()) {
+ parent_context.check_end_layout(os);
+ parent_context.new_paragraph(os);
+ }
+ if (name == "flushleft" || name == "raggedright")
+ parent_context.extra_stuff += "\\align left ";
+ else if (name == "flushright" || name == "raggedleft")
+ parent_context.extra_stuff += "\\align right ";
+ else
+ parent_context.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();
+ // We must begin a new paragraph to reset the alignment
+ parent_context.new_paragraph(os);
}
// The single '=' is meant here.
@@ -360,6 +453,7 @@
parse_text(p, os, FLAG_END, outer, context);
context.check_end_layout(os);
context.check_end_deeper(os);
+ parent_context.new_paragraph(os);
}
else if (name == "appendix") {
@@ -383,19 +477,20 @@
else if (name == "tabbing") {
// We need to remember that we have to handle '\=' specially
- parent_context.check_layout(os);
handle_ert(os, "\\begin{" + name + "}", parent_context);
parse_text_snippet(p, os, FLAG_END | FLAG_TABBING, outer,
parent_context);
handle_ert(os, "\\end{" + name + "}", parent_context);
}
else {
- 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);
}
+
active_environments.pop_back();
+ if (name != "math")
+ p.skip_spaces();
}
} // anonymous namespace
@@ -485,9 +580,10 @@
skip_braces(p);
}
+ else if (t.cat() == catSpace || (t.cat() == catNewline &&
t.cs().size() == 1))
+ check_space(p, os, context);
else if (t.cat() == catLetter ||
- t.cat() == catSpace ||
t.cat() == catOther ||
t.cat() == catAlign ||
t.cat() == catParameter) {
@@ -495,16 +591,9 @@
os << t.character();
}
- else if (t.cat() == catNewline) {
- if (p.next_token().cat() == catNewline) {
- // this should have been be done by
- // the parser already
- cerr << "what are we doing here?" << endl;
- p.get_token();
- context.need_layout = true;
- } else {
- os << " "; // note the space
- }
+ else if (t.cat() == catNewline || (t.cat() == catEscape && t.cs() ==
"par")) {
+ p.skip_spaces();
+ context.new_paragraph(os);
}
else if (t.cat() == catActive) {
@@ -519,20 +608,19 @@
}
else if (t.cat() == catBegin) {
-// FIXME???
// special handling of size changes
context.check_layout(os);
bool const is_size = is_known(p.next_token().cs(),
known_sizes);
- 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 {}``
+ Token const prev = p.prev_token();
+ string const s = parse_text(p, FLAG_BRACE_LAST, outer,
context);
+ if (s.empty() && (p.next_token().character() == '`' ||
+ (prev.character() == '-' &&
p.next_token().character())))
+ ; // ignore it in {}`` or -{}-
else if (is_size || s == "[" || s == "]" || s == "*")
os << s;
else {
- handle_ert(os, "{", context);
+ handle_ert(os, "{", context, false);
+ // s will end the current layout and begin a new one
if necessary
os << s;
handle_ert(os, "}", context);
}
@@ -540,15 +628,26 @@
else if (t.cat() == catEnd) {
if (flags & FLAG_BRACE_LAST) {
- context.check_end_layout(os);
return;
}
cerr << "stray '}' in text\n";
handle_ert(os, "}", context);
}
- else if (t.cat() == catComment)
- handle_comment(p);
+ else if (t.cat() == catComment) {
+ context.check_layout(os);
+ if (t.cs().size()) {
+ handle_comment(os, '%' + t.cs(), context);
+ if (p.next_token().cat() == catNewline) {
+ // A newline after a comment line starts a new
paragraph
+ context.new_paragraph(os);
+ p.skip_spaces();
+ }
+ } else {
+ // "%\n" combination
+ p.skip_spaces();
+ }
+ }
//
// control sequences
@@ -588,8 +687,7 @@
}
else if (t.cs() == "item") {
- // should be done automatically by Parser::tokenize
- //p.skip_spaces();
+ p.skip_spaces();
string s;
bool optarg = false;
if (p.next_token().character() == '[') {
@@ -598,11 +696,10 @@
s = parse_text(p, FLAG_BRACK_LAST, outer, newcontext);
optarg = true;
}
- context.need_layout = true;
- context.has_item = true;
+ context.set_item();
context.check_layout(os);
if (optarg) {
- if (active_environment() == "itemize") {
+ if (context.layout->labeltype != LABEL_MANUAL) {
// lyx does not support \item[\mybullet] in
itemize environments
handle_ert(os, "[", context);
os << s;
@@ -610,13 +707,13 @@
} else if (s.size()) {
// The space is needed to separate the item
from the rest of the sentence.
os << s << ' ';
+ p.skip_spaces();
}
}
}
else if (t.cs() == "bibitem") {
- context.need_layout = true;
- context.has_item = true;
+ context.set_item();
context.check_layout(os);
os << "\\bibitem ";
os << p.getOpt();
@@ -624,6 +721,7 @@
}
else if (t.cs() == "def") {
+ p.skip_spaces();
context.check_layout(os);
string name = p.get_token().cs();
while (p.next_token().cat() != catBegin)
@@ -631,20 +729,14 @@
handle_ert(os, "\\def\\" + name + '{' + p.verbatim_item() +
'}', context);
}
- else if (t.cs() == "par") {
+ else if (t.cs() == "noindent") {
p.skip_spaces();
- context.check_end_layout(os);
- context.need_layout = true;
+ context.extra_stuff += "\\noindent ";
}
else if (t.cs() == "appendix") {
- context.check_end_layout(os);
- Context newcontext(true, context.textclass, context.layout,
- context.layout);
- newcontext.check_layout(os);
- os << "\\start_of_appendix\n";
- parse_text(p, os, FLAG_END, outer, newcontext);
- newcontext.check_end_layout(os);
+ p.skip_spaces();
+ context.extra_stuff += "\\start_of_appendix ";
}
// Must attempt to parse "Section*" before "Section".
@@ -655,12 +747,14 @@
newlayout->isCommand()) {
p.get_token();
output_command_layout(os, p, outer, context, newlayout);
+ p.skip_spaces();
}
// The single '=' is meant here.
else if ((newlayout = findLayout(context.textclass, t.cs())).get() &&
newlayout->isCommand()) {
output_command_layout(os, p, outer, context, newlayout);
+ p.skip_spaces();
}
else if (t.cs() == "includegraphics") {
@@ -763,22 +857,25 @@
}
else if (t.cs() == "footnote") {
+ p.skip_spaces();
context.check_layout(os);
begin_inset(os, "Foot\n");
- os << "collapsed true\n";
+ os << "collapsed true\n\n";
parse_text_in_inset(p, os, FLAG_ITEM, false, context);
end_inset(os);
}
else if (t.cs() == "marginpar") {
+ p.skip_spaces();
context.check_layout(os);
begin_inset(os, "Marginal\n");
- os << "collapsed true\n";
+ os << "collapsed true\n\n";
parse_text_in_inset(p, os, FLAG_ITEM, false, context);
end_inset(os);
}
else if (t.cs() == "ensuremath") {
+ p.skip_spaces();
context.check_layout(os);
Context newcontext(false, context.textclass);
string s = parse_text(p, FLAG_ITEM, false, newcontext);
@@ -793,12 +890,16 @@
context.check_layout(os);
os << "\n\\hfill\n";
skip_braces(p);
+ p.skip_spaces();
}
- else if (t.cs() == "makeindex" || t.cs() == "maketitle")
+ else if (t.cs() == "makeindex" || t.cs() == "maketitle") {
+ p.skip_spaces();
skip_braces(p); // swallow this
+ }
else if (t.cs() == "tableofcontents") {
+ p.skip_spaces();
context.check_layout(os);
begin_inset(os, "LatexCommand \\tableofcontents\n");
end_inset(os);
@@ -806,6 +907,7 @@
}
else if (t.cs() == "listoffigures") {
+ p.skip_spaces();
context.check_layout(os);
begin_inset(os, "FloatList figure\n");
end_inset(os);
@@ -813,6 +915,7 @@
}
else if (t.cs() == "listoftables") {
+ p.skip_spaces();
context.check_layout(os);
begin_inset(os, "FloatList table\n");
end_inset(os);
@@ -820,6 +923,7 @@
}
else if (t.cs() == "listof") {
+ p.skip_spaces(true);
string const name = p.get_token().asString();
if (context.textclass.floats().typeExist(name)) {
context.check_layout(os);
@@ -906,6 +1010,7 @@
else if (is_known(t.cs(), known_quotes)) {
char const ** where = is_known(t.cs(), known_quotes);
+ context.check_layout(os);
begin_inset(os, "Quotes ");
os << known_coded_quotes[where - known_quotes];
end_inset(os);
@@ -916,6 +1021,7 @@
char const ** where = is_known(t.cs(), known_sizes);
context.check_layout(os);
os << "\n\\size " << known_coded_sizes[where - known_sizes] <<
"\n";
+ p.skip_spaces();
}
else if (t.cs() == "LyX" || t.cs() == "TeX"
@@ -1096,6 +1202,35 @@
end_inset(os);
}
+ else if ( t.cs() == "smallskip" ||
+ t.cs() == "medskip" ||
+ t.cs() == "bigskip" ||
+ t.cs() == "vfill" ||
+ (t.cs() == "vspace" && p.next_token().asInput() != "*")) {
+ string arg;
+ if (t.cs() == "vspace")
+ arg = p.getArg('{', '}');
+ else
+ arg = t.cs();
+ // We may only add the vspace to the current context if the
+ // current paragraph is not empty.
+ if (context.atParagraphStart()
+ && (p.next_token().cat() != catNewline ||
p.next_token().cs().size() == 1)
+ && (! (p.next_token().cat() == catEscape &&
p.next_token().cs() == "end"))
+ && (! (p.next_token().cat() == catEscape &&
p.next_token().cs() == "par"))) {
+ context.extra_stuff += "\\added_space_top " + arg + "
";
+ p.skip_spaces();
+ } else {
+ if (t.cs() == "vspace")
+ handle_ert(os, t.asInput() + '{' + arg + '}',
context);
+ else
+ handle_ert(os, t.asInput(), context);
+ }
+ // Would be nice to recognize added_space_bottom too...
+ // At the moment this is parsed as added_space_top of the
+ // next paragraph.
+ }
+
else if (t.cs() == "psfrag") {
// psfrag{ps-text}[ps-pos][tex-pos]{tex-text}
// TODO: Generalize this!
@@ -1103,7 +1238,6 @@
arguments += '}';
arguments += p.getOpt();
arguments += p.getOpt();
- p.skip_spaces();
handle_ert(os, "\\psfrag{" + arguments, context);
}
@@ -1122,7 +1256,13 @@
handle_ert(os, s + ' ', context);
*/
context.check_layout(os);
- handle_ert(os, t.asInput() + ' ', context);
+ string name = t.asInput();
+ if (p.next_token().asInput() == "*") {
+ // Starred commands like \vspace*{}
+ p.get_token(); // Eat '*'
+ name += '*';
+ }
+ handle_ert(os, name, context);
}
if (flags & FLAG_LEAVE) {