From 30f15aca8999c43d6911b0ff3a019c686d151b76 Mon Sep 17 00:00:00 2001 From: andy bunce Date: Mon, 17 May 2021 23:19:44 +0100 Subject: [PATCH] [add] examples --- code/diag-xqdoc.xq | 70 +++++++++++++++++ code/graphviz.xqm | 119 ++++++++++++++++++++++++++++ process.gv | 27 +++++++ xml/dotpatch.xsl | 121 +++++++++++++++++++++++++++++ lines7000.xml => xml/lines7000.xml | 0 5 files changed, 337 insertions(+) create mode 100644 code/diag-xqdoc.xq create mode 100644 code/graphviz.xqm create mode 100644 process.gv create mode 100644 xml/dotpatch.xsl rename lines7000.xml => xml/lines7000.xml (100%) diff --git a/code/diag-xqdoc.xq b/code/diag-xqdoc.xq new file mode 100644 index 0000000..4b51a81 --- /dev/null +++ b/code/diag-xqdoc.xq @@ -0,0 +1,70 @@ +(:~ +: generate dotml from xqdoc source +: apb Jan 2013 +:) +declare namespace doc="http://www.xqdoc.org/1.0"; +declare namespace dotml="http://www.martin-loetzsch.de/DOTML"; + +declare variable $ns-ignore:=("http://www.w3.org/2005/xpath-functions", + "http://www.w3.org/2010/xslt-xquery-serialization", + "http://www.w3.org/2001/XMLSchema", + "http://www.w3.org/2005/xpath-functions/math" ); +declare function local:sid($s as xs:string){ + "A" || xs:hexBinary(hash:md5($s)) +}; +declare function local:fid($uri as xs:string ,$name as xs:string,$arity as xs:string){ + let $a:=fn:trace(($uri || "*" || $name || "*" || $arity),"fid: ") + return "A" || xs:hexBinary(hash:md5($uri || $name ||$arity)) +}; + +declare function local:foo($dml){ + let $moduri:=$dml/doc:xqdoc/doc:module/doc:uri/fn:string() + return + + +{for $import in $dml//doc:import + let $ns:=$import/doc:uri/fn:string() + where some $call in $dml//doc:invoked satisfies $call/doc:uri=$import/doc:uri + + return + + {for $call in $dml//doc:invoked[doc:uri=$import/doc:uri] + return + } + +} + +{for $f in $dml//doc:function + return , +for $v in $dml//doc:variable + return +} + + +{for $call in $dml//doc:invoked + let $f:=$call/.. + where not($call/doc:name/@uri/fn:string()=$ns-ignore) + return } + +}; + +let $a:=local:foo(/) + +(: +let $req:= +data={fn:encode-for-uri(fn:serialize($a))} + +let $ws:= http:send-request($req,"http://localhost:8984/restxq/graphxq/api/dotml") +return file:write("aa.svg",$ws[2]) +:) +return $a \ No newline at end of file diff --git a/code/graphviz.xqm b/code/graphviz.xqm new file mode 100644 index 0000000..8a1cc9c --- /dev/null +++ b/code/graphviz.xqm @@ -0,0 +1,119 @@ +(:~ +: 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"; + +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")) +}; + diff --git a/process.gv b/process.gv new file mode 100644 index 0000000..cf1bc18 --- /dev/null +++ b/process.gv @@ -0,0 +1,27 @@ +digraph process { + + 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]; +} diff --git a/xml/dotpatch.xsl b/xml/dotpatch.xsl new file mode 100644 index 0000000..4a8f013 --- /dev/null +++ b/xml/dotpatch.xsl @@ -0,0 +1,121 @@ + + + + MyFilter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Produces a 3D lighting effect suitable for pies and lines + + + + + + + + + + + + + + Simple blurred shadow (ideal for headings) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lines7000.xml b/xml/lines7000.xml similarity index 100% rename from lines7000.xml rename to xml/lines7000.xml