Enrich Kumu SVG

Using Enrich Arrows SVG as a starting place, here we offer a workflow to enrich the SVG export from Kumu with wiki internal links.

//wiki.dbbs.co/assets/pages/js-snippet-template/esm.html HEIGHT 45

The form works fine if you upload the exported SVG from Kumu as a wiki asset, and use the link to that in the form.


We annotate the code which enriches the Kumu SVG.

Import Frame Integration Promises and setup DOM helpers.

import * as frame from "https://wiki.dbbs.co/assets/v1/frame.js" const $ = (s, el=document) => el.querySelector(s) const $$ = (s, el=document) => Array.from(el.querySelectorAll(s))

Given a Kumu SVG export URL, get the SVG DOM. We also remove the height and width attributes so browsers will scale the image to fit.

async function getSvg(url) { let res = await fetch(url) let string = await res.text() let dom = new DOMParser() .parseFromString(string, "image/svg+xml") let svg = dom.documentElement let width = svg.getAttribute('width') let height = svg.getAttribute('height') svg.removeAttribute("width") svg.removeAttribute("height") svg.setAttribute("viewbox", `0 0 ${width} ${height}`) return svg }

Here is where we encode our understanding of the DOM structure of Kumu SVG export diagrams. We wrap specific elements in the document with annotated anchor tags that our HTML plugin interprets as internal links.

function enrich(svg) { $$('text', svg) .filter((item) => item.previousSibling?.tagName != 'text') .forEach((item) => { let text = item.textContent; let curr = item while (curr.nextSibling?.tagName == 'text') { curr = curr.nextSibling text += ' ' + curr.textContent } console.log(text) wrapNode(item, text) }) }

function wrapNode(node, title) { console.log(node, title) let anchor = anchorFor(title) let parent = node.parentNode parent.insertBefore(anchor, node) let curr = node while (curr?.tagName == 'text') { let next = curr.nextSibling parent.removeChild(curr) anchor.appendChild(curr) curr = next } }

function anchorFor(title) { let anchor = document.createElementNS( "http://www.w3.org/2000/svg", "a") anchor.setAttribute("class", "internal") anchor.setAttribute("data-title", title) anchor.setAttribute("href", `/${asSlug(title)}.html`) return anchor }

const asSlug = title => title .replace(/\s/g, '-') .replace(/[^A-Za-z0-9-]/g, '') .toLowerCase()

Emit the HTML form.

export async function emit(el) { el.innerHTML = ` <style>input {width: 100%; display: block;}</style> <input name="title" type="text" placeholder="page title"> <input name="source" type="text" placeholder="URL to svg file"> <button>Create</button> ` }

Bind a click handler to the form button.

export async function bind(el) { el.querySelector('button').onclick = async e => { let title = $("[name=title]").value.trim() || "Enriched Arrows SVG" let url = $("input[name=source]").value.trim() let svg = await getSvg(url) enrich(svg) frame.open({ title, story: [ {type:"paragraph", text: "Describe this graph."}, {type:"html", text: svg.outerHTML} ] }, e.shiftKey) } }