Skip to content

Instantly share code, notes, and snippets.

@kodaka
Last active July 25, 2019 07:37
Show Gist options
  • Save kodaka/6110032 to your computer and use it in GitHub Desktop.
Save kodaka/6110032 to your computer and use it in GitHub Desktop.
Plackup Graphviz!
use Plack::Builder;
use Plack::Request;
use File::Slurp;
use File::Temp;
use MIME::Base64;
my $app = sub {
my $req = Plack::Request->new(shift);
my $res = $req->new_response(200);
$res->content_type('text/plain');
if ($req->param('img')) {
my $tmp = File::Temp->new;
write_file("$tmp", { binmode => ':raw' }, sprintf('digraph{%s}', $req->param('digraph')));
my $png_or_errstr = `dot -Tpng "$tmp" 2>&1`;
$res->body($png_or_errstr);
if ($png_or_errstr !~ /^.PNG/) {
$res->status(500);
}
elsif ($req->param('base64')) {
$res->body('data:image/png;base64,'.encode_base64($res->body, q{}));
}
else {
$res->content_type('image/png');
}
}
else {
$res->content_type('text/html');
$res->body(_html());
}
$res->finalize;
};
sub _html {
return << '__HTML__';
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Graphviz on the fly</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.2.1/pure-min.css">
<style>
#main { padding:2em 3em; }
#result { width:100%; height:auto; }
#digraph { background:transparent; font-size:140%; }
#errstr { color:red; }
#graph { display:none; max-width:100%; height:auto; }
.pure-button-strong { font-weight:bold; }
</style>
</head>
<body>
<div id="main">
<form method="post" class="pure-form pure-form-stacked">
<fieldset>
<input type="hidden" name="img" value="1">
<textarea id="digraph" name="digraph" class="pure-input-1-2" rows="10" placeholder="A -> B;" autofocus></textarea>
<button type="submit" class="pure-button pure-button-primary pure-button-strong">Draw</button>
</fieldset>
</form>
<p id="errstr"></p>
</div>
<div id="result">
<img id="graph" src="">
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>
$(function(){
var $digraph = $("#digraph");
var $errstr = $("#errstr");
var $graph = $("#graph");
$("button[type=submit]").on("click", function(){
$.post("/", { "img":1, "base64":1, "digraph":$digraph.val() })
.done(function(data){
$errstr.empty();
$graph.attr("src", data).show();
})
.fail(function(xhr){
$errstr.text(xhr.responseText);
})
.always(function(){
$digraph.focus();
})
;
return false;
});
$digraph.keyup(function(e){
if (e.keyCode == 27) { // ESC
$digraph.val("");
}
});
});
</script>
</body>
</html>
__HTML__
}
builder {
$app;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment