small documentation fixes

small documentation fixes

xquery version "1.0";
(:
 : Copyright 2006-2011 The FLWOR Foundation.
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 : http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
 :)

(:~
 : This module provides a function (np:node-position) that, given a node,
 : returns positional information about the node in the form of an xs:anyURI
 : item. The module also defines functions that use such positional information
 : to determine: (1) positional relationships between two nodes (e.g. if one
 : is the ancestor of another) and (2) positional properties of a single node
 : (e.g. its level in the tree).
 :
 : Within this module, the term "node position" will be used to refer to an
 : xs:anyURI item that is returned by the np:node-position function.
 :
 : @author Federico Cavalieri, Markos Zaharioudakis
 :)
module namespace np = "http://www.zorba-xquery.com/modules/node-position";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
declare option ver:module-version "2.0";

(:~
 : Return a URI item containing positional information for a given node.
 :
 :
Within a snapshot, each has a different positional URI. However,
 : different nodes in different snapshots might have the same URI.

 :
 : @param $arg the node for which the positional information URI
 :  should be computed
 :
 : @return the opaque positional information URI of the node.
 :)
declare function np:node-position(
  $arg as node()
) as xs:anyURI external;

(:~
 : Determines whether the node position given as second argument is
 : an ancestor of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an ancestor of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential descendant node position
 : @param $n-pos2 the potential ancestor node position
 :
 : @return true if the node position $n-pos2 is an ancestor of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:ancestor-of(
  $pos1 as xs:anyURI,
  $pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a descendant of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a descendant of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential ancestor node position
 : @param $n-pos2 the potential descendant node position
 :
 : @return true if the node position $n-pos2 is a descendant of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:descendant-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument belongs
 : to the subtree rooted at the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node belongs to the subtree rooted at the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : This function differs from np:descendant-of in the way it treats attribute
 : nodes. np:descendant-of follows the XQuery/XPath specification for the
 : descendant axis, and as a result, it does not consider attributes as
 : descendants of any nodes; it will always return false if $n-pos2 was
 : obtained from an attribute node.In contrast, np:in-subtree-of will return
 : true if $n-pos2 was obtained from an attribute node that appeared in the
 : subtree of the node that $n-pos1 was obtained from.
 :
 : @param $n-pos1 the potential subtree root node position
 : @param $n-pos2 the potential node in the subtree node position
 :
 : @return true if the node position $n-pos2 belongs to the subtree rooted at
 : the node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-subtree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : the parent of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is the parent of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential child node position
 : @param $n-pos2 the potential parent node position
 :
 : @return true if the node position $n-pos2 is the parent of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:parent-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a child of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a child of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential child node position
 :
 : @return true if the node position $n-pos2 is a child of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:child-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : an attribute of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an attribute of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential attribute node position
 :
 : @return true if the node position $n-pos2 is an attribute of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:attribute-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a following-sibling of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a following-sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding-sibling node position
 : @param $n-pos2 the potential following-sibling node position
 :
 : @return true if the node position $n-pos2 is a following-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a preceding-sibling of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a preceding-sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following-sibling node position
 : @param $n-pos2 the potential preceding-sibling node position
 :
 : @return true if the node position $n-pos2 is a preceding-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions are siblings.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two node positions $n-pos1 and $n-pos2 are siblings;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : following the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is following the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node position
 :        computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : following in document order the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following in document order the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if the node position $n-pos2 is following in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : preceding the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is preceding the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : preceding in document order the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding in document order the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if the node position $n-pos2 is preceding in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Computes the level of a node position in its tree.
 :
 : Note: The root node of a tree is at level one.
 :
 : The result of the function applies to the corresponding node as well,
 : that is, within the snapshot in which the position was computed, the node
 : level is the returned one.
 : The result of the function does not imply anything about the
 : node level in other snapshots.
 :
 : @param $n-pos the node position of the node whose level should be
 : determined.
 :
 : @return the level in the tree of the node position $n-pos as xs:integer.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:level(
  $n-pos as xs:anyURI) as xs:integer external;

(:~
 : Determines whether a node position corresponds to an attribute node.
 :
 : @param $n-pos the potential attribute node position
 :
 : @return true if the node position $n-pos corresponds to an attribute;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-attribute(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a comment node.
 :
 : @param $n-pos the potential comment node position
 :
 : @return true if the node position $n-pos corresponds to an comment;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-comment(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a document node.
 :
 : @param $n-pos the potential document node position
 :
 : @return true if the node position $n-pos corresponds to a document;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-document(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to an element node.
 :
 : @param $n-pos the potential element node position
 :
 : @return true if the node position $n-pos corresponds to an element;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-element(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to an processing-instruction
 : node.
 :
 : @param $n-pos the potential processing-instruction node position
 :
 : @return true if the node position $n-pos corresponds to a processing
 : instruction; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-processing-instruction(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a text node.
 :
 : @param $n-pos the potential text node position
 :
 : @return true if the node position $n-pos corresponds to a text;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-text(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions belong to the same tree.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same tree.
 : Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same tree.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-tree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position belongs to a collection.
 :
 : @param $n-pos the node position
 :
 : @return true if the node position $n-pos
 : belongs to a collection; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-collection(
  $n-pos as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions belong to the same collection.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same collection.
 : Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same collection.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-collection-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

xquery version "1.0";
(:
 : Copyright 2006-2011 The FLWOR Foundation.
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 : http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
 :)

(:~
 : This module provides a function (np:node-position) that, given a node,
 : returns positional information about the node in the form of an xs:anyURI
 : item. The module also defines functions that use such positional information
 : to determine: (1) positional relationships between two nodes (e.g. if one
 : is the ancestor of another) and (2) positional properties of a single node
 : (e.g. its level in the tree).
 :
 : Within this module, the term "node position" will be used to refer to an
 : xs:anyURI item that is returned by the np:node-position function.
 :
 : @author Federico Cavalieri, Markos Zaharioudakis
 :)
module namespace np = "http://www.zorba-xquery.com/modules/node-position";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
declare option ver:module-version "2.0";

(:~
 : Compute a stable and opaque positional information representation
 : (with type xs:anyURI) for a given node.
 :
 :
Each node in a snapshot has a different URI. Note however that
 : different nodes in different snapshots might have the same URI.

 :
 : @param $arg the node for which the positional information URI
 :  should be computed
 :
 : @return the opaque positional information URI of the node.
 :)
declare function np:node-position(
  $arg as node()
) as xs:anyURI external;

(:~
 : Determines whether the node position given as second argument is
 : an ancestor of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an ancestor of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential descendant node position
 : @param $n-pos2 the potential ancestor node position
 :
 : @return true if the node position $n-pos2 is an ancestor of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:ancestor-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument belongs
 : to the subtree rooted at the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node belongs to the subtree rooted at the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential subtree root node position
 : @param $n-pos2 the potential node in the subtree node position
 :
 : @return true if the node position $n-pos2 belongs to the subtree rooted at
 : the node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-subtree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a descendant of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a descendant of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential ancestor node position
 : @param $n-pos2 the potential descendant node position
 :
 : @return true if the node position $n-pos2 is a descendant of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:descendant-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : the parent of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is the parent of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential child node position
 : @param $n-pos2 the potential parent node position
 :
 : @return true if the node position $n-pos2 is the parent of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:parent-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a child of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a child of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential child node position
 :
 : @return true if the node position $n-pos2 is a child of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:child-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : an attribute of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an attribute of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential attribute node position
 :
 : @return true if the node position $n-pos2 is an attribute of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:attribute-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a following-sibling of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a following-sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding-sibling node position
 : @param $n-pos2 the potential following-sibling node position
 :
 : @return true if the node position $n-pos2 is a following-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : a preceding-sibling of the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a preceding-sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following-sibling node position
 : @param $n-pos2 the potential preceding-sibling node position
 :
 : @return true if the node position $n-pos2 is a preceding-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions are siblings.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a sibling of the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two node positions $n-pos1 and $n-pos2 are siblings;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : following the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if the node position $n-pos2 is following the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : following in document order the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following in document order the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if the node position $n-pos2 is following in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : preceding the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding the first.
 : Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if the node position $n-pos2 is preceding the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether the node position given as second argument is
 : preceding in document order the node position given as first argument.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding in document order the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if the node position $n-pos2 is preceding in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Computes the level of a node position in its tree.
 :
 : Note: The first level has the number one.
 :
 : The result of the function applies to the corresponding node as well,
 : that is, within the snapshot in which the position was computed, the node
 : level is the returned one.
 : The result of the function does not imply anything about the
 : node level in other snapshots.
 :
 : @param $n-pos the node position of the node whose level should be
 : determined.
 :
 : @return the level in the tree of the node position $n-pos as xs:integer.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:level(
  $n-pos as xs:anyURI) as xs:integer external;

(:~
 : Determines whether a node position corresponds to an attribute node.
 :
 : @param $n-pos the potential attribute node position
 :
 : @return true if the node position $n-pos corresponds to an attribute;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-attribute(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a comment node.
 :
 : @param $n-pos the potential comment node position
 :
 : @return true if the node position $n-pos corresponds to an comment;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-comment(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a document node.
 :
 : @param $n-pos the potential document node position
 :
 : @return true if the node position $n-pos corresponds to a document;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-document(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to an element node.
 :
 : @param $n-pos the potential element node position
 :
 : @return true if the node position $n-pos corresponds to an element;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-element(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to an processing-instruction
 : node.
 :
 : @param $n-pos the potential processing-instruction node position
 :
 : @return true if the node position $n-pos corresponds to a processing
 : instruction; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-processing-instruction(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position corresponds to a text node.
 :
 : @param $n-pos the potential text node position
 :
 : @return true if the node position $n-pos corresponds to a text;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-text(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions belong to the same tree.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same tree.
 : Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same tree.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-tree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether a node position belongs to a collection.
 :
 : @param $n-pos the node position
 :
 : @return true if the node position $n-pos
 : belongs to a collection; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-collection(
  $n-pos as xs:anyURI) as xs:boolean external;

(:~
 : Determines whether two node positions belong to the same collection.
 :
 : If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same collection.
 : Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.
 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same collection.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-collection-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;


Intermediate check-in.

Intermediate check-in.

(:
 : Copyright 2006-2009 The FLWOR Foundation.
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 : http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
:)

(:
 : author Sorin Nasoi
 :)

module namespace z = "http://www.zorba-xquery.com/module-dependencies";

declare namespace an = "http://zorba.io/annotations";
declare namespace zm = "http://zorba.io/manifest";

import module namespace file        = "http://expath.org/ns/file";
import module namespace functx      = "http://www.functx.com";

import module namespace dot   = "http://www.zorba-xquery.com/modules/image/graphviz";
import module namespace xqd   = "http://www.zorba-xquery.com/modules/xqdoc";
import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
import module namespace dml   = "http://zorba.io/modules/store/static/collections/dml";
import module namespace ddl   = "http://zorba.io/modules/store/static/collections/ddl";
import module namespace menu  = "http://www.zorba-xquery.com/modules/xqdoc/menu";
import module namespace xqdoc-html  = "http://www.zorba-xquery.com/xqdoc-html" at "xqdoc-html.xqy";

declare namespace werr = "http://www.w3.org/2005/xqt-errors";

import schema namespace xqdoc = "http://www.xqdoc.org/1.0";

declare variable $z:nodesCollector := <modules/>;

declare variable $z:edgesCollector := <edges/>;

declare variable $z:typeModule          := 'module';
declare variable $z:typeExternalLibrary := 'library';
declare variable $z:typeSchema          := 'schema';

declare variable $z:colors      as xs:string* := ('red'       , 'green');
declare variable $z:moduleTypes as xs:string* := ('Zorba-core', 'External module');

(:~
 :  Collector for the Zorba manifest
 :)
declare %private variable $z:ZorbaManifest := <manifest/>;

declare %private variable $z:batchModules := <modules/>;

(:=========================================================================================================:)
declare variable $z:level1Weight as xs:string* :=
("JSONiq", "W3C", "FunctX", "EXPath", "DB Drivers",
 "Zorba");

declare variable $z:level1Colors as xs:string* :=
( "lime", "red", "tan", "OrangeRed", "LimeGreen",
  "lightsteelblue");

declare variable $z:collection as xs:QName := xs:QName("z:collection");
declare collection z:collection as node()*;

declare %an:nondeterministic function z:load-manifest(
  $zorbaManifestPath as xs:string) as document-node()?
{
  try
  {
    fn:parse-xml(file:read-text($zorbaManifestPath))
  }
  catch *
  {
    fn:error(fn:concat("The file <",$zorbaManifestPath,"> does not have the correct structure."))
  }
};

declare %private function z:get-is-core(
  $moduleUri) as xs:boolean
{
  if(fn:string(data($z:ZorbaManifest/module[@uri= $moduleUri]/@isCore)) = "true") then fn:true()
  else fn:false()
};

declare %an:sequential function z:create-collections($ZorbaBuildFolder as xs:string)
{
  ddl:create($z:collection);

  variable $zorbaManifestPath := concat($ZorbaBuildFolder,
                                        file:directory-separator(),
                                        "ZorbaManifest.xml");

  variable $manifestXML := z:load-manifest($zorbaManifestPath);

  insert nodes xqdoc-html:modules($manifestXML)/*
  as last into $z:batchModules;

  variable $moduleManifests := $manifestXML/zm:manifest/zm:module;
  if(count($moduleManifests) eq xs:integer(0)) then ();
  else
  {
    try
    {
      for $module in $moduleManifests
      let $moduleURI := data($module/zm:uri)
      let $moduleFetched := fetch:content($moduleURI, "MODULE")
      let $xqdoc := xqd:xqdoc-content($moduleFetched)
      return
      {
        insert node <module uri="{$moduleURI}"
                            isCore="{data($module/@isCore)}"/> as last into $z:ZorbaManifest;

        dml:apply-insert($z:collection, $xqdoc);

      }
    }
    catch *
    {
      fn:error(concat("Error processing module ",
                      $werr:code,
                      " - ",
                      $werr:description));
    }
  }

  z:fill-nodesCollector();

  z:fill_edgesCollector();
};

declare %an:sequential function z:delete-collections()
{
  dml:delete(dml:collection(xs:QName("z:collection")));
  ddl:delete(xs:QName("z:collection"));
};

declare %private function z:getModuleProject(
    $moduleUri as xs:string) as xs:string {

    for $docNode in dml:collection(xs:QName("z:collection"))
    let $lModuleUri := data($docNode/xqdoc:module/xqdoc:uri),
        $lModuleProject := $docNode/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="project"]/text(),
        $lTmp := substring-after($lModuleUri,'http://'),
        $lTmpTok := tokenize($lTmp,'/'),
        $lTmp2 := if(ends-with($lTmp,'/')) then substring($lTmp,1,string-length($lTmp)-1) else string-join(functx:value-except($lTmpTok,$lTmpTok[last()]),'/'),
        $lModuleName    := if(ends-with($lModuleUri,'/')) then $lTmpTok[last()-1] else $lTmpTok[last()],
        $structure      := if(exists($lModuleProject)) then $lModuleProject else $lTmp2
    where fn:string($lModuleUri) eq $moduleUri
    return $structure
};

(:~
 : Fill the $z:nodesCollector with all the available modules.
 :)
declare %an:sequential function z:fill-nodesCollector()
{
  for $docNode in dml:collection(xs:QName("z:collection"))
  let $lModuleUri := data($docNode/xqdoc:module/xqdoc:uri)
  let $structure := z:getModuleProject(fn:string($lModuleUri))
  return
    z:collect-node ($lModuleUri,
                    $structure,
                    fn:string(index-of(dml:collection(xs:QName("z:collection")), $docNode))
                    )
};

declare %private %an:sequential function z:collect-node (
  $moduleURI        as xs:string,
  $lModuleProject   as xs:string,
  $index            as xs:string)
{
  insert node <module uri="{$moduleURI}"
                      moduleProject="{$lModuleProject}"
                      index="{$index}" />
  as last into $z:nodesCollector;
};

declare %private function z:get_subgraphs() as xs:string*
{
    let $subgraphs as xs:string* := distinct-values(
                        for $module in $z:nodesCollector//module
                        return fn:string(data($module/@moduleProject))
                      )
    (: Order the subgraphs based on the Level1Weight :)
    return for $str in $z:level1Weight
           return
             for $tmp in $subgraphs
             where starts-with($tmp, $str)
             order by $tmp
             return $tmp
};

(:~
 : Fill $z:edgesCollector with all the edges (the links between the nodes) for both modules and eternal library dependencies.
 :)
declare %an:sequential function z:fill_edgesCollector()
{
  for $xqdoc in dml:collection(xs:QName("z:collection"))
  return
    (
    (: add imported modules :)
    if (fn:count($xqdoc/xqdoc:imports//xqdoc:import[@type = "library"]) > 0) then
      for $import in $xqdoc/xqdoc:imports//xqdoc:import[@type = "library"]
      let $tmpTo := if(contains(string($import/xqdoc:uri/text()),"#"))
                    then substring-before(string($import/xqdoc:uri/text()),"#")
                    else string($import/xqdoc:uri/text())
      let $from := $z:nodesCollector//module[@uri=data($xqdoc/xqdoc:module/xqdoc:uri)]
      let $to := $z:nodesCollector//module[@uri=$tmpTo]
      return
        z:collect-edge(data($z:nodesCollector//module[@uri = data($xqdoc/xqdoc:module/xqdoc:uri)]/@catUri),
                       fn:string(data($from/@index)),
                       data($xqdoc/xqdoc:module/xqdoc:uri),
                       fn:string(data($to/@index)),
                       $tmpTo,
                       $z:typeModule)
    else
      (),
    (: add external c++ libraries dependencies :)

    if (fn:count($xqdoc/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="library"]) > 0) then
      for $libraryDependency in $xqdoc/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="library"]
      let $from := $z:nodesCollector//module[@uri=data($xqdoc/xqdoc:module/xqdoc:uri)]
      let $to := $libraryDependency/*:a
      return
        z:collect-edge(fn:string(data($from/@moduleProject)),
                       fn:string(data($from/@index)),
                       fn:string(data($from/@uri)),
                       concat(fn:data($to),'|',data($to/@href) ),
                       "",
                       $z:typeExternalLibrary)
    else
      ())
};

declare %private %an:sequential function z:collect-edge (
  $catUri   as xs:string?,
  $nameFrom as xs:string?,
  $uriFrom  as xs:string?,
  $nameTo   as xs:string?,
  $uriTo    as xs:string?,
  $type     as xs:string?)
{
  insert node <edge catUri  ="{$catUri}"
                    nameFrom="{$nameFrom}"
                    uriFrom ="{$uriFrom}"
                    nameTo  ="{$nameTo}"
                    uriTo   ="{$uriTo}"
                    type    ="{$type}" />
  as last into $z:edgesCollector;
};

declare function z:test() as xs:string
{
(:
  string-join(
  for $edge in $z:edgesCollector//edge
  return fn:concat($edge/@catUri,"|", $edge/@nameFrom, "|",  $edge/@uriFrom, "|", $edge/@nameTo),"
")
 :)
 (:
  string-join(
  for $module in $z:nodesCollector//module
  return fn:concat($module/@uri,"|", $module/@moduleProject, "|", $module/@catUi),"
")
:)
};

(:~
 : This function returns the module type (see $z:moduleType)
 : based on the existance of the externals functions withing the module and also
 : it takes into account the imported modules.
 :)
declare function z:get_module_type($moduleUri as xs:string) as xs:integer
{
  if(z:get-is-core($moduleUri)) then xs:integer(1)
  else xs:integer(2)
};

declare %private function z:filename-from-uri($uri as xs:string) as xs:string
{
  let $tmp := substring-after($uri, "http://")
  let $tmp := replace($tmp, "/", "_")
  return concat($tmp, ".html")
};

(:~
 : Format the properties of a module dot shape (link to a file, tooltip, color of the text showing the module name).
 :)
declare function z:get_shape_properties(
  $ModuleUri as xs:string,
  $lLabel as xs:string) as xs:string
{
  let $file as xs:string := z:filename-from-uri($ModuleUri)
  let $type := z:get_module_type($ModuleUri)
  return
    fn:concat('[URL="../',$file,'" tooltip="(',$z:moduleTypes[$type],') module uri=', $ModuleUri,'" label="',$lLabel,'" fontcolor="', $z:colors[$type] ,'"]')
};

(:~
 : Get the nodes that represent modules based on a provided category URI.
 :)
declare function z:nodes_modules(
  $category as xs:string) as xs:string
{
  let $nodes :=
  string-join(
  for $module in $z:nodesCollector//module
    let $lModuleUri := data($module/@uri)
    let $tok := tokenize($lModuleUri,"/")
    let $lLabel := if(ends-with($lModuleUri,'/')) then $tok[last()-1] else $tok[last()]
    let $lName := concat(data($module/@index),z:get_shape_properties($lModuleUri, $lLabel))
    where fn:string(data($module/@moduleProject)) = $category
    order by $lModuleUri
    return
      $lName,";
    ")
  return
    if($nodes eq '') then ''
    else concat($nodes,';')

};

(:~
 : Get the nodes that represent external library dependencies.
 :)
declare function z:nodes_external_libraries() as xs:string
{
  let $nodes :=
  string-join(
  for $edge in $z:edgesCollector//edge
  let $tok := tokenize(data($edge/@nameTo),'\|')
  let $nodeLabel := replace(replace(tokenize($tok[1],' ')[1],'\+',''),'-','')
  let $link := $tok[2]
  let $node := data($edge/@nameTo)
  let $lName := concat($nodeLabel,'[URL="',$link,'" tooltip="', $tok[1],'" label="',$nodeLabel,'"]')
  where data($edge/@type) eq $z:typeExternalLibrary
  group by $nodeLabel
    return
      $lName,";
    ")
  return
    if($nodes eq '') then ''
    else concat($nodes,';')
};

(:~
 : Get all the edges (the links between the nodes) between modules.
 :)
declare function z:edges_modules() as xs:string
{
let $edges :=
  string-join(
    for $edge in $z:edgesCollector//edge
    where data($edge/@type) eq $z:typeModule
    return concat('    ',$edge/@nameFrom,'->',$edge/@nameTo,'[tooltip="FROM: ',concat($edge/@uriFrom,', TO: ',$edge/@uriTo),'"]')
,';
')
return
  if($edges eq '') then ''
  else concat($edges,';')
};

(:~
 : Get all the edges (the links between the nodes) between modules and externall c++ libraries.
 :)
declare function z:edges_libraries() as xs:string
{
let $edges :=
  string-join(
    for $edge in $z:edgesCollector//edge
    let $tok := tokenize(data($edge/@nameTo),'\|')
    let $nodeLabel := replace(replace(tokenize($tok[1],' ')[1],'\+',''),"-","")
    where data($edge/@type) eq $z:typeExternalLibrary
    return concat('    ',$edge/@nameFrom,'->',$nodeLabel,'[tooltip="FROM: ',
    concat($edge/@uriFrom,', TO: ',$nodeLabel)
    ,'" color="red"]'),
  ';
')
return
  if($edges eq '') then ''
  else concat($edges,';')
};

(:~
 : Generate the cluster for the external c++ libraries.
 :)
declare function z:create_subgraph_libraries() as xs:string
{
  concat('

    subgraph clusterExternalCPPLibs  { style=filled; color=darksalmon; node [shape=box3d, color=red];
    ',
    z:nodes_external_libraries(),'

',
    z:edges_libraries(),'
    label="External C++ Library dependencies"; }')
};

(:~
 : Generate the cluster for a specific category.
 :)
declare function z:create_subgraph(
  $category   as xs:string,
  $subGraphs  as xs:string*,
  $level1     as xs:string*) as xs:string
{
  concat('
    subgraph cluster',
      index-of($level1, $category),
      ' { style=filled; color=',$z:level1Colors[index-of($level1,$category)],'; node [style="filled", color=white];
    ',
    z:create_subgraph-rec($category,
                          for $tmp in $subGraphs
                          where (starts-with($tmp, $category) and (contains($tmp,"/")))
                          return $tmp),'
    ',
z:nodes_modules($category),'
',
'    label="',$category,'"; tooltip="',$category,'"}')
};

declare %private function z:create_subgraph-rec(
  $category   as xs:string,
  $subGraphs  as xs:string*
  ) as xs:string
{
let $lSubGraphs := distinct-values( for $tmp in $subGraphs
                                    return tokenize(substring-after($tmp, concat($category,"/")),"/")[1]
                                    )
return
string-join(
for $sg in $lSubGraphs
let $newSg := concat($category,"/",$sg)
return
concat('
    subgraph cluster',
        translate($newSg," -./",""),'{ style=filled;
    ',
        z:create_subgraph-rec($newSg,
                          for $tmp in $subGraphs
                          where starts-with($tmp, $newSg)
                          return $tmp),'
    ',
z:nodes_modules($newSg),'
',
'    label="',$sg,'"; tooltip="',$newSg,'"}'),'
')
};

(:~
 : Generate the BIG cluster.
 :)
declare function z:create_graph() as xs:string
{
let $subgraphs := z:get_subgraphs()
let $l1 := distinct-values(for $str in $subgraphs return tokenize($str,'/')[1])
return
    concat('digraph G { penwidth=1; pencolor=black; label="Zorba modules dependency graph"; tooltip="Zorba modules dependency graph"
' ,
            string-join(
              for $cat1 in $l1
              return z:create_subgraph( $cat1,
                                        for $val in $subgraphs
                                        where starts-with($val, $cat1)
                                        return $val,
                                        $l1
                                       )
              ,('
  ')), z:create_subgraph_libraries()
    ,"

",
  z:edges_modules(),"
  }"
  )
};

(:
 : Copyright 2006-2009 The FLWOR Foundation.
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 : http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
:)

(:
 : author Sorin Nasoi
 :)

module namespace z = "http://www.zorba-xquery.com/module-dependencies";

declare namespace an = "http://zorba.io/annotations";
declare namespace zm = "http://zorba.io/manifest";

import module namespace file        = "http://expath.org/ns/file";
import module namespace functx      = "http://www.functx.com";

import module namespace dot   = "http://www.zorba-xquery.com/modules/image/graphviz";
import module namespace xqd   = "http://www.zorba-xquery.com/modules/xqdoc";
import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
import module namespace dml   = "http://zorba.io/modules/store/static/collections/dml";
import module namespace ddl   = "http://zorba.io/modules/store/static/collections/ddl";
import module namespace menu  = "http://www.zorba-xquery.com/modules/xqdoc/menu";
import module namespace xqdoc-html  = "http://www.zorba-xquery.com/xqdoc-html" at "xqdoc-html.xqy";

declare namespace werr = "http://www.w3.org/2005/xqt-errors";

import schema namespace xqdoc = "http://www.xqdoc.org/1.0";

declare variable $z:nodesCollector := <modules/>;

declare variable $z:edgesCollector := <edges/>;

declare variable $z:typeModule          := 'module';
declare variable $z:typeExternalLibrary := 'library';
declare variable $z:typeSchema          := 'schema';

declare variable $z:colors      as xs:string* := ('red'       , 'green');
declare variable $z:moduleTypes as xs:string* := ('Zorba-core', 'External module');

(:~
 :  Collector for the Zorba manifest
 :)
declare %private variable $z:ZorbaManifest := <manifest/>;

declare %private variable $z:batchModules := <modules/>;

(:=========================================================================================================:)
declare variable $z:level1Weight as xs:string* :=
("JSONiq", "W3C", "FunctX", "EXPath", "DB Drivers",
 "Zorba");

declare variable $z:level1Colors as xs:string* :=
( "lime", "red", "tan", "OrangeRed", "LimeGreen",
  "lightsteelblue");

declare variable $z:collection as xs:QName := xs:QName("z:collection");
declare collection z:collection as node()*;

declare %an:nondeterministic function z:load-manifest(
  $zorbaManifestPath as xs:string) as document-node()?
{
  try
  {
    fn:parse-xml(file:read-text($zorbaManifestPath))
  }
  catch *
  {
    fn:error(fn:concat("The file <",$zorbaManifestPath,"> does not have the correct structure."))
  }
};

declare %private function z:get-is-core(
  $moduleUri) as xs:boolean
{
  if(fn:string(data($z:ZorbaManifest/module[@uri= $moduleUri]/@isCore)) = "true") then fn:true()
  else fn:false()
};

declare %an:sequential function z:create-collections($ZorbaBuildFolder as xs:string)
{
  ddl:create($z:collection);

  variable $zorbaManifestPath := concat($ZorbaBuildFolder,
                                        file:directory-separator(),
                                        "ZorbaManifest.xml");

  variable $manifestXML := z:load-manifest($zorbaManifestPath);

  insert nodes xqdoc-html:modules($manifestXML)/*
  as last into $z:batchModules;

  variable $moduleManifests := $manifestXML/zm:manifest/zm:module;
  if(count($moduleManifests) eq xs:integer(0)) then ();
  else
  {
    try
    {
      for $module in $moduleManifests
      let $moduleURI := data($module/zm:uri)
      let $moduleFetched := fetch:content($moduleURI, "MODULE")
      let $xqdoc := xqd:xqdoc-content($moduleFetched)
      return
      {
        insert node <module uri="{$moduleURI}"
                            isCore="{data($module/@isCore)}"/> as last into $z:ZorbaManifest;

        dml:apply-insert-nodes($z:collection, $xqdoc);

      }
    }
    catch *
    {
      fn:error(concat("Error processing module ",
                      $werr:code,
                      " - ",
                      $werr:description));
    }
  }

  z:fill-nodesCollector();

  z:fill_edgesCollector();
};

declare %an:sequential function z:delete-collections()
{
  dml:delete-nodes(dml:collection(xs:QName("z:collection")));
  ddl:delete(xs:QName("z:collection"));
};

declare %private function z:getModuleProject(
    $moduleUri as xs:string) as xs:string {

    for $docNode in dml:collection(xs:QName("z:collection"))
    let $lModuleUri := data($docNode/xqdoc:module/xqdoc:uri),
        $lModuleProject := $docNode/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="project"]/text(),
        $lTmp := substring-after($lModuleUri,'http://'),
        $lTmpTok := tokenize($lTmp,'/'),
        $lTmp2 := if(ends-with($lTmp,'/')) then substring($lTmp,1,string-length($lTmp)-1) else string-join(functx:value-except($lTmpTok,$lTmpTok[last()]),'/'),
        $lModuleName    := if(ends-with($lModuleUri,'/')) then $lTmpTok[last()-1] else $lTmpTok[last()],
        $structure      := if(exists($lModuleProject)) then $lModuleProject else $lTmp2
    where fn:string($lModuleUri) eq $moduleUri
    return $structure
};

(:~
 : Fill the $z:nodesCollector with all the available modules.
 :)
declare %an:sequential function z:fill-nodesCollector()
{
  for $docNode in dml:collection(xs:QName("z:collection"))
  let $lModuleUri := data($docNode/xqdoc:module/xqdoc:uri)
  let $structure := z:getModuleProject(fn:string($lModuleUri))
  return
    z:collect-node ($lModuleUri,
                    $structure,
                    fn:string(index-of(dml:collection(xs:QName("z:collection")), $docNode))
                    )
};

declare %private %an:sequential function z:collect-node (
  $moduleURI        as xs:string,
  $lModuleProject   as xs:string,
  $index            as xs:string)
{
  insert node <module uri="{$moduleURI}"
                      moduleProject="{$lModuleProject}"
                      index="{$index}" />
  as last into $z:nodesCollector;
};

declare %private function z:get_subgraphs() as xs:string*
{
    let $subgraphs as xs:string* := distinct-values(
                        for $module in $z:nodesCollector//module
                        return fn:string(data($module/@moduleProject))
                      )
    (: Order the subgraphs based on the Level1Weight :)
    return for $str in $z:level1Weight
           return
             for $tmp in $subgraphs
             where starts-with($tmp, $str)
             order by $tmp
             return $tmp
};

(:~
 : Fill $z:edgesCollector with all the edges (the links between the nodes) for both modules and eternal library dependencies.
 :)
declare %an:sequential function z:fill_edgesCollector()
{
  for $xqdoc in dml:collection(xs:QName("z:collection"))
  return
    (
    (: add imported modules :)
    if (fn:count($xqdoc/xqdoc:imports//xqdoc:import[@type = "library"]) > 0) then
      for $import in $xqdoc/xqdoc:imports//xqdoc:import[@type = "library"]
      let $tmpTo := if(contains(string($import/xqdoc:uri/text()),"#"))
                    then substring-before(string($import/xqdoc:uri/text()),"#")
                    else string($import/xqdoc:uri/text())
      let $from := $z:nodesCollector//module[@uri=data($xqdoc/xqdoc:module/xqdoc:uri)]
      let $to := $z:nodesCollector//module[@uri=$tmpTo]
      return
        z:collect-edge(data($z:nodesCollector//module[@uri = data($xqdoc/xqdoc:module/xqdoc:uri)]/@catUri),
                       fn:string(data($from/@index)),
                       data($xqdoc/xqdoc:module/xqdoc:uri),
                       fn:string(data($to/@index)),
                       $tmpTo,
                       $z:typeModule)
    else
      (),
    (: add external c++ libraries dependencies :)

    if (fn:count($xqdoc/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="library"]) > 0) then
      for $libraryDependency in $xqdoc/xqdoc:module/xqdoc:comment/xqdoc:custom[@tag="library"]
      let $from := $z:nodesCollector//module[@uri=data($xqdoc/xqdoc:module/xqdoc:uri)]
      let $to := $libraryDependency/*:a
      return
        z:collect-edge(fn:string(data($from/@moduleProject)),
                       fn:string(data($from/@index)),
                       fn:string(data($from/@uri)),
                       concat(fn:data($to),'|',data($to/@href) ),
                       "",
                       $z:typeExternalLibrary)
    else
      ())
};

declare %private %an:sequential function z:collect-edge (
  $catUri   as xs:string?,
  $nameFrom as xs:string?,
  $uriFrom  as xs:string?,
  $nameTo   as xs:string?,
  $uriTo    as xs:string?,
  $type     as xs:string?)
{
  insert node <edge catUri  ="{$catUri}"
                    nameFrom="{$nameFrom}"
                    uriFrom ="{$uriFrom}"
                    nameTo  ="{$nameTo}"
                    uriTo   ="{$uriTo}"
                    type    ="{$type}" />
  as last into $z:edgesCollector;
};

declare function z:test() as xs:string
{
(:
  string-join(
  for $edge in $z:edgesCollector//edge
  return fn:concat($edge/@catUri,"|", $edge/@nameFrom, "|",  $edge/@uriFrom, "|", $edge/@nameTo),"
")
 :)
 (:
  string-join(
  for $module in $z:nodesCollector//module
  return fn:concat($module/@uri,"|", $module/@moduleProject, "|", $module/@catUi),"
")
:)
};

(:~
 : This function returns the module type (see $z:moduleType)
 : based on the existance of the externals functions withing the module and also
 : it takes into account the imported modules.
 :)
declare function z:get_module_type($moduleUri as xs:string) as xs:integer
{
  if(z:get-is-core($moduleUri)) then xs:integer(1)
  else xs:integer(2)
};

declare %private function z:filename-from-uri($uri as xs:string) as xs:string
{
  let $tmp := substring-after($uri, "http://")
  let $tmp := replace($tmp, "/", "_")
  return concat($tmp, ".html")
};

(:~
 : Format the properties of a module dot shape (link to a file, tooltip, color of the text showing the module name).
 :)
declare function z:get_shape_properties(
  $ModuleUri as xs:string,
  $lLabel as xs:string) as xs:string
{
  let $file as xs:string := z:filename-from-uri($ModuleUri)
  let $type := z:get_module_type($ModuleUri)
  return
    fn:concat('[URL="../',$file,'" tooltip="(',$z:moduleTypes[$type],') module uri=', $ModuleUri,'" label="',$lLabel,'" fontcolor="', $z:colors[$type] ,'"]')
};

(:~
 : Get the nodes that represent modules based on a provided category URI.
 :)
declare function z:nodes_modules(
  $category as xs:string) as xs:string
{
  let $nodes :=
  string-join(
  for $module in $z:nodesCollector//module
    let $lModuleUri := data($module/@uri)
    let $tok := tokenize($lModuleUri,"/")
    let $lLabel := if(ends-with($lModuleUri,'/')) then $tok[last()-1] else $tok[last()]
    let $lName := concat(data($module/@index),z:get_shape_properties($lModuleUri, $lLabel))
    where fn:string(data($module/@moduleProject)) = $category
    order by $lModuleUri
    return
      $lName,";
    ")
  return
    if($nodes eq '') then ''
    else concat($nodes,';')

};

(:~
 : Get the nodes that represent external library dependencies.
 :)
declare function z:nodes_external_libraries() as xs:string
{
  let $nodes :=
  string-join(
  for $edge in $z:edgesCollector//edge
  let $tok := tokenize(data($edge/@nameTo),'\|')
  let $nodeLabel := replace(replace(tokenize($tok[1],' ')[1],'\+',''),'-','')
  let $link := $tok[2]
  let $node := data($edge/@nameTo)
  let $lName := concat($nodeLabel,'[URL="',$link,'" tooltip="', $tok[1],'" label="',$nodeLabel,'"]')
  where data($edge/@type) eq $z:typeExternalLibrary
  group by $nodeLabel
    return
      $lName,";
    ")
  return
    if($nodes eq '') then ''
    else concat($nodes,';')
};

(:~
 : Get all the edges (the links between the nodes) between modules.
 :)
declare function z:edges_modules() as xs:string
{
let $edges :=
  string-join(
    for $edge in $z:edgesCollector//edge
    where data($edge/@type) eq $z:typeModule
    return concat('    ',$edge/@nameFrom,'->',$edge/@nameTo,'[tooltip="FROM: ',concat($edge/@uriFrom,', TO: ',$edge/@uriTo),'"]')
,';
')
return
  if($edges eq '') then ''
  else concat($edges,';')
};

(:~
 : Get all the edges (the links between the nodes) between modules and externall c++ libraries.
 :)
declare function z:edges_libraries() as xs:string
{
let $edges :=
  string-join(
    for $edge in $z:edgesCollector//edge
    let $tok := tokenize(data($edge/@nameTo),'\|')
    let $nodeLabel := replace(replace(tokenize($tok[1],' ')[1],'\+',''),"-","")
    where data($edge/@type) eq $z:typeExternalLibrary
    return concat('    ',$edge/@nameFrom,'->',$nodeLabel,'[tooltip="FROM: ',
    concat($edge/@uriFrom,', TO: ',$nodeLabel)
    ,'" color="red"]'),
  ';
')
return
  if($edges eq '') then ''
  else concat($edges,';')
};

(:~
 : Generate the cluster for the external c++ libraries.
 :)
declare function z:create_subgraph_libraries() as xs:string
{
  concat('

    subgraph clusterExternalCPPLibs  { style=filled; color=darksalmon; node [shape=box3d, color=red];
    ',
    z:nodes_external_libraries(),'

',
    z:edges_libraries(),'
    label="External C++ Library dependencies"; }')
};

(:~
 : Generate the cluster for a specific category.
 :)
declare function z:create_subgraph(
  $category   as xs:string,
  $subGraphs  as xs:string*,
  $level1     as xs:string*) as xs:string
{
  concat('
    subgraph cluster',
      index-of($level1, $category),
      ' { style=filled; color=',$z:level1Colors[index-of($level1,$category)],'; node [style="filled", color=white];
    ',
    z:create_subgraph-rec($category,
                          for $tmp in $subGraphs
                          where (starts-with($tmp, $category) and (contains($tmp,"/")))
                          return $tmp),'
    ',
z:nodes_modules($category),'
',
'    label="',$category,'"; tooltip="',$category,'"}')
};

declare %private function z:create_subgraph-rec(
  $category   as xs:string,
  $subGraphs  as xs:string*
  ) as xs:string
{
let $lSubGraphs := distinct-values( for $tmp in $subGraphs
                                    return tokenize(substring-after($tmp, concat($category,"/")),"/")[1]
                                    )
return
string-join(
for $sg in $lSubGraphs
let $newSg := concat($category,"/",$sg)
return
concat('
    subgraph cluster',
        translate($newSg," -./",""),'{ style=filled;
    ',
        z:create_subgraph-rec($newSg,
                          for $tmp in $subGraphs
                          where starts-with($tmp, $newSg)
                          return $tmp),'
    ',
z:nodes_modules($newSg),'
',
'    label="',$sg,'"; tooltip="',$newSg,'"}'),'
')
};

(:~
 : Generate the BIG cluster.
 :)
declare function z:create_graph() as xs:string
{
let $subgraphs := z:get_subgraphs()
let $l1 := distinct-values(for $str in $subgraphs return tokenize($str,'/')[1])
return
    concat('digraph G { penwidth=1; pencolor=black; label="Zorba modules dependency graph"; tooltip="Zorba modules dependency graph"
' ,
            string-join(
              for $cat1 in $l1
              return z:create_subgraph( $cat1,
                                        for $val in $subgraphs
                                        where starts-with($val, $cat1)
                                        return $val,
                                        $l1
                                       )
              ,('
  ')), z:create_subgraph_libraries()
    ,"

",
  z:edges_modules(),"
  }"
  )
};


Put All option first. ;-)

Put All option first. ;-)

svn path=/trunk/eXist/; revision=7022

(:~
    Search the built-in function library
:)
xquery version "1.0";
(: $Id$ :)

declare namespace xqdoc="http://www.xqdoc.org/1.0";

import module namespace util="http://exist-db.org/xquery/util";
import module namespace request="http://exist-db.org/xquery/request";
import module namespace xdb="http://exist-db.org/xquery/xmldb";
import module namespace ngram="http://exist-db.org/xquery/ngram" at
    "java:org.exist.xquery.modules.ngram.NGramModule";

(:~
    Collection configuration for the function docs. We use an ngram
    index for fast substring searches.
:)
declare variable $xqdoc:config :=
    <collection xmlns="http://exist-db.org/collection-config/1.0">
        <index xmlns:xqdoc="http://www.xqdoc.org/1.0">
            <fulltext default="none" attributes="no">
            </fulltext>
            <ngram qname="xqdoc:name"/>
            <ngram qname="xqdoc:description"/>
        </index>
    </collection>;

(:~
    Before the function document can be searched, it needs to be extracted
    from the Java files. We use util:extract-docs() to generate one XQDoc
    document for each module and store it into /db/xqdocs.
:)
declare function xqdoc:setup($adminPass as xs:string) {
    if (empty(//xqdoc:module)) then
        let $setuser := xdb:login("/db", "admin", $adminPass)
        let $confCol := (
            xdb:create-collection("/db/system/config", "db"),
            xdb:create-collection("/db/system/config/db", "xqdocs")
        )
        let $confStored := xdb:store("/db/system/config/db/xqdocs", "collection.xconf", $xqdoc:config)
        let $output := (
            xdb:create-collection("/db", "xqdocs"),
            xdb:chmod-collection("/db/xqdocs", 508)
        )
        for $moduleURI in util:registered-modules()
        let $moduleDocs := util:extract-docs($moduleURI)
        let $docName := concat(util:md5($moduleURI), ".xml")
        return (
            xdb:store("/db/xqdocs", $docName, $moduleDocs, "text/xml"),
            xdb:chmod-resource("/db/xqdocs", $docName, 508)
        )
    else
        ()
};

(:~
    Execute a query or list all functions in a given module.
:)
declare function xqdoc:do-query($action as xs:string, $module as xs:string?, $type as xs:string?,
$qs as xs:string?, $print as xs:boolean) as element()* {
    if ($qs != '' or $module != '') then
        let $matches :=
            if ($action eq "Browse") then
                if( $module eq "All" ) then
                    /xqdoc:xqdoc//xqdoc:function
                else
                    /xqdoc:xqdoc[xqdoc:module/xqdoc:uri = $module]//xqdoc:function
            else if( $qs != '' ) then
                if ($type eq "name") then
                    //xqdoc:function[ngram:contains(xqdoc:name, $qs)]
                else
                    //xqdoc:function[ngram:contains(xqdoc:comment/xqdoc:description, $qs)]
            else ()

        let $hideIndicator   := if( $print ) then "" else "-"

        let $hideshowButtons := if( $print ) then ()
                                else

                                                    Modules:  Show All | Hide All

                                                    Function Descriptions: Show All | Hide All

        let $return :=
            for $modURI in distinct-values( $matches/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri )
            order by $modURI
            return

                            { $modURI }
                            {  /xqdoc:xqdoc/xqdoc:module[ xqdoc:uri = $modURI ]/xqdoc:comment/xqdoc:description/text() }
                            { $hideIndicator }

                        {
                            for $match in $matches[ ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri = $modURI ]
                            order by $match/xqdoc:name
                            return

                                        {$match/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri/text()}

{$match/xqdoc:name/text()}

{$match/xqdoc:signature/text()}

{$match/xqdoc:comment/xqdoc:description/text()}

                        }

        return ( $hideshowButtons, $return )
    else
        ()
};

(:~
    Return the main XML page, which will be transformed into HTML by Cocoon.
    If Javascript is enabled on the client, this function will only be called
    once. All subsequent calls to this script will be made via AJAX and we don't
    need to return the entire page.
:)
declare function xqdoc:get-page($action as xs:string, $module as xs:string?, $type as xs:string?,
$query as xs:string?, $askPass as xs:boolean) as element() {
    <book>
        <bookinfo>
            <graphic fileref="logo.jpg"/>

            <productname>Open Source Native XML Database</productname>
            <title>XQuery Function Documentation</title>
            <link rel="stylesheet" type="text/css" href="styles/fundocs.css"/>


Added test

Added test

xquery version "3.0";

(:~
 : Tests for the Inspect module
 :)
module namespace insp = "http://exist-db.org/test/insp";

import module namespace test = "http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";
import module namespace inspect = "http://exist-db.org/xquery/inspection";

declare
    %test:setUp
function insp:setup() {
    let $coll := xmldb:create-collection("/db", "inspect-test")
    return (
        xmldb:store($coll, "mod1.xqy", "<main>{current-dateTime()}</main>", "application/xquery"),
        xmldb:store($coll, "mod1.xqm", "module namespace x = ""http://x.com""; declare function x:y() { <library>{current-dateTime()}</library> };", "application/xquery")
    )
};

declare
    %test:tearDown
function insp:cleanup() {
    xmldb:remove("/db/inspect-test")
};

declare
    %test:assertEquals(0)
function insp:module-functions-main-module() {
    count(inspect:inspect-module(xs:anyURI("xmldb:exist:///db/inspect-test/mod1.xqy")))
};

declare
    %test:assertEquals(1)
function insp:module-functions-library-module() {
    count(inspect:inspect-module(xs:anyURI("xmldb:exist:///db/inspect-test/mod1.xqm")))
};

(: When there is an issue, the issue is printed as part of the error messages:)
declare
    %test:assertEquals("END")
function insp:check_if_prefix_is_present() {
    (
        for $namespace-uri in util:registered-modules()
        let $functions := try { util:registered-functions($namespace-uri) } catch * { <error>{$err:code} raised when getting registered functions for module {$namespace-uri}</error> }
        for $fie in $functions
        return
            if( contains($fie,":") or contains($namespace-uri, "w3.org") )
            then   () else $fie || " in " || $namespace-uri
    ,"END")
};