dia2plantuml - convert textual descriptions for various diagram tools to image URL's using the https://www.plantuml.com/ server (PlantUML manual ).
#!/usr/bin/env tclsh
package provide plantuml2dia 0.1
### file dia2plantuml.tcl
proc dia2plantuml {text {ext svg}} {
### plantuml does use a different order in encoding
set b64 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
set pml 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_
set lmapper [list]
set i 0
foreach char [split $b64 ""] {
lappend lmapper $char
lappend lmapper [string range $pml $i $i]
incr i
}
set b64 [string map $lmapper [binary encode base64 [zlib compress [encoding convertto utf-8 $text]]]]
set uri https://www.plantuml.com/plantuml/$ext/~1$b64
return $uri
}
### converting URL to diagram code back
proc plantuml2dia {uri} {
set b64 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
set pml 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_
set lmapper [list]
set i 0
foreach char [split $pml ""] {
lappend lmapper $char
lappend lmapper [string range $b64 $i $i]
incr i
}
set text [regsub {.+/} $uri ""]
set text [regsub {^~1} $text ""]
set dia [encoding convertfrom utf-8 [zlib decompress [binary decode base64 [string map $lmapper $text]]]]
}
### make it a standalone application
if {[info script] eq $argv0} {
proc usage {} {
puts "Usage: $::argv0 plantuml-url|diagram-file"
}
proc help {} {
puts "PlantUML encoder/decoder"
puts "Converts PlantUML code in files to PlantUML URLS or"
puts "converts PlantUML URL's back to diagram code."
puts "Note: Only URLS with the ~1 prefixes can be currently encoded back!"
puts "Author: Detlef Groth, University of Potsdam, Germany"
puts "License: BSD 3.0"
puts ""
usage
}
if {[llength $argv] == 0} {
usage
} elseif {[info exists argv] && "--help" in $argv} {
help
} elseif {[llength $argv] == 1} {
if {[regexp {^http} [lindex $argv 0]]} {
if {![regexp "~1" [lindex $argv 0]]} {
puts "Error: Only URL's with ~1 inside can be decoded!"
} else {
puts -nonewline [plantuml2dia [lindex $argv 0]]
}
} else {
if {![file exists [lindex $argv 0]]} {
puts "Error: File '[lindex $Eargv 0]' does not exists!"
} else {
if [catch {open [lindex $argv 0] r} infh] {
puts stderr "Cannot open [lindex $argv 0]e: $infh"
exit
} else {
set text [read $infh]
puts -nonewline [dia2plantuml $text]
}
}
}
}
}
This code was translated from Python to Tcl, for the Python code look here: https://github.com/dougn/python-plantuml/blob/master/plantuml.py - the encoding used by PlantUML is explained here: https://plantuml.com/text-encoding
% source dia2plantuml.tcl % puts [dia2plantuml "class TclExample"] https://www.plantuml.com/plantuml/svg/~1U9nBpaaiBbO8ISvnhKZCBSX91G0pUGOc % puts [plantuml2dia [dia2plantuml "class TclExample"]] TclExample
Here the image:
Here now a run as a standalone application:
### make a test file
$ echo -e "class A {}\nclass B {}\nA -> B" > class.pml
### encode it as URL (image below)
$ dia2plantuml.tcl class.pml
https://www.plantuml.com/plantuml/svg/~1U9nBpaaiBbPmLAYkvKe6Cvr0J4S5NJi59ou0Zfe8R0==
### decode it back
$ dia2plantuml.tcl https://www.plantuml.com/plantuml/svg/~1U9nBpaaiBbPmLAYkvKe6Cvr0J4S5NJi59ou0Zfe8R0==
class A {}
class B {}
A -> BPlease discuss here.