(:~ : graphviz module : based on http://www.zorba-xquery.com/html/modules/zorba/image/graphviz :) module namespace gr="apb.graphviz"; declare default function namespace 'apb.graphviz'; import module namespace proc="http://basex.org/modules/proc"; import module namespace file="http://expath.org/ns/file"; import module namespace xslt="http://basex.org/modules/xslt"; import module namespace random="http://basex.org/modules/random"; declare namespace svg= "http://www.w3.org/2000/svg"; declare namespace xlink="http://www.w3.org/1999/xlink"; declare %private variable $gr:dotpath:=if(fn:environment-variable("DOTPATH")) then fn:environment-variable("DOTPATH") else "dot"; (:~ : folder for temp files \=windows :) declare %private variable $gr:tmpdir:=if(file:dir-separator()="\") then fn:environment-variable("TEMP") || "\" else "/tmp/"; declare %private variable $gr:empty:= Empty. ; (:~ :Layout one or more graphs given in the DOT language and render them as SVG. :) declare function dot( $dot as xs:string*, $params as xs:string*) as node()*{ let $params:=("-Tsvg") for $d in $dot return if(fn:not($d)) then $gr:empty else let $r:=dot-execute($d,$params) return dot-svg($r) }; (:~ run dot command :) declare %private function dot-execute( $dot as xs:string, $params as xs:string*) as element(result){ let $fname:=$gr:tmpdir || random:uuid() let $junk:=file:write-text($fname,$dot) let $r:=proc:execute($gr:dotpath , ($params,$fname)) let $junk:=file:delete($fname) return if($r/code!="0") then fn:error(xs:QName('gr:dot1'),$r/error) else $r }; (:~ run dot command returning binary :) declare function dot-executeb( $dot as xs:string, $params as xs:string*) as xs:base64Binary{ let $fname:=$gr:tmpdir || random:uuid() let $oname:=$fname || ".o" let $junk:=file:write-text($fname,$dot) let $r:=proc:execute($gr:dotpath , ($params,"-o"|| $oname,$fname)) let $junk:=file:delete($fname) return if($r/code!="0") then fn:error(xs:QName('gr:dot1'),$r/error) else let $d:=file:read-binary($oname) (: let $junk:=file:delete($oname) :) return $d }; (:~ cleanup dot svg result :) declare %private function dot-svg( $r as element(result)) as element(svg:svg){ let $s:=fn:parse-xml($r/output) (: o/p has comment nodes :) let $ver:=$s/comment()[1]/fn:normalize-space() let $title:=$s/comment()[2]/fn:normalize-space() let $svg:=$s/* return {$svg/@* , {$ver} , $svg/*} }; (:~ : set svg to autosize 100% :) declare function autosize($svg as node()) as node(){ {$svg/@* except ($svg/@width,$svg/@height,$svg/@preserveAspectRatio), $svg/*} }; (:~ : set svg to autosize 100% :) declare function autosize-old($svg as node()) as node(){ xslt:transform($svg , fn:resolve-uri("dotml/dotpatch.xsl")) };