## XQuery Syntax Support for CodeMirror

This is a demonstration of the XQuery highlighting module for CodeMirror. The formatting is CSS driven and very easy to customize to your liking. There are three sample styles sets below. You can edit or paste in any code below to give it a test run.

Light 1 Light 2 Dark
xquery version "1.0-ml"; (: this is : a "comment" :) let $let := <x attr="value">"test"</x> let $joe:=1 return element element { attribute attribute { 1 }, element test { 'a' }, attribute foo { "bar" }, fn:doc()[ foo/@bar eq $let ], //x } module namespace comoms-dls = "http://marklogic.com/comoms-dls"; import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; import module namespace comoms-util = "http://marklogic.com/comoms-util" at "/lib/comoms-util.xqy"; import module namespace comoms-user = "http://marklogic.com/comoms-user" at "/lib/comoms-user.xqy"; (:~ : Make a call to insert and Manage. This IS NOT DONE WITHIN AN EVAL becuase : haven't figured out how to pass the permissions variable through to be bound :) declare function comoms-dls:insert($uri as xs:string, $doc as node(), $note as xs:string){ let $log := xdmp:log("in comoms-dls:insert.") let $collection := "DRAFTS" let $permissions := (xdmp:permission('mkp-admin', 'update'), xdmp:permission('mkp-admin', 'read')) return dls:document-insert-and-manage($uri, fn:false(), $doc, $note, $permissions, $collection) (: let $collection := "DRAFTS" return xdmp:eval( fn:concat( comoms-dls:_import(), " declare variable $uri as xs:string external; declare variable $doc as node() external; declare variable $collection as xs:string external; declare variable $note as xs:string external; dls:document-insert-and-manage($uri, fn:true(), $doc, $note, (xdmp:permission('mkp-anon', 'read'), xdmp:permission('mkp-admin', 'update')) , $collection) " ), (xs:QName("uri"), $uri, xs:QName("doc"), $doc, xs:QName("note"), $note, xs:QName("collection"), $collection) ) :) }; declare function comoms-dls:manage($uri, $manageNote){ let $log := xdmp:log("in comoms-dls:manage with note.") return ( xdmp:eval( fn:concat( comoms-dls:_import(), " declare variable $uri as xs:string external; declare variable $manageNote as xs:string external; dls:document-manage($uri, fn:false(), $manageNote) " ), (xs:QName("uri"), $uri, xs:QName("manageNote"), $manageNote) ) ) }; declare function comoms-dls:update($uri as xs:string, $doc as node(), $note as xs:string){ xdmp:eval( fn:concat( comoms-dls:_import(), " declare variable $uri as xs:string external; declare variable $doc as node() external; declare variable $note as xs:string external; dls:document-update($uri, $doc, $note, fn:true(), (xdmp:permission('mkp-admin', 'update'), xdmp:permission('mkp-admin', 'read')) ) " ), (xs:QName("uri"), $uri, xs:QName("doc"), $doc, xs:QName("note"), $note) ) }; declare function comoms-dls:manage($uri){ let $log := xdmp:log("in comoms-dls:manage without note.") return (xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-manage('", $uri, "', fn:false())")) ) }; declare function comoms-dls:unmanageAndDelete($uris){ for $uri in $uris let $unpublish := (xdmp:eval( fn:concat(comoms-dls:_import(), "import module namespace comoms-dls = 'http://marklogic.com/comoms-dls' at '/lib/comoms-dls.xqy'; comoms-dls:unpublish('", $uri, "')"))) let $unmanage := (xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-unmanage('", $uri, "', fn:false(), fn:true())")) ) return xdmp:document-delete($uri) }; declare function comoms-dls:checkout($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-checkout('", $uri, "', fn:false())")) }; declare function comoms-dls:checkin($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-checkin('", $uri, "', fn:false())")) }; declare function comoms-dls:add($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-manage('", $uri, "', fn:false())") ) }; declare function comoms-dls:documentHistory($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-history('", $uri, "')") ) }; declare function comoms-dls:checkoutStatus($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "dls:document-checkout-status('", $uri, "')") ) }; (:~ : call fn:doc but wrapped in an eval :) declare function comoms-dls:docInEval($uri) { xdmp:eval( fn:concat(comoms-dls:_import(), "fn:doc('", $uri, "')") ) }; (: ########################################################################### :) (: PUBLISHING FUNCTIONS :) (: ########################################################################### :) (:~ : Given a sequence of version URIs, publish all of these versions of each document : If there is a version of the same document already published, unpublish it 1st : : When "publish" is referred to, we mean that it is put into the PUBLISHED collection : unpublish removes content from this collection : @param $version_uris - sequence of uris of versions of managed documents to publish :) declare function comoms-dls:publish($version_uris as item()*) { for $uri in $version_uris let $doc := fn:doc($uri) let $managed_base_uri := $doc/node()/property::dls:version/dls:document-uri/text() let $existing := comoms-dls:publishedDoc($managed_base_uri) let $unpublishExisting := if($existing) then comoms-dls:unpublishVersion((xdmp:node-uri($existing))) else () let $addPermissions := dls:document-add-permissions($uri, (xdmp:permission('mkp-anon', 'read'))) return dls:document-add-collections($uri, ("PUBLISHED")) }; declare function comoms-dls:publishLatest($uri) { (: TODO check if it's in the draft collection probably :) let $latest_version_uri := comoms-dls:latestVersionUri($uri) let $log:= xdmp:log(fn:concat("latest: ", $latest_version_uri)) let $log:= xdmp:log(fn:concat("uri: ", $uri)) return comoms-dls:publish($latest_version_uri) }; declare function comoms-dls:latestVersionUri($uri) { let $latest_version_num := ( for $version in dls:document-history($uri)/dls:version order by fn:number($version//dls:version-id/text()) descending return $version//dls:version-id/text() )[1] return dls:document-version-uri($uri, $latest_version_num) }; declare function comoms-dls:unpublish($uris as item()*) { for $uri in $uris return let $published_doc := comoms-dls:publishedDoc($uri) return if($published_doc) then let $published_version_uri := xdmp:node-uri($published_doc) return comoms-dls:unpublishVersion($published_version_uri) else () }; declare function comoms-dls:latestPublishedDocAuthor($uri) { let $author_id := doc($uri)/property::dls:version/dls:author/text() return if($author_id) then comoms-user:getUsername($author_id) else () }; (:~ : Given a sequence of version URIs, unpublish all of these versions of each document :) declare function comoms-dls:unpublishVersion($version_uris as item()*) { for $uri in $version_uris return let $removePermissions := dls:document-remove-permissions($uri, (xdmp:permission('mkp-anon', 'read'))) return dls:document-remove-collections($uri, ("PUBLISHED")) }; (:~ : Given the base URI of a managed piece of content, return the document of the node : of the version that is published :) declare function comoms-dls:publishedDoc($uri) { fn:collection("PUBLISHED")[property::dls:version/dls:document-uri = $uri] }; (:~ : Test if any version of the managed document is published :) declare function comoms-dls:isPublished($uri) { if( comoms-dls:publishedDoc($uri)) then fn:true() else fn:false() }; declare function comoms-dls:publishedState($uri) { let $doc := comoms-dls:publishedDoc($uri) let $published_uri := if($doc) then xdmp:node-uri($doc) else () let $latest := comoms-dls:latestVersionUri($uri) return if($doc) then if($latest ne $published_uri) then "stale" else "published" else "unpublished" }; declare function comoms-dls:getManagedDocUri($uri) { let $doc := fn:doc($uri) let $managed_uri := $doc/property::dls:version/dls:document-uri/text() let $managed_uri := if($managed_uri) then $managed_uri else $uri return $managed_uri }; (:~ : Given a manage content url (e.g. /content/123456.xml) return the appropriate : version of the document based on what stage collection is being viewed and : what's published : : @param $uri a manage content url (e.g. /content/123456.xml) - NOT A VERSIONED URI :) declare function comoms-dls:doc($uri) { let $doc := fn:root(comoms-dls:collection()[property::dls:version/dls:document-uri = $uri][1]) return if($doc) then $doc else let $managedDocInCollection := comoms-dls:collection-name() = xdmp:document-get-collections($uri) return if($managedDocInCollection) then fn:doc($uri) else () }; (:~ : Get the collection to be used when querying for content : THIS or comoms-dls:collection-name() SHOULD BE USED WHEN BUILDING ANY QUERY FOR MANAGED CONTENT :) declare function comoms-dls:collection() { fn:collection( comoms-dls:collection-name() ) }; (:~ : Get the collection nameto be used when querying for content : THIS or comoms-dls:collection() SHOULD BE USED WHEN BUILDING ANY QUERY FOR MANAGED CONTENT :) declare function comoms-dls:collection-name() as xs:string { let $default_collection := "PUBLISHED" return if(comoms-user:isAdmin()) then let $pub_stage_collection_cookie := comoms-util:getCookie("COMOMS_COLLECTION") return if($pub_stage_collection_cookie) then $pub_stage_collection_cookie else $default_collection else $default_collection }; (:~ : Check if the published collection is being viewed :) declare function comoms-dls:isViewingPublished() { if(comoms-dls:collection-name() = "PUBLISHED") then fn:true() else fn:false() }; (:~ : Get the best URL for the content URI. : This is either the default URI based on detail type or should also take : into account friendly urls and navigation structures to figure out the : best choice :) declare function comoms-dls:contentUrl($uri) { (: TODO: add friendly URL and nav structure logic 1st :) let $doc := fn:doc($uri) let $managedDocUri := $doc/property::dls:version/dls:document-uri let $uri := if($managedDocUri) then $managedDocUri else $uri let $type := $doc/node()/fn:name() let $content_id := fn:tokenize( fn:tokenize($uri, "/")[3], "\.")[1] return fn:concat("/", $type, "/", $content_id) }; (: : : gets list of doc versions and uri. : :) declare function comoms-dls:versionHistory($uri) { let $published_doc := comoms-dls:publishedDoc($uri) let $published_uri := if($published_doc) then xdmp:node-uri($published_doc) else () return <versions> { for $version in dls:document-history($uri)/dls:version let $version_num := $version/dls:version-id/text() let $created := $version/dls:created/text() let $author_id := $version/dls:author/text() let $author := comoms-user:getUsername($author_id) let $note := $version/dls:annotation/text() let $version_uri := xdmp:node-uri(dls:document-version($uri, $version_num)) let $published := $published_uri eq $version_uri return <version> <version-number>{$version_num}</version-number> <created>{$created}</created> <author>{$author}</author> <published>{$published}</published> <version-uri>{$version_uri}</version-uri> </version> } </versions> }; (: ########################################################################### :) (: PRIVATE FUNCTIONS :) (: ########################################################################### :) declare function comoms-dls:_import() { "xquery version '1.0-ml'; import module namespace dls = 'http://marklogic.com/xdmp/dls' at '/MarkLogic/dls.xqy'; " }; (: CODE SAMPLE BELOW BORROWED FROM PARTICK WIED :) declare function local:document-move-forest($uri as xs:string, $forest-ids as xs:unsignedLong*) { xdmp:document-insert( $uri, fn:doc($uri), xdmp:document-get-permissions($uri), xdmp:document-get-collections($uri), xdmp:document-get-quality($uri), $forest-ids ) }; let $xml := <xml att="blah" att2="blah"> sdasd<b>asdasd</b> </xml> (: -------- :) for $d in fn:doc("depts.xml")/depts/deptno let $e := fn:doc("emps.xml")/emps/emp[deptno = $d] where fn:count($e) >= 10 order by fn:avg($e/salary) descending return <big-dept> { $d, <headcount>{fn:count($e)}</headcount>, <avgsal>{fn:avg($e/salary)}</avgsal> } </big-dept> (: -------- :) declare function local:depth($e as node()) as xs:integer { (: A node with no children has depth 1 :) (: Otherwise, add 1 to max depth of children :) if (fn:empty($e/*)) then 1 else fn:max(for $c in $e/* return local:depth($c)) + 1 }; local:depth(fn:doc("partlist.xml")) (: -------- :) <html><head/><body> { for $act in doc("hamlet.xml")//ACT let $speakers := distinct-values($act//SPEAKER) return <div>{ string($act/TITLE) }</h1> <ul> { for $speaker in $speakers return <li>{ $speaker }</li> } </ul> </div> } </body></html> (: -------- :) { for $book in doc("books.xml")//book return if (contains($book/author/text(),"Herbert") or contains($book/author/text(),"Asimov")) then $book else $book/text() let $let := <x>"test"</x> return element element { attribute attribute { 1 }, element test { 'a' }, attribute foo { "bar" }, fn:doc()[ foo/@bar eq $let ], //x } } (: -------- :) <bib> { for $b in doc("http://bstore1.example.com/bib.xml")/bib/book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 return <book year="{ $b/@year }"> { $b/title } </book> } </bib> (: -------- :)
Developed by Mike Brevoort (@mbrevoort)
Apache License, Version 2.0