about summary refs log tree commit diff stats
path: root/cpp/tangle
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/tangle')
-rw-r--r--cpp/tangle/030tangle.cc38
-rw-r--r--cpp/tangle/030tangle.test.cc7
2 files changed, 39 insertions, 6 deletions
diff --git a/cpp/tangle/030tangle.cc b/cpp/tangle/030tangle.cc
index 2d1bc191..cdf28d91 100644
--- a/cpp/tangle/030tangle.cc
+++ b/cpp/tangle/030tangle.cc
@@ -70,13 +70,39 @@ void process_next_hunk(istream& in, const string& directive, list<string>& out)
       RAISE << "No target for " << cmd << " directive.\n" << die();
       return;
     }
-    list<string>::iterator target = find_substr(out, pat);
-    if (target == out.end()) {
-      RAISE << "Couldn't find target " << pat << '\n' << die();
-      return;
-    }
 
-    if (next_tangle_token(directive_stream) == "then") {
+    list<string>::iterator target = out.begin();
+    string next_token = next_tangle_token(directive_stream);
+    if (next_token == "") {
+      target = find_substr(out, pat);
+      if (target == out.end()) {
+        RAISE << "Couldn't find target " << pat << '\n' << die();
+        return;
+      }
+    }
+    else if (next_token == "following") {
+      string pat2 = next_tangle_token(directive_stream);
+      if (pat2 == "") {
+        RAISE << "No target for 'following' in " << directive << ".\n" << die();
+        return;
+      }
+      target = find_substr(out, pat2);
+      if (target == out.end()) {
+        RAISE << "Couldn't find target " << pat2 << die();
+        return;
+      }
+      target = find_substr(out, target, pat);
+      if (target == out.end()) {
+        RAISE << "Couldn't find target " << pat << '\n' << die();
+        return;
+      }
+    }
+    else if (next_token == "then") {
+      target = find_substr(out, pat);
+      if (target == out.end()) {
+        RAISE << "Couldn't find target " << pat << '\n' << die();
+        return;
+      }
       string pat2 = next_tangle_token(directive_stream);
       if (pat2 == "") {
         RAISE << "No target for then directive following " << cmd << ".\n" << die();
diff --git a/cpp/tangle/030tangle.test.cc b/cpp/tangle/030tangle.test.cc
index cf42d71c..eb468894 100644
--- a/cpp/tangle/030tangle.test.cc
+++ b/cpp/tangle/030tangle.test.cc
@@ -83,6 +83,13 @@ void test_tangle_nested_patterns() {
   CHECK_TRACE_CONTENTS("tangle", "acbced");
 }
 
+void test_tangle_nested_patterns2() {
+  istringstream in("a\nc\nb\nc\nd\n:(after \"c\" following \"b\")\ne");
+  list<string> dummy;
+  tangle(in, dummy);
+  CHECK_TRACE_CONTENTS("tangle", "acbced");
+}
+
 // todo: include line numbers in tangle errors