Jean-Marc Lasgouttes wrote:

> We should see what reLyX did and port that to tex2lyx, then.

I did that (at least partially). It works well with the example file.

Is it OK to apply?


I am not sure if I got all noweb features that noweb2lyx could convert.
Kayvan, could you please check whether something is missing?


Georg
Index: src/tex2lyx/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/ChangeLog,v
retrieving revision 1.108
diff -u -p -r1.108 ChangeLog
--- src/tex2lyx/ChangeLog	22 Aug 2005 09:51:44 -0000	1.108
+++ src/tex2lyx/ChangeLog	30 Sep 2005 08:43:14 -0000
@@ -1,3 +1,12 @@
+2005-09-30  Georg Baum  <[EMAIL PROTECTED]>
+
+	* text.C (parse_noweb): new, parse a noweb code chunck
+	* text.C (parse_text): handle noweb <<xxx>>= and [[xxx]] constructs
+	* tex2lyx.[Ch]: new global variable noweb_mode and command line
+	option to set it
+	* preamble.C (): prepend "literate-" to the textclass name in noweb
+	mode
+
 2005-08-19  Georg Baum  <[EMAIL PROTECTED]>
 
 	* text.C (parse_text): Output \item in list environments that are
Index: src/tex2lyx/preamble.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/preamble.C,v
retrieving revision 1.31
diff -u -p -r1.31 preamble.C
--- src/tex2lyx/preamble.C	18 Jul 2005 13:07:16 -0000	1.31
+++ src/tex2lyx/preamble.C	30 Sep 2005 08:43:14 -0000
@@ -18,6 +18,7 @@
 #include "lyxtextclass.h"
 #include "lyxlex.h"
 #include "support/filetools.h"
+#include "support/lstrings.h"
 
 #include <algorithm>
 #include <iostream>
@@ -481,9 +674,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: src/tex2lyx/tex2lyx.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/tex2lyx.C,v
retrieving revision 1.74
diff -u -p -r1.74 tex2lyx.C
--- src/tex2lyx/tex2lyx.C	25 Jul 2005 16:27:23 -0000	1.74
+++ src/tex2lyx/tex2lyx.C	30 Sep 2005 08:43:15 -0000
@@ -161,6 +161,9 @@ void add_known_command(string const & co
 }
 
 
+bool noweb_mode = false;
+
+
 namespace {
 
 
@@ -268,6 +273,7 @@ typedef boost::function<int(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,15 +348,23 @@ 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;
 
 	cmdmap["-c"] = parse_class;
 	cmdmap["-f"] = parse_force;
 	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/tex2lyx.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/tex2lyx.h,v
retrieving revision 1.22
diff -u -p -r1.22 tex2lyx.h
--- src/tex2lyx/tex2lyx.h	26 Jul 2005 11:58:43 -0000	1.22
+++ src/tex2lyx/tex2lyx.h	30 Sep 2005 08:43:15 -0000
@@ -92,6 +96,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/text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/tex2lyx/text.C,v
retrieving revision 1.65
diff -u -p -r1.65 text.C
--- src/tex2lyx/text.C	22 Aug 2005 09:51:44 -0000	1.65
+++ src/tex2lyx/text.C	30 Sep 2005 08:43:15 -0000
@@ -429,7 +448,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
@@ -1006,6 +1178,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
 
 
@@ -1092,10 +1327,28 @@ void parse_text(Parser & p, ostream & os
 			p.get_token();
 			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 ||

Reply via email to