summaryrefslogtreecommitdiff
path: root/schemeato
blob: c950af099c2e3f00e01b432e83c05068b82d2204 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#|
#!/usr/bin/env sh
exec chibi-scheme -A `dirname $0` $0 $@
|#
(import
        (scheme base)
        (srfi 1)
        (srfi 69)
        (srfi 115)
        (chibi)
        (chibi app)
        (chibi config)
        (chibi filesystem)
        (chibi process)
        (chibi io)
        (chibi pathname)
        (chibi string)
        (chibi sxml))

; - [X] Read all the locales
; - [ ] Prepare needed variables per file:
;   - [X] List of languages available
;   - [X] Current language
;   - [ ] Current file
;   - [X] Markdown parser
;     - [X] pandoc
;     - [ ] Check how to do it in scheme
;   - [ ] Some more: check schiumato for reference
; - [X] `load` or `eval` files in the created environment and extract their
;   exports to dump them to target folder
; - [ ] deal with input arguments or config, that can be cool for language
;   selection and directory config.
;     - [ ] Move globs to default config stuff.
; - [ ] Make a `new` command that creates the file structure and the default
;   configuration file

(define (string-startswith? str char)
  (string-cursor=?
    (string-cursor-start str)
    (string-find str (lambda (y) (char=? y char)))))

; Move this to input/config parameters
(define staticdir "static")
(define templatedir "templates")
(define outdir "www")

(define (md-to-html md-text)
  "Markdown to HTML converter using external Pandoc command"
  (call-with-process-io "pandoc"
    (lambda (pid in out err)
      (display md-text in)
      (close-output-port in)
      (let ((res (port->string out)))
        (waitpid pid 0)
        res))))

(define (load-templates)
  "Read templates `templatedir`.
  Returns them as a alist where keys are the filename of the template relative
  to the `templatedir` and the values are the contents of the file."
  (directory-fold-tree
    templatedir
    #f
    #f
    (lambda (file acc)
      (if (or (string-startswith? (path-strip-directory file) #\.)
              (string-startswith? (path-strip-directory file) #\_))
          acc
          (cons (list (path-relative-to file templatedir)
                      (call-with-input-file
                        file
                        (lambda (p)
                          (let loop ((x (read p)))
                            (if (eof-object? x)
                                '()
                                (cons x (loop (read p))))))))
                acc)))
    '()))

(define (render-template tpl env)
  "Render one template"
  (let* ((code (let ((codelist (cdr tpl)))
                 (reduce (lambda (x acc)
                           (append x acc))
                         '()
                         codelist)))
         (fullcode (append env code)))
    (eval fullcode)))

(define (copy-static)
  "Copy static directory in output directory"
  (directory-fold-tree
    staticdir
    #f
    #f
    (lambda (file acc)
      (let ((output (make-path outdir
                               (make-path "static"
                                          (path-relative-to file staticdir)))))
        (create-directory* (path-directory output))
        (call-with-output-file output
          (lambda (x)
            (send-file file x)))))
    #\null))

(define (include-template name)
  ; TODO make template loader
  #f)

(define (create-output cfg spec . args)
  "Dumps the templates in the output directory"
  (let ((templates (load-templates)))
    (or (create-directory* outdir) (error "Unable to create output directory"))
    (display "Copying static files...")
    (newline)
    (copy-static)
    (let* ((env `(let ((include-template ,include-template)))))
      (for-each
        (lambda (x)
          (let ((outfile (make-path outdir (car x))))
            (or (create-directory* (path-directory outfile))
                (error "Unable to create directory"))

            (display "Rendering template ")
            (display (car x))
            (display " to ")
            (display outfile)

            (call-with-output-file
              outfile
              (lambda (f)
                (display (render-template x env) f)))

            (display "\t[Done]")
            (newline)))
        templates))))


(run-application
  `(schemeato
     "Schemeato: an easy to translate static site generator"
     (or
       (create "Create output from current folder" ,create-output)
       (help "Show this help" (,app-help-command))))
  (command-line)
  #;(conf-load "conf.scm"))