From 1e1ba151183bcaf7898d6708f2188569eb8ba742 Mon Sep 17 00:00:00 2001 From: len0rd Date: Wed, 22 Jun 2022 12:27:14 -0400 Subject: [PATCH] generate recipe link and hashtag list on startup. filter recipes in list based on active tags. tags in recipes dont link back yet --- .gitignore | 3 +- prestart.js | 161 +++++++++++++++++++++---------- recipes/bananaBread.md | 2 + recipes/cinnamonRolls.md | 2 + recipes/pizzaDough.md | 2 + views/pages/recipe_navigator.ejs | 55 +++++++++-- views/partials/include.ejs | 1 + 7 files changed, 169 insertions(+), 57 deletions(-) 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 + ![Cinnamon Roll](/img/recipes/cinnamonRolls.jpeg) ## 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

-
- Chocolate Chip Cookies - Pizza Dough - Banana Bread - Cinnamon Rolls +
+
+ <%- include('../partials/generated/recipe-tags') %> +
+
+
+
<%- include('../partials/post_html_include') %> + diff --git a/views/partials/include.ejs b/views/partials/include.ejs index 7bb30f8..cd5f313 100644 --- a/views/partials/include.ejs +++ b/views/partials/include.ejs @@ -6,3 +6,4 @@ +