m
(:~
Search the built-in function library
:)
xquery version "1.0";
(: $Id: functions.xq 8359 2008-12-03 20:31:47Z wolfgang_m $ :)
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";
import module namespace setup="http://exist-db.org/xquery/docs/setup" at "docsetup.xql";
declare option exist:serialize "media-type=text/xml";
(:~
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
<div>
<table class="f-hideshow-buttons">
<tr>
<td class="f-show-buttons">
Modules: <a id="showAllModules" href="#">Show All</a> | <a id="hideAllModules" href="#">Hide All</a>
</td>
<td class="f-hide-buttons">
Function Descriptions: <a id="showAllDescriptions" href="#">Show All</a> | <a id="hideAllDescriptions" href="#">Hide All</a>
</td>
</tr>
</table>
<br/>
</div>
let $return :=
for $modURI in distinct-values( $matches/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri )
order by $modURI
return
<div class="f-module-heading">
<br/>
<table class="f-module-heading-table">
<tr>
<td class="f-module-heading-namespace">{ $modURI }</td>
<td class="f-module-heading-description"><div>{ /xqdoc:xqdoc/xqdoc:module[ xqdoc:uri = $modURI ]/xqdoc:comment/xqdoc:description/text() }</div>
<br/>
<div>{if (/xqdoc:xqdoc/xqdoc:module[ xqdoc:uri = $modURI ]/xqdoc:comment/xqdoc:release-version/text() eq "trunk") then "Can only be used with current svn trunk from sourceforge at https://exist.svn.sourceforge.net/svnroot/exist/trunk/" else concat("Available from release: ", /xqdoc:xqdoc/xqdoc:module[ xqdoc:uri = $modURI ]/xqdoc:comment/xqdoc:release-version/text())}</div>
</td>
<td class="f-module-heading-hideshow">{ $hideIndicator }</td>
</tr>
</table>
<div class="f-module-heading-section">
<br/>
{
for $match in $matches[ ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri = $modURI ]
let $modName := $match/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:name
let $modUri := $match/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri
order by $match/xqdoc:name
return
<div class="f-function">
<div class="f-module">
{$match/ancestor::xqdoc:xqdoc/xqdoc:module/xqdoc:uri/text()}
</div>
<h3>{$match/xqdoc:name/text()}</h3>
<div class="f-signature">
<a href="../functions/{replace($modUri, '^.*/([^/]+)$', '$1')}/{$match/xqdoc:name}"
class="f-link" target="_new"
title="Open docs in new windows">
Link
</a>
{$match/xqdoc:signature/text()}
</div>
<div class="f-description">
{ xqdoc:print-description($match/xqdoc:comment) }
{ xqdoc:print-parameters($match/xqdoc:comment) }
{ xqdoc:print-return($match/xqdoc:comment) }
</div>{
if (string-length($match/xqdoc:comment/xqdoc:deprecated/text()) > 0)
then
<div class="f-deprecated"><div>Deprecated: {$match/xqdoc:comment/xqdoc:deprecated/text()}</div></div>
else ()
}</div>
}
</div>
</div>
return <div class="query-result">{ $hideshowButtons, $return }</div>
else
()
};
declare function xqdoc:print-description($comment as element(xqdoc:comment)) {
for $desc in tokenize($comment/xqdoc:description, "\n")
return
<div class="f-description-para">{$desc}</div>
};
declare function xqdoc:print-parameters($comment as element(xqdoc:comment)) {
let $params := $comment/xqdoc:param
return
if ($params[1] != '$a') then
<table class="f-params">
{
for $param in $comment/xqdoc:param
let $split := text:groups($param, "^(\$[^ ]+) (.*)$")
return
<tr>
<td>{$split[2]}</td>
<td>{$split[3]}</td>
</tr>
}
</table>
else
()
};
declare function xqdoc:print-return($comment as element(xqdoc:comment)) {
let $returning := $comment/xqdoc:return
return
if (string-length($returning/text())) then
<div class="f-return">Returns {$returning/text()}</div>
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"/>
<link rel="shortcut icon" href="../resources/exist_icon_16x16.ico"/>
<link rel="icon" href="../resources/exist_icon_16x16.png" type="image/png"/>
<script type="text/javascript" src="../scripts/yui/utilities2.7.0.js"/>
<script type="text/javascript" src="scripts/fundocs.js"/>
<source>functions.xql/source</source>
</bookinfo>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sidebar.xml"/>
<chapter>
<title>XQuery Function Documentation</title>
{
if ($askPass) then
<form id="f-pass" name="f-pass" action="functions.xql" method="POST">
<para>The function documentation needs to be generated first,
which requires administrator rights. Please enter the
password for the admin user below:</para>
<input type="password" name="pass" value=""/>
<input type="hidden" name="generate" value="true"/>
<button type="submit">Generate</button>
</form>
else (
<div id="f-search">
<form name="f-query" action="functions.xql" method="POST">
<table>
<tr>
<td>
<label for="q">Search:</label>
<input name="q" type="text" value="{$query}"/>
<label for="type">in</label>
<select name="type">
<option value="name">Function Name</option>
<option value="desc">Description</option>
</select>
</td>
<td class="f-btn">
<input id="f-btn-search" type="submit"
name="action" value="Search"/>
</td>
<td>
<input id="f-btn-print" type="submit"
name="action" value="Print"/>
</td>
</tr>
<tr>
<td>
<label for="module">Or display <b>all</b> in:</label>
<select name="module">
<option value="All">All</option>
{
for $mod in collection("/db")//xqdoc:module
let $uri := $mod/xqdoc:uri/text()
order by $uri
return
<option value="{$uri}">
{ if ($uri eq $module) then attribute selected { "true" } else () }
{ $uri }
</option>
}
</select>
</td>
<td class="f-btn">
<input id="f-btn-browse" type="submit" name="action" value="Browse"/>
</td>
<td><img id="f-loading" src="../resources/loading.gif"/></td>
</tr>
</table>
<input type="hidden" name="prev" value="{$action}"/>
</form>
<p class="f-reload"><a href="?action=reload">Reload documentation</a>
(click here if you enabled/disabled additional modules)</p>
<p class="f-info">(<b>eXist version: {util:system-property("product-version")},
build: {util:system-property("product-build")},
functions: {count(//xqdoc:function)}</b>). Modules have to be enabled
in conf.xml to appear here.
</p>
<div id="f-result">
{ if ($query or $module) then xqdoc:do-query($action, $module, $type, $query, false()) else () }
</div>
</div>
)
}
</chapter>
</book>
};
declare function xqdoc:print-page($module as xs:string?, $type as xs:string?,
$query as xs:string?) as element() {
let $prevAction := request:get-parameter("prev", "Browse")
return
<html>
<head>
<title>XQuery Function Documentation</title>
<link rel="stylesheet" type="text/css" href="styles/fundocs.css"/>
<link rel="shortcut icon" href="../resources/exist_icon_16x16.ico"/>
<link rel="icon" href="../resources/exist_icon_16x16.png" type="image/png"/>
</head>
<body class="f-print">
<h1>XQuery Function Documentation</h1>
{
if ($prevAction = "Search") then
<p>Query: "{$query}" in {$type}.</p>
else ()
}
{ xqdoc:do-query($prevAction, $module, $type, $query, true() ) }
</body>
</html>
};
declare function xqdoc:debug-parameters() {
for $param in request:get-parameter-names()
return
util:log("DEBUG", ($param , " = ", request:get-parameter($param, ())))
};
(:
The mainline of the script. First checks if the documentation has
already been extracted. If not, ask for the admin password and
call xqdoc:setup() to generate the documentation.
:)
let $action := request:get-parameter("action", "Search")
let $generate := request:get-parameter("generate", ())
let $askPass :=
if (empty(//xqdoc:module) or $generate) then
let $adminPass := request:get-parameter("pass", ())
return
if ($generate) then
let $setup-result := util:catch("java.lang.Exception",
let $result := setup:setup($adminPass) return false(),
true())
return $setup-result
else
true()
else
$action eq 'reload'
let $log := xqdoc:debug-parameters()
let $query := request:get-parameter("q", ())
let $type := request:get-parameter("type", "name")
let $mode := request:get-parameter("mode", ())
let $module := request:get-parameter("module", ())
return
if ($mode = "ajax") then
xqdoc:do-query($action, $module, $type, $query, false())
else if ($action eq "Print") then
xqdoc:print-page($module, $type, $query)
else
xqdoc:get-page($action, $module, $type, $query, $askPass)