'use strict'; import util from 'util'; const YOUTUBE_WATCH = 'https://youtu.be/%s'; const GRAPH_NODE = ' "%s" [label="%s", URL="%s", fontcolor=blue]'; const GRAPH_LINK = ' "%s" -> "%s"'; /** * Escape double quotes in a string. */ const escapeQuotes = str => str.replace(/"/g, '\\"'); /** * Convert a graph of videos to the DOT format. * * @param nodes Nodes of the graph. * @param next For each node, list of next neighbors. * @param [title=identity] Function giving the name of each node. * @param [url=none] Function given the URL of each node, or an empty string * if a node has no URL. * @return DOT representation of the graph. */ export const graphToDOT = (nodes, next) => { // Convert nodes const nodesStr = Object.entries(nodes).map(([id, {title}]) => { const url = util.format(YOUTUBE_WATCH, id); return util.format(GRAPH_NODE, id, escapeQuotes(title), url); }).join('\n'); // Convert edges const nextStr = Object.entries(next).map(([id, neighbors]) => Array.from(neighbors) .map(neighbor => util.format(GRAPH_LINK, id, neighbor)) .join('\n') ).join('\n'); return `digraph youtube { ${nodesStr} ${nextStr} }`; };