diff --git a/src/graphxq/dotml.xqm b/src/graphxq/dotml.xqm new file mode 100644 index 0000000..5aafff6 --- /dev/null +++ b/src/graphxq/dotml.xqm @@ -0,0 +1,18 @@ +(:~ +: dotml module +: @see http://www.martin-loetzsch.de/DOTML/ +:) + +module namespace dotml="http://www.martin-loetzsch.de/DOTML"; +declare default function namespace 'http://www.martin-loetzsch.de/DOTML'; + +import module namespace xslt="http://basex.org/modules/xslt"; + +(:~ +: @return graphviz dot string +:) +declare function generate($dotml) as xs:string +{ + xslt:transform($dotml, fn:resolve-uri( "dotml/dotml2dot.xsl")) +}; + diff --git a/src/graphxq/dotml/dotml2dot.xsl b/src/graphxq/dotml/dotml2dot.xsl index 46a261e..c5aef7c 100644 --- a/src/graphxq/dotml/dotml2dot.xsl +++ b/src/graphxq/dotml/dotml2dot.xsl @@ -1,11 +1,10 @@ + - - bgcolor fontcolor fontname fontsize label margin nodesep rankdir ranksep ratio size bgcolor color fillcolor fontcolor fontname fontsize label labeljust labelloc style color fillcolor fixedsize fontcolor fontname fontsize height shape style URL width @@ -16,12 +15,11 @@ Translates dotml documents into the native dot syntax. - digraph g {compound="true"; + digraph g {compound="true"; - } -<dot-filename></dot-filename> + } subgraph sub_graph_{rank="";} subgraph cluster_{ diff --git a/src/graphxq/graphviz.xqm b/src/graphxq/graphviz.xqm index 8332cd4..4be2913 100644 --- a/src/graphxq/graphviz.xqm +++ b/src/graphxq/graphviz.xqm @@ -38,7 +38,8 @@ declare function dot( $dot as xs:string*, $params as xs:string*) as node()*{ else $gr:empty }; -declare %private function dot1( $dot as xs:string) as node(){ +declare %private function dot1( $dot as xs:string) as element(svg:svg) +{ let $fname:=$gr:tmpdir || random:uuid() let $junk:=file:write-text($fname,$dot) let $r:=proc:execute($gr:dotpath , ("-Tsvg",$fname)) @@ -77,6 +78,7 @@ declare %private function dot1( $dot as xs:string) as node(){ }; + (:~ :Layout one ore more graphs given in the GXL language and render them as SVG. : gxl2dot Test.gxl > Test.dot diff --git a/src/graphxq/graphxq.xqm b/src/graphxq/graphxq.xqm index 58ff245..dc89638 100644 --- a/src/graphxq/graphxq.xqm +++ b/src/graphxq/graphxq.xqm @@ -1,5 +1,5 @@ (:~ -: restxq interface for graphviz +: RESTXQ interface for graphviz : @author andy bunce : @since sept 2012 :) @@ -8,13 +8,19 @@ module namespace grxq = 'apb.graphviz.web'; declare default function namespace 'apb.graphviz.web'; import module namespace gr = 'apb.graphviz' at "graphviz.xqm"; +import module namespace dotml = 'http://www.martin-loetzsch.de/DOTML' at "dotml.xqm"; import module namespace dotui = 'apb.graphxq.dotui' at "dotui.xqm"; import module namespace txq = 'apb.txq' at "lib/txq.xqm"; import module namespace request = "http://exquery.org/ns/request"; + +declare namespace svg= "http://www.w3.org/2000/svg"; declare namespace rest = 'http://exquery.org/ns/restxq'; declare variable $grxq:layout:=fn:resolve-uri("views/layout.xml"); +(:~ +: Home page for app +:) declare %rest:GET %rest:path("graphxq") %output:method("html") %output:version("5.0") @@ -23,14 +29,14 @@ declare function graphxq($dot,$url) { let $edot:=if($url) then "" else fn:encode-for-uri($dot) let $dot2:=getdot($dot,$url) - let $svg:=get-svg($dot) - let $map:=map{"dot":=$dot,"url":=$url,"svg":=$svg,"edot":=$edot} - let $page:=render("views/page1.xml",$map) - return $page + let $svg:=dot2svg($dot) + let $map:=map{"dot":=$dot,"url":=$url,"svg":=$svg,"edot":=$edot} + let $page:=render("views/page1.xml",$map) + return $page }; (:~ -: return svg for dot, with download option +: GET or POST return svg for dot, with download option :) declare %rest:path("graphxq/svg") @@ -39,18 +45,18 @@ declare %rest:form-param("dl","{$dl}") %output:media-type("image/svg+xml") function graphxq-svg($dot,$url,$dl) { - let $dot2:=getdot($dot,$url) - let $svg:=get-svg($dot2) - let $resp:= - - - {if($dl) - then - else ()} - - - - return ($resp,$svg) + let $dot2:=getdot($dot,$url) + let $svg:=dot2svg($dot2) + let $resp:= + + + {if($dl) + then + else ()} + + + + return ($resp,$svg) }; (:~ @@ -64,25 +70,34 @@ declare function dotform($src){ let $dot:= getdot("digraph {{a -> b}}",$src) let $svgwidget:=fn:doc("views/widget.svg") - let $map:=map{"list-shapes":=dotui:shapes(""), - "list-colors":=dotui:colors(""), - "svgwidget":=$svgwidget, - "dot":=$dot} - return render("views/dotform.xml",$map) + let $map:=map{"list-shapes":=dotui:shapes(""), + "list-colors":=dotui:colors(""), + "svgwidget":=$svgwidget, + "dot":=$dot} + return render("views/dotform.xml",$map) }; declare %rest:GET %rest:path("graphxq/dotml") %output:method("html") %output:version("5.0") function dotmlform(){ - render("views/dotmlform.xml",map{}) + render("views/dotmlform.xml",map{}) }; +(:~ static about page :) declare %rest:GET %rest:path("graphxq/about") %output:method("html") %output:version("5.0") function about(){ - render("views/about.xml",map{}) + render("views/about.xml",map{}) +}; + +(:~ static api page :) +declare +%rest:GET %rest:path("graphxq/api") +%output:method("html") %output:version("5.0") +function api(){ + render("views/api.xml",map{}) }; declare @@ -93,44 +108,72 @@ function search($q ) { let $map:=map{"q":=$q} return render("views/search.xml",$map) }; + declare %rest:GET %rest:path("graphxq/library") %output:method("html") %output:version("5.0") - function library( ) { let $map:=map{ } return render("views/library.xml",$map) }; +(:~ +: @return svg from dotml +:) +declare +%rest:POST %rest:path("graphxq/api/dotml") +%rest:form-param("dotml","{$dotml}") +function api-dotml($dotml ) as node() +{ + let $dotml:=fn:parse-xml($dotml) + let $x:=dotml:generate($dotml) +(: let $svg:=dot2svg($x) :) + return $x + +}; -(:~ use dot or url :) -declare %private function getdot($dot,$url) as xs:string{ +(:~ if url is defined then treat as url and fetch else use dot :) +declare %private function getdot($dot as xs:string,$url) as xs:string{ if($url) then try{fn:unparsed-text(fn:resolve-uri($url))} catch * { "digraph {{ failed to load remote }}" } else $dot }; -(:~ post process svg :) -declare %private function get-svg($dot as xs:string) as node(){ +(:~ if url is defined then treat as url and fetch else use dotml :) +declare %private function getdotml($dotml as xs:string,$url) as xs:string{ + if($url) then + try{fn:unparsed-text(fn:resolve-uri($url))} catch * { "digraph {{ failed to load remote }}" } +else + $dotml +}; + +(:~ Generate svg from dot :) +declare %private function dot2svg($dot as xs:string) as node(){ let $svgx:=gr:dot($dot,()) return gr:autosize($svgx) -}; +}; -declare function render($template,$locals){ +(:~ +: Render html page +: @param template path to page template +: @params locals map of page variables +:) +declare function render($template as xs:string,$locals){ let $sidebar:=
- viewbox work - + viewbox work +
- let $default:=map{"sidebar":=$sidebar , + let $default:=map{"sidebar":=$sidebar , "usermenu":=
users
, "title":=request:path(), - "messages":=()} - let $locals:=map:new(($default,$locals)) - return txq:render(fn:resolve-uri($template),$locals,$grxq:layout) -}; \ No newline at end of file + "messages":=()} + let $locals:=map:new(($default,$locals)) + return txq:render(fn:resolve-uri($template),$locals,$grxq:layout) +}; \ No newline at end of file diff --git a/src/graphxq/samples/dotml/sample1.xml b/src/graphxq/samples/dotml/sample1.xml index 1a0852e..d4c8a85 100644 --- a/src/graphxq/samples/dotml/sample1.xml +++ b/src/graphxq/samples/dotml/sample1.xml @@ -1,4 +1,4 @@ - + diff --git a/src/graphxq/txq.xqm b/src/graphxq/txq.xqm deleted file mode 100644 index 4c2e36d..0000000 --- a/src/graphxq/txq.xqm +++ /dev/null @@ -1,46 +0,0 @@ -(:~ -: A(nother) templating Engine for XQuery (BaseX 7.5+(or -) specific) -: -: @author andy bunce -: @since sept 2012 -:) - -module namespace txq = 'apb.txq'; -declare default function namespace 'apb.txq'; -import module namespace xquery = "http://basex.org/modules/xquery"; - - -(:~ -: template function -: @return updated doc from map -:) -declare function render($map as map(*),$layout as xs:string,$file as xs:string) -{ - let $content:=render($map,$file) - let $map:=map:new(($map,map{"body":=$content})) - return render($map,$layout) - -}; - -(:~ -: template function -: @return updated doc from map -:) -declare function render($layout as xs:string,$map as map(*)) -{ - let $map:=map:new(($map,map{"partial":=partial(?,?,?,$map,$layout)})) - return xquery:invoke($layout,$map) - -}; - -(:~ -: partial template function: evaluate part for each value in sequence -: @return updated doc from map -:) -declare function partial($part as xs:string,$name,$seq,$map,$base) -{ - for $s in $seq - let $map:=map:new(($map,map{$name:=$s})) - return render($map,fn:resolve-uri($part,$base)) -}; - diff --git a/src/graphxq/views/about.xml b/src/graphxq/views/about.xml index cc211ce..afedfa4 100644 --- a/src/graphxq/views/about.xml +++ b/src/graphxq/views/about.xml @@ -42,7 +42,7 @@
  • \ No newline at end of file diff --git a/src/graphxq/views/api.xml b/src/graphxq/views/api.xml new file mode 100644 index 0000000..7ff7274 --- /dev/null +++ b/src/graphxq/views/api.xml @@ -0,0 +1,7 @@ +
    +

    About GraphXQ API

    +

    + POST or GET

    restxq/svg?dot=..
    +

    + +
    \ No newline at end of file diff --git a/src/graphxq/views/dotmlform.xml b/src/graphxq/views/dotmlform.xml index 61a9c7e..87d4551 100644 --- a/src/graphxq/views/dotmlform.xml +++ b/src/graphxq/views/dotmlform.xml @@ -1,8 +1,17 @@ -
    +
    -
    + - +
    diff --git a/src/graphxq/views/layout.xml b/src/graphxq/views/layout.xml index 3979a29..996fa40 100644 --- a/src/graphxq/views/layout.xml +++ b/src/graphxq/views/layout.xml @@ -5,7 +5,7 @@ - + @@ -63,11 +63,22 @@ -
  • Library
  • -