diff --git a/packages/rehype-vizdom/src/dotToSvg.ts b/packages/rehype-vizdom/src/dotToSvg.ts new file mode 100644 index 0000000..9a0f910 --- /dev/null +++ b/packages/rehype-vizdom/src/dotToSvg.ts @@ -0,0 +1,131 @@ +import { fromDot, NodeModel, NodeRef } from "ts-graphviz"; +import { + DirectedGraph, + RankDir, + Shape, + VertexWeakRef, +} from "@stereobooster/vizdom-ts-esm"; + +function titleCase(str: string) { + return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase(); +} + +const shapes: Record = { + Rectangle: Shape.Rectangle, + Rect: Shape.Rectangle, + Square: Shape.Square, + Box: Shape.Square, + Circle: Shape.Circle, + Ellipse: Shape.Ellipse, + Oval: Shape.Ellipse, + Default: Shape.Ellipse, + Triangle: Shape.Triangle, + Diamond: Shape.Diamond, + Plaintext: Shape.Plaintext, + Underline: Shape.Underline, +}; + +function shape(node: NodeModel) { + const sh = node.attributes.get("shape"); + if (!sh) return shapes.Default; + return shapes[titleCase(sh)] ?? shapes.Default; +} + +const rankDirs = { + TB: RankDir.TB, + BT: RankDir.BT, + LR: RankDir.LR, + RL: RankDir.RL, +}; + +export async function dotToSvg(code: string) { + const graph = new DirectedGraph(); + const model = fromDot(code); + graph.attrs().set((graph) => { + if (!graph.layout) graph.layout = {}; + if (model.get("rankdir")) { + graph.layout.rank_dir = rankDirs[model.get("rankdir")!]; + } + return graph; + }); + + const nodes: Record = {}; + model.nodes.forEach((node) => { + nodes[node.id] = graph.new_vertex({ + render: { + id: node.id, + label: node.attributes.get("label"), + tooltip: node.attributes.get("tooltip"), + shape: shape(node), + // fill_color: node.attributes.get("fillcolor") as string, + // font_color: node.attributes.get("fontcolor") as string, + // color: node.attributes.get("color") as string, + // font_size: node.attributes.get("fontsize"), + // pen_width: node.attributes.get("penwidth"), + // style: node.attributes.get("style") as any, + }, + }); + }); + + model.subgraphs.forEach((subg) => { + // TODO + }); + + model.edges.forEach((edge) => { + for (let i = 0; i <= edge.targets.length - 2; i++) { + const from: NodeRef[] = ( + Array.isArray(edge.targets[i]) ? edge.targets[i] : [edge.targets[i]] + ) as any; + const to: NodeRef[] = ( + Array.isArray(edge.targets[i + 1]) + ? edge.targets[i + 1] + : [edge.targets[i + 1]] + ) as any; + + from.forEach((f) => { + if (!nodes[f.id]) { + nodes[f.id] = graph.new_vertex({ + render: { + label: f.id, + id: f.id, + shape: shapes.Default, + }, + }); + } + to.forEach((t) => { + if (!nodes[t.id]) { + nodes[t.id] = graph.new_vertex({ + render: { + label: t.id, + id: t.id, + shape: shapes.Default, + }, + }); + } + + graph.new_edge(nodes[f.id], nodes[t.id], { + render: { + label: edge.attributes.get("label"), + tooltip: edge.attributes.get("tooltip"), + // pen_width: edge.attributes.get("penwidth"), + // font_size: edge.attributes.get("fontsize"), + // style: edge.attributes.get("style") as any, + // // shape: edge.attributes.get("shape") as any, + // // curve: edge.attributes.get("curve") as any, + // arrow_head: edge.attributes.get("arrowhead") as any, + // dir: edge.attributes.get("dir") as any, + // color: edge.attributes.get("color") as string, + // font_color: edge.attributes.get("fontcolor") as string, + // fill_color: edge.attributes.get("fillcolor") as string, + // // id?: string; + }, + }); + }); + }); + } + }); + + // const positioned = graph.layout(); + const positioned = graph.layout(); + return await positioned.to_svg().to_string(); +} diff --git a/packages/rehype-vizdom/src/index.ts b/packages/rehype-vizdom/src/index.ts index efd974f..256bb33 100644 --- a/packages/rehype-vizdom/src/index.ts +++ b/packages/rehype-vizdom/src/index.ts @@ -2,80 +2,8 @@ import type { Plugin } from "unified"; import type { Root } from "hast"; import { rehypeCodeHook, type MapLike } from "@beoe/rehype-code-hook"; import { type Config as SvgoConfig } from "svgo"; -import { fromDot } from "ts-graphviz"; import { processVizdomSvg } from "./vizdom.js"; -import { DirectedGraph, VertexWeakRef } from "@stereobooster/vizdom-ts-esm"; - -export async function getSvg(code: string) { - const graph = new DirectedGraph(); - const model = fromDot(code); - - const nodes: Record = {}; - model.nodes.forEach((node) => { - nodes[node.id] = graph.new_vertex({ - render: { - id: node.id, - label: node.attributes.get("label"), - tooltip: node.attributes.get("tooltip"), - fill_color: node.attributes.get("fillcolor") as string, - font_color: node.attributes.get("fontcolor") as string, - color: node.attributes.get("color") as string, - font_size: node.attributes.get("fontsize"), - pen_width: node.attributes.get("penwidth"), - shape: node.attributes.get("shape") as any, - style: node.attributes.get("style") as any, - }, - }); - }); - - model.edges.forEach((edge) => { - const from = edge.targets[0]; - const to = edge.targets[1]; - - if (Array.isArray(from) || Array.isArray(to)) { - throw new Error("what is it?"); - } - - if (!nodes[from.id]) { - nodes[from.id] = graph.new_vertex({ - render: { - label: from.id, - id: from.id, - }, - }); - } - - if (!nodes[to.id]) { - nodes[to.id] = graph.new_vertex({ - render: { - label: to.id, - id: to.id, - }, - }); - } - - graph.new_edge(nodes[from.id], nodes[to.id], { - render: { - pen_width: edge.attributes.get("penwidth"), - font_size: edge.attributes.get("fontsize"), - style: edge.attributes.get("style") as any, - // shape: edge.attributes.get("shape") as any, - // curve: edge.attributes.get("curve") as any, - arrow_head: edge.attributes.get("arrowhead") as any, - dir: edge.attributes.get("dir") as any, - color: edge.attributes.get("color") as string, - font_color: edge.attributes.get("fontcolor") as string, - fill_color: edge.attributes.get("fillcolor") as string, - // id?: string; - label: edge.attributes.get("label"), - tooltip: edge.attributes.get("tooltip"), - }, - }); - }); - - const positioned = graph.layout(); - return await positioned.to_svg().to_string(); -} +import { dotToSvg } from "./dotToSvg.js"; export type RenderVizdomOptions = { code: string; @@ -101,8 +29,8 @@ export const rehypeVizdom: Plugin<[RehypeVizdomConfig?], Root> = ( salt, language: "vizdom", code: ({ code }) => - getSvg(code).then( - (str) => processVizdomSvg(str, options.class, options.svgo) + dotToSvg(code).then((str) => + processVizdomSvg(str, options.class, options.svgo) ), }); }; diff --git a/packages/rehype-vizdom/test/dotToSvg.test.ts b/packages/rehype-vizdom/test/dotToSvg.test.ts new file mode 100644 index 0000000..7dfd1b2 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg.test.ts @@ -0,0 +1,28 @@ +import { expect, it, describe } from "vitest"; +import fs from "node:fs/promises"; + +import { dotToSvg } from "../src/dotToSvg"; + +function example(x: number) { + it(`example ${x}`, async () => { + const file = await dotToSvg( + ( + await fs.readFile(new URL(`./dotToSvg/${x}.dot`, import.meta.url)) + ).toString() + ); + + expect(file.toString()).toMatchFileSnapshot(`./dotToSvg/${x}.svg`); + }); +} + +describe("dotToSvg", () => { + example(1); + example(2); + // I have no idea how to set rank + // example(3); + example(7); + // parser doesn't support it + // example(8); + example(10); + example(11); +}); diff --git a/packages/rehype-vizdom/test/dotToSvg/1.dot b/packages/rehype-vizdom/test/dotToSvg/1.dot new file mode 100644 index 0000000..fda5598 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/1.dot @@ -0,0 +1,3 @@ +digraph { + a -> b +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/1.svg b/packages/rehype-vizdom/test/dotToSvg/1.svg new file mode 100644 index 0000000..5ddfc14 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/1.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +a -> b + + +a -> b + + + + +a + + +a + + + + +b + + +b + + + \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/10.dot b/packages/rehype-vizdom/test/dotToSvg/10.dot new file mode 100644 index 0000000..9cce17d --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/10.dot @@ -0,0 +1,16 @@ +digraph { + + V1 -> V2; + V1 -> V4; + V2 -> V5; + V3 -> V1; + V4 -> V2; + V4 -> V3; + V4 -> V6; + V4 -> V7; + V5 -> V4; + V5 -> V7; + V6 -> V3; + V7 -> V6; + +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/10.svg b/packages/rehype-vizdom/test/dotToSvg/10.svg new file mode 100644 index 0000000..ec1b547 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/10.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +V1 -> V2 + + +V1 -> V2 + + + + +V1 -> V4 + + +V1 -> V4 + + + + +V2 -> V5 + + +V2 -> V5 + + + + +V4 -> V3 + + +V4 -> V3 + + + + +V4 -> V6 + + +V4 -> V6 + + + + +V4 -> V7 + + +V4 -> V7 + + + + +V5 -> V4 + + +V5 -> V4 + + + + +V5 -> V7 + + +V5 -> V7 + + + + +V6 -> V3 + + +V6 -> V3 + + + + +V7 -> V6 + + +V7 -> V6 + + + + +V3 -> V1 + + +V3 -> V1 + + + + +V4 -> V2 + + +V4 -> V2 + + + + +V1 + + +V1 + + + + +V2 + + +V2 + + + + +V4 + + +V4 + + + + +V5 + + +V5 + + + + +V3 + + +V3 + + + + +V6 + + +V6 + + + + +V7 + + +V7 + + + \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/11.dot b/packages/rehype-vizdom/test/dotToSvg/11.dot new file mode 100644 index 0000000..3ae3da5 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/11.dot @@ -0,0 +1,25 @@ +digraph G { + subgraph cluster_0 { + style=filled; + color=lightgrey; + node [style=filled, color=white]; + a0 -> a1 -> a2 -> a3; + label = "process #1"; + } + subgraph cluster_1 { + node [style=filled]; + b0 -> b1 -> b2 -> b3; + label = "process #2"; + color=blue + } + start -> a0; + start -> b0; + a1 -> b3; + b2 -> a3; + a3 -> a0; + a3 -> end; + b3 -> end; + + start [shape=Mdiamond]; + end [shape=Msquare]; +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/11.svg b/packages/rehype-vizdom/test/dotToSvg/11.svg new file mode 100644 index 0000000..49c4aae --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/11.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +start -> a0 + + +start -> a0 + + + + +start -> b0 + + +start -> b0 + + + + +a1 -> b3 + + +a1 -> b3 + + + + +b2 -> a3 + + +b2 -> a3 + + + + +a3 -> a0 + + +a3 -> a0 + + + + +a3 -> end + + +a3 -> end + + + + +b3 -> end + + +b3 -> end + + + + +start + + + + +end + + + + +a0 + + +a0 + + + + +b0 + + +b0 + + + + +a1 + + +a1 + + + + +b3 + + +b3 + + + + +b2 + + +b2 + + + + +a3 + + +a3 + + + \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/2.dot b/packages/rehype-vizdom/test/dotToSvg/2.dot new file mode 100644 index 0000000..2758d24 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/2.dot @@ -0,0 +1,14 @@ +digraph shapes { + rankdir=LR + 0 [shape=plaintext label="no shape"] + 1 [shape=box label=box] + 2 [shape=rect label=rect] + 3 [shape=rectangle label=rectangle] + 4 [shape=square label=square] + 5 [shape=oval label=oval] + 6 [shape=ellipse label=ellipse] + 7 [shape=circle label=circle] + 8 [shape=triangle label=triangle] + 9 [shape=diamond label=diamond] + 10 [shape=default label=default] +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/2.svg b/packages/rehype-vizdom/test/dotToSvg/2.svg new file mode 100644 index 0000000..a980d1b --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/2.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +no shape + + +no shape + + + + +box + + +box + + + + +rect + + +rect + + + + +rectangle + + +rectangle + + + + +square + + +square + + + + +oval + + +oval + + + + +ellipse + + +ellipse + + + + +circle + + +circle + + + + +triangle + + +triangle + + + + +diamond + + +diamond + + + + +default + + +default + + + \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/3.dot b/packages/rehype-vizdom/test/dotToSvg/3.dot new file mode 100644 index 0000000..fb6fe51 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/3.dot @@ -0,0 +1,13 @@ +digraph { + rankdir=LR; + a -> { b c d }; b -> { c e }; c -> { e f }; d -> { f g }; e -> h; + f -> { h i j g }; g -> k; h -> { o l }; i -> { l m j }; j -> { m n k }; + k -> { n r }; l -> { o m }; m -> { o p n }; n -> { q r }; + o -> { s p }; p -> { s t q }; q -> { t r }; r -> t; s -> z; t -> z; + { rank=same; b; c; d; } + { rank=same; e; f; g; } + { rank=same; h; i; j; k; } + { rank=same; l; m; n; } + { rank=same; o; p; q; r; } + { rank=same; s; t; } +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/4.dot b/packages/rehype-vizdom/test/dotToSvg/4.dot new file mode 100644 index 0000000..b1ed539 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/4.dot @@ -0,0 +1,13 @@ +digraph g { + node [shape=plaintext]; + A1 -> B1; + A2 -> B2; + A3 -> B3; + A1 -> A2 [label=f]; + A2 -> A3 [label=g]; + B2 -> B3 [label="g'"]; + B1 -> B3 [label="(g o f)'" tailport=s headport=s]; + + { rank=same; A1 A2 A3 } + { rank=same; B1 B2 B3 } +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/5.dot b/packages/rehype-vizdom/test/dotToSvg/5.dot new file mode 100644 index 0000000..911bfa4 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/5.dot @@ -0,0 +1,102 @@ +digraph yours_truly { + splines=true; + //newrank=true; + nodesep="0.25"; + label="Complex Architecture"; + labelloc=t; + subgraph cluster_clients_mobvm_a { + label="xvm_a Clients"; + style=dashed; + mobvm_a_req [label="xvm_a Application .."]; + mobvm_a_req1 [label="xvm_a Application 1"]; + { + rank=same; + mobvm_a_req1; + mobvm_a_req; + } + } + subgraph cluster_clients_prot_a { + label="Z Clients"; + style=dashed; + z_req [label="Z Application .."]; + z_req1 [label="Z Application 1"]; + { + rank=same; + z_req1; + z_req; + } + } + subgraph cluster_prot_asrv { + label="Z Shapeshifters\n(Configurable\nZ Shapeshifter)"; + style=dashed; + z_shapeshifter [label="Z Shapeshifter Appearances"]; + z_req1 -> z_shapeshifter [dir=both constraint=true]; + z_req -> z_shapeshifter [dir=both constraint=true]; + } + subgraph cluster_machsrv { + label="Machsrv Shapeshifter"; + machsrv_xprot_gen [label="Machsrv Core|PROT_A-to-XPROT Converter"]; + z_shapeshifter -> machsrv_xprot_gen:f0 [label="Foo SCADA" dir=both constraint=true]; + mobvm_a_req1 -> machsrv_xprot_gen:f0 [dir=both constraint=true]; + mobvm_a_req -> machsrv_xprot_gen:f0 [dir=both constraint=true]; + } + subgraph cluster_accel { + label="NOXd Shapeshifter"; + accel_appearance [label="NOXd Appearance"]; + } + subgraph cluster_yours_trulybox { + label=YoursTruly; + subgraph cluster_tunnel { + label="Foo Reactor"; + tunnel_ingress [label="Ingress Shapeshifter"]; + accel [label="NOX Shapeshifter"]; + tunnel_egress [label="Egress Shapeshifter"]; + tunnel_ingress -> accel [dir=both]; + accel -> tunnel_egress [dir=both]; + accel_appearance -> accel [dir=both constraint=true]; + } + subgraph cluster_frontend { + label="YoursTruly Front-End"; + others [label="Other Chunks"]; + other_xprot [label="XPROT \"crystalizer\""]; + front_end_jz [label="JZ Chunk"]; + arbiter_vadam [label="Arbiter Chunks"]; + arbiter_vadam -> other_xprot [style=dotted]; + arbiter_vadam -> front_end_jz [style=dotted]; + arbiter_vadam -> others [style=dotted]; + front_end_jz -> tunnel_ingress [dir=both label="XPROT over PROT_G"]; + front_end_jz -> other_xprot [dir=both]; + other_xprot -> machsrv_xprot_gen [dir=both label="XPROT over PROT_G" constraint=true]; + } + } + subgraph cluster_shapeshifter_misc { + label="Other Shapeshifters"; + style=dashed; + handle_x [label="Shapeshift X"]; + handle_1 [label="Shapeshift 1"]; + others -> handle_1 [style=dotted dir=both constraint=true]; + others -> handle_x [style=dotted dir=both constraint=true]; + } + subgraph cluster_space_ship_a { + label=ShipX; + subgraph cluster_vm_a { + label=ReactorX; + subgraph cluster_tungsten { + label=Tungsten + zzz [label=ZZZ]; + yyy [label=YYY]; + } + } + subgraph cluster_piston { + label=ReactorY; + zzz_worker [label="{ZZZ Worker}"]; + yyy_worker [label="{YYY Worker}"]; + foo_agent [label="{Foo Agent}"]; + foo_agent -> zzz_worker [dir=both constraint=true label=MechCmd]; + foo_agent -> yyy_worker [dir=both constraint=true label=MechCmd]; + } + zzz_worker -> zzz [dir=both constraint=true label="SCADA_A()"]; + yyy_worker -> yyy [dir=both constraint=true label="SCADA_A()"]; + } + tunnel_egress -> foo_agent [dir=both label="Raw PROT_G" constraint=true]; +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/6.dot b/packages/rehype-vizdom/test/dotToSvg/6.dot new file mode 100644 index 0000000..596a6d5 --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/6.dot @@ -0,0 +1,55 @@ +digraph { + graph [fontname=monospace, fontsize=10, color=grey, fontcolor=grey]; + node [fontname=monospace, style=filled]; + edge [fontname=monospace, color=blue, fontcolor=blue, fontsize=10]; + /* + define components in the clusters they belong to + */ + subgraph clusterProvider { + label="3rd party" + user + app + "provider-backend" [label="3rd party\nbackend"] + "provider-developer" + } + subgraph clusterPublicSubnet { + label="public subnet" + "public-api" + "admin-api" + "admin-gui" + } + subgraph clusterPrivateSubnet { + label="private subnet" + "IOT Gateway" + "resource-service" + "state-service" + DynamoDB + RDS + Kinesis + } + subgraph clusterCustomerService { + label="customer service" + "customer-service" + } + subgraph clusterFleet { + label=things + thing [color=""] + } + /* + define calls between existing components + */ + user -> app + app -> "provider-backend" + "provider-backend" -> "public-api" [label="x-auth-token=API_KEY"] + "public-api" -> "state-service" [label=" get thing\nlocation"] + "public-api" -> "resource-service" [label=" get user,"] + "resource-service" -> RDS [dir=both, label="read/write\nnon-transient\nresources"] + "customer-service" -> "admin-gui" [label="manage users"] + "customer-service" -> "provider-developer" [label="issue api key"] + "admin-gui" -> "admin-api" + "admin-api" -> "resource-service" [label="add users"] + "IOT Gateway" -> Kinesis + Kinesis -> DynamoDB [label="upsert \nthing state"] + "state-service" -> DynamoDB [label="read \nthing state"] + thing -> "IOT Gateway" [label="thing\ntelematics\nstream"] +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/7.dot b/packages/rehype-vizdom/test/dotToSvg/7.dot new file mode 100644 index 0000000..af3435a --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/7.dot @@ -0,0 +1,25 @@ +digraph G { + // 17 -> 7 -> O; + // 4 -> SPACE; + // 10 -> IMAD -> 2 -> I; + // AD -> A; + // 6 -> 3 -> W; + // RT -> R; + // 7 -> 4 -> S; + // 2 -> M; + // IMAD -> AD -> D; + // 3 -> RT -> T; + // 17 -> 10 -> 6 -> E; + // This also works, but uses more friendly nodeIds + A -> B -> C; + D -> E; + G -> H -> I -> J; + L -> N; + O -> P -> Q; + R -> S; + B -> D -> F; + I -> K; + H -> L -> M; + P -> R -> T; + A -> G -> O -> U; +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/7.svg b/packages/rehype-vizdom/test/dotToSvg/7.svg new file mode 100644 index 0000000..2b0b87a --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/7.svg @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A -> B + + +A -> B + + + + +B -> C + + +B -> C + + + + +D -> E + + +D -> E + + + + +G -> H + + +G -> H + + + + +H -> I + + +H -> I + + + + +I -> J + + +I -> J + + + + +L -> N + + +L -> N + + + + +O -> P + + +O -> P + + + + +P -> Q + + +P -> Q + + + + +R -> S + + +R -> S + + + + +B -> D + + +B -> D + + + + +D -> F + + +D -> F + + + + +I -> K + + +I -> K + + + + +H -> L + + +H -> L + + + + +L -> M + + +L -> M + + + + +P -> R + + +P -> R + + + + +R -> T + + +R -> T + + + + +A -> G + + +A -> G + + + + +G -> O + + +G -> O + + + + +O -> U + + +O -> U + + + + +A + + +A + + + + +B + + +B + + + + +C + + +C + + + + +D + + +D + + + + +E + + +E + + + + +G + + +G + + + + +H + + +H + + + + +I + + +I + + + + +J + + +J + + + + +L + + +L + + + + +N + + +N + + + + +O + + +O + + + + +P + + +P + + + + +Q + + +Q + + + + +R + + +R + + + + +S + + +S + + + + +F + + +F + + + + +K + + +K + + + + +M + + +M + + + + +T + + +T + + + + +U + + +U + + + \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/8.dot b/packages/rehype-vizdom/test/dotToSvg/8.dot new file mode 100644 index 0000000..9cddecf --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/8.dot @@ -0,0 +1,3 @@ +digraph { + A -> { B -> C -> D; E F G; { H -> I } } -> { J -> K } [label=edge_label] +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/dotToSvg/9.dot b/packages/rehype-vizdom/test/dotToSvg/9.dot new file mode 100644 index 0000000..053cb8d --- /dev/null +++ b/packages/rehype-vizdom/test/dotToSvg/9.dot @@ -0,0 +1,81 @@ +/* + * This example is used to test graph expansion +*/ +digraph { + { + { A; }; + B; + C -> D; + E -> { }; + F -> { + { }; + G; + H -> I; + J -> { }; + K -> L -> M; + N -> { } -> O; + P -> Q -> { }; + R -> { } -> { }; + { } -> { } -> { }; + { } -> S; + { } -> T -> U; + }; + V -> W -> X; + Y -> { } -> Z; + AA -> AB -> { }; + AC -> { } -> { }; + { } -> { } -> { }; + { } -> AD; + { } -> AE -> AF; + } -> { + { AG; }; + AH; + AI -> AJ; + AK -> { }; + AL -> { + { }; + AM; + AN -> AO; + AP -> { }; + AQ -> AR -> AS; + AT -> { } -> AU; + AV -> AW -> { }; + AX -> { } -> { }; + { } -> { } -> { }; + { } -> AY; + { } -> AZ -> BA; + }; + BB -> BC -> BD; + BE -> { } -> BF; + BG -> BH -> { }; + BI -> { } -> { }; + { } -> { } -> { }; + { } -> BJ; + { } -> BK -> BL; + } -> { + { BM; }; + BN; + BO -> BP; + BQ -> { }; + BR -> { + { }; + BS; + BT -> BU; + BV -> { }; + BW -> BX -> BY; + BZ -> { } -> CA; + CB -> CC -> { }; + CD -> { } -> { }; + { } -> { } -> { }; + { } -> CE; + { } -> CF -> CG; + }; + CH -> CI -> CJ; + CK -> { } -> CL; + CM -> CN -> { }; + CO -> { } -> { }; + { } -> { } -> { }; + { } -> CP; + { } -> CQ -> CR; + }; +} \ No newline at end of file diff --git a/packages/rehype-vizdom/test/fixtures/a.html b/packages/rehype-vizdom/test/fixtures/a.html index 3727837..d1de0ae 100644 --- a/packages/rehype-vizdom/test/fixtures/a.html +++ b/packages/rehype-vizdom/test/fixtures/a.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file