logo

Grimgrains

Unnamed repository; edit this file 'description' to name the repository.
commit: 19f41a5a42389dbfaae01eab7563b499fdf0bcaf
parent b67942c2b8eed39baabe52bd58ab510b9f189383
Author: Devine Lu Linvega <aliceffekt@gmail.com>
Date:   Thu,  8 Mar 2018 15:05:27 +1300

Implemented Runic

Diffstat:

Mindex.html3+++
Mriven.html3+++
Mscripts/graph.js37++++++++++++++++++++++---------------
Ascripts/lib/runic.js172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ascripts/nodes/parser.js15+++++++++++++++
Mscripts/nodes/router.js3+--
Mscripts/nodes/template.js28+++++++++++++++++-----------
Mscripts/templates/ingredient.js47+++++++++++------------------------------------
Ascripts/templates/related.js15+++++++++++++++
9 files changed, 259 insertions(+), 64 deletions(-)

diff --git a/index.html b/index.html @@ -4,6 +4,7 @@ <meta charset="utf-8"> <script src="scripts/lib/riven.js"></script> <script src="scripts/graph.js"></script> + <script src="scripts/lib/runic.js"></script> <script src="scripts/nodes/query.js"></script> <script src="scripts/nodes/router.js"></script> @@ -11,10 +12,12 @@ <script src="scripts/nodes/indental.js"></script> <script src="scripts/nodes/template.js"></script> <script src="scripts/nodes/dom.js"></script> + <script src="scripts/nodes/parser.js"></script> <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/related.js"></script> <script src="scripts/database/ingredients.js"></script> <script src="scripts/database/recipes.js"></script> diff --git a/riven.html b/riven.html @@ -4,6 +4,7 @@ <meta charset="utf-8"> <script src="scripts/lib/riven.js"></script> <script src="scripts/lib/riven.graph.js"></script> + <script src="scripts/lib/runic.js"></script> <script src="scripts/graph.js"></script> <script src="scripts/nodes/query.js"></script> @@ -12,10 +13,12 @@ <script src="scripts/nodes/indental.js"></script> <script src="scripts/nodes/template.js"></script> <script src="scripts/nodes/dom.js"></script> + <script src="scripts/nodes/parser.js"></script> <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/related.js"></script> <script src="scripts/database/ingredients.js"></script> <script src="scripts/database/recipes.js"></script> diff --git a/scripts/graph.js b/scripts/graph.js @@ -5,20 +5,23 @@ function graph() Ø("model").mesh({x:6,y:0},[ Ø("router").create({x:5,y:2},RouterNode), - Ø("database").create({x:5,y:9},DatabaseNode), - Ø("recipes").create({x:2,y:17},IndentalNode), - Ø("ingredients").create({x:5,y:17},IndentalNode), - Ø("pages").create({x:8,y:17},IndentalNode), + Ø("database").create({x:5,y:8},DatabaseNode), + Ø("recipes").create({x:2,y:14},IndentalNode), + Ø("ingredients").create({x:5,y:14},IndentalNode), + Ø("pages").create({x:8,y:14},IndentalNode), ]) - Ø("view").mesh({x:19,y:0},[ - Ø("template").create({x:2,y:2},TemplateNode), + Ø("assoc").mesh({x:19,y:0},[ + Ø("parser").create({x:5,y:2},ParserNode), + Ø("recipe").create({x:2,y:8},RecipeTemplate), + Ø("ingredient").create({x:5,y:8},IngredientTemplate), + Ø("page").create({x:8,y:8},PageTemplate), + ]) - Ø("recipe").create({x:2,y:7},RecipeTemplate), - Ø("ingredient").create({x:5,y:7},IngredientTemplate), - Ø("page").create({x:8,y:7},PageTemplate), + Ø("view").mesh({x:32,y:0},[ + Ø("template").create({x:2,y:2},TemplateNode), - Ø("main").create({x:12,y:7},DomNode), + Ø("main").create({x:14,y:7},DomNode), Ø("header").create({x:2,y:12},DomNode), Ø("logo").create({x:2,y:17},DomNode), @@ -26,23 +29,27 @@ function graph() Ø("menu").create({x:10,y:17},DomNode), Ø("body").create({x:14,y:12},DomNode), - Ø("related").create({x:14,y:17},DomNode), + Ø("core").create({x:14,y:17},DomNode), + Ø("suggestions").create({x:17,y:17},DomNode), Ø("footer").create({x:10,y:12},DomNode), ]) + // Model Ø("router").syphon("database") Ø("database").syphon(["recipes","ingredients","pages"]) - - Ø("template").syphon(["recipe","ingredient","page"]) + + // Assoc + Ø("parser").syphon(["recipe","ingredient","page"]) + Ø("parser").connect("template") Ø("template").bind("main") Ø("main").bind(["header","body","footer"]) - Ø("body").bind(["related"]) + Ø("body").bind(["core","suggestions"]) Ø("header").bind(["logo","search","menu"]) Ø("query").connect("router") - Ø("router").connect("template") + Ø("router").connect("parser") Ø("query").bang() } diff --git a/scripts/lib/runic.js b/scripts/lib/runic.js @@ -0,0 +1,171 @@ +function Runic(raw) +{ + this.raw = raw; + + this.runes = { + "&":{glyph:"&",tag:"p",class:""}, + "~":{glyph:"~",tag:"list",sub:"ln",class:"parent",stash:true}, + "-":{glyph:"-",tag:"list",sub:"ln",class:"",stash:true}, + "!":{glyph:"!",tag:"table",sub:"tr",wrap:"th",class:"outline",stash:true}, + "|":{glyph:"|",tag:"table",sub:"tr",wrap:"td",class:"outline",stash:true}, + "#":{glyph:"#",tag:"code",sub:"ln",class:"",stash:true}, + "%":{glyph:"%"}, + "?":{glyph:"?",tag:"note",class:""}, + ":":{glyph:":",tag:"info",class:""}, + "*":{glyph:"*",tag:"h2",class:""}, + "=":{glyph:"=",tag:"h3",class:""}, + "+":{glyph:"+",tag:"hs",class:""}, + ">":{glyph:">",tag:"",class:""} + } + + this.stash = { + rune : "", + all : [], + add : function(rune,item){ + this.rune = this.copy(rune) + this.all.push({rune:rune,item:item}); + }, + pop : function(){ + var copy = this.copy(this.all); + this.all = []; + return copy; + }, + is_pop : function(rune){ + return this.all.length > 0 && rune.tag != this.rune.tag; + }, + length: function() + { + return this.all.length; + }, + copy : function(data){ + return JSON.parse(JSON.stringify(data)); + } + } + + this.markup = function(html) + { + html = html.replace(/{_/g,"<i>").replace(/_}/g,"</i>") + html = html.replace(/{\*/g,"<b>").replace(/\*}/g,"</b>") + html = html.replace(/{\#/g,"<code class='inline'>").replace(/\#}/g,"</code>") + + var parts = html.split("{{") + for(id in parts){ + var part = parts[id]; + if(part.indexOf("}}") == -1){ continue; } + var content = part.split("}}")[0]; + if(content.substr(0,1) == "$"){ html = html.replace(`{{${content}}}`, this.operation(content)); continue; } + if(content.substr(0,1) == "%"){ html = html.replace(`{{${content}}}`, this.media(content)); continue; } + var target = content.indexOf("|") > -1 ? content.split("|")[1] : content; + var name = content.indexOf("|") > -1 ? content.split("|")[0] : content; + var external = (target.indexOf("https:") > -1 || target.indexOf("http:") > -1 || target.indexOf("dat:") > -1); + var redlink = !external && !invoke.vessel.lexicon.has_term(target); if(redlink){ console.warn("broken link",target,html); } + html = html.replace(`{{${content}}}`,`<a target='${external ? "_blank" : "_self"}' href='${external ? target : target.to_url()}' class='${external ? "external" : "local"} ${redlink ? "redlink" : ""}'>${name}</a>`) + } + + return html; + } + + this.media = function(val) + { + var service = val.split(" ")[0]; + var id = val.split(" ")[1]; + + if(service == "itchio"){ + return `<iframe frameborder="0" src="https://itch.io/embed/${id}?link_color=000000" width="600" height="167"></iframe>`; + } + if(service == "bandcamp"){ + return `<iframe style="border: 0; width: 600px; height: 274px;" src="https://bandcamp.com/EmbeddedPlayer/album=${id}/size=large/bgcol=ffffff/linkcol=333333/artwork=small/transparent=true/" seamless></iframe>`; + } + return `<img src='media/${val}'/>` + } + + this.operation = function(val) + { + val = val.replace("$","").trim(); + + if(val == "desamber"){ + return new Date().desamber(); + } + if(val == "clock"){ + return new Date().clock(); + } + if(val.split(" ")[0] == "lietal"){ + return invoke.vessel.lietal.construction(val.replace("lietal","").trim()); + } + return `((${val}))` + } + + this.parse = function(raw = this.raw) + { + if(!raw){ return ""; } + + var html = ""; + var lines = raw; + var lines = !Array.isArray(raw) ? raw.split("\n") : raw; + + for(id in lines){ + var char = lines[id].substr(0,1).trim().toString() + var rune = this.runes[char]; + var trail = lines[id].substr(1,1); + var line = this.markup(lines[id].substr(2)); + if(!line || line.trim() == ""){ continue; } + + if(!rune){ console.log(`Unknown rune:${char} : ${line}`); } + if(trail != " "){ console.warn("Runic","Non-rune["+trail+"] at:"+id+"("+line+")"); continue; } + + if(char == "%"){ html += this.media(line); continue; } + if(this.stash.is_pop(rune)){ html += this.render_stash(); } + if(rune.stash === true){ this.stash.add(rune,line) ; continue; } + html += this.render(line,rune); + } + if(this.stash.length() > 0){ html += this.render_stash(); } + return html; + } + + this.render_stash = function() + { + var rune = this.stash.rune; + var stash = this.stash.pop(); + + var html = ""; + for(id in stash){ + var rune = stash[id].rune; + var line = stash[id].item; + html += rune.wrap ? `<${rune.sub}><${rune.wrap}>${line.replace(/\|/g,`</${rune.wrap}><${rune.wrap}>`).trim()}</${rune.wrap}></${rune.sub}>` : `<${rune.sub}>${line}</${rune.sub}>`; + } + return `<${rune.tag} class='${rune.class}'>${html}</${rune.tag}>` + } + + this.render = function(line = "",rune = null) + { + if(rune && rune.tag == "img"){ return `<img src='media/${line}'/>`; } + if(rune && rune.tag == "table"){ return "HEY"; } + + return rune ? (rune.tag ? "<"+rune.tag+" class='"+rune.class+"'>"+line+"</"+rune.tag+">" : line) : ""; + } + + this.html = function() + { + return this.parse(raw); + } + + this.toString = function() + { + return this.html(); + } +} + +String.prototype.capitalize = function() +{ + return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase(); +} + +String.prototype.to_url = function() +{ + return this.toLowerCase().replace(/ /g,"+").replace(/[^0-9a-z\+]/gi,"").trim(); +} + +String.prototype.to_path = function() +{ + return this.toLowerCase().replace(/ /g,".").replace(/[^0-9a-z\.]/gi,"").trim(); +}+ \ No newline at end of file diff --git a/scripts/nodes/parser.js b/scripts/nodes/parser.js @@ -0,0 +1,14 @@ +function ParserNode(id,rect) +{ + Node.call(this,id,rect); + + this.glyph = NODE_GLYPHS.router + + this.receive = function(q) + { + this.label = `parser=${q.name}` + var assoc = this.signal(q.type.slice(0, -1)); + + this.send(assoc) + } +}+ \ No newline at end of file diff --git a/scripts/nodes/router.js b/scripts/nodes/router.js @@ -3,7 +3,6 @@ function RouterNode(id,rect) Node.call(this,id,rect); this.glyph = NODE_GLYPHS.router - this.label = "router" this.receive = function(q) { @@ -12,7 +11,7 @@ function RouterNode(id,rect) var type = find(q,db) - this.label = `Router(${type})` + this.label = `${type}/${q}` this.send({ name:q, type:type, diff --git a/scripts/nodes/template.js b/scripts/nodes/template.js @@ -8,18 +8,24 @@ function TemplateNode(id,rect) this.receive = function(q) { - var template = this.signal(q.type.slice(0, -1)); + console.log(q) + // var template = this.signal(q.type.slice(0, -1)); + // var related_template = this.signal("related"); - var dom = { - header:{ - search:q.name - }, - body:template.answer(q), - footer:"hello" - } - this.send({main:dom}) + // console.log(related_template) + // var dom = { + // header:{ + // search:q.name + // }, + // body:{ + // core: template.answer(q), + // related: "qq" + // }, + // footer:"hello" + // } + // this.send({main:dom}) - // Install Dom - this.signal("main").request() + // // Install Dom + // this.signal("main").request() } } \ No newline at end of file diff --git a/scripts/templates/ingredient.js b/scripts/templates/ingredient.js @@ -9,28 +9,19 @@ function IngredientTemplate(id,rect) this.answer = function(t) { var ingredient = t.result; - var html = ""; - html += ` - <h1>${t.name}</h1> - <p>${ingredient.DESC}</p> - <p>${ingredient.TAGS}</p> - <h4>Related Recipes</h4> - <list>${print_list(related_recipes(t.name,sort(t.tables.recipes)))}</list> - <h4>Related Ingredients</h4> - <list>${print_list(related_ingredients(t.name,ingredient.TAGS[0],sort(t.tables.ingredients)))}</list>`; - - return html - } - - function print_list(elements) - { - var html = ""; - for(id in elements){ - var name = elements[id]; - html += `<ln><a href='#${name.to_url()}'>${name.capitalize()}</a></ln>` + return { + header:{ + search: t.name.capitalize() + }, + body: { + core: ingredient.DESC, + related:{ + related_recipes:related_recipes(t.name,t.tables.recipes), + related_ingredients:related_ingredients(t.name,ingredient.TAGS[0],sort(t.tables.ingredients)) + } + } } - return html } function sort(o) @@ -65,18 +56,3 @@ function IngredientTemplate(id,rect) return a; } } - -String.prototype.capitalize = function() -{ - return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase(); -} - -String.prototype.to_url = function() -{ - return this.toLowerCase().replace(/ /g,"+").replace(/[^0-9a-z\+]/gi,"").trim(); -} - -String.prototype.to_path = function() -{ - return this.toLowerCase().replace(/ /g,".").replace(/[^0-9a-z\.]/gi,"").trim(); -}- \ No newline at end of file diff --git a/scripts/templates/related.js b/scripts/templates/related.js @@ -0,0 +1,14 @@ +function RelatedTemplate(id,rect) +{ + Node.call(this,id,rect); + + this.glyph = NODE_GLYPHS.render + + // Create the recipe body + + this.answer = function(t) + { + return "" + return html + } +}+ \ No newline at end of file