From 425dfd3a247907eb3312ba5c2af6f4db372794b4 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Sun, 13 Aug 2006 09:46:28 +0000 Subject: [PATCH] Fix bug 2289 * src/tex2lyx/text.C (void parse_noweb): new, parse a noweb code chunck (void parse_text): handle noweb <>= and [[xxx]] constructs * src/tex2lyx/tex2lyx.[Ch]: new global variable noweb_mode and command line option to set it * src/tex2lyx/preamble.C (parse_preamble): prepend "literate-" to the textclass name in noweb mode * lib/configure.py (checkConverterEntries): fix literate -> lyx converter (checkConverterEntries): fix typo in latex -> sxw converter git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14635 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/configure.py | 11 ++---- src/tex2lyx/preamble.C | 6 ++- src/tex2lyx/tex2lyx.C | 12 ++++++ src/tex2lyx/tex2lyx.h | 2 + src/tex2lyx/text.C | 83 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 104 insertions(+), 10 deletions(-) diff --git a/lib/configure.py b/lib/configure.py index af20febd5e..641e0fbe0f 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -315,15 +315,12 @@ def checkConverterEntries(): os.environ["PATH"] = os.path.join('..', 'src', 'tex2lyx') + \ os.pathsep + path_orig - checkProg('a LaTeX -> LyX converter', ['tex2lyx -f $$i $$o', \ - 'tex2lyx' + version_suffix + ' -f $$i $$o' ], - rc_entry = [ r'\converter latex lyx "%%" ""' ]) + checkProg('a LaTeX/Noweb -> LyX converter', ['tex2lyx', 'tex2lyx' + version_suffix], + rc_entry = [r'''\converter latex lyx "%% -f $$i $$o" "" +\converter literate lyx "%% -n -f $$i $$o" ""''']) os.environ["PATH"] = path_orig - # - checkProg('a Noweb -> LyX converter', ['noweb2lyx' + version_suffix + ' $$i $$o'], path = ['./reLyX'], - rc_entry = [ r'\converter literate lyx "%%" ""' ]) # checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'], rc_entry = [ r'\converter literate latex "%%" ""' ]) @@ -340,7 +337,7 @@ def checkConverterEntries(): checkProg('an OpenOffice.org -> LaTeX converter', ['w2l -clean $$i'], rc_entry = [ r'\converter sxw latex "%%" ""' ]) # - checkProg('an LaTeX -> OpenOffice.org LaTeX converter', ['oolatex $$i', 'oolatex.sh $$i'], + checkProg('a LaTeX -> OpenOffice.org converter', ['oolatex $$i', 'oolatex.sh $$i'], rc_entry = [ r'\converter latex sxw "%%" "latex"' ]) # checkProg('a PS to PDF converter', ['ps2pdf13 $$i $$o'], diff --git a/src/tex2lyx/preamble.C b/src/tex2lyx/preamble.C index a68d279d57..738d4576c1 100644 --- a/src/tex2lyx/preamble.C +++ b/src/tex2lyx/preamble.C @@ -18,6 +18,7 @@ #include "lyxtextclass.h" #include "lyxlex.h" #include "support/filetools.h" +#include "support/lstrings.h" #include #include @@ -483,9 +484,10 @@ LyXTextClass const parse_preamble(Parser & p, ostream & os, string const & force p.skip_spaces(); // Force textclass if the user wanted it - if (!forceclass.empty()) { + if (!forceclass.empty()) h_textclass = forceclass; - } + if (noweb_mode && !lyx::support::prefixIs(h_textclass, "literate-")) + h_textclass.insert(0, "literate-"); string layoutfilename = libFileSearch("layouts", h_textclass, "layout"); if (layoutfilename.empty()) { cerr << "Error: Could not find layout file for textclass \"" << h_textclass << "\"." << endl; diff --git a/src/tex2lyx/tex2lyx.C b/src/tex2lyx/tex2lyx.C index 09dcf7cbbc..f37f9cd0d8 100644 --- a/src/tex2lyx/tex2lyx.C +++ b/src/tex2lyx/tex2lyx.C @@ -161,6 +161,9 @@ void add_known_command(string const & command, string const & o1, } +bool noweb_mode = false; + + namespace { @@ -275,6 +278,7 @@ int parse_help(string const &, string const &) "\t-userdir dir try to set user directory to dir\n" "\t-sysdir dir try to set system directory to dir\n" "\t-c textclass declare the textclass\n" + "\t-n translate a noweb (aka literate programming) file.\n" "\t-s syntaxfile read additional syntax file" << endl; exit(0); } @@ -337,6 +341,13 @@ int parse_force(string const &, string const &) } +int parse_noweb(string const &, string const &) +{ + noweb_mode = true; + return 0; +} + + void easyParse(int & argc, char * argv[]) { map cmdmap; @@ -346,6 +357,7 @@ void easyParse(int & argc, char * argv[]) cmdmap["-s"] = parse_syntaxfile; cmdmap["-help"] = parse_help; cmdmap["--help"] = parse_help; + cmdmap["-n"] = parse_noweb; cmdmap["-sysdir"] = parse_sysdir; cmdmap["-userdir"] = parse_userdir; diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h index 136cce2515..f7ad2e76be 100644 --- a/src/tex2lyx/tex2lyx.h +++ b/src/tex2lyx/tex2lyx.h @@ -94,6 +94,8 @@ extern CommandMap known_commands; extern CommandMap known_environments; /// Known TeX math environments with arguments that get parsed into LyX mathed. extern CommandMap known_math_environments; +/// +extern bool noweb_mode; /// path of the master .tex file extern std::string getMasterFilePath(); diff --git a/src/tex2lyx/text.C b/src/tex2lyx/text.C index 3e3a3d3afb..bbcfa593f0 100644 --- a/src/tex2lyx/text.C +++ b/src/tex2lyx/text.C @@ -433,7 +433,7 @@ private: LyXLayout_ptr findLayout(LyXTextClass const & textclass, string const & name) { - LyXTextClass::const_iterator beg = textclass.begin(); + LyXTextClass::const_iterator beg = textclass.begin(); LyXTextClass::const_iterator end = textclass.end(); LyXTextClass::const_iterator @@ -1011,6 +1011,68 @@ void fix_relative_filename(string & name) getParentFilePath()); } + +/// Parse a NoWeb Scrap section. The initial "<<" is already parsed. +void parse_noweb(Parser & p, ostream & os, Context & context) +{ + // assemble the rest of the keyword + string name("<<"); + bool scrap = false; + while (p.good()) { + Token const & t = p.get_token(); + if (t.asInput() == ">" && p.next_token().asInput() == ">") { + name += ">>"; + p.get_token(); + scrap = (p.good() && p.next_token().asInput() == "="); + if (scrap) + name += p.get_token().asInput(); + break; + } + name += t.asInput(); + } + + if (!scrap || !context.new_layout_allowed || + !context.textclass.hasLayout("Scrap")) { + cerr << "Warning: Could not interpret '" << name + << "'. Ignoring it." << endl; + return; + } + + context.check_end_layout(os); + Context newcontext(true, context.textclass, context.textclass["Scrap"]); + newcontext.check_layout(os); + os << name; + while (p.good()) { + Token const & t = p.get_token(); + // We abuse the parser a bit, because this is no TeX syntax + // at all. + if (t.cat() == catEscape) + os << subst(t.asInput(), "\\", "\n\\backslash\n"); + else + os << subst(t.asInput(), "\n", "\n\\newline\n"); + // The scrap chunk is ended by an @ at the beginning of a line. + // After the @ the line may contain a comment and/or + // whitespace, but nothing else. + if (t.asInput() == "@" && p.prev_token().cat() == catNewline && + (p.next_token().cat() == catSpace || + p.next_token().cat() == catNewline || + p.next_token().cat() == catComment)) { + while (p.good() && p.next_token().cat() == catSpace) + os << p.get_token().asInput(); + if (p.next_token().cat() == catComment) + // The comment includes a final '\n' + os << p.get_token().asInput(); + else { + if (p.next_token().cat() == catNewline) + p.get_token(); + os << '\n'; + } + break; + } + } + newcontext.check_end_layout(os); +} + } // anonymous namespace @@ -1098,9 +1160,28 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, skip_braces(p); } + else if (t.asInput() == "<" + && p.next_token().asInput() == "<" && noweb_mode) { + p.get_token(); + parse_noweb(p, os, context); + } + else if (t.cat() == catSpace || (t.cat() == catNewline && ! p.isParagraph())) check_space(p, os, context); + else if (t.character() == '[' && noweb_mode && + p.next_token().character() == '[') { + // These can contain underscores + p.putback(); + string const s = p.getFullOpt() + ']'; + if (p.next_token().character() == ']') + p.get_token(); + else + cerr << "Warning: Inserting missing ']' in '" + << s << "'." << endl; + handle_ert(os, s, context); + } + else if (t.cat() == catLetter || t.cat() == catOther || t.cat() == catAlign ||