]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/Parser.cpp
InsetLine.cpp: remove unused include
[lyx.git] / src / tex2lyx / Parser.cpp
index 2c826fed4aec579698464544f5876977173c52f9..0b6bbe2db2c28f9838a4839ca16af5c26fd6cfc7 100644 (file)
@@ -3,17 +3,17 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author André Pönitz
+ * \author André Pönitz 
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include <config.h>
 
+#include "Encoding.h"
 #include "Parser.h"
 
 #include <iostream>
-#include <sstream>
 
 using namespace std;
 
@@ -25,6 +25,11 @@ CatCode theCatcode[256];
 
 void catInit()
 {
+       static bool init_done = false;
+       if (init_done) 
+               return;
+       init_done = true;
+
        fill(theCatcode, theCatcode + 256, catOther);
        fill(theCatcode + 'a', theCatcode + 'z' + 1, catLetter);
        fill(theCatcode + 'A', theCatcode + 'Z' + 1, catLetter);
@@ -49,13 +54,12 @@ void catInit()
        theCatcode[int('@')]  = catLetter;
 }
 
-
 /*!
  * Translate a line ending to '\n'.
  * \p c must have catcode catNewline, and it must be the last character read
  * from \p is.
  */
-char getNewline(istream & is, char c)
+char_type getNewline(idocstream & is, char_type c)
 {
        // we have to handle 3 different line endings:
        // - UNIX (\n)
@@ -63,9 +67,10 @@ char getNewline(istream & is, char c)
        // - DOS  (\r\n)
        if (c == '\r') {
                // MAC or DOS
-               if (is.get(c) && c != '\n') {
+               char_type wc;
+               if (is.get(wc) && wc != '\n') {
                        // MAC
-                       is.putback(c);
+                       is.putback(wc);
                }
                return '\n';
        }
@@ -73,18 +78,14 @@ char getNewline(istream & is, char c)
        return c;
 }
 
-}
-
-
-//
-// catcodes
-//
-
-CatCode catcode(unsigned char c)
+CatCode catcode(char_type c)
 {
-       return theCatcode[c];
+       if (c < 256)
+               return theCatcode[(unsigned char)c];
+       return catOther;
 }
 
+}
 
 
 //
@@ -100,28 +101,22 @@ ostream & operator<<(ostream & os, Token const & t)
        else if (t.cat() == catEscape)
                os << '\\' << t.cs() << ' ';
        else if (t.cat() == catLetter)
-               os << t.character();
+               os << t.cs();
        else if (t.cat() == catNewline)
                os << "[" << t.cs().size() << "\\n," << t.cat() << "]\n";
        else
-               os << '[' << t.character() << ',' << t.cat() << ']';
+               os << '[' << t.cs() << ',' << t.cat() << ']';
        return os;
 }
 
 
-string Token::asString() const
-{
-       return cs_.size() ? cs_ : string(1, char_);
-}
-
-
 string Token::asInput() const
 {
        if (cat_ == catComment)
                return '%' + cs_ + '\n';
-       if (cat_ == catSpace || cat_ == catNewline)
-               return cs_;
-       return char_ ? string(1, char_) : '\\' + cs_;
+       if (cat_ == catEscape)
+               return '\\' + cs_;
+       return cs_;
 }
 
 
@@ -130,55 +125,71 @@ string Token::asInput() const
 //
 
 
-Parser::Parser(istream & is)
-       : lineno_(0), pos_(0)
+Parser::Parser(idocstream & is)
+       : lineno_(0), pos_(0), iss_(0), is_(is), encoding_latex_("utf8")
 {
-       tokenize(is);
 }
 
 
 Parser::Parser(string const & s)
-       : lineno_(0), pos_(0)
+       : lineno_(0), pos_(0), 
+         iss_(new idocstringstream(from_utf8(s))), is_(*iss_), 
+         encoding_latex_("utf8")
 {
-       istringstream is(s);
-       tokenize(is);
 }
 
 
-void Parser::push_back(Token const & t)
+Parser::~Parser()
 {
-       tokens_.push_back(t);
+       delete iss_;
 }
 
 
