logo

Grimgrains

[mirror] Plant-based cooking website <https://grimgrains.com/>
commit: d18c3c5a0e0f87701469ca55b4f26a29050f5889
parent ba6f16a696c0b241751ed8ffba76cabf440e1b6e
Author: Лu Лinveгa <aliceffekt@gmail.com>
Date:   Fri, 28 Jun 2019 13:54:53 +0900

Merge pull request #14 from microlith57/parent-ingredients

Add parent-child relationships

Diffstat:

Mindex.html3++-
Amedia/ingredients/beans.png0
Amedia/ingredients/beets.png0
Amedia/ingredients/black.beans.png0
Amedia/ingredients/black.mushrooms.png0
Amedia/ingredients/cauliflower.png0
Amedia/ingredients/cayenne.powder.png0
Amedia/ingredients/cucumber.png0
Amedia/ingredients/flour.png0
Amedia/ingredients/ginger.png0
Amedia/ingredients/green.olives.png0
Amedia/ingredients/green.peppers.png0
Amedia/ingredients/kidney.beans.png0
Amedia/ingredients/lentils.png0
Amedia/ingredients/mungbeans.png0
Amedia/ingredients/mushrooms.png0
Amedia/ingredients/nori.png0
Amedia/ingredients/olives.png0
Amedia/ingredients/onion.png0
Amedia/ingredients/peas.png0
Amedia/ingredients/peppers.png0
Rmedia/ingredients/potatoe.png -> media/ingredients/potato.png0
Amedia/ingredients/seaweed.png0
Amedia/ingredients/sesame.seeds.png0
Amedia/ingredients/soy.beans.png0
Amedia/ingredients/straw.mushrooms.png0
Mriven.html1+
Mscripts/database/ingredients.ndtl99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mscripts/database/recipes.ndtl18+++++++++---------
Mscripts/graph.js5+++--
Mscripts/templates/home.js4++--
Mscripts/templates/ingredient.js80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Ascripts/templates/service.js143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33 files changed, 317 insertions(+), 36 deletions(-)

