summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/guile/skribilo/resolve.scm39
-rw-r--r--tests/resolve.test18
2 files changed, 47 insertions, 10 deletions
diff --git a/src/guile/skribilo/resolve.scm b/src/guile/skribilo/resolve.scm
index 062161f..2073f25 100644
--- a/src/guile/skribilo/resolve.scm
+++ b/src/guile/skribilo/resolve.scm
@@ -1,6 +1,6 @@
 ;;; resolve.scm  --  Skribilo reference resolution.
 ;;;
-;;; Copyright 2005, 2006, 2008  Ludovic Courtès <ludo@gnu.org>
+;;; Copyright 2005, 2006, 2008, 2009  Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright 2003, 2004  Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
 ;;;
 ;;;
@@ -202,15 +202,34 @@
 
        (let* ((proc (slot-ref node 'proc))
               (res  (proc node engine env))
-              (loc  (ast-loc node))
-              (doc  (ast-document node)))
-         (ast-fold (lambda (node result)
-                     (if (markup? node)
-                         (document-bind-node! doc node))
-                     (if (ast? node)
-                         (ast-loc-set! node loc)))
-                   #t ;; unused
-                   res)
+              (loc  (ast-loc node)))
+
+         ;; Bind non-unresolved children of RES now so that unresolved
+         ;; children of RES (if any) can look them up in the next `resolve!'
+         ;; run.  (XXX: This largely duplicated `document-bind-nodes!'.)
+         (let loop ((node res)
+                    (doc  (ast-document node)))
+           (if (ast? node)
+               (ast-loc-set! node loc))
+
+           (cond ((document? node)
+                  ;; Bind NODE in its parent's document.  This is so
+                  ;; that (i) a sub-document is bound in its parent
+                  ;; document, and (ii) a node within a sub-document
+                  ;; is bound in this sub-document.
+                  (document-bind-node! doc node)
+                  (loop (markup-body node) node))
+
+                 ((markup? node)
+                  (document-bind-node! doc node)
+                  (loop (markup-body node) doc))
+
+                 ((pair? node)
+                  (for-each (lambda (n) (loop n doc)) node))
+
+                 ((command? node)
+                  (loop (command-body node) doc))))
+
          (debug-item "res=" res)
          (*unresolved* #t)
          res))))
diff --git a/tests/resolve.test b/tests/resolve.test
index bfbdd27..027b191 100644
--- a/tests/resolve.test
+++ b/tests/resolve.test
@@ -174,6 +174,24 @@
            (and (is-markup? x 'chapter)
                 (eq? (ast-document x) sub))))))
 
+(test-assert "resolved nested document bindings"
+  ;; Prior to 0.9.2, nodes of a sub-document returned by an `unresolved' node
+  ;; would be bound in the root document.
+  (let* ((doc (document #:title "Doc"
+                (resolve (lambda (n e env)
+                           (document #:title "Nested Doc"
+                             (chapter #:ident "inner")))))))
+    (resolve! doc %engine '())
+    (and (not (document-lookup-node doc "inner"))
+         (let* ((sub (car (markup-body doc)))
+                (ch  (car (markup-body sub)))
+                (x   (document-lookup-node sub "inner")))
+           (and (document? sub)
+                (is-markup? x 'chapter)
+                (eq? x ch)
+                (eq? (ast-parent x) sub)
+                (eq? (ast-document x) sub))))))
+
 (test-end "resolve")