Website version 6 v6.j0.lol
at trunk 55 lines 1.5 kB view raw
1import { execSync } from 'node:child_process'; 2 3const html = (strings, ...values) => String.raw({ raw: strings }, ...values); 4 5function htmlEscape(s) { 6 const lookup = { 7 '&': "&amp;", 8 '"': "&quot;", 9 '\'': "&apos;", 10 '<': "&lt;", 11 '>': "&gt;" 12 }; 13 return s.replace( /[&"'<>]/g, c => lookup[c] ); 14} 15 16/** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */ 17export function setupShortcodes(eleventyConfig) { 18 eleventyConfig.addPairedShortcode('code', (code, lang, filename) => { 19 let highlighted; 20 if (lang != null && lang !== "" && lang !== "plain") { 21 highlighted = execSync(`arborium --html --lang ${lang}`, { 22 input: code.trim(), 23 encoding: 'utf-8', 24 }) 25 } 26 27 const caption = lang || filename 28 ? html`<figcaption> 29 ${lang ? html`<span class="lang code-lang-tag">${lang}</span>` : ''} 30 ${filename ? html`<span class="filename code-filename-tag">${filename}</span>` : ''} 31 </figcaption>` 32 : '' 33 34 return html` 35 <figure class="code-block"> 36 ${caption} 37 <pre><code>${highlighted ?? htmlEscape(code.trim())}</code></pre> 38 </figure>` 39 }) 40 41 eleventyConfig.addPairedShortcode('speech', (contents, option) => { 42 return html` 43 <aside class="speech-box"> 44 <div class="speech-character character-${option}"> 45 <div class="glass glassleft"></div> 46 <div class="eye glassleft"></div> 47 48 <div class="glass glassright"></div> 49 <div class="eye glassright"></div> 50 <div class="nose"></div> 51 </div> 52 <p class="speech-content">${contents}</p> 53 </aside>` 54 }) 55}