diff --git a/index.html b/index.html @@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=800, initial-scale=1.0"> - <meta name="description" content="Grim Grains is an illustrated food blog, it features plant-based (vegan) recipes with a strong attention to colour and form."> + <meta name="description" content="Grimgrains is an illustrated food blog, it features plant-based (vegan) recipes with a strong attention to colour and form."> <!-- Twitter --> <meta name="twitter:card" content="summary"> <meta name="twitter:site" content="@RekkaBell"> @@ -40,6 +40,7 @@ <script src="scripts/templates/page.js"></script> <script src="scripts/templates/home.js"></script> <script src="scripts/templates/search.js"></script> + <script src="scripts/templates/service.js"></script> <link rel="stylesheet" type="text/css" href="links/reset.css"/> <link rel="stylesheet" type="text/css" href="links/main.css"/> diff --git a/media/ingredients/beans.png b/media/ingredients/beans.png Binary files differ. diff --git a/media/ingredients/beets.png b/media/ingredients/beets.png Binary files differ. diff --git a/media/ingredients/black.beans.png b/media/ingredients/black.beans.png Binary files differ. diff --git a/media/ingredients/black.mushrooms.png b/media/ingredients/black.mushrooms.png Binary files differ. diff --git a/media/ingredients/cauliflower.png b/media/ingredients/cauliflower.png Binary files differ. diff --git a/media/ingredients/cayenne.powder.png b/media/ingredients/cayenne.powder.png Binary files differ. diff --git a/media/ingredients/cucumber.png b/media/ingredients/cucumber.png Binary files differ. diff --git a/media/ingredients/flour.png b/media/ingredients/flour.png Binary files differ. diff --git a/media/ingredients/ginger.png b/media/ingredients/ginger.png Binary files differ. diff --git a/media/ingredients/green.olives.png b/media/ingredients/green.olives.png Binary files differ. diff --git a/media/ingredients/green.peppers.png b/media/ingredients/green.peppers.png Binary files differ. diff --git a/media/ingredients/kidney.beans.png b/media/ingredients/kidney.beans.png Binary files differ. diff --git a/media/ingredients/lentils.png b/media/ingredients/lentils.png Binary files differ. diff --git a/media/ingredients/mungbeans.png b/media/ingredients/mungbeans.png Binary files differ. diff --git a/media/ingredients/mushrooms.png b/media/ingredients/mushrooms.png Binary files differ. diff --git a/media/ingredients/nori.png b/media/ingredients/nori.png Binary files differ. diff --git a/media/ingredients/olives.png b/media/ingredients/olives.png Binary files differ. diff --git a/media/ingredients/onion.png b/media/ingredients/onion.png Binary files differ. diff --git a/media/ingredients/peas.png b/media/ingredients/peas.png Binary files differ. diff --git a/media/ingredients/peppers.png b/media/ingredients/peppers.png Binary files differ. diff --git a/media/ingredients/potatoe.png b/media/ingredients/potato.png Binary files differ. diff --git a/media/ingredients/seaweed.png b/media/ingredients/seaweed.png Binary files differ. diff --git a/media/ingredients/sesame.seeds.png b/media/ingredients/sesame.seeds.png Binary files differ. diff --git a/media/ingredients/soy.beans.png b/media/ingredients/soy.beans.png Binary files differ. diff --git a/media/ingredients/straw.mushrooms.png b/media/ingredients/straw.mushrooms.png Binary files differ. diff --git a/riven.html b/riven.html @@ -25,6 +25,7 @@ <script src="scripts/templates/recipe.js"></script> <script src="scripts/templates/ingredient.js"></script> <script src="scripts/templates/page.js"></script> + <script src="scripts/templates/service.js"></script> <link rel="stylesheet" type="text/css" href="links/reset.css"/> <link rel="stylesheet" type="text/css" href="links/riven.fonts.css"/> diff --git a/scripts/database/ingredients.ndtl b/scripts/database/ingredients.ndtl @@ -1,6 +1,7 @@ DATABASE.ingredients = ` Coffee + PARENT : Beans BREF : {{Coffee}} is a brewed drink prepared from roasted coffee beans, which are the seeds of berries from the {{Coffea plant|https://en.wikipedia.org/wiki/Coffea}}. LONG % blog/coffee.2.jpg @@ -28,11 +29,13 @@ Lentils Lentil Beluga Lentils + PARENT : Lentils COLOR : #000000 TAGS Legume Lentil Brown Lentils + PARENT : Lentils BREF : The most common variety of lentils, found in most grocery stores. They have a mild, earthy-flavor. TAGS Legume @@ -45,6 +48,7 @@ Peanut Butter Peanuts BREF : A crop grown mainly for its edible seeds! Peanuts are similar in taste and nutritional profile to tree nuts, and can be made into {{peanut butter}}. Soy beans + PARENT : Beans COLOR : #EFEFEF LONG & A staple in Eastern Asia, soy beans are used as a base for many vegan faux-meat dishes. If you produce your own {{soy milk}}, know that there won't be any waste. The pulp can be used to make okara, which you can use to make baked goods. @@ -53,13 +57,21 @@ Beans LONG & Fun fact: there are over 130 varieties of {{green beans}}. & See also: {{black beans}}, {{green beans}}, and {{kidney beans}} +Black beans + PARENT : Beans +Green beans + PARENT : Beans +Kidney beans + PARENT : Beans Edamame Chickpeas Chickpea Flour - BREF : Chickpea flour is made from {{chickpeas}}. + PARENT : chickpeas, flour Peas Green Peas + PARENT : Peas Mungbeans + PARENT : Beans ~ CRUCIFEROUS @@ -96,28 +108,41 @@ Radish ~ ALGEA FUNGI +Seaweed +Mushroom Wakame + PARENT : Seaweed COLOR : #006633 BREF : Wakame is a very invasive plant - it's even banned in Australia. Dried Hijiki + PARENT : Seaweed Bull kelp powder + PARENT : Seaweed Nori + PARENT : Seaweed COLOR : #000000 - BREF : Nori can be made into {{sheets|nori sheets}}. Fun fact: seaweed takes about 45 days to grow. + BREF : Fun fact: seaweed takes about 45 days to grow. Nori Sheets + PARENT : Nori, Seaweed Shiitake + PARENT : Mushroom COLOR : #875A2C Crimini + PARENT : Mushroom COLOR : #875A2C BREF : Mature crimini mushrooms are actually {{portobello}} mushrooms. Portobello + PARENT : Mushroom COLOR : #875A2C - BREF : Portobello are mature {{crimini}} (or common) mushrooms. They can be used in plantbased recipes as hamburger steaks, you can even use them as buns. + BREF : Portobello are mature {{crimini}} (or common) mushrooms. They can be used in plant-based recipes as hamburger steaks, you can even use them as buns. Shimeji + PARENT : Mushroom Button Mushrooms -Dehydrated mushro + PARENT : Mushroom Black mushrooms + PARENT : Mushroom Straw mushrooms + PARENT : Mushroom ~ SEEDS @@ -136,35 +161,43 @@ Chia seeds ~ ROOT VEGETABLES Nagaimo -Carrot +Carrots BREF : Overconsumming carrots can cause what is reffered to as "Carotenosis", a condition in which the skin turns orange. Heirloom Carrots Ginger Ginger Root + PARENT : Ginger Potatoes BREF : Since vitamin A deficiency is a common problem in Africa, people are encouraged to eat {{sweet potatoes}}. Russet Potatoes - BREF : A type of {{potato|potatoes}}. + PARENT : Potatoes Sweet Potatoes - BREF : A type of {{potato|potatoes}}. + PARENT : Potatoes Beets LONG & {{Golden beets}} are rich in b-xanthin pigment, so they cannot replace {{red beets}} (which contain betalain pigment). Both pigments offer different health benefits! & The root of the beet plant is called a beetroot. Don't be alarmed, beetroot juice will make your urine red for a day. Golden Beets + PARENT : Beets BREF : A type of {{beet|beets}} containing b-xanthin pigment. Red Beets + PARENT : Beets BREF : A type of {{beet|beets}} containing betalain pigment. Yuka BREF : Tapioca is actually a starch extracted from Yuca roots. Garlic BREF : Garlic has been used in many cultures around the world for thousands of years, dating all the way back to the time the pyramids were built! Garlic Powder + PARENT : Garlic +Onion Red Onion + PARENT : Onion COLOR : #C820B3 - BREF : There is a variety of red onions in italy that has a stronger and sweeter taste, it is sometimes made into marmalades. + BREF : There is a variety of red onion in Italy that has a stronger and sweeter taste, and is sometimes made into marmalade. Onion Powder + PARENT : Onion Yellow Onion + PARENT : Onion ~ OTHER VEGETABLES @@ -177,11 +210,14 @@ Chives Peppers BREF : The misleading name 'pepper' was given by Christopher Columbus when he brought back a plant to Europe. The word pepper was given to all spices in Europe that had a hot and pungent taste. Green Peppers + PARENT : Peppers Red Peppers + PARENT : Peppers Yellow Peppers + PARENT : Peppers Tomato - BREF : The tomatoes can also be dried with an oven. Tomato Paste + PARENT : Tomato BREF : The tomatoes can also be dried with an oven. Avocado BREF : Avocados are botanically 'berries', they may be pear-shaped, round or egg-shaped. They are a good source of fat. Fun fact: Avocado trees don't self-pollinate, they need another avocado tree nearby to bear fruit. @@ -189,7 +225,11 @@ Pumpkin BREF : The darker the skin of the pumpkin, the higher the beta-carotene content. Olives Green Olives + PARENT : Olives Black Olives + PARENT : Olives +Pimento Olives + PARENT : Olives Palm BREF : Heart of palm is a vegetable that is harvested from the inner core of certain palm trees. They can be eaten as is, but they're especially delicious when tossed into a salad. Squash @@ -208,6 +248,7 @@ Alfaalfa sprouts Raisins Dried Raisins + PARENT : Raisins Blackberries Cherries Mulberries @@ -249,19 +290,22 @@ Persimmon Dates BREF : Date palms have been around for at least 50 million years! Deglet Noor Dates + PARENT : Dates +Date caramel + PARENT : Dates + BREF : Date caramel is used to make {{salted caramel carob chip cookies}}, and has a recipe there. Pamplemousse Rhubarb Apricot Jam Starfruit Mixed fruits Coconut -Date Plums Pineapple ~ SPICES -Aonori +Ao nori Kanten powder BREF : A seaweed-based gelling agent derived from tengusa, a specific type of red seaweed. Kanten confections don't dissolve at room temperature, unlike gelatin. Turmeric @@ -284,10 +328,13 @@ Mint COLOR : #006633 BREF : Oil derived from {{fresh mint}} can be used as a friendly insecticide. Fresh Mint + PARENT : Mint Cocoa Cocoa Powder -Cayenne + PARENT : Cocoa Cayenne Pepper +Cayenne Powder + PARENT : Cayenne Pepper Anise Anise Seeds Nutritional yeast @@ -366,18 +413,26 @@ Fenugreek ~ WHOLEGRAINS Whole wheat flour + PARENT : Flour Buckwheat Buckwheat noodles Buckwheat flour + PARENT : Flour Quinoa Whole wheat Einkorn Einkorn Flour + PARENT : Flour Spelt Spelt Flour + PARENT : Flour +Gluten Flour + PARENT : Flour Corn Cornmeal + PARENT : Corn Corn Semolina + PARENT : Corn ~ GRAINS @@ -387,14 +442,24 @@ Oats Rice BREF : Preparing puffed rice this way makes it less perishable. Brown rice is a wholegrain rice that has a nutty flavour, and it's more nutritious and chewy than white rice. It is produced by only removing the outermost husk, while white rice has several other layers removed. It is best to soak the rice for a day before cooking it to obtain a more nutritionally complete food, soaking it beforehand activates various enzymes in the rice. Basmati Rice + PARENT : Rice White Rice + PARENT : Rice +Short Grain White Rice + PARENT : White Rice, Rice Black Rice + PARENT : Rice Puffed Rice + PARENT : Rice Brown Rice + PARENT : Rice Black Glutinous Rice + PARENT : Black Rice, Rice Wholegrain Brown Rice + PARENT : Brown Rice, Rice Rice Noodles Rice Flour + PARENT : Rice, Flour Flour COLOR : #EFEFEF @@ -405,7 +470,9 @@ Flour & {{Einkorn|einkorn flour}} wheat was one of the first plants to be domesticated and cultivated. It has a high percentage of protein, more than regular wheat. It also has high levels of fat, phosphorus, potassium, pyridoxine (a form of vitamin b6) and beta-carotene, making it more nutritious than other kinds of grains. Another great thing about einkorn is that it isn't as toxic to people on gluten-free diets, it as yet to be proven but it should definitely be looked into! & {{Breadfruit flour}} is a type of flour made from dried and ground breadfruit. All Purpose Flour + PARENT : Flour Breadfruit Flour + PARENT : Flour BREF : The product of dried and ground breadfruit. Can be used to make cakes, pasta and a number of other meals. Wheat Semolina Oatmeal @@ -424,14 +491,18 @@ Red Miso ~ Tell me (microlith57) if this color needs changing. White Miso COLOR : #955C19 -~ #FFD800 mayo? Tofu COLOR : #EFEFEF BREF : The word {_bean curds_} for tofu has been used in the US since 1840. See also: {{silken tofu}}, {{burmese tofu}}. Silken Tofu + PARENT : Tofu COLOR : #EFEFEF Burmese Tofu + PARENT : Tofu COLOR : #EFEFEF +Tofu Mayo + PARENT : Tofu + COLOR : #FFD800 Nutolene Soy protein @@ -458,7 +529,7 @@ Cornstarch Active dry yeast Baking soda BREF : Since sodium bicarbonate can cause alkalosis, it's sometimes used to treat aspirin overdoses. -Agar agar +Agar agar powder BREF : Agar is used to make impression material in dentistry. Arrowroot starch diff --git a/scripts/database/recipes.ndtl b/scripts/database/recipes.ndtl @@ -98,10 +98,10 @@ SWEET AND SOUR LENTILS Main Brown lentils : 1/2 cup Vegetable bouillon : 1 1/2 cups - carrot : 1, cubed - daikon : 2", cubed - chives : 3 stalks - salt : 1/4 tsp + Carrots : 1, cubed + Daikon : 2", cubed + Chives : 3 stalks + Salt : 1/4 tsp Sauce Soy sauce : 2 tbsp Rice vinegar : 2 tbsp @@ -1153,7 +1153,7 @@ CHILI POMEGRANATE BROWNIES - Stir in the flax 'egg', as well as the {_2 tbsp_} of {{red pepper flakes}} and {_1 tsp_} of {{cayenne powder}}. Add {_1/2 cup_} of {{all purpose flour}} and mix well. Mixture should be very thick. - Pour into a 8X8 baking dish lined with parchment papper. Flatten with the back of a spoon to even it out and bake for {#25 minutes#}, or until knife comes out clean. Let cool. {_Cut in 24 small squares_}. Syrup - - Pour {_2 cups_} of {{unsweetened pomegranate juice}} into a pot with {_1 tsp_} {{red pepper flakes}} and {_1 tsp_} {{cayenne}}. Bring to a boil, lower to medium-high heat and leave for up to {#1h#} or until liquid has been reduced to {_1 cup_}. + - Pour {_2 cups_} of {{unsweetened pomegranate juice}} into a pot with {_1 tsp_} {{red pepper flakes}} and {_1 tsp_} {{cayenne powder}}. Bring to a boil, lower to medium-high heat and leave for up to {#1h#} or until liquid has been reduced to {_1 cup_}. - Let cool, the syrup will thicken when cooled. - Top brownies with fresh {{pomegranate seeds}}, and drizzle with the chili-infused syrup! INGR @@ -1167,12 +1167,12 @@ CHILI POMEGRANATE BROWNIES Sea salt : 1/4 tsp All purpose flour : 1/2 cup Chili pepper flakes : 2 tbsp - Cayenne pepper : 1 tsp + Cayenne powder : 1 tsp Syrup Pomegranate juice : 2 cups Sugar : 3/4 cup Chili pepper flakes : 1 tsp - Cayenne pepper : 1 tsp + Cayenne powder : 1 tsp Topping Pomegranate seeds : 1 cup @@ -1686,7 +1686,7 @@ SALTED CARAMEL CAROB CHIP COOKIES Cooking batter Vegan butter : 1/4 cup, earth balance Coconut sugar : 3/4 cup - Dates caramel : 1/4 cup, see above + Date caramel : 1/4 cup, see above Flax seeds : 1 tbsp Einkorn flour : 1 cup + 3 tbsp Baking soda : 3/4 tsp @@ -1760,7 +1760,7 @@ CHICKPEA KELP SANDWICH Dijon mustard : 1 tbsp Bull kelp powder : 1/2 tsp Scallions : 2 branches - Cayenne pepper : 1/4 tsp + Cayenne powder : 1/4 tsp Sea salt : 1/4 tsp Black pepper : 1/4 tsp Shichimi togarashi : To taste diff --git a/scripts/graph.js b/scripts/graph.js @@ -16,7 +16,8 @@ function graph () { Ø('search').create({ x: 5, y: 14 }, SearchTemplate), Ø('home').create({ x: 2, y: 14 }, HomeTemplate), Ø('recipe').create({ x: 5, y: 8 }, RecipeTemplate), - Ø('ingredient').create({ x: 8, y: 8 }, IngredientTemplate) + Ø('ingredient').create({ x: 8, y: 8 }, IngredientTemplate), + Ø('service').create({ x: 8, y: 14 }, ServiceTemplate) ]) Ø('client').mesh({ x: 32, y: 0 }, [ @@ -44,7 +45,7 @@ function graph () { // Assoc Ø('template').syphon(['recipe', 'ingredient', 'page']) - Ø('page').syphon(['home', 'search']) + Ø('page').syphon(['home', 'search', 'service']) Ø('template').connect(['view', 'document']) Ø('view').bind(['header', 'core', 'footer']) diff --git a/scripts/templates/home.js b/scripts/templates/home.js @@ -57,14 +57,14 @@ function HomeTemplate (id, rect) { for (id in ingredients) { let name = ingredients[id][0] html += ` - <li class='ingredient ${!table[name] ? 'missing' : ''}'> + <li class='ingredient${!table[name] ? ' missing' : ''}'> <a href='#${name.to_url()}' onclick="Ø('query').bang('${name}')"> <img src='media/ingredients/${name.to_path()}.png'/> </a> <t class='name'>${name.capitalize()}</t> </li>` } - return `<ul class='ingredients'>${html}<hr/></ul>` + return `<ul class='ingredients'>${html}</ul>` } function count_ingredients (recipe) { diff --git a/scripts/templates/ingredient.js b/scripts/templates/ingredient.js @@ -12,27 +12,73 @@ function IngredientTemplate (id, rect) { title: `GrimGrains — ${t.name.capitalize()}`, view: { core: { - content: make_ingredient(t.name, ingredient, t.tables.recipes), + content: make_ingredient(t.name, ingredient, t.tables.recipes, t.tables.ingredients), related: make_related(related_recipes(t.name, t.tables.recipes)) } } } } - function make_ingredient (name, ingredient, recipes) { + function make_ingredient (name, ingredient, recipes, all_ingredients) { let html = '' - html += `<h1>${ingredient.TYPE ? ingredient.TYPE.capitalize() + '/' : ''}${name.capitalize()}</h1>` + html += `<h1>${name.capitalize()}</h1>` html += ingredient.BREF ? `<p class='bref'>${ingredient.BREF.to_markup()}</p>` : '' html += ingredient.LONG ? `${new Runic(ingredient.LONG)}` : '' - html += `${make_similar(name, recipes)}` + html += `${make_parents(ingredient)}` + html += `${make_children(name, all_ingredients)}` + html += `${make_similar(name, recipes, all_ingredients)}` + return html + } + + function make_parents (ingredient) { + let html = '' + if (!ingredient.PARENT) {return html} + + html += "<h2>Parent Ingredients</h2><ul class='ingredients'>" + let parents = ingredient.PARENT.split(",") + + for (id in parents) { + let name = parents[id].trim() + html += ` + <li class='ingredient'> + <a onclick="Ø('query').bang('${name}')" href='#${name.to_url()}'> + <img src='media/ingredients/${name.to_path()}.png'/> + </a> + <t class='name'>${name.capitalize()}</t> + </li>` + } + + html += "</ul>" + return html + } + + function make_children (ingredient, all_ingredients) { + let html = '' + let child_ingredients = find_child_ingredients(ingredient, all_ingredients) + if (child_ingredients.length == 0) {return html} + + html += "<h2>Child Ingredients</h2><ul class='ingredients'>" + + for (id in child_ingredients) { + let name = child_ingredients[id] + html += ` + <li class='ingredient'> + <a onclick="Ø('query').bang('${name}')" href='#${name.to_url()}'> + <img src='media/ingredients/${name.to_path()}.png'/> + </a> + <t class='name'>${name.capitalize()}</t> + </li>` + } + + html += "</ul>" return html } - function make_similar (search_name, recipes) { + function make_similar (search_name, recipes, all_ingredients) { let html = '' let ingredients = find_ingredients(recipes) - let similar_ingredients = find_similar_ingredients(search_name, ingredients) + let similar_ingredients = find_similar_ingredients(search_name, ingredients, all_ingredients) for (id in similar_ingredients) { if (similar_ingredients[id][1] < 1) { break } @@ -46,7 +92,7 @@ function IngredientTemplate (id, rect) { <t class='name'>${name.capitalize()}</t> </li>` } - return similar_ingredients.length > 1 ? `<h2>Related Ingredients</h2><ul class='ingredients'>${html}<hr /></ul>` : '' + return similar_ingredients.length >= 1 ? `<h2>Related Ingredients</h2><ul class='ingredients'>${html}<hr /></ul>` : '' } function find_ingredients (recipes) { @@ -63,10 +109,13 @@ function IngredientTemplate (id, rect) { return h } - function find_similar_ingredients (name, ingredients) { + function find_similar_ingredients (name, ingredients, all_ingredients) { let a = [] + + let children = find_child_ingredients(name, all_ingredients) for (id in ingredients) { + if (children.includes(id.toLowerCase())) {continue} let words = id.toLowerCase().split(' ') let index = similarity(name.toLowerCase().split(' '), words) if (index > 0) { @@ -80,6 +129,21 @@ function IngredientTemplate (id, rect) { return a.reverse() } + + function find_child_ingredients (search_name, all_ingredients) { + let a = [] + + for (name in all_ingredients) { + let ingr = all_ingredients[name] + if (!ingr.PARENT) { continue } + let parents = ingr.PARENT.split(",").map(function (name) {return name.trim().toLowerCase()}) + if (parents.includes(search_name.toLowerCase())) { + a.push(name.toLowerCase()) + } + } + + return a + } function similarity (a, b) { let score = 0 diff --git a/scripts/templates/service.js b/scripts/templates/service.js @@ -0,0 +1,143 @@ +function ServiceTemplate (id, rect) { + Node.call(this, id, rect) + + this.glyph = NODE_GLYPHS.render + + this.answer = function (q) { + let recipe_ingredients = find_ingredients(q.tables.recipes) + + let html = ` + ${make_pageless(recipe_ingredients, q.tables.ingredients)} + ${make_unused(recipe_ingredients, q.tables.ingredients)} + ` + return { + title: `GrimGrains — Service Panel`, + view: { + core: { + content: html, + related: '' + } + } + } + } + + function find_ingredients (recipes) { + let h = [] + for (id in recipes) { + let recipe = recipes[id] + for (id in recipe.INGR) { + let category = recipe.INGR[id] + for (name in category) { + if (!h.includes(name.toLowerCase())) {h.push(name.toLowerCase())} + } + } + } + return h + } + + function make_pageless (used, pages) { + let pageless = find_pageless(used, pages) + let html = "" + for (id in pageless) { + html += ` + <li class='ingredient missing'> + <a href='#${pageless[id].to_url()}' onclick="Ø('query').bang('${pageless[id]}')"> + <img src='media/ingredients/${pageless[id].to_path()}.png'/> + </a> + <t class='name'>${pageless[id].capitalize()}</t> + </li>` + } + if (html == "") {return `<h2>No Ingredients Without Pages!</h2>`} + return `<h2>Ingredients Without Pages</h2><ul class='ingredients'>${html}</ul>` + } + + function find_pageless (used, pages) { + let pageless = [] + + for (id in used) { + let name = used[id].toUpperCase() + if (!pages[name]) {pageless.push(name)} + } + + return pageless + } + + function make_unused (used, pages) { + let unused = find_unused(used, pages) + let html = "" + + for (id in unused) { + html += ` + <li class='ingredient'> + <a href='#${unused[id].to_url()}' onclick="Ø('query').bang('${unused[id]}')"> + <img src='media/ingredients/${unused[id].to_path()}.png'/> + </a> + <t class='name'>${unused[id].capitalize()}</t> + </li>` + } + if (html == "") {return `<h2>No Unused Ingredients!</h2>`} + return `<h2>Unused Ingredients</h2><ul class='ingredients'>${html}</ul>` + } + + function find_unused (used, pages) { + let unused = [] + + for (name in pages) { + if (!used.includes(name.toLowerCase())) {unused.push(name)} + } + + return unused + } + + function make_ingredients (ingredients, table) { + let html = '' + for (id in ingredients) { + let name = ingredients[id][0] + html += ` + <li class='ingredient${!table[name] ? ' missing' : ''}'> + <a href='#${name.to_url()}' onclick="Ø('query').bang('${name}')"> + <img src='media/ingredients/${name.to_path()}.png'/> + </a> + <t class='name'>${name.capitalize()}</t> + </li>` + } + return `<ul class='ingredients'>${html}</ul>` + } + + function count_ingredients (recipe) { + let ingredients = {} + for (cat in recipe.INGR) { + for (id in recipe.INGR[cat]) { + ingredients[id] = 1 + } + } + return Object.keys(ingredients).length + } + + function make_recipes (recipes) { + let html = '' + + // Sort by tag + + let categorized = {} + + for (name in recipes) { + let recipe = recipes[name] + if (!categorized[recipe.TAGS[0]]) { categorized[recipe.TAGS[0]] = [] } + recipe.name = name + categorized[recipe.TAGS[0]].push(recipe) + } + + for (cat in categorized) { + let recipes = categorized[cat] + html += `<h3>${cat.capitalize()}</h3>` + html += "<ul style='margin-bottom:15px'>" + for (id in recipes) { + let recipe = recipes[id] + html += `<li><a href="#${recipe.name.to_url()}" onclick="Ø('query').bang('${recipe.name.capitalize()}')">${recipe.name.capitalize()}</a></li>` + } + html += '</ul>' + } + return `<columns id='recipes'>${html}</columns>` + } +}