Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Last active September 16, 2025 09:53
Show Gist options
  • Save snipsnipsnip/2b896019ef9081c7a81ee3ad71e681f6 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/2b896019ef9081c7a81ee3ad71e681f6 to your computer and use it in GitHub Desktop.
I've accidentally deleted a PlantUML file but luckily SVG output had them embedded
#!/usr/bin/perl
use v5.36;
use autodie;
use HTML::TokeParser ();
use MIME::Base64 qw(encode_base64 decode_base64);
use Compress::Zlib qw(deflateInit inflateInit);
main() if $0 eq __FILE__;
sub main() {
for (glob '*.svg') {
print "$_: ";
if (extract($_)) {
say "ok";
} else {
say "skipped";
}
}
}
sub extract($filename) {
my $encoded = find_src($filename) or return 0;
my $src = decode_part($encoded) or return 0;
open my $fh, ">", "$filename.txt";
$fh->print("\@startuml \"$filename\"\n", $src, "\n\@enduml");
1;
}
sub decode_part($part) {
my $tr = $part =~ tr{-_0-9A-Za-z}{+/A-Za-z0-9}r;
my $bin = "\x78\x9c" . decode_base64($tr);
scalar inflateInit()->inflate($bin);
}
sub find_src_comment($filename) {
open my $fh, "<:utf8", $filename;
my $parser = HTML::TokeParser->new($fh);
while (my $token = $parser->get_token) {
if ($token->[0] eq 'C' && $token->[1] =~ /<!--SRC=\[([^\]]+)/) {
return $1;
}
}
warn "couldn't find the PlantUML source embedded in $filename"
}
@snipsnipsnip
Copy link
Author

snipsnipsnip commented Sep 16, 2025

After I've written this script, I've found out that PlantUML has the functionality: java -jar plantuml.jar -metadata foo.svg > foo.puml.txt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment