Add static asset support.

* haunt/asset.scm: New file.
* Makefile.am (SOURCES): Add it.
* haunt/site.scm (build-site): Add support for assets.
* haunt/utils.scm (file-name-components, join-file-name-components): New
  procedures.
This commit is contained in:
David Thompson 2015-04-13 21:59:29 -04:00
parent 395b510a6d
commit 1f1784f9f1
4 changed files with 101 additions and 3 deletions

View File

@ -45,6 +45,7 @@ SOURCES = \
haunt/post.scm \ haunt/post.scm \
haunt/reader.scm \ haunt/reader.scm \
haunt/page.scm \ haunt/page.scm \
haunt/asset.scm \
haunt/site.scm \ haunt/site.scm \
haunt/build/html.scm \ haunt/build/html.scm \
haunt/builder/atom.scm \ haunt/builder/atom.scm \

75
haunt/asset.scm Normal file
View File

@ -0,0 +1,75 @@
;;; Haunt --- Static site generator for GNU Guile
;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;;
;;; This file is part of Haunt.
;;;
;;; Haunt is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; Haunt is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Haunt. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Static asset data type.
;;
;;; Code:
(define-module (haunt asset)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
#:use-module (ice-9 ftw)
#:use-module (ice-9 match)
#:use-module (haunt utils)
#:export (make-asset
asset?
asset-source
asset-target
install-asset
directory-assets))
(define-record-type <asset>
(make-asset source target)
asset?
(source asset-source)
(target asset-target))
(define (install-asset asset prefix)
"Install ASSET source file into destination directory within
PREFIX."
(match asset
(($ <asset> source target)
(let ((target* (string-append prefix "/" target)))
(mkdir-p (dirname target*))
(copy-file source target*)))))
(define (directory-assets directory dest)
"Create a list of asset objects to be stored within DEST for all
files in DIRECTORY, recursively."
(define enter? (const #t))
;; In order to do accurate file name manipulation, every file name
;; is converted into a list of components, manipulated, then
;; converted back into a string.
(define leaf
(let ((base-length (length (file-name-components directory)))
(dest* (file-name-components dest)))
(lambda (file-name stat memo)
(let* ((file-name* (file-name-components file-name))
(target (join-file-name-components
(append dest* (drop file-name* base-length)))))
(cons (make-asset file-name target) memo)))))
(define (noop file-name stat memo) memo)
(define (err file-name stat errno memo)
(error "asset processing failed with errno: " file-name errno))
(file-system-fold enter? leaf noop noop noop err '() directory))

View File

@ -25,9 +25,11 @@
(define-module (haunt site) (define-module (haunt site)
#:use-module (srfi srfi-9) #:use-module (srfi srfi-9)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:use-module (haunt utils) #:use-module (haunt utils)
#:use-module (haunt reader) #:use-module (haunt reader)
#:use-module (haunt page) #:use-module (haunt page)
#:use-module (haunt asset)
#:export (site #:export (site
site? site?
site-title site-title
@ -77,8 +79,18 @@ BUILDERS: A list of procedures for building pages from posts"
(site-readers site) (site-readers site)
(site-default-metadata site))) (site-default-metadata site)))
(build-dir (absolute-file-name (site-build-directory site)))) (build-dir (absolute-file-name (site-build-directory site))))
(delete-file-recursively build-dir) (when (file-exists? build-dir)
(for-each (lambda (page) (delete-file-recursively build-dir)
(format #t "writing '~a'~%" (page-file-name page)) (mkdir build-dir))
(for-each (match-lambda
((? page? page)
(format #t "writing page '~a'~%" (page-file-name page))
(write-page page build-dir)) (write-page page build-dir))
((? asset? asset)
(format #t "copying asset '~a' -> '~a'~%"
(asset-source asset)
(asset-target asset))
(install-asset asset build-dir))
(obj
(error "unrecognized site object: " obj)))
(flat-map (cut <> site posts) (site-builders site))))) (flat-map (cut <> site posts) (site-builders site)))))

View File

@ -32,6 +32,8 @@
#:export (flatten #:export (flatten
flat-map flat-map
string-split-at string-split-at
file-name-components
join-file-name-components
absolute-file-name absolute-file-name
delete-file-recursively delete-file-recursively
mkdir-p mkdir-p
@ -63,6 +65,14 @@ flattened."
(string-drop str (1+ i))) (string-drop str (1+ i)))
(list str)))) (list str))))
(define (file-name-components file-name)
"Split FILE-NAME into the components delimited by '/'."
(string-split file-name #\/))
(define (join-file-name-components components)
"Join COMPONENTS into a file name string."
(string-join components "/"))
(define (absolute-file-name file-name) (define (absolute-file-name file-name)
(if (absolute-file-name? file-name) (if (absolute-file-name? file-name)
file-name file-name