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'],