build-pipeline.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. const typeDecorator = require("./decorators/typeDecorator");
  2. const outputDecorator = require("./decorators/outputDecorator");
  3. const articleDecorator = require("./decorators/articleDecorator");
  4. function toNameContentObject(items) {
  5. return items.reduce(
  6. (contentObject, item) =>
  7. Object.assign({}, contentObject, {
  8. [item.name]: item.content
  9. }),
  10. {}
  11. );
  12. }
  13. module.exports = {
  14. steps: [
  15. [
  16. {
  17. func: "rmrf",
  18. item: {
  19. path: "./output/*"
  20. }
  21. }
  22. ],
  23. [
  24. {
  25. name: "Read in markdown for index",
  26. func: "listDirectory",
  27. selector: state => [
  28. { path: "./content", tags: ["markdown"], outputExtension: ".html" },
  29. { path: "./images" },
  30. { path: "./static" },
  31. { path: "./styles", outputExtension: ".css" },
  32. { path: "./partials" },
  33. { path: "./helpers" },
  34. { path: "./fonts" },
  35. { path: "./js", outputExtension: ".js" },
  36. { path: "./pages" }
  37. ]
  38. }
  39. ],
  40. [
  41. {
  42. func: "decorateFileObject",
  43. selector: state => state.selectAll(),
  44. config: {
  45. decorators: [typeDecorator],
  46. defaultName: "Home"
  47. }
  48. }
  49. ],
  50. [
  51. {
  52. func: "decorateFileObject",
  53. selector: state =>
  54. state
  55. .matchingAnyTag(["fonts", "content", "js", "styles"])
  56. .and(state.selectByTag("images").not(state.selectByTag("favicon"))),
  57. config: {
  58. decorators: [outputDecorator],
  59. baseDir: "content"
  60. }
  61. },
  62. {
  63. func: "decorateFileObject",
  64. selector: state => state.selectByTag("favicon"),
  65. config: {
  66. decorators: [outputDecorator],
  67. baseDir: "images",
  68. outputExtension: ".ico"
  69. }
  70. },
  71. {
  72. func: "decorateFileObject",
  73. selector: state => state.selectByTag("static"),
  74. config: {
  75. decorators: [outputDecorator],
  76. baseDir: "static"
  77. }
  78. },
  79. {
  80. func: "copy",
  81. selector: state =>
  82. state.matchingAnyTag(["helpers", "partials", "svgs", "pages"])
  83. }
  84. ],
  85. [
  86. {
  87. func: "copyFileTo",
  88. selector: state => state.matchingAnyTag(["fonts", "static"]),
  89. config: { outputDir: "./output" }
  90. },
  91. {
  92. func: "imageMin",
  93. allowEmpty: true,
  94. selector: state =>
  95. state.selectByTag("images").not(state.selectByTag("svgs")),
  96. config: {
  97. outputDir: "./output"
  98. }
  99. },
  100. {
  101. func: "readInFile",
  102. selector: state => {
  103. return state.not(
  104. state
  105. .selectByTag("images")
  106. .not(state.selectByTag("svgs").and(state.selectByTag("fonts")))
  107. );
  108. }
  109. }
  110. ],
  111. [
  112. {
  113. func: "markdownToHtml",
  114. selector: state => state.selectByTag("markdown")
  115. },
  116. {
  117. func: "compileTemplates",
  118. selector: state => state.selectByTag("pages"),
  119. getConfig: state => ({
  120. partials: state.selectByTag("partials"),
  121. helpers: state.selectByTag("helpers")
  122. })
  123. },
  124. {
  125. func: "copy",
  126. selector: state => state.matchingAnyTag(["styles", "svgs", "js"])
  127. }
  128. ],
  129. [
  130. {
  131. func: "decorateFileObject",
  132. selector: state =>
  133. state
  134. .selectByTag("content")
  135. .selectByTag("markdown")
  136. .not(state.selectByTag("index")),
  137. config: {
  138. decorators: [articleDecorator],
  139. cutoffLength: 180
  140. }
  141. },
  142. {
  143. func: "copy",
  144. selector: state => {
  145. return state.matchingAnyTag([
  146. "pages",
  147. "styles",
  148. "svgs",
  149. "index",
  150. "work",
  151. "js"
  152. ]);
  153. }
  154. }
  155. ],
  156. [
  157. {
  158. func: "renderTemplate",
  159. deferConfig: true,
  160. selector: state => state.selectByTag("content").selectByTag("index"),
  161. getConfig: (state, currentItem) => {
  162. const matchingTemplate = state
  163. .selectByTag("pages")
  164. .mostMatchingTags(currentItem.tags);
  165. console.log(
  166. `Rendering ${currentItem.dir}/${currentItem.name} with ${
  167. matchingTemplate.dir
  168. }/${matchingTemplate.name}`
  169. );
  170. const entries = state
  171. .selectByTag("content")
  172. .selectByTag("markdown")
  173. .matchingAllTags(currentItem.dirPath)
  174. .not(state.selectByTag("index"))
  175. .selectMany(item => item.depth <= currentItem.depth);
  176. const sections = state
  177. .matchingAllTags(currentItem.dirPath)
  178. .selectByTag("index")
  179. .not([currentItem])
  180. .selectMany(item => item.depth <= currentItem.depth + 1);
  181. return {
  182. meta: {
  183. title: currentItem.niceName,
  184. name: currentItem.name,
  185. now: new Date().toLocaleString(),
  186. context: currentItem.dirPath[1],
  187. isIndex: true,
  188. svgs: toNameContentObject(state.selectByTag("svgs")),
  189. partials: toNameContentObject(state.selectByTag("partials")),
  190. entries: entries,
  191. sections: sections,
  192. trail: [...currentItem.dirPath.slice(1), currentItem.name]
  193. },
  194. template: matchingTemplate
  195. };
  196. }
  197. },
  198. {
  199. func: "renderTemplate",
  200. deferConfig: true,
  201. selector: state =>
  202. state.selectByTag("content").not(state.selectByTag("index")),
  203. getConfig: (state, currentItem) => {
  204. const matchingTemplate = state
  205. .selectByTag("pages")
  206. .mostMatchingTags(currentItem.tags);
  207. console.log(
  208. `Rendering ${currentItem.dir}/${currentItem.name} with ${
  209. matchingTemplate.dir
  210. }/${matchingTemplate.name}`
  211. );
  212. return {
  213. meta: {
  214. title: currentItem.niceName,
  215. name: currentItem.name,
  216. now: new Date().toLocaleString(),
  217. context: currentItem.dirPath[1],
  218. isIndex: false,
  219. svgs: toNameContentObject(state.selectByTag("svgs")),
  220. partials: toNameContentObject(state.selectByTag("partials")),
  221. trail: [...currentItem.dirPath.slice(1), currentItem.name]
  222. },
  223. template: matchingTemplate
  224. };
  225. }
  226. },
  227. {
  228. func: "copy",
  229. selector: state =>
  230. state.selectByTag("styles").and(state.selectByTag("js"))
  231. }
  232. ],
  233. [
  234. {
  235. func: "minifyHtml",
  236. selector: state => state.selectAll().not(state.selectByTag("js"))
  237. },
  238. {
  239. func: "minifyJS",
  240. selector: state => state.selectByTag("js")
  241. }
  242. ],
  243. [
  244. {
  245. func: "writeOutFile",
  246. selector: state => state.selectAll(),
  247. config: { outputDir: "./output" }
  248. }
  249. ]
  250. ]
  251. };