runic.js (3034B)
1 function esc(s) { 2 return he.encode(s, {useNamedReferences: true}) 3 } 4 5 function Runic(lines = [], templater = null) 6 { 7 this.lines = lines; 8 9 var runes = { 10 "&":{tag:"p"}, 11 "?":{tag:"p",class:"note"}, 12 "-":{tag:"ln",wrapper:"list"}, 13 "#":{tag:"ln",wrapper:"bcode"}, 14 "*":{tag:"h4"}, 15 "+":{tag:"hs"}, 16 "@":{tag:"quote",fn:quote}, 17 "|":{tag:"tr",wrapper:"table",fn:table}, 18 "!":{tag:"th",wrapper:"table",fn:table}, 19 "%":{fn:media}, 20 ">":{} 21 } 22 23 function is_runic(l) 24 { 25 var rune = l.substr(0,1); 26 var trail = l.substr(1,1); 27 28 if(trail != " "){ console.warn("Non-Runic",l); return false; } 29 if(!runes[rune]){ console.warn(`Non-Runic[${rune}]`,l); return false; } 30 31 return true; 32 } 33 34 function stash(acc,l) 35 { 36 var rune = l.substr(0,1) 37 var line = l.substr(2).trim() 38 var prev = acc[acc.length-1] ? acc[acc.length-1] : [{rune:rune,a:[]}] 39 40 if(prev.rune == rune){ 41 prev.a.push(line) 42 } 43 else{ 44 acc.push({rune:rune,a:[line]}) 45 } 46 47 return acc 48 } 49 50 function _html(acc,stash) 51 { 52 var html = "" 53 var wr = runes[stash.rune].wrapper 54 for(var id in stash.a){ 55 var r = runes[stash.rune] 56 var txt = r.fn ? r.fn(stash.a[id]) : stash.a[id] 57 var htm = templater ? new templater(txt) : txt 58 html += r.tag ? `<${r.tag} class='${r.class ? r.class : ''}'>${htm}</${r.tag}>` : `${htm}` 59 } 60 return wr ? `${acc}<${wr}>${html}</${wr}>` : `${acc}${html}` 61 } 62 63 // Templates 64 65 function quote(content) 66 { 67 var parts = content.split(" | ") 68 var text = parts[0].trim() 69 var author = parts[1] 70 var source = parts[2] 71 var link = parts[3] 72 73 return ` 74 ${text.length > 1 ? `<p class=\'text\'>${text}</p>` : ''} 75 ${author ? `<p class='attrib'>${author}${source && link ? `, <a class="external" href='${link}'>${source}</a>` : source ? `, <b>${source}</b>` : ''}</p>` : ''}` 76 } 77 78 function media(content) 79 { 80 var service = content.split(" ")[0]; 81 var id = content.split(" ")[1]; 82 83 if(service == "itchio"){ return `<iframe frameborder="0" src="https://itch.io/embed/${id}?link_color=000000" width="600" height="167"></iframe>`; } 84 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>`; } 85 if(service == "youtube"){ return `<iframe width="100%" height="380" src="https://www.youtube.com/embed/${id}?rel=0" style="max-width:700px" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>`; } 86 if(service == "custom"){ return `<iframe src='${id}' style='width:100%;height:350px;'></iframe>`; } 87 return `<img src='media/${service}' class='${id}'/>` 88 } 89 90 function table(content) 91 { 92 return `<td>${content.replace(/ \| /g,"</td><td>")}</td>` 93 } 94 95 // 96 97 this.toString = function() 98 { 99 var lines = this.lines.filter(is_runic); 100 return lines.reduce(stash,[]).reduce(_html,""); 101 } 102 }