diff --git a/.gitignore b/.gitignore index 330fb7a..22eec06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.DS_STORE node_modules views/partials/md/ -*.mp4 \ No newline at end of file +views/partials/generated/ +*.mp4 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..aac26fc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "html.format.enable": false, + "html.format.endWithNewline": true +} diff --git a/assets/css/site.css b/assets/css/site.css index 26659f7..53d3fa0 100644 --- a/assets/css/site.css +++ b/assets/css/site.css @@ -1,21 +1,21 @@ .icon-footer { - padding: 2%; - padding: 2vh; + padding: 2%; + padding: 2vh; } .bgimage { - width:100%; - height:100vh; + width: 100%; + height: 100vh; background: url('../img/logo.svg'); background-repeat: no-repeat; background-position: center; - background-size:cover; + background-size: cover; background-attachment: fixed; } .bgimage h1 { - color:white; - text-shadow:2px 2px #333; + color: white; + text-shadow: 2px 2px #333; } .center { @@ -27,7 +27,7 @@ .navbar-transparent { background-color: transparent; - border-color: rgba(255,255,255,0.4); + border-color: rgba(255, 255, 255, 0.4); } .cenMain { @@ -35,16 +35,22 @@ padding-bottom: 40%; padding-top: 40vh; padding-bottom: 40vh; - width: 60%; - margin: auto; - + width: 60%; + margin: auto; } .container-cenMain { - height: 100%; - background-position: center; - background-repeat: no-repeat; - background-size: cover; + height: 100%; + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + +.topMargin { + padding-top: 5%; + padding-top: 5vh; + width: 60%; + margin: auto; } .code { @@ -56,6 +62,8 @@ padding-left: 2%; } -.card { +.card-homepage { background-color: rgba(0, 0, 0, 0.1) !important; -} \ No newline at end of file + padding: 2%; + height: 100%; +} diff --git a/assets/img/favicon.ico b/assets/img/favicon.ico new file mode 100644 index 0000000..cef459b Binary files /dev/null and b/assets/img/favicon.ico differ diff --git a/assets/img/recipes/chocolateChipCookies.jpg b/assets/img/recipes/chocolateChipCookies.jpg new file mode 100644 index 0000000..956415d Binary files /dev/null and b/assets/img/recipes/chocolateChipCookies.jpg differ diff --git a/assets/img/recipes/cinnamonRolls.jpeg b/assets/img/recipes/cinnamonRolls.jpeg new file mode 100644 index 0000000..5ea77ef Binary files /dev/null and b/assets/img/recipes/cinnamonRolls.jpeg differ diff --git a/assets/img/recipes/coconutClouds.jpg b/assets/img/recipes/coconutClouds.jpg new file mode 100644 index 0000000..2655adf Binary files /dev/null and b/assets/img/recipes/coconutClouds.jpg differ diff --git a/assets/img/recipes/karaChili.jpg b/assets/img/recipes/karaChili.jpg new file mode 100644 index 0000000..39d97e5 Binary files /dev/null and b/assets/img/recipes/karaChili.jpg differ diff --git a/assets/img/recipes/karaLentil.jpg b/assets/img/recipes/karaLentil.jpg new file mode 100644 index 0000000..a5d8a83 Binary files /dev/null and b/assets/img/recipes/karaLentil.jpg differ diff --git a/package-lock.json b/package-lock.json index 24a431f..cb0001d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,11 @@ "dynamic-scrollspy": "^0.2.0", "ejs": "^3.1.8", "express": "^4.17.1", + "markdown-it": "^13.0.1", + "markdown-it-hashtag": "^0.4.0", "mkdirp": "^1.0.4", - "showdown": "^1.9.1", - "showdown-highlight": "^2.1.8" + "showdown": "^2.1.0", + "showdown-highlight": "^3.0.0" } }, "node_modules/accepts": { @@ -29,24 +31,10 @@ "node": ">= 0.6" } }, - "node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", @@ -100,14 +88,6 @@ "node": ">= 0.8" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -153,29 +133,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "node_modules/commander": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", + "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==", + "engines": { + "node": "^12.20.0 || >=14" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -221,14 +186,6 @@ "ms": "2.0.0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -266,11 +223,6 @@ "node": ">=0.10.0" } }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -279,6 +231,17 @@ "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -376,17 +339,6 @@ "node": ">= 0.8" } }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -403,14 +355,6 @@ "node": ">= 0.6" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -428,11 +372,11 @@ } }, "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.5.1.tgz", + "integrity": "sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==", "engines": { - "node": "*" + "node": ">=12.0.0" } }, "node_modules/html-encoder-decoder": { @@ -484,14 +428,6 @@ "node": ">= 0.10" } }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, "node_modules/iterate-object": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz", @@ -514,18 +450,39 @@ "node": ">=10" } }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "uc.micro": "^1.0.1" } }, + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-hashtag": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-hashtag/-/markdown-it-hashtag-0.4.0.tgz", + "integrity": "sha512-+VCMH+f4/Ud5wPEtcAMrlLbUrrGViwR9JvjPy//X3Z7ZG1j5nQuHtDLTGZfMhkqYTMY+cTZgZkVNBsXMfU93Yg==" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -623,36 +580,6 @@ "node": ">= 0.8" } }, - "node_modules/p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -661,14 +588,6 @@ "node": ">= 0.8" } }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -721,19 +640,6 @@ "resolved": "https://registry.npmjs.org/regex-escape/-/regex-escape-3.4.10.tgz", "integrity": "sha512-qEqf7uzW+iYcKNLMDFnMkghhQBnGdivT6KqVQyKsyjSWnoFyooXVnxrw9dtv3AFLnD6VBGXxtZGAQNFGFTnCqA==" }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -786,35 +692,34 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, "node_modules/setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "node_modules/showdown": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", - "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", "dependencies": { - "yargs": "^14.2" + "commander": "^9.0.0" }, "bin": { "showdown": "bin/showdown.js" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/tiviesantos" } }, "node_modules/showdown-highlight": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/showdown-highlight/-/showdown-highlight-2.1.8.tgz", - "integrity": "sha512-WqrMzMPYrWEwbA03GJT8mc82QxTe91kFwvNWpEPfTgEwd/5G32d44bn5Z7zMYgOcePnXInmYClldezqHDAyGZg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/showdown-highlight/-/showdown-highlight-3.0.0.tgz", + "integrity": "sha512-xrMPNGaECoFMueD3uortV5r69NFY4oZp50QTrHf21T6aYgBO6FBdv5ibBvGd2atd/FeSsPjUhJOipLL6pwELhg==", "dependencies": { - "highlight.js": "^10.7.2", + "highlight.js": "^11.5.0", "html-encoder-decoder": "^1.3.9", - "showdown": "^1.9.1" + "showdown": "^2.0.3" } }, "node_modules/statuses": { @@ -825,30 +730,6 @@ "node": ">= 0.6" } }, - "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -880,6 +761,11 @@ "node": ">= 0.6" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -903,56 +789,6 @@ "engines": { "node": ">= 0.8" } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" - }, - "node_modules/yargs": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", - "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", - "dependencies": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.0" - } - }, - "node_modules/yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } }, "dependencies": { @@ -965,18 +801,10 @@ "negotiator": "0.6.2" } }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "array-flatten": { "version": "1.1.1", @@ -1024,11 +852,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1061,28 +884,10 @@ } } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "commander": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", + "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==" }, "concat-map": { "version": "0.0.1", @@ -1120,11 +925,6 @@ "ms": "2.0.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1153,16 +953,16 @@ "jake": "^10.8.5" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1250,14 +1050,6 @@ "unpipe": "~1.0.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1268,11 +1060,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1284,9 +1071,9 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.5.1.tgz", + "integrity": "sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==" }, "html-encoder-decoder": { "version": "1.3.9", @@ -1328,11 +1115,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, "iterate-object": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz", @@ -1349,15 +1131,36 @@ "minimatch": "^3.0.4" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "uc.micro": "^1.0.1" } }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-hashtag": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-hashtag/-/markdown-it-hashtag-0.4.0.tgz", + "integrity": "sha512-+VCMH+f4/Ud5wPEtcAMrlLbUrrGViwR9JvjPy//X3Z7ZG1j5nQuHtDLTGZfMhkqYTMY+cTZgZkVNBsXMfU93Yg==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1422,37 +1225,11 @@ "ee-first": "1.1.1" } }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -1493,16 +1270,6 @@ "resolved": "https://registry.npmjs.org/regex-escape/-/regex-escape-3.4.10.tgz", "integrity": "sha512-qEqf7uzW+iYcKNLMDFnMkghhQBnGdivT6KqVQyKsyjSWnoFyooXVnxrw9dtv3AFLnD6VBGXxtZGAQNFGFTnCqA==" }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1551,32 +1318,27 @@ "send": "0.17.1" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "showdown": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", - "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", "requires": { - "yargs": "^14.2" + "commander": "^9.0.0" } }, "showdown-highlight": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/showdown-highlight/-/showdown-highlight-2.1.8.tgz", - "integrity": "sha512-WqrMzMPYrWEwbA03GJT8mc82QxTe91kFwvNWpEPfTgEwd/5G32d44bn5Z7zMYgOcePnXInmYClldezqHDAyGZg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/showdown-highlight/-/showdown-highlight-3.0.0.tgz", + "integrity": "sha512-xrMPNGaECoFMueD3uortV5r69NFY4oZp50QTrHf21T6aYgBO6FBdv5ibBvGd2atd/FeSsPjUhJOipLL6pwELhg==", "requires": { - "highlight.js": "^10.7.2", + "highlight.js": "^11.5.0", "html-encoder-decoder": "^1.3.9", - "showdown": "^1.9.1" + "showdown": "^2.0.3" } }, "statuses": { @@ -1584,24 +1346,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1624,6 +1368,11 @@ "mime-types": "~2.1.24" } }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1638,53 +1387,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" - }, - "yargs": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", - "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.0" - } - }, - "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } } diff --git a/package.json b/package.json index 5f2ea0e..77b3813 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,15 @@ "bugs": { "url": "https://github.com/len0rd/personal-website/issues" }, - "homepage": "https://github.com/len0rd/personal-website#readme", + "homepage": "https://github.com/len0rd/personal-website", "dependencies": { "dynamic-scrollspy": "^0.2.0", "ejs": "^3.1.8", "express": "^4.17.1", + "markdown-it": "^13.0.1", + "markdown-it-hashtag": "^0.4.0", "mkdirp": "^1.0.4", - "showdown": "^1.9.1", - "showdown-highlight": "^2.1.8" + "showdown": "^2.1.0", + "showdown-highlight": "^3.0.0" } } diff --git a/prestart.js b/prestart.js index 7dba6e3..eee84d4 100644 --- a/prestart.js +++ b/prestart.js @@ -5,73 +5,258 @@ // md changes), it is more efficient in // that we aren't converting MD -> ejs // on EVERY request -const showdown = require('showdown'), +const showdown = require('showdown'), showdownHighlight = require("showdown-highlight"), - fs = require('fs'), - mkdirp = require('mkdirp'), - inputDir = './project_writeups/', - outputDir = './views/partials/md/', - classMap = { + fs = require('fs'), + mkdirp = require('mkdirp'), + projectInputDir = './project_writeups/', + projectOutputDir = './views/partials/md/projects/', + recipeInputDir = './recipes/', + recipeOutputDir = './views/partials/md/recipes/', + recipeListGeneratedOutputDir = './views/partials/generated/', + projectClassMap = { h1: 'display-1' //tag type : class to add to all tags of that type (class="display-1" added to all

) }; +const { assert } = require('console'); + + +function addClassToTag(text, classMap) { + var modifiedText = text; + Object.keys(classMap).forEach(function (key) { + var regex = new RegExp(`<(${key})(.*?)>`, 'g'); + matcher = regex.exec(modifiedText); + + // only proceed if we found a match, and the class we add isn't already on the tag somehow + while (matcher != null && !matcher[2].includes(classMap[key])) { + // add the class content WHILE preserving any other properties already in the tag! + console.log("adding class content in: " + matcher[0]); + + var restOfTag = matcher[2]; + modifiedText = modifiedText.replace(matcher[0], `<${key} class="${classMap[key]}" ${restOfTag}>`); + + matcher = regex.exec(modifiedText); + } + }); + return modifiedText; +} // handles adding classes to specific -// tag types automatically -const addClass = { +// tag types automatically in project writeups +const projectsAddHeaderClass = { type: 'output', // when it's triggered -> output is at the very end when text is html - filter: text => { - var modifiedText = text; - Object.keys(classMap).forEach(function(key) { - var regex = new RegExp(`<${key}(.*?)>`, 'g'); - matcher = regex.exec(modifiedText); - - // only proceed if we found a match, and the class we add isn't already on the tag somehow - while (matcher != null && !matcher[0].includes(classMap[key])) { - // add the class content WHILE preserving any other properties already in the tag! - console.log("adding class content in: " + matcher[0]); - - var restOfTag = matcher[1]; - modifiedText = modifiedText.replace(matcher[0], `<${key} class="${classMap[key]}" ${restOfTag}>`); - - matcher = regex.exec(modifiedText); - } - }); - return modifiedText; - } + filter: text => { return addClassToTag(text, projectClassMap); } }; -// create our Showdown converter with our custom extension -const converter = new showdown.Converter({ - extensions: [addClass, showdownHighlight], +// create Showdown converters +const projectsConverter = new showdown.Converter({ + extensions: [projectsAddHeaderClass, showdownHighlight], + tables: true }); -// make the directory for our html output if necessary -mkdirp(outputDir, null, (err) => { - if (err) { - console.error(err); - } else { - console.log('output dir created'); +function convertMarkdownInDirWithShowdown(inputDir, outputDir, converter) { + // make the directory for the html output if necessary + mkdirp.sync(outputDir); + fs.readdir(inputDir, (err, files) => { + files.forEach(file => { + if (file.endsWith('.md')) { + let fileNameNoExtension = file.slice(0, -3); + console.log('converting: ' + fileNameNoExtension); + fs.readFile(inputDir + file, 'utf8', (err, data) => { + if (err) { + console.error(err); + } else { + let html = converter.makeHtml(data); // where the magic happens + fs.writeFile(outputDir + fileNameNoExtension + '.ejs', html, 'utf8', (err) => { + if (err) { + console.error(err); + } + }); + } + }); + } + }); + }); +} + +function convertRecipeMarkdown(inputDir, outputDir) { + var md = require('markdown-it')() + .use(require('markdown-it-hashtag')); + + md.renderer.rules.hashtag_open = function (tokens, idx) { + var tagName = tokens[idx].content.toLowerCase(); + return ''; } -}); -// Lets start the actual conversion! -fs.readdir(inputDir, (err, files) => { - files.forEach(file => { - if (file.endsWith('.md')) { + md.renderer.rules.hashtag_close = function () { return ''; } + + // This is a hardcoded markdown header section number to html file name + // + // Example.md: + // """ + // ... maybe some other header info here -| - exported as filename-title.ejs + // # Delicious Recipe Name -| + // Catch phrase or yield -| + // | - exported as filename-subtitle + // image of the food | + // -| + // ## Ingredients -| + // ... ingredients table, etc | - exported as filename-ingredients.ejs + // -| + // ## Instructions + // """ + // + // NOTE: these titles are HARDCODED in recipe_template.ejs! + const mdSectionHtmlTitles = [ + 'title', + // 'subtitle', + 'ingredients', + 'instructions', + ] + + mkdirp.sync(outputDir); + fs.readdir(inputDir, (err, files) => { + files.forEach(file => { + if (!file.endsWith('.md')) { + return; + } let fileNameNoExtension = file.slice(0, -3); console.log('converting: ' + fileNameNoExtension); fs.readFile(inputDir + file, 'utf8', (err, data) => { if (err) { console.error(err); - } else { - let html = converter.makeHtml(data); // where the magic happens - fs.writeFile(outputDir + fileNameNoExtension + '.ejs', html, 'utf8', (err) => { - if (err) { - console.error(err); + return; + } + + var ingredientTableRegex = new RegExp(`^(\\|?.*?)\\|(.*?)(\\|.*?\\|.*?)\n`, `gm`); + var ingredientDashCheck = new RegExp("^\-+$"); + ingredientTableMatcher = ingredientTableRegex.exec(data); + while (ingredientTableMatcher != null) { + meas = ingredientTableMatcher[1]; + let unit = ingredientTableMatcher[2].toLowerCase().trim(); + if (unit != "unit" && unit && !ingredientDashCheck.test(unit)) { + meas += unit + " "; + } + data = data.replace(ingredientTableMatcher[0], `${meas}${ingredientTableMatcher[3]}\n`); + ingredientTableMatcher = ingredientTableRegex.exec(data); + } + ingredientTableMatcher = ingredientTableRegex.exec(data); + while (ingredientTableMatcher != null) { + meas = ingredientTableMatcher[1]; + let unit = ingredientTableMatcher[2].toLowerCase().trim(); + if (unit != "unit" && unit && !ingredientDashCheck.test(unit)) { + meas += unit + " "; + } + data = data.replace(ingredientTableMatcher[0], `${meas}${ingredientTableMatcher[3]}\n`); + ingredientTableMatcher = ingredientTableRegex.exec(data); + } + + let tokens = md.parse(data) + + let sections = [] + sections.push([]); // start off the array and put everything before and including the first header in title + let numSections = 0; + for (const token of tokens) { + if (token.type === 'heading_open') { + if (numSections == 0) { + numSections++; } - }); + else if (numSections < mdSectionHtmlTitles.length) { + numSections++; + sections.push([]); + } + } + sections[sections.length - 1].push(token) + } + + assert(sections.length <= mdSectionHtmlTitles.length); + + // hardcode bootstrap class attribute to add to tag in ingredients + for (let ii = 0; ii < sections[1].length; ii++) { + if (sections[1][ii].type == 'table_open') { + sections[1][ii].attrs = [["class", "table table-striped table-sm table-hover"]]; + break; + } + } + + for (let ii = 0; ii < sections.length; ii++) { + let html = md.renderer.render(sections[ii], md.options); + // hardcode making images in the title section larger + if (ii == 0) { + var regex = new RegExp(``, `g`); + matcher = regex.exec(html); + while (matcher != null && !matcher[1].includes("w-100")) { + var restOfTag = matcher[1]; + html = html.replace(matcher[0], ``); + matcher = regex.exec(html); + } + } + fs.writeFileSync(outputDir + fileNameNoExtension + '-' + mdSectionHtmlTitles[ii] + '.ejs', html, 'utf8'); } }); - } + }); }); -}); +} + +function generateRecipeNavigatorList(recipeSrcDir, generatedOutputDir) { + // generate a list of recipe links. While doing so generate an array + // of unique hashtags found in all recipes + mkdirp.sync(generatedOutputDir); + let recipeListPartialOut = ""; + let allRecipeHashtags = []; + fs.readdir(recipeSrcDir, (err, files) => { + files.sort().forEach(file => { + if (!file.endsWith('.md')) { + return; + } + let fileNameNoExtension = file.slice(0, -3); + + const data = fs.readFileSync(recipeSrcDir + file, { encoding: 'utf8', flag: 'r' }); + + // find all hashtags in the file + var hashtagRegex = new RegExp(`#(\\w+)`, `g`); + hashtagMatcher = hashtagRegex.exec(data); + var recipeTags = []; // hashtags of the current recipe only + while (hashtagMatcher != null) { + var hashtag = hashtagMatcher[1].toLowerCase(); + if (!allRecipeHashtags.includes(hashtag)) { + allRecipeHashtags.push(hashtag); + } + if (!recipeTags.includes(hashtag)) { + recipeTags.push(hashtag); + } + hashtagMatcher = hashtagRegex.exec(data); + } + + let combinedRecipeTags = ""; + if (recipeTags.length > 0) { + combinedRecipeTags = recipeTags.join(","); + } + + // get first recipe title from document + var titleRegex = new RegExp(`#\\s+(.+)\\n`, `g`); + titleMatcher = titleRegex.exec(data); + var recipeTitle = fileNameNoExtension; + if (titleMatcher != null) { + recipeTitle = titleMatcher[1]; + } + + recipeListPartialOut += `${recipeTitle}\n`; + }); + + // writeout the link list partial + fs.writeFileSync(generatedOutputDir + "recipe-links.ejs", recipeListPartialOut, "utf-8"); + + // now generate the hashtag button list partial + // TODO: in the future sort the list by number of hashtag hits (most -> least common) + // instead of alphabetically + let tagListPartialOut = ""; + allRecipeHashtags.sort().forEach(hashtag => { + tagListPartialOut += `\n`; + }); + fs.writeFileSync(generatedOutputDir + "recipe-tags.ejs", tagListPartialOut, "utf-8"); + }); +} + +convertMarkdownInDirWithShowdown(projectInputDir, projectOutputDir, projectsConverter); +convertRecipeMarkdown(recipeInputDir, recipeOutputDir); +generateRecipeNavigatorList(recipeInputDir, recipeListGeneratedOutputDir); diff --git a/project_writeups/palletDesk.md b/project_writeups/palletDesk.md index 2e178e4..ccbeb9c 100755 --- a/project_writeups/palletDesk.md +++ b/project_writeups/palletDesk.md @@ -28,15 +28,15 @@ With the requirements thought out, I started planning how I was going to build e There were some really cool designs online, but I needed something simple. This was my first woodworking project, and I knew I *would* (hehe) be making a lot of mistakes. All of these thoughts culminated into a single whiteboard sketch: -![Whiteboard sketch of ititial design](/img/writeup/palletDesk/plans-1-sm.jpg) +![Whiteboard sketch of initial design](/img/writeup/palletDesk/plans-1-sm.jpg) Yep. That's it. It was all a lot clearer in my head. Essentially the red 'rectangles' are 2x4 cross beams that would support the desktop and create a structure to build onto. The measurements were mainly based on what would fit in my Camry. Note: this only fits in the car when I put the back seats down so the desk can go through the trunk and into the back of the car. pics further down. I also measured a few desks nearby to see what an appropriate depth for a monitor + keyboard would be. ## Build -### Pallet Aquisition +### Pallet Acquisition -There are a lot of guides on how to get pallets online. If you're in the US, check the free section of Craigslist or your local classifieds. You can also just walk into local places and ask if they have any pallets that you can use. Alternatively, just drive behind businesses and see if they have pallets stacked near the dumpster. +There are a lot of guides on how to get pallets online. If you're in the US, check the free section of Craigslist or your local classifieds. You can also just walk into local places and ask if they have any pallets that you can use. Alternatively, just drive behind businesses and see if they have pallets stacked near the dumpster. If you have a smaller car, be prepared to potentially tear down the pallet on site. Pallets were a bit larger than I expected and some of them would not fit in my car! Because of this, I had to pass up on some of the nicer pallets out there. In all, I think this project took 2-3 pallets. It could be done with less, but my teardown methods were less than ideal. @@ -44,9 +44,9 @@ The problem with pallet wood is that it's a bit of a mixed bag. Sometimes you ge ### Pallet Teardown -The best way to get usable wood from a pallet is to use a jig saw. Period. If you don't have one, buy one online or borrow a friends. It's worth it especially if you want to do a lot of projects like this. With a jig saw, it's very easy to align the blade between the pallet planks and cut through the nails holding them in place. If you have room to spare, you could also use a table saw and just cut off the pallet planks before they're nailed into the base. +The best way to get usable wood from a pallet is to use a jig saw. Period. If you don't have one, buy one online or borrow a friends. It's worth it especially if you want to do a lot of projects like this. With a jig saw, it's very easy to align the blade between the pallet planks and cut through the nails holding them in place. If you have room to spare, you could also use a table saw and just cut off the pallet planks before they're nailed into the base. -If you're a poor college student as I was, the other option is a crowbar, hammer and *a lot* of patience. With this method you need to jimmy the crow bar in between the pallet plank and base and slowely wedge out the nails holding the plank in place. Making sure you dont strain one end of the plank too much and crack it. This is a delicate process that takes a long time and often ends in breaking the pallet planks much to the despair of the builder. +If you're a poor college student as I was, the other option is a crowbar, hammer and *a lot* of patience. With this method you need to jimmy the crow bar in between the pallet plank and base and slowely wedge out the nails holding the plank in place. Making sure you dont strain one end of the plank too much and crack it. This is a delicate process that takes a long time and often ends in breaking the pallet planks much to the despair of the builder. Because of this expense of learning, Perhaps only 50% of the 3 pallets I had turned out usable. Unfortunately I don't have any images of this stage of the process likely due to the rage-inducing nature of it all. I worked on this portion of the project at night after getting home from school across a couple of days. @@ -70,7 +70,7 @@ Also, for this entire project, wood was cut to size using my friends chop saw. N ![Closeup of desktop frame with crossbeams](/img/writeup/palletDesk/build-4-sm.jpg) -With the basic frame in place, it was time to start building the visible part of the desktop. I started by bordering the exterior with pallet plants to make something like a picture frame for the middle. The chop saw came in handy, helping make angles that match. +With the basic frame in place, it was time to start building the visible part of the desktop. I started by bordering the exterior with pallet plants to make something like a picture frame for the middle. The chop saw came in handy, helping make angles that match. ![Desktop border mostly in place](/img/writeup/palletDesk/build-5-sm.jpg) @@ -86,9 +86,9 @@ Once the crate paper was secured I started cutting and fitting pallet planks. I Once a single board was pushed to the far right side, It would be secured on the 3 2x4 frame pieces with screws and glue. Once all the pieces were secured I went back and started sanding. The desktop was made from a combination of three different pallets, so the wood was vastly different in quality and thickness. -My **biggest** regret in this project was not spending enough time sanding the top. Especially the middle of the desk, I should've spend multiple hours sanding it, with multiple passes at different levels of courseness to make sure it was smooth and flat. A planar and/or a really good electric sander should be a must for this portion of the project. A single board in the middle of my destop is slightly thicker than the others, which means my keyboard can not lie flat without wobbling. +My **biggest** regret in this project was not spending enough time sanding the top. Especially the middle of the desk, I should've spend multiple hours sanding it, with multiple passes at different levels of courseness to make sure it was smooth and flat. A planar and/or a really good electric sander should be a must for this portion of the project. A single board in the middle of my destop is slightly thicker than the others, which means my keyboard can not lie flat without wobbling. -If you plan on covering the top in epoxy as I did, this is also a good time to make *sure* any and all holes are filled with wood filler (I made wood filler by mixing wood glue with some sawdust). You dont want anywhere for the epoxy to escape so make sure all the old nail holes on the pallet boards are properly filled. +If you plan on covering the top in epoxy as I did, this is also a good time to make *sure* any and all holes are filled with wood filler (I made wood filler by mixing wood glue with some sawdust). You dont want anywhere for the epoxy to escape so make sure all the old nail holes on the pallet boards are properly filled. ### Legs @@ -138,4 +138,4 @@ And, in case you doubted, here's the desk broken down and in the trunk of my Cam The desk works great, and overall the design is very forgiving to rookie mistakes. Make sure you have the proper tools (Jigsaw) for pallet dissassembly. Dont skimp on sanding the desktop, and if you're going to use epoxy, make *absolutely* sure that you have adequately filled in all the nail holes in the pallet wood before application. -![Done! 4](/img/writeup/palletDesk/finished-1-lg.jpg) \ No newline at end of file +![Done! 4](/img/writeup/palletDesk/finished-1-lg.jpg) diff --git a/recipes/bananaBread.md b/recipes/bananaBread.md new file mode 100644 index 0000000..5b1edb2 --- /dev/null +++ b/recipes/bananaBread.md @@ -0,0 +1,25 @@ +# Banana Bread + +#bread #dessert + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1/4 | c | | Cinnamon-Sugar +3 | c | | Sugar +3 | | | Eggs +6 | | | Banana +3/4 | c | | Butter +16 | oz | | Sour Cream +2 | tsp | | Vanilla +2 | tsp | | Cinnamon +1/2 | tsp | | Salt +3 | tsp | | Baking Soda +4 1/2 | c | | Flour + +## Instructions + +1. Cream butter and 3c Sugar. Mix in eggs, bananas, sour cream, vanilla and cinnamon +2. Add salt, baking soda and flour. Mix well. Optionally add chocolate chips +3. Preheat to 300. Grease bread pans and dust with cinnamon sugar. Fill ~3/4 pan with dough. Bake 1hr, or until a toothpick removes cleanly diff --git a/recipes/chocolateChipCookies.md b/recipes/chocolateChipCookies.md new file mode 100644 index 0000000..64ad564 --- /dev/null +++ b/recipes/chocolateChipCookies.md @@ -0,0 +1,32 @@ +# Chocolate Chip Cookies + +#dessert #cookie + +*yields: ~4 dozen* + +![Cookies](/img/recipes/chocolateChipCookies.jpg) + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 | c | | Unsalted Butter +1 1/4 | c | 290g | Brown Sugar +1/4 | c | 60g | Sugar +1 | | | Egg +1 | | | Egg Yolk +2 | tbsp | | Whole Milk +1 1/2 | tsp | | Vanilla +2 3/4 | c | 370g | Flour +1 | tsp | 7g | Baking Soda +1 | tsp | 7g | Salt +1/4 | tsp | 1g | Cinnamon +2 | c | | Chocolate Chip + +## Instructions + +1. Melt butter on stove. In a medium bowl sift flour, salt and baking soda together, set aside. +2. Mix butter and sugars for 2 minutes +3. In a separate bowl, whisk together egg, egg yolk, milk and vanilla. Add to mixer and mix until thoroughly combined. +4. Gradually add dry ingredients until you have the proper consistency (generally not all the mixture). Mix in chocolate chips. Refrigerate for 1 hour. +5. Preheat oven to 355. Bake for 10 minutes (temp may vary depending on oven and altitude) diff --git a/recipes/cinnamonRolls.md b/recipes/cinnamonRolls.md new file mode 100644 index 0000000..502617f --- /dev/null +++ b/recipes/cinnamonRolls.md @@ -0,0 +1,28 @@ +# Cinnamon Rolls + +#breakfast #bread #dessert + +![Cinnamon Roll](/img/recipes/cinnamonRolls.jpeg) + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +4 3/4 | c | | Flour +1 1/2 | tsp | | Salt +1/3 | c | | Sugar +1/3 | c | | Oil +2 | | | Eggs +1 1/4 | c | | Warm water (110F) +2 | tbsp | | Yeast +4 | tbsp | | Melted Butter +1/2 | c | | Cinnamon Sugar + + +## Instructions + +1. Mix sugar, water and yeast. Let bloom 5m. Beat Eggs. Add oil, egg, salt, 2c flour. Mix well +2. Add the rest of the flour until you have a stiff dough. Hand knead 5min. Let rise 15m +3. Roll out into rectangular shape on floured surface. Brush with butter, sprinkle with cinnamon sugar +4. Roll up dough and cut in 1-1/2” slices. Place in rectangular pan and press. +5. Let rise 10m. Preheat to 425. Bake for 12-15m until golden brown diff --git a/recipes/coconutMeringueMacaroons.md b/recipes/coconutMeringueMacaroons.md new file mode 100644 index 0000000..284050b --- /dev/null +++ b/recipes/coconutMeringueMacaroons.md @@ -0,0 +1,22 @@ +# Coconut Meringue Macaroons + +#dessert + +![CoconutClouds](/img/recipes/coconutClouds.jpg) + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 1/4 | c | 250g | Sugar +3/4 | c | 180g | Water +3 | | 102g | Egg Whites +3 | c | 227g | Coconut + +## Instructions + +1. Toast coconut by spreading evenly on a sheet and baking at 325. Check/stir every 2-3 minutes until lightly browned. +2. Combine sugar and water in saucepan over medium heat. Stir until clear. Bring to a boil and watch on candy thermometer for soft ball. +3. While sugar cooks, place egg whites in stand mixer. Time so they reach medium peaks when sugar mixture hits soft ball. +4. When sugar ready, put mixer on medium-low and slowly add to egg whites. Once incorporated, mix on high until back at room temperature. Fold in toasted coconut and scoop onto sheet. +5. Bake 12 minutes at 325 diff --git a/recipes/drunkBananas.md b/recipes/drunkBananas.md new file mode 100644 index 0000000..a96f0e8 --- /dev/null +++ b/recipes/drunkBananas.md @@ -0,0 +1,20 @@ +# Drunk Bananas + +#dessert + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +3 | | | Bananas +1/3 | c | | Brandy or Rum +Dash | | | Cinnamon +1/2 | c | | Butter +1 | c | | Brown Sugar +1 | tsp | | Vanilla + +## Instructions + +1. Quarter bananas In a frying pan, mix butter and brown sugar over medium heat for a sticky caramel +2. Add vanilla, bananas and brandy/rum to the caramel, mix +3. Ignite the alcohol. Sprinkle cinnamon into the flames. Allow all alcohol to burn out. Serve with ice cream diff --git a/recipes/hotFudgePudding.md b/recipes/hotFudgePudding.md new file mode 100644 index 0000000..a05cf34 --- /dev/null +++ b/recipes/hotFudgePudding.md @@ -0,0 +1,25 @@ +# Hot Fudge Pudding + +#dessert + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 1/2 | c | | Flour +3 | tsp | | Baking Powder +1/2 | tsp | | Salt +3/4 | c | | Sugar +3 | tbsp | | Cocoa +3/4 | c | | Milk +3 | tbsp | | Oil +1 | c | | Brown Sugar +1/4 | c | | Cocoa +2 1/4 | c | | Water + +## Instructions + +1. Mix flour, baking powder, salt, sugar and 3T cocoa. Stir in milk and oil. Pour into 2q baking dish +2. Combine brown sugar and 1/4c cocoa. Distribute evenly over batter in pan +3. Heat water. Pour hot water over everything +4. Bake 45 minutes at 375. Serve warm with whipped cream or ice cream diff --git a/recipes/jillyChicken.md b/recipes/jillyChicken.md new file mode 100644 index 0000000..cbe0184 --- /dev/null +++ b/recipes/jillyChicken.md @@ -0,0 +1,23 @@ +# Jilly Chicken + +#dinner #chicken + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 | Ib | | Chicken +1/2 | c | | Soy Sauce +1/2 | c | | Lemon Juice +1/2 | c | | Oil +1 | tbsp | | Basil + +## Instructions + +1. Cut chicken in strips (about the size of chicken fingers) +2. Combine all other ingredients in the pan you plan to cook the chicken in +3. Lay each piece of chicken in the sauce so they are not overlapped (touching is ok) +4. Marinate chicken for 30-60 minutes, preheat oven to 350 +5. Bake the marinated chicken in the sauce for 30ish minutes, or until done +Note: take the pan out of the oven and flip the chicken pieces (using a fork) after 10 minutes of baking. +6. Enjoy on rice diff --git a/recipes/karaChili.md b/recipes/karaChili.md new file mode 100644 index 0000000..6be5a7e --- /dev/null +++ b/recipes/karaChili.md @@ -0,0 +1,26 @@ +# Kara's Chili + +#dinner #soup + +![Chili](/img/recipes/karaChili.jpg) + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +2 | can | | Kidney Beans +2 | can | | Pinto Beans +2 | can | | Black Beans +1 (8oz) | can | | Tomato Paste +1 | can | | Petite Diced Tomatoes +4 | clove | | Garlic +1 | Ib | | Ground Beef +| | | | Salt +| | | | Pepper +| | | | Cumin +| | | | Cayenne Pepper + +## Instructions + +1. Brown beef on medium heat. Mince garlic while it cooks +2. Remove excess fat. Add everything. Season to taste. Let simmer 20m diff --git a/recipes/karaLentil.md b/recipes/karaLentil.md new file mode 100644 index 0000000..bf8cc99 --- /dev/null +++ b/recipes/karaLentil.md @@ -0,0 +1,37 @@ +# Kara's Lentils + +#dinner #soup + +![Lentils](/img/recipes/karaLentil.jpg) + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 | Ib | | Lentil +2 | | | Potato +2 | | | Red Bell Pepper +2 | | | Jalapeño +8 | clove | | Garlic +6 | tbsp | | Curry Powder +6 | c | | Chicken Broth +| | | | Cumin +| | | | Cayenne Pepper +| | | | Turmeric +| | | | Coriander +| | | | Plain Yogurt +| | | | Mustard Seeds +1 | bunch | | Cilantro +2 | tbsp | | Sesame Oil + +## Instructions + +1. Wash and dry produce +2. Small dice potatoes, jalapeños and bell pepper +3. Warm sesame oil in large pot +4. Once oil is warm, add mustard seeds. Stir occassionally until they start to pop +5. Add diced potato and fry until slightly tender. Add lentils +6. Add all the seasonings and mix until the potatoes and lentils are evenly coated +7. Pour in broth. Add all fresh vegetables +8. Bring to a boil. Then simmer, stirring occasionally until lentils are tender +9. Serve in bowls with a dollop of yogurt and a sprinkle of cilantro diff --git a/recipes/monkeyBread.md b/recipes/monkeyBread.md new file mode 100644 index 0000000..36a89a2 --- /dev/null +++ b/recipes/monkeyBread.md @@ -0,0 +1,22 @@ +# Monkey Bread + +#bread #dessert #breakfast + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +4 | | | Biscuit Cans +2/3 | c | | Sugar +1 1/2 | tsp | | Cinnamon +**Sauce** | | | +1 1/8 | c | | Butter +1 1/2 | c | | Sugar +1 1/2 | tsp | | Cinnamon + +## Instructions + +1. Quarter biscuits. Combine sugar and cinnamon in bowl +2. Toss biscuits in bowl, coating each with cinnamon sugar. Dump into greased pan +3. Boil sauce ingredients over low heat fo 2-3 minutes, stirring constantly. Pour over biscuits in pan +4. Bake at 350 for 30-35m. Cool for 10m diff --git a/recipes/peppermintBrownies.md b/recipes/peppermintBrownies.md new file mode 100644 index 0000000..97b3478 --- /dev/null +++ b/recipes/peppermintBrownies.md @@ -0,0 +1,25 @@ +# Peppermint Brownies + +#dessert + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +17 | | | York Patties +3/4 | c | | Cocoa +1/2 | tsp | | Baking Soda +2/3 | c | | Butter +1/2 | c | | Water +2 | c | | Sugar +2 | | | Egg +1 1/3 | c | | Flour +1 | tsp | | Vanilla +1 | tsp | | Powdered Sugar + +## Instructions + +1. Coarsely chop peppermint patties, set aside. Bring water to a boil +2. Mix cocoa and baking soda in large bowl. Melt and mix in 1/3c butter. Add boiling water, mix well +3. Add sugar, eggs and remaining butter. Add flour, vanilla and salt. Mix well, then stir in York pieces +4. Preheat oven to 350. Grease pan well and sprinkle with cinnamon before spreading batter. Bake 35-40m diff --git a/recipes/pizzaDough.md b/recipes/pizzaDough.md new file mode 100644 index 0000000..ce5435d --- /dev/null +++ b/recipes/pizzaDough.md @@ -0,0 +1,21 @@ +# Pizza Dough + +#bread #italian + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +2 1/2 | c | | Flour +1 | tsp | 7g | Salt +1 | tsp | | Sugar +2 | tbsp | | Olive Oil +1 | c | | Warm Water (110F) +2 1/3 | tsp | | Yeast + +## Instructions + +1. Dissolve yeast and sugar in warm water. Let bloom (10m) +2. Mix in flour, salt and oil. Beat until smooth. Rest 5m +3. Roll dough into desired shape on lightly floured surface. Transfer to lightly greased pan or parchment paper dusted with cornmeal +4. Preheat to 450. Bake 15-20m. Let cool 5m diff --git a/recipes/spinachCasserole.md b/recipes/spinachCasserole.md new file mode 100644 index 0000000..95e0650 --- /dev/null +++ b/recipes/spinachCasserole.md @@ -0,0 +1,36 @@ +# Spinach Casserole + +#dinner #chicken + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 | c | | Sour Cream +1/3 | c | | Milk +1/2 | tsp | | Garlic Powder +1/4 | tsp | | Cumin +Dash | | | Hot Pepper Sauce +1 | can | | Cream of Chicken +9 | oz | | Frozen Chopped Spinach +2-3 | c | | Cubed Chicken, cooked +1 | c | | Shredded Monterey Jack Cheese +1/2 | c | | Shredded Cheddar +**Topping** | | | +2 | | | Egg +1 | c | | Flour +1 1/2 | tsp | | Baking Powder +3/4 | c | | Milk +1/4 | c | | Butter +Dash | | | Paprika + +## Instructions + +1. Grease 2qt casserole pan. +2. In large bowl: combine sour cream, milk, garlic salt, cumin, hot pepper sauce, soup, spinach and chilies. Blend well +3. In second bowl: combine chicken and cheeses, toss lightly +4. Spoon half of spinach mixture into casserole pan, then half of chicken mixture. Repeat +5. Separate eggs. In separate bowl beat egg whites until stiff +6. Topping: combine flour, milk, butter and egg yolks. Beat at low speed until moistened. Beat 4m at high speed +7. Fold egg whites into topping. Pour over filling. Sprinkle with paprika +8. Bake 40-45m at 375 or until deep golden brown diff --git a/recipes/waffles.md b/recipes/waffles.md new file mode 100644 index 0000000..03fe00f --- /dev/null +++ b/recipes/waffles.md @@ -0,0 +1,23 @@ +# Waffles + +#breakfast #pastry + +## Ingredients + +Measure | Unit | Weight | Ingredient +--------|------|--------|----------- +1 3/4 | c | | Flour +1/2 | tsp | | Salt +3 | tsp | | Baking Powder +1/2 | c | | Instant Dry Milk +2 | | | Eggs +1/2 | c | | Oil +1 3/4 | c | | Water +Dash | | | Cinnamon + +## Instructions + +1. Separate eggs/ Stiffly beat whites in mixer +2. Combine flour, salt, baking power, dry milk, cinnamon in large bowl +3. Combine egg yolks, oil, and water in small bowl. Combine with dry +4. Gently fold egg whites. Leaving a few folds. Cook in waffle iron diff --git a/server.js b/server.js index 94c8517..b0a0891 100644 --- a/server.js +++ b/server.js @@ -10,7 +10,7 @@ app.set('view engine', 'ejs'); // add folder for static content: app.use(express.static(__dirname + '/assets')); -app.get(/\/.*/, function(req, res) { +app.get(/\/.*/, function (req, res) { let pathname = 'pages' + req.path; let page = pathname.substr(pathname.lastIndexOf('/') + 1); @@ -26,12 +26,18 @@ app.get(/\/.*/, function(req, res) { pathname = pathname.substr(0, pathname.lastIndexOf(page)); pathname += 'project_template' // provide the pagename for project_template to use for main content - page = 'partials/md/' + page; + page = 'partials/md/projects/' + page; + } + else if (pathname.includes('recipes') && page !== 'index') { + pathname = pathname.substr(0, pathname.lastIndexOf(page)); + pathname += 'recipe_template' + // provide the pagename for project_template to use for main content + page = 'partials/md/recipes/' + page; } } console.log('request for path: ' + pathname + ', and page: ' + page); - res.render(pathname, {"page": page}); + res.render(pathname, { "page": page }); }); app.listen(PORT); diff --git a/views/pages/contact.ejs b/views/pages/contact.ejs index 0a0ef5a..6bc8d51 100644 --- a/views/pages/contact.ejs +++ b/views/pages/contact.ejs @@ -19,7 +19,7 @@ <%- include('../partials/footer') %> - <%- include('../partials/post_html_include') %> + <%- include('../partials/post_html_include') %> diff --git a/views/pages/index.ejs b/views/pages/index.ejs index 30e478a..66f431f 100644 --- a/views/pages/index.ejs +++ b/views/pages/index.ejs @@ -38,9 +38,9 @@ -
-
-
+
+
+
Yama Crawler
Selenium-Based Web Crawler
@@ -52,7 +52,9 @@ Code
-
+
+
+
Mavlib Gen
Modern Mavlink C generator
@@ -63,7 +65,9 @@ See Code
-
+
+
+
Darkstar
Why buy a quad when you can build it
@@ -78,7 +82,9 @@ Code
-
+
+
+
Pallet Desk
Reliable and cheap desk
@@ -89,7 +95,9 @@ Read More
-
+
+
+
My Website
Is this meta
@@ -103,8 +111,9 @@ Code
- -
+
+
+
LS-1 Synth
Music to my ears
@@ -119,7 +128,6 @@ Code
-
diff --git a/views/pages/recipe_navigator.ejs b/views/pages/recipe_navigator.ejs new file mode 100644 index 0000000..ae6df09 --- /dev/null +++ b/views/pages/recipe_navigator.ejs @@ -0,0 +1,102 @@ + + + + + <%- include('../partials/include' ) %> + + + + +
+ <%- include('../partials/nav') %> +
+ +
+
+
+

Recipes

+
+
+ +
+
+
+
+ <%- include('../partials/generated/recipe-tags') %> +
+
+
+ +
+
+ + <%- include('../partials/post_html_include') %> + + + + diff --git a/views/pages/recipes/recipe_template.ejs b/views/pages/recipes/recipe_template.ejs new file mode 100644 index 0000000..632cfc6 --- /dev/null +++ b/views/pages/recipes/recipe_template.ejs @@ -0,0 +1,34 @@ +<% var rootPath = '../../'; %> + + + + + <%- include(rootPath + 'partials/include' ) %> + + + + +
+ <%- include(rootPath + 'partials/nav') %> +
+ +
+
+
+ <%- include(rootPath + page + '-title') %> +
+
+
+
+ <%- include(rootPath + page + '-ingredients') %> +
+
+
+
+ + <%- include(rootPath + page + '-instructions') %> +
+ + <%- include(rootPath + 'partials/post_html_include') %> + + diff --git a/views/partials/include.ejs b/views/partials/include.ejs index 74ba87e..cd5f313 100644 --- a/views/partials/include.ejs +++ b/views/partials/include.ejs @@ -1,8 +1,9 @@ - + + diff --git a/views/partials/nav.ejs b/views/partials/nav.ejs index 97d1c16..1cae67e 100644 --- a/views/partials/nav.ejs +++ b/views/partials/nav.ejs @@ -7,12 +7,12 @@