X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2FParser.cpp;h=41ab92063c031a50b2a496d67dd75de963f039a6;hb=d3c63f97c4fce4e091277ced6c1829473c311231;hp=d7d3144b4b0013a10bfbe2407d7c93b07e1d7896;hpb=47b8ab14db71c6932ba5a8f159fc71a745792aca;p=lyx.git diff --git a/src/tex2lyx/Parser.cpp b/src/tex2lyx/Parser.cpp index d7d3144b4b..41ab92063c 100644 --- a/src/tex2lyx/Parser.cpp +++ b/src/tex2lyx/Parser.cpp @@ -12,7 +12,6 @@ #include "Encoding.h" #include "Parser.h" -#include "support/foreach.h" #include "support/lstrings.h" #include "support/textutils.h" @@ -114,15 +113,55 @@ void debugToken(std::ostream & os, Token const & t, unsigned int flags) #endif +// +// Wrapper +// + +void iparserdocstream::setEncoding(std::string const & e) +{ + is_ << lyx::setEncoding(e); +} + + +void iparserdocstream::putback(char_type c) +{ + s_ = c + s_; +} + + +void iparserdocstream::putback(docstring s) +{ + s_ = s + s_; +} + + +iparserdocstream & iparserdocstream::get(char_type &c) +{ + if (s_.empty()) + is_.get(c); + else { + //cerr << "unparsed: " << to_utf8(s_) <iconvName()); + return setEncoding(enc->iconvName()); } @@ -223,11 +264,17 @@ void Parser::setCatcodes(cat_type t) } -void Parser::setEncoding(std::string const & e) +bool Parser::setEncoding(std::string const & e) { //cerr << "setting encoding to " << e << std::endl; - is_.docstream() << lyx::setEncoding(e); encoding_iconv_ = e; + // If the encoding is fixed, we must not change the stream encoding + // (because the whole input uses that encoding, e.g. if it comes from + // the clipboard). We still need to track the original encoding in + // encoding_iconv_, so that the generated output is correct. + if (!fixed_enc_) + is_.setEncoding(e); + return true; } @@ -257,7 +304,11 @@ Token const Parser::curr_token() const Token const Parser::next_token() { static const Token dummy; - return good() ? tokens_[pos_] : dummy; + if (!good()) + return dummy; + if (pos_ >= tokens_.size()) + tokenize_one(); + return pos_ < tokens_.size() ? tokens_[pos_] : dummy; } @@ -265,12 +316,14 @@ Token const Parser::next_token() Token const Parser::next_next_token() { static const Token dummy; - // If good() has not been called after the last get_token() we need - // to tokenize two more tokens. - if (pos_ + 1 >= tokens_.size()) { + if (!good()) + return dummy; + // If tokenize_one() has not been called after the last get_token() we + // need to tokenize two more tokens. + if (pos_ >= tokens_.size()) tokenize_one(); + if (pos_ + 1 >= tokens_.size()) tokenize_one(); - } return pos_ + 1 < tokens_.size() ? tokens_[pos_ + 1] : dummy; } @@ -279,10 +332,16 @@ Token const Parser::next_next_token() Token const Parser::get_token() { static const Token dummy; - // if (good()) - // cerr << "looking at token " << tokens_[pos_] - // << " pos: " << pos_ << '\n'; - return good() ? tokens_[pos_++] : dummy; + if (!good()) + return dummy; + if (pos_ >= tokens_.size()) { + tokenize_one(); + if (pos_ >= tokens_.size()) + return dummy; + } + // cerr << "looking at token " << tokens_[pos_] + // << " pos: " << pos_ << '\n'; + return tokens_[pos_++]; } @@ -374,23 +433,23 @@ void Parser::popPosition() { pos_ = positions_.back(); positions_.pop_back(); + deparse(); } -bool Parser::good() +void Parser::dropPosition() { - if (pos_ < tokens_.size()) - return true; - tokenize_one(); - return pos_ < tokens_.size(); + positions_.pop_back(); } -char Parser::getChar() +bool Parser::good() { - if (!good()) - error("The input stream is not well..."); - return get_token().character(); + if (pos_ < tokens_.size()) + return true; + if (!is_.good()) + return false; + return is_.peek() != idocstream::traits_type::eof(); } @@ -443,7 +502,8 @@ Parser::Arg Parser::getFullArg(char left, char right, bool allow_escaping) putback(); return make_pair(false, string()); } else { - for (t = get_token(); good(); t = get_token()) { + while (good()) { + t = get_token(); // Ignore comments if (t.cat() == catComment) { if (!t.cs().empty()) @@ -578,11 +638,12 @@ string const Parser::plainCommand(char left, char right, string const & name) } -string const Parser::verbatimStuff(string const & end_string) +Parser::Arg Parser::verbatimStuff(string const & end_string, bool const allow_linebreak) { if (!good()) - return string(); + return Arg(false, string()); + pushPosition(); ostringstream oss; size_t match_index = 0; setCatcodes(VERBATIM_CATCODES); @@ -593,22 +654,38 @@ string const Parser::verbatimStuff(string const & end_string) match_index += t.asInput().length(); if (match_index >= end_string.length()) break; - } else if (match_index) { - oss << end_string.substr(0, match_index) << t.asInput(); - match_index = 0; - } else - oss << t.asInput(); + } else { + if (!allow_linebreak && t.asInput() == "\n") { + cerr << "unexpected end of input" << endl; + popPosition(); + setCatcodes(NORMAL_CATCODES); + return Arg(false, string()); + } + if (match_index) { + oss << end_string.substr(0, match_index) + << t.asInput(); + match_index = 0; + } else + oss << t.asInput(); + } } - setCatcodes(NORMAL_CATCODES); - if (!good()) + + if (!good()) { cerr << "unexpected end of input" << endl; - return oss.str(); + popPosition(); + setCatcodes(NORMAL_CATCODES); + return Arg(false, string()); + } + setCatcodes(NORMAL_CATCODES); + dropPosition(); + return Arg(true, oss.str()); } string const Parser::verbatimEnvironment(string const & name) { - string s = verbatimStuff("\\end{" + name + "}"); + //FIXME: do something if endstring is not found + string s = verbatimStuff("\\end{" + name + "}").second; // ignore one newline at beginning or end of string if (prefixIs(s, "\n")) s.erase(0,1); @@ -628,7 +705,7 @@ string Parser::verbatimOption() putback(); res += '{' + verbatim_item() + '}'; } else - res += t.cs(); + res += t.asInput(); } } return res;