-void Parser::pop_back()
+void Parser::setEncoding(std::string const & e)
 {
-       tokens_.pop_back();
+       Encoding const * enc = encodings.fromLaTeXName(e);
+       if (!enc) {
+               cerr << "Unknown encoding " << e << ". Ignoring." << std::endl;
+               return;
+       }
+       //cerr << "setting encoding to " << enc->iconvName() << std::endl;
+       is_ << lyx::setEncoding(enc->iconvName());
+       encoding_latex_ = e;
 }
 
 
-Token const & Parser::prev_token() const
+void Parser::push_back(Token const & t)
+{
+       tokens_.push_back(t);
+}
+
+
+// We return a copy here because the tokens_ vector may get reallocated
+Token const Parser::prev_token() const
 {
        static const Token dummy;
        return pos_ > 1 ? tokens_[pos_ - 2] : dummy;
 }
 
 
-Token const & Parser::curr_token() const
+// We return a copy here because the tokens_ vector may get reallocated
+Token const Parser::curr_token() const
 {
        static const Token dummy;
        return pos_ > 0 ? tokens_[pos_ - 1] : dummy;
 }
 
 
-Token const & Parser::next_token() const
+// We return a copy here because the tokens_ vector may get reallocated
+Token const Parser::next_token()
 {
        static const Token dummy;
        return good() ? tokens_[pos_] : dummy;
 }
 
 
-Token const & Parser::get_token()
+// We return a copy here because the tokens_ vector may get reallocated
+Token const Parser::get_token()
 {
        static const Token dummy;
        //cerr << "looking at token " << tokens_[pos_] << " pos: " << pos_ << '\n';
@@ -186,7 +197,7 @@ Token const & Parser::get_token()
 }
 
 
-bool Parser::isParagraph() const
+bool Parser::isParagraph()
 {
        // A new paragraph in TeX ist started
        // - either by a newline, following any amount of whitespace
@@ -252,8 +263,11 @@ void Parser::putback()
 }
 
 
-bool Parser::good() const
+bool Parser::good()
 {
+       if (pos_ < tokens_.size())
+               return true;
+       tokenize_one();
        return pos_ < tokens_.size();
 }
 
@@ -262,7 +276,7 @@ char Parser::getChar()
 {
        if (!good())
                error("The input stream is not well...");
-       return tokens_[pos_++].character();
+       return get_token().character();
 }
 
 
@@ -273,14 +287,14 @@ Parser::Arg Parser::getFullArg(char left, char right)
        // This is needed if a partial file ends with a command without arguments,
        // e. g. \medskip
        if (! good())
-               return std::make_pair(false, string());
+               return make_pair(false, string());
 
        string result;
        char c = getChar();
 
        if (c != left) {
                putback();
-               return std::make_pair(false, string());
+               return make_pair(false, string());
        } else
                while ((c = getChar()) != right && good()) {
                        // Ignore comments
@@ -292,7 +306,7 @@ Parser::Arg Parser::getFullArg(char left, char right)
                                result += curr_token().asInput();
                }
 
-       return std::make_pair(true, result);
+       return make_pair(true, result);
 }
 
 
@@ -307,7 +321,7 @@ string Parser::getFullOpt()
        Arg arg = getFullArg('[', ']');
        if (arg.first)
                return '[' + arg.second + ']';
-       return arg.second;
+       return string();
 }
 
 
@@ -318,6 +332,23 @@ string Parser::getOpt()
 }
 
 
+string Parser::getOptContent()
+// the same as getOpt but without the brackets
+{
+       string const res = getArg('[', ']');
+       return res.empty() ? string() : res;
+}
+
+
+string Parser::getFullParentheseArg()
+{
+       Arg arg = getFullArg('(', ')');
+       if (arg.first)
+               return '(' + arg.second + ')';
+       return string();
+}
+
+
 string const Parser::verbatimEnvironment(string const & name)
 {
        if (!good())
@@ -348,86 +379,80 @@ string const Parser::verbatimEnvironment(string const & name)
 }
 
 
