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/prestart.js b/prestart.js
index 6ad7d89..c13bb94 100644
--- a/prestart.js
+++ b/prestart.js
@@ -13,6 +13,7 @@ const showdown = require('showdown'),
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
)
};
@@ -115,63 +116,123 @@ function convertRecipeMarkdown(inputDir, outputDir) {
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 tokens = md.parse(data)
+ 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);
+ return;
+ }
+ 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) {
- console.log("found heading open. start new section arr");
- numSections++;
- sections.push([]);
- }
- }
- sections[sections.length - 1].push(token)
+ 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++;
}
-
- 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;
- }
- }
- // console.log(sections[0]);
-
- 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');
+ 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/recipes/bananaBread.md b/recipes/bananaBread.md
index 5f38f82..cf1672c 100644
--- a/recipes/bananaBread.md
+++ b/recipes/bananaBread.md
@@ -1,5 +1,7 @@
# Banana Bread
+#bread #dessert
+
## Ingredients
Measure | Weight | Ingredient
diff --git a/recipes/cinnamonRolls.md b/recipes/cinnamonRolls.md
index 4f1131c..1c283a9 100644
--- a/recipes/cinnamonRolls.md
+++ b/recipes/cinnamonRolls.md
@@ -1,5 +1,7 @@
# Cinnamon Rolls
+#breakfast #bread #dessert
+

## Ingredients
diff --git a/recipes/pizzaDough.md b/recipes/pizzaDough.md
index a34e8d9..eacb693 100644
--- a/recipes/pizzaDough.md
+++ b/recipes/pizzaDough.md
@@ -1,5 +1,7 @@
# Pizza Dough
+#bread #italian
+
## Ingredients
Measure | Weight | Ingredient
diff --git a/views/pages/recipe_navigator.ejs b/views/pages/recipe_navigator.ejs
index 5bf3a38..b9aa34a 100644
--- a/views/pages/recipe_navigator.ejs
+++ b/views/pages/recipe_navigator.ejs
@@ -3,7 +3,7 @@
<%- include('../partials/include' ) %>
-
+
@@ -13,15 +13,58 @@
Recipes
-
<%- include('../partials/post_html_include') %>
+