diff --git a/exscribe-html.lisp b/exscribe-html.lisp
index 535d785c030811364980492fc06c393ebc363c06..4f22302f4b8b63893b0a63c5a5eb871e87e24abe 100644
--- a/exscribe-html.lisp
+++ b/exscribe-html.lisp
@@ -49,14 +49,14 @@
(defun find-first-paragraph (x)
(labels
- ((fail ()
+ ((fail! ()
(return-from find-first-paragraph nil))
(walk (x)
(match x
((tag :p _ _) x)
((tag :id _ x) (walk x))
- ((tag _ _ _) (fail))
- ((type string) (fail))
+ ((tag _ _ _) (fail!))
+ ((type string) (fail!))
((cons x y) (or (walk x) (walk y)))
(_ nil))))
(walk x)))
diff --git a/exscribe.asd b/exscribe.asd
index a581f895b5957bd089cbb8f3538c4d075194c7d7..f715919f0321a7706d64bdda8546bbd28552e0e0 100644
--- a/exscribe.asd
+++ b/exscribe.asd
@@ -10,7 +10,7 @@
:long-description "Exscribe helps you author documents and produce HTML output,
using a high-level syntax (Scribble) completely integrated with the CL syntax.
It notably features proper support for footnotes, table-of-contents, bibliography."
- :depends-on (:cl-launch :scribble :fare-utils :alexandria :fare-quasiquote-optima :fare-memoization
+ :depends-on (:scribble :fare-utils :alexandria :fare-quasiquote-optima :fare-memoization
#+exscribe-typeset :cl-typesetting)
:components ((:file "packages")
(:file "macros" :depends-on ("packages"))
diff --git a/exscribe.lisp b/exscribe.lisp
index d687cab5134ef1ba690c82cf0fd37775ffc105e6..8be50e75dfff41367b36909fa0b4793c9a983f21 100644
--- a/exscribe.lisp
+++ b/exscribe.lisp
@@ -68,6 +68,52 @@
(file-optimization)
(load* file :verbose *exscribe-verbose* :print *exscribe-verbose*))
+
+;;; These two functions initially from cl-launch.
+(defun file-newer-p (new-file old-file)
+ "Returns true if NEW-FILE is strictly newer than OLD-FILE."
+ (> (file-write-date new-file) (file-write-date old-file)))
+(defun compile-and-load-file (source &key force-recompile
+ (verbose *load-verbose*) (load t)
+ output-file)
+ "compiles and load specified SOURCE file, if either required by keyword
+argument FORCE-RECOMPILE, or not yet existing, or not up-to-date.
+Keyword argument VERBOSE specifies whether to be verbose.
+Returns two values: the fasl path, and T if the file was (re)compiled"
+
+ ;; When in doubt, don't trust - recompile. Indeed, there are
+ ;; edge cases cases when on the first time of compiling a simple
+ ;; auto-generated file (e.g. from the automated test suite), the
+ ;; fasl ends up being written to disk within the same second as the
+ ;; source was produced, which cannot be distinguished from the
+ ;; reverse case where the source code was produced in the same split
+ ;; second as the previous version was done compiling. Could be
+ ;; tricky if a big system needs be recompiled as a dependency on an
+ ;; automatically generated file, but for cl-launch those
+ ;; dependencies are not detected anyway (BAD). If/when they are, and
+ ;; lacking better timestamps than the filesystem provides, you
+ ;; should sleep after you generate your source code.
+ #+(and gcl (not gcl<2.7))
+ (setf source (ensure-lisp-file-name source (concatenate 'string (pathname-name source) ".lisp")))
+ (let* ((truesource (truename source))
+ (fasl (or output-file (compile-file-pathname* truesource)))
+ (compiled-p
+ (when (or force-recompile
+ (not (probe-file fasl))
+ (not (file-newer-p fasl source)))
+ (ensure-directories-exist fasl)
+ (multiple-value-bind (path warnings failures)
+ (compile-file* truesource :output-file fasl)
+ (declare (ignorable warnings failures))
+ (unless (equal (truename fasl) (truename path))
+ (error "CL-Launch: file compiled to ~A, expected ~A" path fasl))
+ (when failures
+ (error "CL-Launch: failures while compiling ~A" source)))
+ t)))
+ (when load
+ (load* fasl :verbose verbose))
+ (values fasl compiled-p)))
+
(defun exscribe-load-style (style)
(unless (member style *loaded-styles*)
(push style *loaded-styles*)
@@ -75,7 +121,7 @@
(let* ((file (find-exscribe-file style))
(date (file-write-date file))
(force (and *latest-style-date* (< date *latest-style-date*)))
- (object (cl-launch:compile-and-load-file
+ (object (compile-and-load-file
file :force-recompile force :verbose *exscribe-verbose*))
(object-date (file-write-date object)))
(setf *latest-style-date*
diff --git a/packages.lisp b/packages.lisp
index dce00d0d92aba35064aeea9d646bb458dd8d3960..945aab0d3cc7140a6a85351ff5eb3f9e421ac831 100644
--- a/packages.lisp
+++ b/packages.lisp
@@ -41,7 +41,7 @@ not to actually implement deep Scheme semantics.")
(:documentation "core infrastructure for exscribe")
(:mix :asdf/driver :fare-utils :alexandria)
(:reexport :asdf/driver :fare-utils :alexandria)
- (:use :scribble :fare-quasiquote :optima :common-lisp :cl-launch)
+ (:use :scribble :fare-quasiquote :optima :common-lisp)
#+exscribe-typeset
(:import-from :typeset
#:*paper-size* #:*page-margins* #:*twosided* #:*toc-depth*