mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-26 06:15:16 +00:00
Georg's latest improvements
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8042 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
de36820a5a
commit
e096cc5104
@ -1,3 +1,27 @@
|
||||
2003-11-03 Georg Baum <Georg.Baum@post.rwth-aachen.de>
|
||||
|
||||
* 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 <Georg.Baum@post.rwth-aachen.de>
|
||||
|
||||
* math.C:
|
||||
@ -33,8 +57,6 @@
|
||||
- handle optional arg to \item as ERT in itemize environment, since LyX
|
||||
does not support it directly
|
||||
|
||||
|
||||
|
||||
2003-10-18 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* Makefile.am (BUILT_SOURCES): use this instead of "linked_files"
|
||||
|
@ -23,7 +23,7 @@ namespace {
|
||||
|
||||
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 @@ void Context::check_layout(ostream & os)
|
||||
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::check_end_deeper(ostream & os)
|
||||
}
|
||||
|
||||
|
||||
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 @@ void Context::dump(ostream & os, string const & desc) const
|
||||
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();
|
||||
|
@ -37,6 +37,15 @@ struct Context {
|
||||
// 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;
|
||||
|
@ -100,7 +100,6 @@ void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
|
||||
}
|
||||
|
||||
else if (t.cat() == catLetter ||
|
||||
t.cat() == catSpace ||
|
||||
t.cat() == catSuper ||
|
||||
t.cat() == catSub ||
|
||||
t.cat() == catOther ||
|
||||
@ -109,15 +108,6 @@ void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
|
||||
t.cat() == catParameter)
|
||||
os << t.character();
|
||||
|
||||
else if (t.cat() == catNewline) {
|
||||
//if (p.next_token().cat() == catNewline) {
|
||||
// p.get_token();
|
||||
// handle_par(os);
|
||||
//} else {
|
||||
os << "\n "; // note the space
|
||||
//}
|
||||
}
|
||||
|
||||
else if (t.cat() == catBegin) {
|
||||
os << '{';
|
||||
parse_math(p, os, FLAG_BRACE_LAST, mode);
|
||||
@ -130,8 +120,13 @@ void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
|
||||
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
|
||||
|
@ -188,7 +188,7 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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 +206,6 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
// cat codes
|
||||
//
|
||||
if (t.cat() == catLetter ||
|
||||
t.cat() == catSpace ||
|
||||
t.cat() == catSuper ||
|
||||
t.cat() == catSub ||
|
||||
t.cat() == catOther ||
|
||||
@ -215,24 +214,26 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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")
|
||||
h_paperpagestyle = p.verbatim_item();
|
||||
|
||||
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,24 +247,24 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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 << "}";
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -301,7 +302,6 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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();
|
||||
@ -311,7 +311,7 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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,7 +328,7 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
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") {
|
||||
@ -339,23 +339,21 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
else if (name == "tocdepth")
|
||||
h_tocdepth = content;
|
||||
else
|
||||
h_preamble << "\\setcounter{" << name << "}{" << content << "}\n";
|
||||
h_preamble << "\\setcounter{" << name << "}{" << content << "}";
|
||||
}
|
||||
|
||||
else if (t.cs() == "setlength") {
|
||||
string const name = p.verbatim_item();
|
||||
string const content = p.verbatim_item();
|
||||
// Is this correct?
|
||||
if (name == "parskip")
|
||||
h_paragraph_separation = "skip";
|
||||
else if (name == "parindent")
|
||||
h_paragraph_separation = "skip";
|
||||
else
|
||||
h_preamble << "\\setlength{" << name << "}{" << content << "}\n";
|
||||
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 +362,9 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
@ -192,13 +192,14 @@ void parse_table(Parser & p, ostream & os, unsigned flags)
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void parse_table(Parser & p, ostream & os, unsigned flags)
|
||||
|
||||
else if (t.cat() == catAlign) {
|
||||
os << TAB;
|
||||
p.skip_spaces();
|
||||
}
|
||||
|
||||
else if (t.cs() == "tabularnewline" || t.cs() == "\\") {
|
||||
@ -232,7 +234,7 @@ void parse_table(Parser & p, ostream & os, unsigned flags)
|
||||
hlines += "\\cline{" + p.verbatim_item() + '}';
|
||||
|
||||
else if (t.cat() == catComment)
|
||||
handle_comment(p);
|
||||
os << t.asInput();
|
||||
|
||||
else if (t.cs() == "(") {
|
||||
os << "\\(";
|
||||
|
@ -52,19 +52,6 @@ using lyx::support::IsFileWriteable;
|
||||
// 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 @@ void tex2lyx(std::istream &is, std::ostream &os)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,6 @@ void handle_tabular(Parser & p, std::ostream & os, Context & context);
|
||||
|
||||
|
||||
/// 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,
|
||||
|
@ -28,17 +28,6 @@ namespace {
|
||||
|
||||
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 @@ CatCode catcode(unsigned char c)
|
||||
|
||||
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::asString() const
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
|
||||
@ -152,6 +149,13 @@ void Parser::pop_back()
|
||||
|
||||
|
||||
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,14 +177,35 @@ Token const & Parser::get_token()
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@ -209,7 +234,12 @@ char Parser::getChar()
|
||||
|
||||
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 @@ string Parser::getArg(char left, char right)
|
||||
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 @@ void Parser::tokenize(istream & is)
|
||||
//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,21 +330,14 @@ void Parser::tokenize(istream & is)
|
||||
// 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;
|
||||
}
|
||||
|
||||
case catIgnore: {
|
||||
if (c != 13)
|
||||
cerr << "ignoring a char: " << int(c) << "\n";
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
///
|
||||
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 @@ private:
|
||||
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 catNewline
|
||||
* - Comments and %\n combinations are parsed into one token with CatCode catComment
|
||||
*/
|
||||
|
||||
class Parser {
|
||||
|
||||
@ -136,11 +143,15 @@ public:
|
||||
///
|
||||
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 @@ public:
|
||||
///
|
||||
CatCode getCatCode(char c) const;
|
||||
|
||||
//private:
|
||||
private:
|
||||
///
|
||||
int lineno_;
|
||||
///
|
||||
|
@ -170,8 +170,12 @@ void skip_braces(Parser & p)
|
||||
}
|
||||
|
||||
|
||||
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";
|
||||
@ -187,6 +191,26 @@ void handle_ert(ostream & os, string const & s, Context const & context)
|
||||
}
|
||||
|
||||
|
||||
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";
|
||||
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;
|
||||
}
|
||||
// make sure that our comment is the last thing on the line
|
||||
os << "\n\\newline";
|
||||
newcontext.check_end_layout(os);
|
||||
end_inset(os);
|
||||
}
|
||||
|
||||
|
||||
struct isLayout {
|
||||
isLayout(string const name) : name_(name) {}
|
||||
bool operator()(LyXLayout_ptr const & ptr) {
|
||||
@ -217,10 +241,11 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
|
||||
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,47 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
|
||||
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 have three cases here:
|
||||
* 1. A space must be suppressed. Example: The lyxcode case below
|
||||
* 2. A space may be suppressed. Example: Spaces before "\par"
|
||||
* 3. A space must not be suppressed. Example: A space between two words
|
||||
*
|
||||
* We currently handle only 1. and 3 and from 2. only the case of
|
||||
* spaces before newlines as a side effect.
|
||||
*
|
||||
* 2. could be used to 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 drawback is that the logic inside the function becomes
|
||||
* complicated, and that is the reason why it is not implemented.
|
||||
*/
|
||||
void check_space(Parser const & p, ostream & os, Context & context)
|
||||
{
|
||||
Token const next = p.next_token();
|
||||
Token const curr = p.curr_token();
|
||||
// A space before a single newline and vice versa must be ignored
|
||||
// LyX emits a newline before \end{lyxcode}.
|
||||
// This newline must be ignored,
|
||||
// otherwise LyX will add an additional protected space.
|
||||
if (next.cat() == catSpace ||
|
||||
next.cat() == catNewline ||
|
||||
(next.cs() == "end" && context.layout->free_spacing && curr.cat() == catNewline)) {
|
||||
return;
|
||||
}
|
||||
context.check_layout(os);
|
||||
os << ' ';
|
||||
}
|
||||
|
||||
void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
Context & parent_context)
|
||||
{
|
||||
@ -239,6 +302,8 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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 +327,15 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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 +360,8 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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 +385,11 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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 +399,27 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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.
|
||||
@ -349,9 +432,11 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
case LATEX_LIST_ENVIRONMENT:
|
||||
context.extra_stuff = "\\labelwidthstring "
|
||||
+ p.verbatim_item() + '\n';
|
||||
p.skip_spaces();
|
||||
break;
|
||||
case LATEX_BIB_ENVIRONMENT:
|
||||
p.verbatim_item(); // swallow next arg
|
||||
p.skip_spaces();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -360,6 +445,7 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
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 +469,20 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
||||
|
||||
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 +572,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +583,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +600,19 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
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 +620,26 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
|
||||
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 +679,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
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 +688,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +699,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
} 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 +713,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
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 +721,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +739,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +849,25 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
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 +882,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +899,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
else if (t.cs() == "listoffigures") {
|
||||
p.skip_spaces();
|
||||
context.check_layout(os);
|
||||
begin_inset(os, "FloatList figure\n");
|
||||
end_inset(os);
|
||||
@ -813,6 +907,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
else if (t.cs() == "listoftables") {
|
||||
p.skip_spaces();
|
||||
context.check_layout(os);
|
||||
begin_inset(os, "FloatList table\n");
|
||||
end_inset(os);
|
||||
@ -820,6 +915,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
}
|
||||
|
||||
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 +1002,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
|
||||
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 +1013,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +1194,35 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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 +1230,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
arguments += '}';
|
||||
arguments += p.getOpt();
|
||||
arguments += p.getOpt();
|
||||
p.skip_spaces();
|
||||
handle_ert(os, "\\psfrag{" + arguments, context);
|
||||
}
|
||||
|
||||
@ -1122,7 +1248,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user