-void Parser::tokenize(istream & is)
+void Parser::tokenize_one()
 {
-       static bool init_done = false;
+       catInit();
+       char_type c;
+       if (!is_.get(c)) 
+               return;
 
-       if (!init_done) {
-               catInit();
-               init_done = true;
+       switch (catcode(c)) {
+       case catSpace: {
+               docstring 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;
        }
-
-       char c;
-       while (is.get(c)) {
-               //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_;
-                               string s(1, getNewline(is, c));
-                               while (is.get(c) && catcode(c) == catNewline) {
-                                       ++lineno_;
-                                       s += getNewline(is, c);
-                               }
-                               if (catcode(c) != catNewline)
-                                       is.putback(c);
-                               push_back(Token(s, catNewline));
-                               break;
-                       }
-
-                       case 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)
+               
+       case catNewline: {
+               ++lineno_;
+               docstring s(1, getNewline(is_, c));
+               while (is_.get(c) && catcode(c) == catNewline) {
+                       ++lineno_;
+                       s += getNewline(is_, c);
+               }
+               if (catcode(c) != catNewline)
+                       is_.putback(c);
+               push_back(Token(s, catNewline));
+               break;
+       }
+               
+       case catComment: {
+               // We don't treat "%\n" combinations here specially because
+               // we want to preserve them in the preamble
+               docstring s;
+               while (is_.get(c) && catcode(c) != catNewline)
+                       s += c;
+               // handle possible DOS line ending
+               if (catcode(c) == catNewline)
+                       c = getNewline(is_, c);
+               // Note: The '%' at the beginning and the '\n' at the end
+               // of the comment are not stored.
+               ++lineno_;
+               push_back(Token(s, catComment));
+               break;
+       }
+               
+       case catEscape: {
+               is_.get(c);
+               if (!is_) {
+                       error("unexpected end of input");
+               } else {
+                       docstring s(1, c);
+                       if (catcode(c) == catLetter) {
+                               // collect letters
+                               while (is_.get(c) && catcode(c) == catLetter)
                                        s += c;
-                               // handle possible DOS line ending
-                               if (catcode(c) == catNewline)
-                                       c = getNewline(is, c);
-                               // Note: The '%' at the beginning and the '\n' at the end
-                               // of the comment are not stored.
-                               ++lineno_;
-                               push_back(Token(s, catComment));
-                               break;
+                               if (catcode(c) != catLetter)
+                                       is_.putback(c);
                        }
-
-                       case catEscape: {
-                               is.get(c);
-                               if (!is) {
-                                       error("unexpected end of input");
-                               } else {
-                                       string s(1, c);
-                                       if (catcode(c) == catLetter) {
-                                               // collect letters
-                                               while (is.get(c) && catcode(c) == catLetter)
-                                                       s += c;
-                                               if (catcode(c) != catLetter)
-                                                       is.putback(c);
-                                       }
-                                       push_back(Token(s, catEscape));
-                               }
-                               break;
-                       }
-
-                       case catIgnore: {
-                               cerr << "ignoring a char: " << int(c) << "\n";
-                               break;
-                       }
-
-                       default:
-                               push_back(Token(c, catcode(c)));
+                       push_back(Token(s, catEscape));
                }
+               break;
+       }
+               
+       case catIgnore: {
+               cerr << "ignoring a char: " << c << "\n";
+               break;
+       }
+               
+       default:
+               push_back(Token(docstring(1, c), catcode(c)));
        }
+       //cerr << tokens_.back();
 }
 
 
@@ -456,12 +481,12 @@ string Parser::verbatimOption()
        string res;
        if (next_token().character() == '[') {
                Token t = get_token();
-               for (Token t = get_token(); t.character() != ']' && good(); t = get_token()) {
+               for (t = get_token(); t.character() != ']' && good(); t = get_token()) {
                        if (t.cat() == catBegin) {
                                putback();
                                res += '{' + verbatim_item() + '}';
                        } else
-                               res += t.asString();
+                               res += t.cs();
                }
        }
        return res;