UNPKG

6.72 kBtext/coffeescriptView Raw
1coffee = require 'coffee-script'
2cp = require 'child_process'
3fs = require 'fs'
4_ = require 'underscore'
5moment = require 'moment'
6less = require 'less'
7jade = require 'jade'
8ejs = require 'ejs'
9mkdir_p = require( './mkdir_p' ).mkdir_p
10coffeescript = require 'coffee-script'
11
12jade.filters.plain = ( b, c ) ->
13 return b.toString()
14
15SRC_DELIM = '---\n'
16
17renderers = {}
18innerContent = ( meta ) ->
19 type = meta.extension
20 switch type
21 when '.md'
22 meta.preprocessed = ejs.render( meta.src, meta )
23 renderers[type] ?= require( 'node-markdown' ).Markdown
24 return renderers[type]( meta.preprocessed )
25 when '.jade'
26 renderers[type] ?= jade
27 return renderers[type].compile( meta.src )(meta)
28 when '.ejs'
29 return ejs.render( meta.src, meta )
30
31class GenericContent
32 constructor: ( @site, @srcPath ) ->
33 @kind = @constructor.name.toLowerCase()
34 process: ( cb ) ->
35 pathParts = @srcPath.split('.')
36 if pathParts.length > 1
37 @extension = ".#{pathParts.pop()}"
38 pathParts = pathParts.join('.').split('/')
39 else
40 @extension = ""
41 pathParts = @srcPath.split('/')
42
43 @filename = pathParts.pop()
44 @path = pathParts.join('/')
45 @path += '/' if @path
46 @permalink = "#{@path}#{@filename}"
47 @fullPath = "#{@site.root}/_#{@kind}s/#{@srcPath}"
48
49 @thing = "#{@permalink}#{@extension}"
50
51 Logger.debug "Processing #{@kind}/#{@permalink}..."
52 if cb then cb( null, @ ) else @
53
54 render: ( cb ) ->
55 Logger.debug "Rendering #{@kind}/#{@permalink}..."
56 if cb then cb( null, @ ) else @
57
58class PageOrPost extends GenericContent
59 constructor: ( @site, @srcPath, @kind ) ->
60 super( @site, @srcPath )
61 @index = false
62 @draft = false
63 process: ( cb ) ->
64 super()
65 fs.readFile @fullPath, ( err, src ) =>
66 if err
67 Logger.error "Error reading source of #{@kind}/#{@srcPath} - #{err}"
68 cb( err, @ )
69 return
70
71 src = src.toString().split( SRC_DELIM )
72 meta = eval coffee.compile( src[0], { bare: true } )
73
74 for k, v of meta
75 @[k] = v
76 @scripts ?= []
77 @styles ?= []
78 @src = src.splice(1).join( SRC_DELIM )
79
80 if @kind == 'post'
81 @timestamp = moment( meta.date, @site.config.dateFormat || "DD.MM.YYYY" )
82
83 cb( null, @ )
84 render: ( cb ) ->
85 super()
86 dir = "#{@site.root}/build/#{@permalink}"
87 mkdir_p dir, 0777, ( err ) =>
88 if err
89 Logger.error "Error in mkdir_p - #{dir} - #{err}"
90 cb( err, null )
91 return
92
93 @posts = @site.posts()
94 @pages = @site.pages()
95
96 @config = @site.config
97 @_ = _
98
99 self = @
100 @h = _.reduce(
101 _.keys( Config.helpers||{} ),
102 (
103 (uh, key) ->
104 uh[key] = _.bind( Config.helpers[key], self )
105 return uh
106 ),
107 {
108 _: _,
109 moment: moment
110 innerContent: innerContent
111 }
112 )
113
114 try
115 @content = innerContent( @ )
116 catch e
117 Logger.error "Could not process file: #{@permalink} - #{e}, #{e.stack}"
118 return
119
120 writeFile = ( dest, html, cb ) ->
121 fs.writeFile dest, html.toString(), ( err ) ->
122 Logger.error "Error writing final render #{err}" if err
123 cb( err )
124
125 dest = "#{@site.root}/build/#{@permalink}/index.html"
126
127 if @layout == false
128 writeFile( dest, @content, cb )
129 else
130 fs.readFile "#{@site.root}/_inc/#{@layout||'layout'}.jade", ( err, layoutSrc ) =>
131 Logger.error( @permalink, err, err.stack ) if err
132 tmpl = jade.compile layoutSrc.toString()
133 html = tmpl( @, (err) -> Logger.error("OMG#{err}") if err )
134 writeFile( dest, html, ( err ) =>
135 if @index
136 writeFile( "#{@site.root}/build/index.html", html, (err) -> cb(err, true) )
137 else
138 cb( err, true )
139 )
140
141class Page extends PageOrPost
142 constructor: ( @site, @srcPath ) ->
143 super( @site, @srcPath, 'page' )
144class Post extends PageOrPost
145 constructor: ( @site, @srcPath ) ->
146 super( @site, @srcPath, 'post' )
147
148
149class Script extends GenericContent
150 render: ( cb ) ->
151 super()
152 fs.readFile @fullPath, ( err, coffee ) =>
153 fs.mkdir "#{@site.root}/build/js", 0777, ( err ) =>
154 src = if @extension == '.coffee'
155 coffeescript.compile( coffee+"" )
156 else
157 coffee+""
158 fs.writeFile "#{@site.root}/build/js/#{@thing.replace(/coffee$/, 'js')}", src.toString(), ( err ) ->
159 Logger.error "Error in script done callback #{err}" if err
160 cb( null, true )
161
162class Style extends GenericContent
163 render: ( cb ) ->
164 super()
165 parser = new(less.Parser)(
166 paths: [ "#{@site.root}/_styles" ]
167 )
168 fs.readFile @fullPath, ( err, css ) =>
169 return cb( err ) if err
170 fs.mkdir "#{@site.root}/build/css", 0777, () =>
171 done = ( err, src ) =>
172 if err
173 Logger.error "Could not process style: #{@permalink}, #{JSON.stringify(err,undefined,2)}"
174 cb( err )
175 return
176 fs.writeFile "#{@site.root}/build/css/#{@thing.replace(/less$/, 'css')}", src.toString(), ( err ) ->
177 Logger.error "Error in style done callback #{err}" if err
178 cb( null, true )
179
180 if @extension == '.less'
181 parser.parse( css.toString(), ( err, src ) ->
182 if err
183 done( err, src )
184 return
185 try
186 result = src.toCSS( compress: true )
187 done( null, result )
188 catch err2
189 done( err2, src )
190 )
191 else
192 done( null, css+"" )
193
194class Static extends GenericContent
195 render: ( cb ) ->
196 # force delete anything that exists in data/static
197 # and then based on env:
198 # development: symlink anything in data/static to build
199 # production: fs copy anything in data/static to build
200 super()
201 cp.exec "rm -rf #{@site.root}/build/#{@thing}", ( err ) =>
202 if err
203 Logger.error "Error in static copy #{err}"
204 cb( err )
205 return
206
207 src = "#{@site.root}/_static/#{@thing}"
208 dest = "#{@site.root}/build/#{@thing}"
209
210 if !@site.config.DEV
211 cp.exec "cp -R #{src} #{dest}", ( err ) =>
212 if err
213 Logger.error "Could not write build/#{@thing} during generation. #{arguments}, #{err}"
214 cb( err )
215 else
216 cb( null, true )
217
218 else
219 fs.symlink src, dest, ( err ) ->
220 if err
221 Logger.error "Error symlinking statics #{err}"
222 cb( err )
223 else
224 cb( null, true )
225
226module.exports =
227 Page: Page
228 Post: Post
229 Script: Script
230 Style: Style
231 Static: Static