From c8d7cbd790463ff1a8789419f7d018a0235959cd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Thu, 17 Apr 2003 15:05:17 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6830 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/tex2lyx/preamble.C | 326 +++++++++++++++++++++++++++++++++++++++++ src/tex2lyx/tex2lyx.h | 39 +++++ 2 files changed, 365 insertions(+) create mode 100644 src/tex2lyx/preamble.C create mode 100644 src/tex2lyx/tex2lyx.h diff --git a/src/tex2lyx/preamble.C b/src/tex2lyx/preamble.C new file mode 100644 index 0000000000..e94968c8d4 --- /dev/null +++ b/src/tex2lyx/preamble.C @@ -0,0 +1,326 @@ +/** The .tex to .lyx converter + \author André Pönitz (2003) + */ + +// {[( + +#include + +#include "Lsstream.h" +#include "tex2lyx.h" + +#include +#include +#include +#include + +using std::cerr; +using std::endl; +using std::getline; +using std::istream; +using std::istringstream; +using std::ostream; +using std::ostringstream; +using std::string; +using std::vector; + + +namespace { + +const char * known_languages[] = { "austrian", "babel", "bahasa", "basque", +"breton", "british", "bulgarian", "catalan", "croatian", "czech", "danish", +"dutch", "english", "esperanto", "estonian", "finnish", "francais", +"frenchb", "galician", "german", "germanb", "greek", "hebcal", "hebfont", +"hebrew", "hebrew_newcode", "hebrew_oldcode", "hebrew_p", "hyphen", +"icelandic", "irish", "italian", "latin", "lgrcmr", "lgrcmro", "lgrcmss", +"lgrcmtt", "lgrenc", "lgrlcmss", "lgrlcmtt", "lheclas", "lhecmr", +"lhecmss", "lhecmtt", "lhecrml", "lheenc", "lhefr", "lheredis", "lheshold", +"lheshscr", "lheshstk", "lsorbian", "magyar", "naustrian", "ngermanb", +"ngerman", "norsk", "polish", "portuges", "rlbabel", "romanian", +"russianb", "samin", "scottish", "serbian", "slovak", "slovene", "spanish", +"swedish", "turkish", "ukraineb", "usorbian", "welsh", 0}; + +char const * known_fontsizes[] = { "10pt", "11pt", "12pt", 0 }; + +// some ugly stuff +ostringstream h_preamble; +string h_textclass = "article"; +string h_options = ""; +string h_language = "english"; +string h_inputencoding = "latin1"; +string h_fontscheme = "default"; +string h_graphics = "default"; +string h_paperfontsize = "default"; +string h_spacing = "single"; +string h_papersize = "default"; +string h_paperpackage = "default"; +string h_use_geometry = "0"; +string h_use_amsmath = "0"; +string h_use_natbib = "0"; +string h_use_numerical_citations = "0"; +string h_paperorientation = "portrait"; +string h_secnumdepth = "3"; +string h_tocdepth = "3"; +string h_paragraph_separation = "indent"; +string h_defskip = "medskip"; +string h_quotes_language = "english"; +string h_quotes_times = "2"; +string h_papercolumns = "1"; +string h_papersides = "1"; +string h_paperpagestyle = "default"; +string h_tracking_changes = "0"; + + +void handle_opt(vector & opts, char const ** what, string & target) +{ + if (opts.empty()) + return; + + for ( ; *what; ++what) { + vector::iterator it = find(opts.begin(), opts.end(), *what); + if (it != opts.end()) { + //cerr << "### found option '" << *what << "'\n"; + target = *what; + opts.erase(it); + return; + } + } +} + + +void handle_package(string const & name, string const & options) +{ + //cerr << "handle_package: '" << name << "'\n"; + if (name == "a4wide") { + h_papersize = "a4paper"; + h_paperpackage = "widemarginsa4"; + } else if (name == "ae") + h_fontscheme = "ae"; + else if (name == "aecompl") + h_fontscheme = "ae"; + else if (name == "amsmath") + h_use_amsmath = "1"; + else if (name == "amssymb") + h_use_amsmath = "1"; + else if (name == "babel") + ; // ignore this + else if (name == "fontenc") + ; // ignore this + else if (name == "inputenc") + h_inputencoding = options; + else if (name == "makeidx") + ; // ignore this + else if (name == "verbatim") + ; // ignore this + else if (is_known(name, known_languages)) { + h_language = name; + h_quotes_language = name; + } else { + if (options.size()) + h_preamble << "\\usepackage[" << options << "]{" << name << "}\n"; + else + h_preamble << "\\usepackage{" << name << "}\n"; + } +} + + + +void end_preamble(ostream & os) +{ + os << "# tex2lyx 0.0.2 created this file\n" + << "\\lyxformat 222\n" + << "\\textclass " << h_textclass << "\n" + << "\\begin_preamble\n" << h_preamble.str() << "\n\\end_preamble\n" + << "\\options " << h_options << "\n" + << "\\language " << h_language << "\n" + << "\\inputencoding " << h_inputencoding << "\n" + << "\\fontscheme " << h_fontscheme << "\n" + << "\\graphics " << h_graphics << "\n" + << "\\paperfontsize " << h_paperfontsize << "\n" + << "\\spacing " << h_spacing << "\n" + << "\\papersize " << h_papersize << "\n" + << "\\paperpackage " << h_paperpackage << "\n" + << "\\use_geometry " << h_use_geometry << "\n" + << "\\use_amsmath " << h_use_amsmath << "\n" + << "\\use_natbib " << h_use_natbib << "\n" + << "\\use_numerical_citations " << h_use_numerical_citations << "\n" + << "\\paperorientation " << h_paperorientation << "\n" + << "\\secnumdepth " << h_secnumdepth << "\n" + << "\\tocdepth " << h_tocdepth << "\n" + << "\\paragraph_separation " << h_paragraph_separation << "\n" + << "\\defskip " << h_defskip << "\n" + << "\\quotes_language " << h_quotes_language << "\n" + << "\\quotes_times " << h_quotes_times << "\n" + << "\\papercolumns " << h_papercolumns << "\n" + << "\\papersides " << h_papersides << "\n" + << "\\paperpagestyle " << h_paperpagestyle << "\n" + << "\\tracking_changes " << h_tracking_changes << "\n"; +} + + +} // anonymous namespace + +void parse_preamble(Parser & p, ostream & os) +{ + while (p.good()) { + Token const & t = p.getToken(); + +#ifdef FILEDEBUG + cerr << "t: " << t << " flags: " << flags << "\n"; + //cell->dump(); +#endif + + // + // cat codes + // + if (t.cat() == catLetter || + t.cat() == catSpace || + t.cat() == catSuper || + t.cat() == catSub || + t.cat() == catOther || + t.cat() == catMath || + t.cat() == catActive || + t.cat() == catBegin || + t.cat() == catEnd || + t.cat() == catAlign || + t.cat() == catNewline || + t.cat() == catParameter) + h_preamble << t.character(); + + else if (t.cat() == catComment) + handle_comment(p); + + else if (t.cs() == "pagestyle") + h_paperpagestyle == p.verbatimItem(); + + else if (t.cs() == "makeatletter") { + p.setCatCode('@', catLetter); + h_preamble << "\\makeatletter\n"; + } + + else if (t.cs() == "makeatother") { + p.setCatCode('@', catOther); + h_preamble << "\\makeatother\n"; + } + + else if (t.cs() == "newcommand" || t.cs() == "renewcommand" + || t.cs() == "providecommand") { + bool star = false; + if (p.nextToken().character() == '*') { + p.getToken(); + star = true; + } + string const name = p.verbatimItem(); + string const opts = p.getOpt(); + string const body = p.verbatimItem(); + // only non-lyxspecific stuff + 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"; + h_preamble << ss.str(); +/* + ostream & out = in_preamble ? h_preamble : os; + out << "\\" << t.cs() << "{" << name << "}" + << opts << "{" << body << "}\n"; +*/ + } + } + + else if (t.cs() == "documentclass") { + vector opts; + split(p.getArg('[', ']'), opts, ','); + handle_opt(opts, known_languages, h_language); + handle_opt(opts, known_fontsizes, h_paperfontsize); + h_quotes_language = h_language; + h_options = join(opts, ","); + h_textclass = p.getArg('{', '}'); + } + + else if (t.cs() == "usepackage") { + string const options = p.getArg('[', ']'); + string const name = p.getArg('{', '}'); + if (options.empty() && name.find(',')) { + vector vecnames; + split(name, vecnames, ','); + vector::const_iterator it = vecnames.begin(); + vector::const_iterator end = vecnames.end(); + for (; it != end; ++it) + handle_package(trim(*it), string()); + } else { + handle_package(name, options); + } + } + + else if (t.cs() == "newenvironment") { + string const name = p.getArg('{', '}'); + ostringstream ss; + ss << "\\newenvironment{" << name << "}"; + ss << p.getOpt(); + ss << p.getOpt(); + ss << '{' << p.verbatimItem() << '}'; + ss << '{' << p.verbatimItem() << '}'; + ss << '\n'; + if (name != "lyxcode" && name != "lyxlist" + && name != "lyxrightadress" && name != "lyxaddress") + h_preamble << ss.str(); + } + + else if (t.cs() == "def") { + string name = p.getToken().cs(); + while (p.nextToken().cat() != catBegin) + name += p.getToken().asString(); + h_preamble << "\\def\\" << name << '{' << p.verbatimItem() << "}\n"; + } + + else if (t.cs() == "setcounter") { + string const name = p.getArg('{', '}'); + string const content = p.getArg('{', '}'); + if (name == "secnumdepth") + h_secnumdepth = content; + else if (name == "tocdepth") + h_tocdepth = content; + else + h_preamble << "\\setcounter{" << name << "}{" << content << "}\n"; + } + + else if (t.cs() == "setlength") { + string const name = p.verbatimItem(); + string const content = p.verbatimItem(); + if (name == "parskip") + h_paragraph_separation = "skip"; + else if (name == "parindent") + h_paragraph_separation = "skip"; + else + h_preamble << "\\setlength{" + name + "}{" + content + "}\n"; + } + + else if (t.cs() == "par") + h_preamble << '\n'; + + else if (t.cs() == "begin") { + string const name = p.getArg('{', '}'); + if (name == "document") { + end_preamble(os); + os << "\n\n\\layout Standard\n\n"; + return; + } + h_preamble << "\\begin{" << name << "}"; + } + + else if (t.cs().size()) + h_preamble << '\\' << t.cs() << ' '; + } +} + + +// }]) diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h new file mode 100644 index 0000000000..9fcc175d4a --- /dev/null +++ b/src/tex2lyx/tex2lyx.h @@ -0,0 +1,39 @@ +#ifndef TEX2LYX_H +#define TEX2LYX_H + +#include "texparser.h" + +#include +#include +#include + + +void parse_preamble(Parser & p, std::ostream & os); + +void parse_text(Parser & p, std::ostream & os, unsigned flags, bool outer); + +void parse_table(Parser & p, std::ostream & os, unsigned flags); + +void parse_math(Parser & p, std::ostream & os, unsigned flags, mode_type mode); + +void handle_tabular(Parser & p, std::ostream & os); + +// Helper +std::string parse_text(Parser & p, unsigned flags, const bool outer); + +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 & result, char delim = ','); +std::string join(std::vector const & input, char const * delim); + +bool is_math_env(std::string const & name); +char const ** is_known(string const & str, char const ** what); + +// Access to environment stack +std::string curr_env(); +void active_environments_push(std::string const & name); +void active_environments_pop(); +bool active_environments_empty(); + +#endif -- 2.39.2