summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/guile/skribilo/ast.scm25
-rw-r--r--tests/resolve.test49
2 files changed, 69 insertions, 5 deletions
diff --git a/src/guile/skribilo/ast.scm b/src/guile/skribilo/ast.scm
index 3de6947..86fa781 100644
--- a/src/guile/skribilo/ast.scm
+++ b/src/guile/skribilo/ast.scm
@@ -496,11 +496,26 @@
   (if (document-nodes-bound? doc)
       #t
       (begin
-	(ast-fold (lambda (node result)
-		    (if (markup? node) (document-bind-node! doc node))
-		    #t)
-		  #t ;; unused
-		  doc)
+        (let loop ((node doc)
+                   (doc  doc))
+          (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))))
+
 	(slot-set! doc 'nodes-bound? #t))))
 
 
diff --git a/tests/resolve.test b/tests/resolve.test
index 0e29614..bfbdd27 100644
--- a/tests/resolve.test
+++ b/tests/resolve.test
@@ -46,6 +46,36 @@
                 (eq? (ast-parent sec) ch)
                 (eq? (ast-parent par) sec))))))
 
+(test-assert "root document has no parent"
+  (let ((doc (document #:title "Doc")))
+    (resolve! doc %engine '())
+    (and (not (ast-parent doc))
+         (eq? doc (ast-document doc)))))
+
+(test-assert "nested document has a parent"
+  ;; Nested documents are sometimes used in the manual.
+  (let* ((doc (document #:title "Doc"
+                (document #:title "Nested Doc"
+                  (chapter #:title "C"))))
+         (sub (car (markup-body doc)))
+         (ch  (car (markup-body sub))))
+    (resolve! doc %engine '())
+    (and (not (ast-parent doc))
+         (document? sub)
+         (eq? doc (ast-document doc))
+         (eq? doc (ast-parent sub)))))
+
+(test-assert "nested document is its own `ast-document'"
+  (let* ((doc (document #:title "Doc"
+                (document #:title "Nested Doc"
+                  (chapter #:title "C"))))
+         (sub (car (markup-body doc)))
+         (ch  (car (markup-body sub))))
+    (resolve! doc %engine '())
+    (and (document? sub)
+         (eq? sub (ast-document sub))
+         (eq? sub (ast-document ch)))))
+
 (test-assert "unresolved node in body"
   (let* ((resolved? #f)
          (doc (document #:title "Doc"
@@ -125,6 +155,25 @@
            (and (is-markup? (document-lookup-node doc "c") 'chapter)
                 (is-markup? (document-lookup-node doc "s") 'section))))))
 
+(test-assert "nested document bindings"
+  ;; Bindings in nested documents are scoped.  This was not the case prior
+  ;; to 0.9.2.
+  (let* ((doc (document #:title "Doc"
+                (chapter #:ident "outer")
+                (document #:title "Nested Doc"
+                  (chapter #:ident "inner"))))
+         (out (car  (markup-body doc)))
+         (sub (cadr (markup-body doc)))
+         (in  (car  (markup-body sub))))
+    (resolve! doc %engine '())
+    (and (let ((x (document-lookup-node doc "outer")))
+           (and (is-markup? x 'chapter)
+                (eq? (ast-document x) doc)))
+         (not (document-lookup-node doc "inner"))
+         (let ((x (document-lookup-node sub "inner")))
+           (and (is-markup? x 'chapter)
+                (eq? (ast-document x) sub))))))
+
 (test-end "resolve")