youtube-maze/explore/graph.mjs

45 lines
1.2 KiB
JavaScript
Raw Normal View History

2017-04-02 00:54:46 +00:00
'use strict';
2020-07-15 17:31:09 +00:00
import util from 'util';
2017-04-02 00:54:46 +00:00
const YOUTUBE_WATCH = 'https://youtu.be/%s';
const GRAPH_NODE = ' "%s" [label="%s", URL="%s", fontcolor=blue]';
2017-04-02 00:54:46 +00:00
const GRAPH_LINK = ' "%s" -> "%s"';
/**
* Escape double quotes in a string.
*/
const escapeQuotes = str => str.replace(/"/g, '\\"');
2017-04-02 00:54:46 +00:00
/**
* Convert a graph of videos to the DOT format.
2017-04-02 00:54:46 +00:00
*
* @param nodes Nodes of the graph.
* @param next For each node, list of next neighbors.
2020-07-15 17:14:31 +00:00
* @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.
2017-04-02 00:54:46 +00:00
*/
export const graphToDOT = (nodes, next) =>
2017-04-02 00:54:46 +00:00
{
2020-07-15 17:14:31 +00:00
// Convert nodes
const nodesStr = Object.entries(nodes).map(([id, {title}]) =>
2017-04-02 00:54:46 +00:00
{
const url = util.format(YOUTUBE_WATCH, id);
return util.format(GRAPH_NODE, id, escapeQuotes(title), url);
}).join('\n');
2017-04-02 00:54:46 +00:00
2020-07-15 17:14:31 +00:00
// Convert edges
const nextStr = Object.entries(next).map(([id, neighbors]) =>
Array.from(neighbors)
.map(neighbor => util.format(GRAPH_LINK, id, neighbor))
.join('\n')
2017-04-02 00:54:46 +00:00
).join('\n');
return `digraph youtube {
${nodesStr}
${nextStr}
}`;
2017-04-02 00:54:46 +00:00
};