This goes in trunk now as discussed. Jean-Marc, also for 1.4.3?

Georg

Log:
Fix bug 2289
        * src/tex2lyx/text.C
        (void parse_noweb): new, parse a noweb code chunck
        (void parse_text): handle noweb <<xxx>>= 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
Index: src/tex2lyx/tex2lyx.C
===================================================================
--- src/tex2lyx/tex2lyx.C	(Revision 14634)
+++ src/tex2lyx/tex2lyx.C	(Arbeitskopie)
@@ -161,6 +161,9 @@ void add_known_command(string const & co
 }
 
 
+bool noweb_mode = false;
+
+
 namespace {
 
 
@@ -275,6 +278,7 @@ int parse_help(string const &, string co
 		"\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 c
 }
 
 
+int parse_noweb(string const &, string const &)
+{
+	noweb_mode = true;
+	return 0;
+}
+
+
 void easyParse(int & argc, char * argv[])
 {
 	map<string, cmd_helper> 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;
 
Index: src/tex2lyx/text.C
===================================================================
--- src/tex2lyx/text.C	(Revision 14634)
+++ src/tex2lyx/text.C	(Arbeitskopie)
@@ -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
 			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 ||
Index: src/tex2lyx/tex2lyx.h
===================================================================
--- src/tex2lyx/tex2lyx.h	(Revision 14634)
+++ src/tex2lyx/tex2lyx.h	(Arbeitskopie)
@@ -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();
Index: src/tex2lyx/preamble.C
===================================================================
--- src/tex2lyx/preamble.C	(Revision 14634)
+++ src/tex2lyx/preamble.C	(Arbeitskopie)
@@ -18,6 +18,7 @@
 #include "lyxtextclass.h"
 #include "lyxlex.h"
 #include "support/filetools.h"
+#include "support/lstrings.h"
 
 #include <algorithm>
 #include <iostream>
@@ -483,9 +484,10 @@ LyXTextClass const parse_preamble(Parser
 	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;
Index: lib/configure.py
===================================================================
--- lib/configure.py	(Revision 14634)
+++ lib/configure.py	(Arbeitskopie)
@@ -315,16 +315,13 @@ 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'],

Reply via email to