1module Build exposing ( main )
2
3import About.Layout
4import Bytes exposing ( Bytes )
5import Bytes.Decode
6import Bytes.Encode
7import Dict
8import Json.Encode
9import Markdown
10import Shikensu
11import Shikensu.Bundle as Bundle
12import Shikensu.Contrib as Shikensu
13import Shikensu.Definition as Definition
14import Shikensu.Focus exposing ( Focus(..) )
15import Shikensu.Path as Path exposing (..)
16import Shikensu.Path.Encapsulated as Path.Encapsulated
17import Task
18import Transmutable.Html
19
20
21
22-- | (• ◡•)| (❍ᴥ❍ʋ)
23
24
25main =
26 Shikensu.programs
27 [ -- Copy static files to dist
28 copy (staticDir "Favicons")
29 , copy (staticDir "Hosting")
30 , copyInto "fonts" (staticDir "Fonts")
31 , copyInto "images" (staticDir "Images")
32
33 , -- Copy more static files with some alterations
34 copyWithAlterations
35 { focus = staticDir "Html"
36 , alt = Shikensu.rename (filePath "Application.html") (filePath "index.html")
37 }
38 , copyWithAlterations
39 { focus = staticDir "Manifests"
40 , alt = Shikensu.rename (filePath "manifest.json") (filePath "site.webmanifest")
41 }
42
43 , -- Render about pages
44 about
45
46 , -- Make a file tree so the service worker knows what to cache
47 tree
48 ]
49
50
51
52-- FOCUSES & PATHS
53
54
55dist =
56 Relative
57 (Path.directory
58 [ "dist"
59 ]
60 )
61
62
63filePath path =
64 path
65 |> Path.fromPosix
66 |> Path.Encapsulated.toFile
67 |> Maybe.withDefault (Path.file (Array.singleton path))
68
69
70staticDir dirName =
71 Relative
72 (Path.directory
73 [ "src"
74 , "Static"
75 , dirName
76 ]
77 )
78
79
80
81-- PROGRAMS
82
83
84about =
85 { focus = staticDir "About"
86 , sequence = read >> Task.map aboutAlts >> write
87 }
88
89
90copy focus =
91 { focus = focus
92 , sequence = read >> write
93 }
94
95
96copyInto dirName focus =
97 { focus = focus
98 , sequence = read >> Task.map (prefixDirname dirName) >> write
99 }
100
101
102copyWithAlterations { focus, alt } =
103 { focus = focus
104 , sequence = read >> Task.map alt >> write
105 }
106
107
108tree =
109 { focus = dist
110 , sequence =
111 Task.map
112 (\bundle ->
113 bundle.compendium
114 |> Array.map
115 (\def ->
116 def
117 |> Definition.relativePath
118 |> Path.toPosix
119 { absolute = False
120 }
121 )
122 |> Array.filter (String.contains "images/Background/" >> (==) False)
123 |> Json.Encode.array Json.Encode.string
124 |> Json.Encode.encode 0
125 |> stringToBytes
126 |> (\content ->
127 { baseName = "tree"
128 , content = Just content
129 , directoryPath = Path.directory []
130 , extensionName = Just "json"
131 , metadata = Dict.empty
132 }
133 )
134 |> (\def ->
135 { bundle
136 | compendium =
137 [ def
138 ]
139 }
140 )
141 )
142 >> write
143 }
144
145
146
147-- ALTERATIONS
148
149
150aboutAlts bundle =
151 bundle
152 |> Shikensu.withExtension "md"
153 |> lowerCasePath
154 |> prefixDirname "about"
155 |> Shikensu.renameExtension "md" "html"
156 |> Shikensu.permalink "index"
157 |> Shikensu.renderContent
158 (\def ->
159 def.content
160 |> Maybe.andThen bytesToString
161 |> Maybe.withDefault ""
162 |> Markdown.parse
163 { frontmatter = Nothing
164 }
165 |> (\{ blocks } -> Array.map Markdown.toHtml blocks)
166 |> About.Layout.layout
167 { pathToRoot =
168 def.directoryPath
169 |> Path.unwrap
170 |> Array.map (\_ -> "..")
171 |> String.join "/"
172 |> (\a -> a ++ "/")
173 }
174 |> Transmutable.Html.arrayToString
175 |> stringToBytes
176 |> Just
177 )
178
179
180lowerCasePath =
181 (\def ->
182 def
183 |> Definition.relativePath
184 |> Path.map (Array.map String.toLower)
185 |> (\path -> Definition.fork path def)
186 )
187 |> Array.map
188 |> Bundle.mapCompendium
189
190
191prefixDirname dirName =
192 (\def -> { def | directoryPath = Path.map (Array.pushFirst dirName) def.directoryPath })
193 |> Array.map
194 |> Bundle.mapCompendium
195
196
197
198-- TASKS
199
200
201read =
202 Task.andThen Shikensu.read
203
204
205write =
206 Task.andThen (Shikensu.write dist)
207
208
209
210-- 🛠️
211
212
213bytesToString : Bytes -> Maybe String
214bytesToString bytes =
215 bytes
216 |> Bytes.width
217 |> Bytes.Decode.string
218 |> (\decoder -> Bytes.Decode.decode decoder bytes)
219
220
221stringToBytes : String -> Bytes
222stringToBytes =
223 Bytes.Encode.string >> Bytes.Encode.encode