summaryrefslogtreecommitdiff
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")