changeset 7:5589d865af7a

Erstellung XQL/XSL Applikation
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Tue, 08 Feb 2011 15:16:46 +0100
parents 2396a569e446
children d2a1c14fde31
files software/eXist/webapp/mpdl/_stuff/futureDev/archimedes-xml-fragment-Highlight-WordAtBeginningOfText.xsl software/eXist/webapp/mpdl/_stuff/futureDev/fulltext-query-result-detail.xql software/eXist/webapp/mpdl/_stuff/futureDev/fulltext-query-result-in-one-doc.xql software/eXist/webapp/mpdl/_stuff/futureDev/highlight-matches-test.xql software/eXist/webapp/mpdl/_stuff/futureDev/html2fop.xsl software/eXist/webapp/mpdl/_stuff/futureDev/rest-doc-operation.xql software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-image-fragment.xsl software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-text-fragment.xsl software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-xml-fragment.xsl software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/book-pointer.gif software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/image.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/imageU.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/left.gif software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/right.gif software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/text.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/textU.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/xml.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/xmlU.jpg software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/lucene/search.xql software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/monte-page1.xml software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/monte-page1.xpr software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page-query-result.xquery software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page-query-result.xquery.old.xquery software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page.xsl software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/text/all.xql software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/util/functx.xql software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/util/time.xql software/eXist/webapp/mpdl/_stuff/oxygen-projects/xql/xql.xpr software/eXist/webapp/mpdl/_stuff/testDev/archimedes-figures.xql software/eXist/webapp/mpdl/_stuff/testDev/controller.xql software/eXist/webapp/mpdl/_stuff/testDev/doc.xql software/eXist/webapp/mpdl/_stuff/testDev/dummy.xql software/eXist/webapp/mpdl/_stuff/testDev/echo-figures.xql software/eXist/webapp/mpdl/_stuff/testDev/echo-post.xql software/eXist/webapp/mpdl/_stuff/testDev/echo.xql software/eXist/webapp/mpdl/_stuff/testDev/get-fragment.xql software/eXist/webapp/mpdl/_stuff/testDev/kwic.xql software/eXist/webapp/mpdl/_stuff/testDev/test-trigger.xql software/eXist/webapp/mpdl/_stuff/testDev/test2.xql software/eXist/webapp/mpdl/_stuff/testDev/test3.xql software/eXist/webapp/mpdl/_stuff/testDev/testXslFO.xql software/eXist/webapp/mpdl/attribute-query-result.xql software/eXist/webapp/mpdl/doc/admin.xql software/eXist/webapp/mpdl/doc/doc-operation-exist.xql software/eXist/webapp/mpdl/doc/doc-operation-result-exist.xql software/eXist/webapp/mpdl/doc/doc-operation-result.xql software/eXist/webapp/mpdl/doc/doc-operation.xql software/eXist/webapp/mpdl/doc/get-escidoc-containerid.xql software/eXist/webapp/mpdl/doc/index.html software/eXist/webapp/mpdl/doc/login-exist.xql software/eXist/webapp/mpdl/doc/login.xql software/eXist/webapp/mpdl/escidoc/controller.xql software/eXist/webapp/mpdl/images/2downarrow.png software/eXist/webapp/mpdl/images/2leftarrow.png software/eXist/webapp/mpdl/images/2rightarrow.png software/eXist/webapp/mpdl/images/2uparrow.png software/eXist/webapp/mpdl/images/book-pointer.gif software/eXist/webapp/mpdl/images/book.png software/eXist/webapp/mpdl/images/camera.png software/eXist/webapp/mpdl/images/copyleft.png software/eXist/webapp/mpdl/images/dictionary.gif software/eXist/webapp/mpdl/images/dictionaryMorph.gif software/eXist/webapp/mpdl/images/dot.gif software/eXist/webapp/mpdl/images/download.png software/eXist/webapp/mpdl/images/echo.gif software/eXist/webapp/mpdl/images/figures.png software/eXist/webapp/mpdl/images/help.png software/eXist/webapp/mpdl/images/image.jpg software/eXist/webapp/mpdl/images/imageU.jpg software/eXist/webapp/mpdl/images/info.png software/eXist/webapp/mpdl/images/left.gif software/eXist/webapp/mpdl/images/malcolm.jpg software/eXist/webapp/mpdl/images/malcolm.tif software/eXist/webapp/mpdl/images/pirate-joey.gif software/eXist/webapp/mpdl/images/right.gif software/eXist/webapp/mpdl/images/search.gif software/eXist/webapp/mpdl/images/searchMorph.gif software/eXist/webapp/mpdl/images/searchStructural.gif software/eXist/webapp/mpdl/images/searchXPath.gif software/eXist/webapp/mpdl/images/text.jpg software/eXist/webapp/mpdl/images/textPollux.jpg software/eXist/webapp/mpdl/images/textPolluxU.jpg software/eXist/webapp/mpdl/images/textU.jpg software/eXist/webapp/mpdl/images/toc.gif software/eXist/webapp/mpdl/images/xml.jpg software/eXist/webapp/mpdl/images/xmlU.jpg software/eXist/webapp/mpdl/index.html software/eXist/webapp/mpdl/info.xql software/eXist/webapp/mpdl/interface/doc-query.xql software/eXist/webapp/mpdl/interface/echo/controller.xql software/eXist/webapp/mpdl/interface/echo/echoDocuView.xql software/eXist/webapp/mpdl/interface/external/object.xql software/eXist/webapp/mpdl/interface/lt/lemma.xql software/eXist/webapp/mpdl/interface/lt/lex.xql software/eXist/webapp/mpdl/interface/lt/wordInfo.xql software/eXist/webapp/mpdl/interface/page-fragment.xql software/eXist/webapp/mpdl/interface/queryResult.xql software/eXist/webapp/mpdl/interface/xpath.xql software/eXist/webapp/mpdl/interface/xquery.xql software/eXist/webapp/mpdl/lt/encoder.xql software/eXist/webapp/mpdl/lt/lemma.xql software/eXist/webapp/mpdl/lt/lex.xql software/eXist/webapp/mpdl/lucene/search.xql software/eXist/webapp/mpdl/page-query-result.xql software/eXist/webapp/mpdl/pq.xql software/eXist/webapp/mpdl/presentation/functions-functx.xsl software/eXist/webapp/mpdl/presentation/functions-mpdl.xsl software/eXist/webapp/mpdl/presentation/functions-text.xsl software/eXist/webapp/mpdl/presentation/functions-util.xsl software/eXist/webapp/mpdl/presentation/pageFragmentHtml.xsl software/eXist/webapp/mpdl/presentation/pageHtml.css software/eXist/webapp/mpdl/presentation/pageHtml.xsl software/eXist/webapp/mpdl/presentation/pageXml.xsl software/eXist/webapp/mpdl/presentation/queryHtml.xsl software/eXist/webapp/mpdl/query.xql software/eXist/webapp/mpdl/scheduler/get-jobs.xql software/eXist/webapp/mpdl/sitemap.xml software/eXist/webapp/mpdl/text/all.xql software/eXist/webapp/mpdl/util/functx.xql software/eXist/webapp/mpdl/util/time.xql
diffstat 120 files changed, 12755 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/archimedes-xml-fragment-Highlight-WordAtBeginningOfText.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,265 @@
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<!-- Compare two strings ignoring case, returning same values as compare(). -->
+<xsl:function name="foo:compareCI">
+  <xsl:param name="string1"/>
+  <xsl:param name="string2"/>
+  <xsl:value-of select="compare(upper-case($string1),upper-case($string2))"/>
+</xsl:function>
+  
+
+<xsl:output method="html"/>
+
+<xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+<xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($ftQueryName) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <xsl:otherwise><xsl:value-of select="'word'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryValue">
+  <xsl:choose>
+  <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:variable name="ft-query-name" select="/result/ft-query/name"/>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <form action="" method="get"></form>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number(number)"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
+      <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
+      <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
+      <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
+      <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
+      <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="70%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          [<a href="?{$textLink}">Text</a>] 
+          [<a href="?{$imageLink}">Image</a>]
+          [XML] 
+        </td>
+        <td align="right" nowrap="true">
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &gt; 1">
+                <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+          </td>
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &lt; $countPages">
+                <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <input type="hidden" name="document" value="{$documentName}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/> 
+            <input type="hidden" name="mode" value="xml"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>   
+      <table align="middle" width="100%">
+        <colgroup>
+          <col width="70%"/>
+          <col width="30%"/>
+        </colgroup>
+        <tr>
+          <td align="left" valign="top">
+            <xsl:for-each select="content">
+              <xsl:apply-templates/>
+            </xsl:for-each>
+          </td>
+          <xsl:if test="$ftQueryValue!=''">
+          <td align="left" valign="top">
+            <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
+            <ol>
+              <xsl:for-each select="/result/ft-query/result/hits/hit">
+              <li>
+                <xsl:variable name="hitPN" select="pn"/>
+                <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeXmlValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>
+              </li>
+              </xsl:for-each>
+            </ol>
+          </td>
+          </xsl:if>
+        </tr>
+      </table>
+      <hr/>
+      Elapsed time:  <xsl:value-of select="/result/document-description/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/xsl/archimedes-xml-fragment.xsl?_source=yes">XSL source</a> of this page
+      <br/>
+      [<a href="page-query-result.xql?{$xmlLink}">fast mechanism (file system search)</a>] [<a href="page-query-result-old.xql?{$xmlLink}">slower mechanism (XQL search)</a>]
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|text()|comment()|processing-instruction()">
+  <xsl:variable name="elementName" select="name()"/>
+  <span style="color: brown;">&lt;<xsl:value-of select="$elementName"/><xsl:apply-templates select="attribute()"/>&gt;</span>
+    <xsl:apply-templates select="element()|text()|comment()|processing-instruction()"/>
+  <span style="color: brown;">&lt;/<xsl:value-of select="$elementName"/>&gt;</span>
+  <br/>
+</xsl:template>
+
+<xsl:template match="attribute()">
+  <xsl:variable name="attributeName" select="name()"/>
+  <xsl:text> </xsl:text><xsl:value-of select="$attributeName"/>=<xsl:value-of select="."/>
+    <xsl:apply-templates select="attribute()"/>
+</xsl:template>
+
+<!-- Highlight all term occurrences for the fulltext query. It recognizes all text nodes and then does the highlighting -->
+<xsl:template match="text()">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <xsl:variable name="queryExpr" select="$ftQueryName"/>
+    <xsl:call-template name="highlightQueryTerms">
+    <xsl:with-param name="elemTextContent" select="."/>
+    <xsl:with-param name="queryExprStr" select="$queryExpr"/>
+    <xsl:with-param name="mode" select="$ftQueryMode"/>
+    </xsl:call-template>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Highlight term occurrences in one text node. It recognizes the first occorrence in a text node and then does 
+this template recursive with the first substring before the first term cut off -->
+<xsl:template name="highlightQueryTerms">
+  <xsl:param name="elemTextContent"/>
+  <xsl:param name="queryExprStr"/>
+  <xsl:param name="mode"/>
+  <!-- Translation from Lucene fulltext query to text query  -->  
+  <xsl:variable name="textQuery">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="substring-before(substring-after($queryExprStr, '&quot;'), '&quot;')"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="$queryExprStr"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Word delimiter -->
+  <xsl:variable name="wordDelimRegExpr" select="'[\s,:\.$ ]+'"/>  
+  <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
+  <xsl:variable name="queryRegExprSubstringBefore">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="concat('^.*?', $textQuery)"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="concat('^', $textQuery, '(', $wordDelimRegExpr, ')', '|', '^.*?', $wordDelimRegExpr, $textQuery, '(',  $wordDelimRegExpr, ')')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Recognizes the substring after the query term -->
+  <xsl:variable name="queryRegExprSubstringAfter">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="concat($textQuery, '.*')"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="concat('^', $textQuery, $wordDelimRegExpr, '.*', '|', '(', $wordDelimRegExpr, ')', $textQuery, $wordDelimRegExpr, '.*')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Deletes the substring up to the query term -->
+  <xsl:variable name="substringBefore" select="replace($elemTextContent, $queryRegExprSubstringAfter, '$1', 'i')"/>
+  <!-- Deletes the substring after the query term -->
+  <xsl:variable name="substringAfter" select="replace($elemTextContent, $queryRegExprSubstringBefore, '$1$2', 'i')"/>
+  <xsl:choose>
+    <xsl:when test="matches($elemTextContent, $queryRegExprSubstringBefore, 'i')">
+      <!-- Prints the original part of the substring up to the first occurrence of the query term -->
+      <xsl:value-of select="$substringBefore"/>
+      <!-- Highlight the query term -->
+      <xsl:variable name="matchQueryTermRegExpr">
+        <xsl:choose>
+        <xsl:when test="$mode = 'phrase'">
+          <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+        </xsl:when>
+        <xsl:when test="$mode = 'word'">
+          <xsl:value-of select="concat('^', $textQuery, $wordDelimRegExpr, '|', '.*?', $wordDelimRegExpr, '(', $textQuery, ')', $wordDelimRegExpr, '.*')"/>
+        </xsl:when>
+        <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="matchQueryTerm" select="replace($elemTextContent, $matchQueryTermRegExpr, '$1', 'i')"/>
+      <span style="background-color: yellow;">
+        <xsl:value-of select="$matchQueryTerm"/>
+      </span>
+      <!-- Recursive call of this template with the substring after the first occurrence of the term: further occurrences of the query 
+      term  -->
+      <xsl:call-template name="highlightQueryTerms">
+        <xsl:with-param name="elemTextContent" select="$substringAfter"/>
+        <xsl:with-param name="queryExprStr" select="$queryExprStr"/>
+        <xsl:with-param name="mode" select="$mode"/>
+      </xsl:call-template>
+    </xsl:when>
+    <!-- if no occurrence of the query term could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:value-of select="$elemTextContent"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/fulltext-query-result-detail.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,234 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace string-util = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/string-util"; 
+declare namespace time-util = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/time-util"; 
+
+declare function time-util:duration-as-ms($t) {
+  round((minutes-from-duration($t) * 60 + seconds-from-duration($t)) * 1000 )
+};
+
+declare function string-util:getWords($strInput as xs:string?) as xs:string* {
+  let $wordDelim := "[,;.\s]+" 
+  (: let $words := fn:tokenize($strInput, $wordDelim, "i")  :)
+  let $words := mpdltext:getWords($strInput, $wordDelim, "i")
+  let $distinctWords := fn:distinct-values($words)
+  return $distinctWords
+};
+
+declare function string-util:putCommaBetween($elems as element()*) as element()* {
+  let $count := count($elems)
+  for $elem at $pos in $elems
+  let $ret := if ($pos < $count and not(empty($elem/text()))) then
+                <w>{$elem}, </w>
+              else
+                $elem
+  return $ret
+};
+
+declare function string-util:getSortedLinkedWords($words as xs:string*, $language as xs:string) as element()* {
+  let $count := count($words)
+  let $dictURLPart1 := "http://archimedes.mpiwg-berlin.mpg.de/cgi-bin/toc/dict?step=table;word="
+  for $word in $words
+  let $lowerCaseWord := fn:lower-case($word)
+  let $wordLength := string-length($lowerCaseWord)
+  let $linkedWord := <a href="{$dictURLPart1}{$lowerCaseWord};lang={$language};pro=echo">{$lowerCaseWord}</a>
+  let $ret := if ($wordLength > 0) then
+                $linkedWord
+              else
+                <a></a>
+  order by $lowerCaseWord
+  return $ret
+};
+
+declare function string-util:toSortedLinkedWords($strInput as xs:string?, $language as xs:string?) as element()* {
+  let $words := string-util:getWords($strInput)
+  let $wordsWithLinks := string-util:getSortedLinkedWords($words, $language)
+  let $commaSep := string-util:putCommaBetween($wordsWithLinks)
+  return $commaSep
+};
+
+declare function string-util:getDummyDocument() as node() {
+  let $bla := 
+    document {
+      element product {
+        attribute dept { "ACC" },
+        element number { 563 },
+        element name { attribute language {"en"}, "Floppy Sun Hat"}
+      },
+      element product {
+        attribute dept { "BCC" },
+        element number { 564 },
+        element name { attribute language {"en"}, "Floppy SBun Iat"}
+      }
+    }
+  return $bla
+};
+
+let $currentTimeBegin := util:system-time()
+let $lang := request:get-parameter("lang", "0")
+let $language := request:get-parameter("language", "fr")
+let $document := request:get-parameter("document", "")
+
+let $tempArchimedesDocPath :=
+  if ($lang = "0")
+  then "/db/archimedes"
+  else concat("/db/arch/", $language)
+
+let $archimedesDocPath := 
+  if ($document = "")
+  then $tempArchimedesDocPath
+  else concat($tempArchimedesDocPath, "/", $document, ".xml")
+
+let $archCollection := 
+  if ($document = "")
+  then collection($archimedesDocPath)
+  else doc($archimedesDocPath)
+
+let $lucene-query := 
+  if ($lang = "0")
+  then request:get-parameter("ft-query", "Illuſtriſsimi")
+  else request:get-parameter("ft-lang-query", "Illuſtriſsimi")
+
+let $tempResultElems :=
+  for $s at $pos in $archCollection//s[ft:query(., $lucene-query)]
+    let $documentName := util:document-name($s)
+    let $collectionName := util:collection-name($s)
+    let $fullDocName := concat($collectionName, "/", $documentName)
+    let $docRoot := doc($fullDocName)
+    let $sArchInfo := $s/root()/archimedes/info
    let $author := string($sArchInfo/author/text())
+    let $language := string($sArchInfo/lang/text())
+    let $dictLinks := string-util:toSortedLinkedWords($s, $language)
+    let $pnOfS := count($docRoot//pb[. << $s])    (: faster: comparision only in pb elements of this document :)
+    (: let $pnOfS := count($s/preceding::pb[util:document-name(root()) = $documentName])  too slow: comparision in pb elements of all found documents  :)
+    let $posOfS := count($docRoot//pb[$pnOfS]/following::s[. << $s]) + 1    (: faster: comparision only in s elements of this document :)
+    let $resultElem := 
+      <elem>
+        <pos>{$pos}</pos>
+        <full-doc>{$fullDocName}</full-doc>
+        <pn>{$pnOfS}</pn>
+        <pos-of-s>{$posOfS}</pos-of-s>
+        {$s}
+        <links>{$dictLinks}</links>
+      </elem>
+  order by $author, $pos
+  return $resultElem
+
+(: group by operator: group documents with their hits    :) 
+let $resultElems :=
+  for $full-doc at $docPos in distinct-values($tempResultElems/full-doc)
+    let $docName := substring-before(util:document-name($full-doc), ".")
+    let $docPath := doc($full-doc)
+    let $sArchInfo := $docPath/archimedes/info
    let $author := string($sArchInfo/author/text())
+    let $authorLit := concat($author, ". ") 
+    let $title := string($sArchInfo/title/text())
+    let $titleLit := if ($title = "") then "" else concat($title, ". ") 
+    let $place := string($sArchInfo/place/text())
+    let $date := string($sArchInfo/date/text())
+    let $placeDateLit := if ($place = "" and $date = "") then "" else if ($place != "" and $date = "") then concat($place, ". ") else if ($place = "" and $date != "") then concat($date, ". ") else concat($place, ", ", $date, ". ")  
+    let $docShortDesc := ($authorLit, $titleLit, $placeDateLit, " [", <a href="/exist/rest{$full-doc}">XML content</a>, "]")
+    let $sInDocElem := $tempResultElems[full-doc = $full-doc]
+    let $docElem := 
+      for $e at $pos in $sInDocElem
+        let $pnOfS := $e/pn
+        let $posOfS := $e/pos-of-s
+      order by $pos
+        return 
+          <hit>
+            <pos>{$pos}</pos>
+            <pn>{$pnOfS}</pn>
+            <pos-of-s>{$posOfS}</pos-of-s>
+            {$e/s}
+            {$e/links}
+          </hit>
+  return
+    <doc>
+      <pos>{$docPos}</pos>
+      <name>{$docName}</name>
+      <desc>{$docShortDesc}</desc>
+      <hits>
+        {$docElem}
+      </hits>
+    </doc>
+
+let $countElems := count($tempResultElems)
+let $countPages := $countElems idiv 10 + 1 
+
+let $pn := fn:number(request:get-parameter("pn", "1"))
+let $positionFrom := xs:integer((($pn - 1) * 10) + 1)
+let $positionTo := 
+  if ($pn = $countPages)
+  then $countElems
+  else $pn * 10
+
+let $pagesURLs :=
+  if ($lang = "0")
+  then concat("?ft-query=", $lucene-query)
+  else concat("?ft-lang-query=", $lucene-query, "&amp;lang=1&amp;language=", $language)
+
+let $countPagesURLs :=
+  for $i in (1 to $countPages)
+  let $pageURL := 
+    if ($i = $pn) 
+    then ($i, " ")
+    else (<a href="{$pagesURLs}&amp;pn={$i}">{$i}</a>, " ")
+  return $pageURL
+
+(: let $pageHits := subsequence($resultElems/hits/hit, $positionFrom, $positionTo)     does not work correctly !!!    :)
+let $pageHits := $resultElems/hits/hit     (: fetch all hit elements   :)
+let $pageResult := 
+  for $hit at $pos in $pageHits
+    let $hitFatherDoc := $hit/../..
+    let $countHitsFatherDoc := count($hit/../hit)
+    let $hitPos := xs:integer($hit/pos)
+    let $pnOfS := xs:integer($hit/pn)
+    let $posOfS := xs:integer($hit/pos-of-s)
+    let $docName := $hitFatherDoc/name
+    let $linkPageQuery := (<a href="page-query-result.xql?document={$docName}&amp;pn={$pnOfS}&amp;mode=xml">Page {$pnOfS}</a>)
+    let $hitFatherPos := xs:integer($hitFatherDoc/pos)
+    let $hitInnerLI :=
+        <li value="{$hitPos}">
+          {$linkPageQuery}, Sentence: {$posOfS}<br></br>
+          <b>Sentence: </b>{data($hit/s)}<br></br>
+          <b>Dictionary links: </b>{$hit/links}<br></br>
+        </li>
+    let $hitLI := 
+      if ($countHitsFatherDoc = 1)   (: if only one hit for the document exist then an ul element is used else an ol element    :)
+      then
+        <ul>
+          {$hitInnerLI}
+        </ul>
+      else   
+        <ol>
+          {$hitInnerLI}
+        </ol>
+    let $hitLiFatherLI :=
+      if ($hitPos = 1)
+      then
+        <li value="{$hitFatherPos}">{$hitFatherDoc/desc}
+          {$hitLI}
+        </li>
+      else
        $hitLI
+  where $pos >= $positionFrom and $pos <= $positionTo
+  return $hitLiFatherLI 
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := time-util:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+
+return
+<html>
+ <head>
+  <title>Result for your query: "{$lucene-query}"</title>
+ </head>
+<body>
+<h2>Result of query: "{$lucene-query}"</h2>
+{$positionFrom}-{$positionTo} of {$countElems} results. Page: {$countPagesURLs}
+<ol>
+{$pageResult}
+</ol>
+<hr></hr>
+<p></p>
+Elapsed time: {$neededTime} ms, Back to <a href="query.xql">query page</a>, see the <a href="fulltext-query-result.xql?_source=yes">XQuery source</a> of this page
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/fulltext-query-result-in-one-doc.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,168 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace string-util = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/string-util"; 
+declare namespace time-util = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/time-util"; 
+
+declare function time-util:duration-as-ms($t) {
+  round((minutes-from-duration($t) * 60 + seconds-from-duration($t)) * 1000 )
+};
+
+declare function string-util:getWords($strInput as xs:string?) as xs:string* {
+  let $wordDelim := "[,;.\s]+" 
+  (: let $words := fn:tokenize($strInput, $wordDelim, "i")  :)
+  let $words := mpdltext:getWords($strInput, $wordDelim, "i")
+  let $distinctWords := fn:distinct-values($words)
+  return $distinctWords
+};
+
+declare function string-util:putCommaBetween($elems as element()*) as element()* {
+  let $count := count($elems)
+  for $elem at $pos in $elems
+  let $ret := if ($pos < $count and not(empty($elem/text()))) then
+                <w>{$elem}, </w>
+              else
+                $elem
+  return $ret
+};
+
+declare function string-util:getSortedLinkedWords($words as xs:string*, $language as xs:string) as element()* {
+  let $count := count($words)
+  let $dictURLPart1 := "http://archimedes.mpiwg-berlin.mpg.de/cgi-bin/toc/dict?step=table;word="
+  for $word in $words
+  let $lowerCaseWord := fn:lower-case($word)
+  let $wordLength := string-length($lowerCaseWord)
+  let $linkedWord := <a href="{$dictURLPart1}{$lowerCaseWord};lang={$language};pro=echo">{$lowerCaseWord}</a>
+  let $ret := if ($wordLength > 0) then
+                $linkedWord
+              else
+                <a></a>
+  order by $lowerCaseWord
+  return $ret
+};
+
+declare function string-util:toSortedLinkedWords($strInput as xs:string?, $language as xs:string?) as element()* {
+  let $words := string-util:getWords($strInput)
+  let $wordsWithLinks := string-util:getSortedLinkedWords($words, $language)
+  let $commaSep := string-util:putCommaBetween($wordsWithLinks)
+  return $commaSep
+};
+
+declare function string-util:getDummyDocument() as node() {
+  let $bla := 
+    document {
+      element product {
+        attribute dept { "ACC" },
+        element number { 563 },
+        element name { attribute language {"en"}, "Floppy Sun Hat"}
+      },
+      element product {
+        attribute dept { "BCC" },
+        element number { 564 },
+        element name { attribute language {"en"}, "Floppy SBun Iat"}
+      }
+    }
+  return $bla
+};
+
+let $currentTimeBegin := util:system-time()
+let $lang := request:get-parameter("lang", "0")
+let $language := request:get-parameter("language", "fr")
+let $document := request:get-parameter("document", "alber_archi_003_en_1755")
+
+let $tempArchimedesDocPath :=
+  if ($lang = "0")
+  then "/db/archimedes"
+  else concat("/db/arch/", $language)
+let $archimedesDocPath := concat($tempArchimedesDocPath, "/", $document, ".xml")
+let $archDoc := doc($archimedesDocPath)
+
+let $lucene-query := 
+  if ($lang = "0")
+  then request:get-parameter("ft-query", "Illuſtriſsimi")
+  else request:get-parameter("ft-lang-query", "Illuſtriſsimi")
+
+let $resultElems :=
+  for $s at $pos in $archDoc//s[ft:query(., $lucene-query)]
+    let $documentName := util:document-name($s)
+    let $collectionName := util:collection-name($s)
+    let $fullDocName := concat($collectionName, "/", $documentName)
+    let $docRoot := doc($fullDocName)
+    let $sArchInfo := $s/root()/archimedes/info
    let $author := string($sArchInfo/author/text())
+    let $language := string($sArchInfo/lang/text())
+    let $dictLinks := string-util:toSortedLinkedWords($s, $language)
+    let $pnOfS := count($docRoot//pb[. << $s])    (: faster: comparision only in pb elements of this document :)
+    (: let $pnOfS := count($s/preceding::pb[util:document-name(root()) = $documentName])  too slow: comparision in pb elements of all found documents  :)
+    let $posOfS := count($docRoot//pb[$pnOfS]/following::s[. << $s]) + 1    (: faster: comparision only in s elements of this document :)
+    let $resultElem := 
+      <elem>
+        <pos>{$pos}</pos>
+        <full-doc>{$fullDocName}</full-doc>
+        <name>{$documentName}</name>
+        <pn>{$pnOfS}</pn>
+        <pos-of-s>{$posOfS}</pos-of-s>
+        {$s}
+        <links>{$dictLinks}</links>
+      </elem>
+  order by $author, $pos
+  return $resultElem
+
+let $countElems := count($resultElems)
+let $countPages := $countElems idiv 10 + 1 
+
+let $pn := fn:number(request:get-parameter("pn", "1"))
+let $positionFrom := xs:integer((($pn - 1) * 10) + 1)
+let $positionTo := 
+  if ($pn = $countPages)
+  then $countElems
+  else $pn * 10
+
+let $pagesURLs :=
+  if ($lang = "0")
+  then concat("?ft-query=", $lucene-query)
+  else concat("?ft-lang-query=", $lucene-query, "&amp;lang=1&amp;language=", $language)
+
+let $countPagesURLs :=
+  for $i in (1 to $countPages)
+  let $pageURL := 
+    if ($i = $pn) 
+    then ($i, " ")
+    else (<a href="{$pagesURLs}&amp;pn={$i}">{$i}</a>, " ")
+  return $pageURL
+
+let $pageResult := 
+  for $elem at $pos in $resultElems
+    let $hitPos := xs:integer($elem/pos)
+    let $pnOfS := xs:integer($elem/pn)
+    let $posOfS := xs:integer($elem/pos-of-s)
+    let $docName := $elem/name
+    let $linkPageQuery := (<a href="page-query-result.xql?document={$docName}&amp;pn={$pnOfS}&amp;mode=xml">Page {$pnOfS}</a>)
+    let $hitLI :=
+        <li value="{$hitPos}">
+          {$linkPageQuery}, Sentence: {$posOfS}<br></br>
+          <b>Sentence: </b>{$elem/s/text()}<br></br>
+          <b>Dictionary links: </b>{$elem/links}<br></br>
+        </li>
+  where $pos >= $positionFrom and $pos <= $positionTo
+  return $hitLI 
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := time-util:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+
+return
+<html>
+ <head>
+  <title>Result for your query: "{$lucene-query}"</title>
+ </head>
+<body>
+<h2>Result of query: "{$lucene-query}"</h2>
+{$positionFrom}-{$positionTo} of {$countElems} results. Page: {$countPagesURLs}
+<ol>
+{$pageResult}
+</ol>
+<hr></hr>
+<p></p>
+Elapsed time: {$neededTime} ms, Back to <a href="query.xql">query page</a>, see the <a href="fulltext-query-result.xql?_source=yes">XQuery source</a> of this page
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/highlight-matches-test.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,21 @@
+xquery version "1.0";
+
+declare namespace xlink = "http://www.w3.org/1999/xlink";
+declare namespace docc = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/docc"; 
+
+declare function docc:tagmatch($term as xs:string, $node as text(), $args as item()+) as element() {
+  <span class="match">{$term}</span>
+}; 
+
+(: was originally in page-query-result.xql, does not work because match-any does not deliver results because fragment is not in fulltext index  :)
+
+let $retPageFragment := 
+  if ($mode = "image")
+  then ()
+  else doc:getFragmentBetween($docPath, "pb", $pn, $pn + 1)
+
+let $returnPageFragmentTemp := util:parse($retPageFragment)  (: string2xml: returns a valid xml document for that string   :)
+
+let $hitTemp := $returnPageFragmentTemp[match-any(.,"di")]
+let $callback := util:function(QName("http://www.mpiwg-berlin.mpg.de/ns/mpdl/docc", "docc:tagmatch"), 3)
+let $returnPageFragment := text:highlight-matches($hitTemp, $callback, ()) 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/html2fop.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,1727 @@
+<?xml version="1.0"?>
+<xsl:stylesheet 
+  version="1.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="http://www.w3.org/1999/XSL/Format"
+  xmlns:fox="http://xml.apache.org/fop/extensions">
+
+  <!-- ============================================
+    This stylesheet transforms most of the common
+    HTML elements into XSL formatting objects.  
+
+    This version written 1 November 2002 by
+    Doug Tidwell, dtidwell@us.ibm.com.
+
+    Brought to you by your friends at developerWorks:
+    ibm.com/developerWorks.
+    =============================================== -->
+
+  <!-- ============================================
+    This variable sets the size of the page.  If 
+    it's 'ltr', we an 8.5 x 11 inch page; otherwise,
+    we use an A4-sized page.  'ltr' is the default.
+    To change the value, you can make the following
+    line read select="'A4'", or you can check the
+    documentation for your XSLT processor to see 
+    how to set variables externally to the style
+    sheet.  (For Xalan, add "-PARAM page-size a4"
+    to the command.)
+    =============================================== -->
+
+  <xsl:variable name="page-size" select="'ltr'"/>
+
+  <xsl:template match="html">
+
+  <!-- ============================================
+    Because character entities aren't built into 
+    the XSL-FO vocabulary, they're included here.  
+    =============================================== -->
+
+    <xsl:text disable-output-escaping="yes">
+&lt;!DOCTYPE fo:root [
+  &lt;!ENTITY tilde  "&amp;#126;"&gt;
+  &lt;!ENTITY florin "&amp;#131;"&gt;
+  &lt;!ENTITY elip   "&amp;#133;"&gt;
+  &lt;!ENTITY dag    "&amp;#134;"&gt;
+  &lt;!ENTITY ddag   "&amp;#135;"&gt;
+  &lt;!ENTITY cflex  "&amp;#136;"&gt;
+  &lt;!ENTITY permil "&amp;#137;"&gt;
+  &lt;!ENTITY uscore "&amp;#138;"&gt;
+  &lt;!ENTITY OElig  "&amp;#140;"&gt;
+  &lt;!ENTITY lsquo  "&amp;#145;"&gt;
+  &lt;!ENTITY rsquo  "&amp;#146;"&gt;
+  &lt;!ENTITY ldquo  "&amp;#147;"&gt;
+  &lt;!ENTITY rdquo  "&amp;#148;"&gt;
+  &lt;!ENTITY bullet "&amp;#149;"&gt;
+  &lt;!ENTITY endash "&amp;#150;"&gt;
+  &lt;!ENTITY emdash "&amp;#151;"&gt;
+  &lt;!ENTITY trade  "&amp;#153;"&gt;
+  &lt;!ENTITY oelig  "&amp;#156;"&gt;
+  &lt;!ENTITY Yuml   "&amp;#159;"&gt;
+
+  &lt;!ENTITY nbsp   "&amp;#160;"&gt;
+  &lt;!ENTITY iexcl  "&amp;#161;"&gt;
+  &lt;!ENTITY cent   "&amp;#162;"&gt;
+  &lt;!ENTITY pound  "&amp;#163;"&gt;
+  &lt;!ENTITY curren "&amp;#164;"&gt;
+  &lt;!ENTITY yen    "&amp;#165;"&gt;
+  &lt;!ENTITY brvbar "&amp;#166;"&gt;
+  &lt;!ENTITY sect   "&amp;#167;"&gt;
+  &lt;!ENTITY uml    "&amp;#168;"&gt;
+  &lt;!ENTITY copy   "&amp;#169;"&gt;
+  &lt;!ENTITY ordf   "&amp;#170;"&gt;
+  &lt;!ENTITY laquo  "&amp;#171;"&gt;
+  &lt;!ENTITY not    "&amp;#172;"&gt;
+  &lt;!ENTITY shy    "&amp;#173;"&gt;
+  &lt;!ENTITY reg    "&amp;#174;"&gt;
+  &lt;!ENTITY macr   "&amp;#175;"&gt;
+  &lt;!ENTITY deg    "&amp;#176;"&gt;
+  &lt;!ENTITY plusmn "&amp;#177;"&gt;
+  &lt;!ENTITY sup2   "&amp;#178;"&gt;
+  &lt;!ENTITY sup3   "&amp;#179;"&gt;
+  &lt;!ENTITY acute  "&amp;#180;"&gt;
+  &lt;!ENTITY micro  "&amp;#181;"&gt;
+  &lt;!ENTITY para   "&amp;#182;"&gt;
+  &lt;!ENTITY middot "&amp;#183;"&gt;
+  &lt;!ENTITY cedil  "&amp;#184;"&gt;
+  &lt;!ENTITY sup1   "&amp;#185;"&gt;
+  &lt;!ENTITY ordm   "&amp;#186;"&gt;
+  &lt;!ENTITY raquo  "&amp;#187;"&gt;
+  &lt;!ENTITY frac14 "&amp;#188;"&gt;
+  &lt;!ENTITY frac12 "&amp;#189;"&gt;
+  &lt;!ENTITY frac34 "&amp;#190;"&gt;
+  &lt;!ENTITY iquest "&amp;#191;"&gt;
+  &lt;!ENTITY Agrave "&amp;#192;"&gt;
+  &lt;!ENTITY Aacute "&amp;#193;"&gt;
+  &lt;!ENTITY Acirc  "&amp;#194;"&gt;
+  &lt;!ENTITY Atilde "&amp;#195;"&gt;
+  &lt;!ENTITY Auml   "&amp;#196;"&gt;
+  &lt;!ENTITY Aring  "&amp;#197;"&gt;
+  &lt;!ENTITY AElig  "&amp;#198;"&gt;
+  &lt;!ENTITY Ccedil "&amp;#199;"&gt;
+  &lt;!ENTITY Egrave "&amp;#200;"&gt;
+  &lt;!ENTITY Eacute "&amp;#201;"&gt;
+  &lt;!ENTITY Ecirc  "&amp;#202;"&gt;
+  &lt;!ENTITY Euml   "&amp;#203;"&gt;
+  &lt;!ENTITY Igrave "&amp;#204;"&gt;
+  &lt;!ENTITY Iacute "&amp;#205;"&gt;
+  &lt;!ENTITY Icirc  "&amp;#206;"&gt;
+  &lt;!ENTITY Iuml   "&amp;#207;"&gt;
+  &lt;!ENTITY ETH    "&amp;#208;"&gt;
+  &lt;!ENTITY Ntilde "&amp;#209;"&gt;
+  &lt;!ENTITY Ograve "&amp;#210;"&gt;
+  &lt;!ENTITY Oacute "&amp;#211;"&gt;
+  &lt;!ENTITY Ocirc  "&amp;#212;"&gt;
+  &lt;!ENTITY Otilde "&amp;#213;"&gt;
+  &lt;!ENTITY Ouml   "&amp;#214;"&gt;
+  &lt;!ENTITY times  "&amp;#215;"&gt;
+  &lt;!ENTITY Oslash "&amp;#216;"&gt;
+  &lt;!ENTITY Ugrave "&amp;#217;"&gt;
+  &lt;!ENTITY Uacute "&amp;#218;"&gt;
+  &lt;!ENTITY Ucirc  "&amp;#219;"&gt;
+  &lt;!ENTITY Uuml   "&amp;#220;"&gt;
+  &lt;!ENTITY Yacute "&amp;#221;"&gt;
+  &lt;!ENTITY THORN  "&amp;#222;"&gt;
+  &lt;!ENTITY szlig  "&amp;#223;"&gt;
+  &lt;!ENTITY agrave "&amp;#224;"&gt;
+  &lt;!ENTITY aacute "&amp;#225;"&gt;
+  &lt;!ENTITY acirc  "&amp;#226;"&gt;
+  &lt;!ENTITY atilde "&amp;#227;"&gt;
+  &lt;!ENTITY auml   "&amp;#228;"&gt;
+  &lt;!ENTITY aring  "&amp;#229;"&gt;
+  &lt;!ENTITY aelig  "&amp;#230;"&gt;
+  &lt;!ENTITY ccedil "&amp;#231;"&gt;
+  &lt;!ENTITY egrave "&amp;#232;"&gt;
+  &lt;!ENTITY eacute "&amp;#233;"&gt;
+  &lt;!ENTITY ecirc  "&amp;#234;"&gt;
+  &lt;!ENTITY euml   "&amp;#235;"&gt;
+  &lt;!ENTITY igrave "&amp;#236;"&gt;
+  &lt;!ENTITY iacute "&amp;#237;"&gt;
+  &lt;!ENTITY icirc  "&amp;#238;"&gt;
+  &lt;!ENTITY iuml   "&amp;#239;"&gt;
+  &lt;!ENTITY eth    "&amp;#240;"&gt;
+  &lt;!ENTITY ntilde "&amp;#241;"&gt;
+  &lt;!ENTITY ograve "&amp;#242;"&gt;
+  &lt;!ENTITY oacute "&amp;#243;"&gt;
+  &lt;!ENTITY ocirc  "&amp;#244;"&gt;
+  &lt;!ENTITY otilde "&amp;#245;"&gt;
+  &lt;!ENTITY ouml   "&amp;#246;"&gt;
+  &lt;!ENTITY oslash "&amp;#248;"&gt;
+  &lt;!ENTITY ugrave "&amp;#249;"&gt;
+  &lt;!ENTITY uacute "&amp;#250;"&gt;
+  &lt;!ENTITY ucirc  "&amp;#251;"&gt;
+  &lt;!ENTITY uuml   "&amp;#252;"&gt;
+  &lt;!ENTITY yacute "&amp;#253;"&gt;
+  &lt;!ENTITY thorn  "&amp;#254;"&gt;
+  &lt;!ENTITY yuml   "&amp;#255;"&gt;
+]&gt;
+    </xsl:text>
+
+  <!-- ============================================
+    The XSL-FO section starts here....
+    =============================================== -->
+
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+      xmlns:fox="http://xml.apache.org/fop/extensions"> 
+
+  <!-- ============================================
+    Define the page layouts.  There are two sets of
+    three page mastters here; we use one set for 
+    letter-sized paper, the other set for A4.
+    =============================================== -->
+
+      <fo:layout-master-set>
+        <xsl:choose>
+          <xsl:when test="$page-size='ltr'">
+            <fo:simple-page-master master-name="first"
+              page-height="11in" page-width="8.5in"
+              margin-right="72pt" margin-left="72pt"
+              margin-bottom="36pt" margin-top="72pt">
+              <fo:region-body margin-bottom="50pt"/>
+              <fo:region-after region-name="ra-right" 
+                extent="25pt"/>
+            </fo:simple-page-master>
+            
+            <fo:simple-page-master master-name="left"
+              page-height="11in" page-width="8.5in"
+              margin-right="72pt" margin-left="72pt" 
+              margin-bottom="36pt" margin-top="36pt">
+              <fo:region-before region-name="rb-left" 
+                extent="25pt"/>
+              <fo:region-body margin-top="50pt" 
+                margin-bottom="50pt"/>
+              <fo:region-after region-name="ra-left" 
+                extent="25pt"/>
+            </fo:simple-page-master>
+            
+            <fo:simple-page-master master-name="right"
+              page-height="11in" page-width="8.5in"
+              margin-right="72pt" margin-left="72pt" 
+              margin-bottom="36pt" margin-top="36pt">
+              <fo:region-before region-name="rb-right" 
+                extent="25pt"/>
+              <fo:region-body margin-top="50pt" 
+                margin-bottom="50pt"/>
+              <fo:region-after region-name="ra-right" 
+                extent="25pt"/>
+            </fo:simple-page-master>
+          </xsl:when>
+
+  <!-- ============================================
+    Page layouts for A4-sized paper
+    =============================================== -->
+
+          <xsl:otherwise>
+            <fo:simple-page-master master-name="first"
+              page-height="29.7cm" page-width="21cm"
+              margin-right="72pt" margin-left="72pt"
+              margin-bottom="36pt" margin-top="72pt">
+              <fo:region-body margin-top="1.5cm" 
+                margin-bottom="1.5cm"/>
+              <fo:region-after region-name="ra-right" 
+                extent="1cm"/>
+            </fo:simple-page-master>
+            
+            <fo:simple-page-master master-name="left"
+              page-height="29.7cm" page-width="21cm"
+              margin-right="72pt" margin-left="72pt" 
+              margin-bottom="36pt" margin-top="36pt">
+              <fo:region-before region-name="rb-left" 
+                extent="3cm"/>
+              <fo:region-body margin-top="1.5cm" 
+                margin-bottom="1.5cm"/>
+              <fo:region-after region-name="ra-left" 
+                extent="1cm"/>
+            </fo:simple-page-master>
+            
+            <fo:simple-page-master master-name="right"
+              page-height="29.7cm" page-width="21cm"
+              margin-right="72pt" margin-left="72pt" 
+              margin-bottom="36pt" margin-top="36pt">
+              <fo:region-before region-name="rb-right" 
+                extent="3cm"/>
+              <fo:region-body margin-top="1.5cm" 
+                margin-bottom="1.5cm"/>
+              <fo:region-after region-name="ra-right" 
+                extent="1cm"/>
+            </fo:simple-page-master>
+          </xsl:otherwise>
+        </xsl:choose>
+        
+  <!-- ============================================
+    Now we define how we use the page layouts.  One
+    is for the first page, one is for the even-
+    numbered pages, and one is for odd-numbered pages.
+    =============================================== -->
+
+        <fo:page-sequence-master master-name="standard">
+          <fo:repeatable-page-master-alternatives>
+            <fo:conditional-page-master-reference 
+              master-reference="first" 
+              page-position="first"/>
+            <fo:conditional-page-master-reference 
+              master-reference="left" 
+              odd-or-even="even"/>
+            <fo:conditional-page-master-reference 
+              master-reference="right" 
+              odd-or-even="odd"/>
+          </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+        
+      </fo:layout-master-set>
+
+  <!-- ============================================
+    Now that we've defined all of the page layouts,
+    we generate the bookmarks for the PDF file. 
+    =============================================== -->
+      
+      <xsl:call-template name="generate-bookmarks"/>
+        
+  <!-- ============================================
+    This is where the actual content of the document
+    starts. 
+    =============================================== -->
+
+      <fo:page-sequence master-reference="standard">
+
+  <!-- ============================================
+    We define the static content for the headers 
+    and footers of the various page layouts first. 
+    =============================================== -->
+
+        <fo:static-content flow-name="rb-right">
+          <fo:block font-size="10pt" text-align-last="end">
+            <fo:table table-layout="fixed">
+              <fo:table-column column-width="396pt"/>
+              <fo:table-column column-width="72pt"/>
+              <fo:table-body>
+                <fo:table-row>
+                  <fo:table-cell>
+                    <fo:block text-align="start">
+                      developerWorks loves you!
+                    </fo:block>
+                  </fo:table-cell>
+                  <fo:table-cell>
+                    <fo:block text-align="end" font-weight="bold" 
+                      font-family="monospace">
+                      ibm.com/developerWorks
+                    </fo:block>
+                  </fo:table-cell>
+                </fo:table-row>
+              </fo:table-body>
+            </fo:table>
+          </fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="ra-right">
+          <fo:block font-size="10pt" text-align-last="end">
+            <fo:table table-layout="fixed">
+              <fo:table-column column-width="396pt"/>
+              <fo:table-column column-width="72pt"/>
+              <fo:table-body>
+                <fo:table-row>
+                  <fo:table-cell>
+                    <fo:block text-align="start">
+                      <xsl:value-of select="/html/head/title"/>
+                    </fo:block>
+                  </fo:table-cell>
+                  <fo:table-cell>
+                    <fo:block text-align="end">Page 
+                      <fo:page-number/> of 
+                      <fo:page-number-citation 
+                        ref-id="TheVeryLastPage"/>
+                    </fo:block>
+                  </fo:table-cell>
+                </fo:table-row>
+              </fo:table-body>
+            </fo:table>
+          </fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="rb-left">
+          <fo:block font-size="10pt" text-align-last="end">
+            <fo:table table-layout="fixed">
+              <fo:table-column column-width="72pt"/>
+              <fo:table-column column-width="396pt"/>
+              <fo:table-body>
+                <fo:table-row>
+                  <fo:table-cell>
+                    <fo:block text-align="start" font-weight="bold" 
+                      font-family="monospace">
+                      ibm.com/developerWorks
+                    </fo:block>
+                  </fo:table-cell>
+                  <fo:table-cell>
+                    <fo:block text-align="end">
+                      developerWorks loves you!
+                    </fo:block>
+                  </fo:table-cell>
+                </fo:table-row>
+              </fo:table-body>
+            </fo:table>
+          </fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="ra-left">
+          <fo:block font-size="10pt" text-align-last="end">
+            <fo:table table-layout="fixed">
+              <fo:table-column column-width="72pt"/>
+              <fo:table-column column-width="396pt"/>
+              <fo:table-body>
+                <fo:table-row>
+                  <fo:table-cell>
+                    <fo:block text-align="start">Page 
+                      <fo:page-number/> 
+                      of <fo:page-number-citation 
+                      ref-id="TheVeryLastPage"/>
+                    </fo:block>
+                  </fo:table-cell>
+                  <fo:table-cell>
+                    <fo:block text-align="end">
+                      <xsl:value-of select="/html/head/title"/> 
+                    </fo:block>
+                  </fo:table-cell>
+                </fo:table-row>
+              </fo:table-body>
+            </fo:table> 
+          </fo:block>
+        </fo:static-content>
+
+          <xsl:apply-templates select="body"/>
+      </fo:page-sequence>
+    </fo:root>
+  </xsl:template>
+
+  <!-- ============================================
+    Templates for individual HTML elements begin
+    here. 
+    =============================================== -->
+
+  <!-- ============================================
+    Processing for the anchor tag is complex.  First
+    of all, if this is a named anchor, we write an empty
+    <fo:block> with the appropriate id.  (In the special
+    case that the next element is an <h1>, we ignore
+    the element altogether and put the id on the <h1>.)
+    Next, if this is a regular anchor and the href
+    starts with a hash mark (#), we create a link with
+    an internal-destination.  Otherwise, we create a
+    link with an external destination. 
+    =============================================== -->
+
+  <xsl:template match="a">
+    <xsl:choose>
+      <xsl:when test="@name">
+        <xsl:if test="not(name(following-sibling::*[1]) = 'h1')">
+          <fo:block line-height="0pt" space-after="0pt" 
+            font-size="0pt" id="{@name}"/>
+        </xsl:if>
+      </xsl:when>
+      <xsl:when test="@href">
+        <fo:basic-link color="blue">
+          <xsl:choose>
+            <xsl:when test="starts-with(@href, '#')">
+              <xsl:attribute name="internal-destination">
+                <xsl:value-of select="substring(@href, 2)"/>
+              </xsl:attribute>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:attribute name="external-destination">
+                <xsl:value-of select="@href"/>
+              </xsl:attribute>
+            </xsl:otherwise>
+          </xsl:choose>
+          <xsl:apply-templates select="*|text()"/>
+        </fo:basic-link>
+        <xsl:if test="starts-with(@href, '#')">
+          <xsl:text> on page </xsl:text>
+          <fo:page-number-citation ref-id="{substring(@href, 2)}"/>
+        </xsl:if>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- ============================================
+      We render an address element in italics.
+    =============================================== -->
+
+  <xsl:template match="address">
+    <fo:block font-style="italic" space-after="12pt">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    For bold elements, we just change the font-weight.
+    =============================================== -->
+
+  <xsl:template match="b">
+    <fo:inline font-weight="bold">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    The big element is handled with a relative 
+    font size.  That means a <big> element inside
+    another <big> element will be even bigger, just
+    as it is in HTML. 
+    =============================================== -->
+
+  <xsl:template match="big">
+    <fo:inline font-size="120%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    A blockquote is indented on both sides.
+    =============================================== -->
+
+  <xsl:template match="blockquote">
+    <fo:block start-indent="1.5cm" end-indent="1.5cm"
+      space-after="12pt">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    The HTML <body> element contains everything in
+    the main part of the document.  This is analogous
+    to the <fo:flow flow-name="xsl-region-body">
+    element, so we put the main document processing here.  
+    =============================================== -->
+
+  <xsl:template match="body">
+
+  <!-- ============================================
+    Start generating the content for the main page 
+    area (xsl-region-body).
+    =============================================== -->
+        
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:apply-templates select="/html/head/title"/>
+      <fo:block space-after="12pt" line-height="17pt" 
+        font-size="14pt" text-align="center">
+        developerWorks loves you!
+      </fo:block>
+      <fo:block space-after="24pt" line-height="17pt" 
+        font-size="14pt" text-align="center" font-weight="bold" 
+        font-family="monospace">
+        ibm.com/developerWorks
+      </fo:block>
+          
+  <!-- ============================================
+    Now we call the template to build the table
+    of contents.
+    =============================================== -->
+
+      <xsl:call-template name="toc"/>
+            
+  <!-- ============================================
+    This one line of code processes everything in 
+    the body of the document.  The template that
+    processes the <body> element in turn processes
+    everything that's inside it.
+    =============================================== -->
+
+      <xsl:apply-templates select="*|text()"/>
+
+  <!-- ============================================
+    We put an ID at the end of the document so we 
+    can do "Page x of y" numbering.
+    =============================================== -->
+      <fo:block id="TheVeryLastPage" font-size="0pt"
+        line-height="0pt" space-after="0pt"/>
+
+    </fo:flow>
+  </xsl:template>
+
+  <!-- ============================================
+    We handle a break element by inserting an 
+    empty <fo:block>.
+    =============================================== -->
+
+  <xsl:template match="br">
+    <fo:block> </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    We're handling <center> as a block element; if
+    you use it, it creates a new paragraph that's 
+    centered on the page. 
+    =============================================== -->
+
+  <xsl:template match="center">
+    <fo:block text-align="center">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    The <cite> element is rendered in italics, 
+    unless it's inside an italic (<i>) element. 
+    We use the parent axis to check this. 
+    =============================================== -->
+
+  <xsl:template match="cite">
+    <xsl:choose>
+      <xsl:when test="parent::i">
+        <fo:inline font-style="normal">
+          <xsl:apply-templates select="*|text()"/>
+        </fo:inline>
+      </xsl:when>
+      <xsl:otherwise>
+        <fo:inline font-style="italic">
+          <xsl:apply-templates select="*|text()"/>
+        </fo:inline>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- ============================================
+    We render <code> inline in a monospaced font.
+    =============================================== -->
+
+  <xsl:template match="code">
+    <fo:inline font-family="monospace">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    We don't do anything with the <dl> element, we
+    just handle the elements it contains.  Notice
+    that we're ignoring any text that appears 
+    in the <dl> itself; I'm not sure if that's
+    the right call.
+    =============================================== -->
+
+  <xsl:template match="dl">
+    <xsl:apply-templates select="*"/>
+  </xsl:template>
+
+  <!-- ============================================
+    A definition term is rendered in bold.  We 
+    specify keep-with-next here, although it doesn't
+    always work with FOP.
+    =============================================== -->
+
+  <xsl:template match="dt">
+    <fo:block font-weight="bold" space-after="2pt"
+      keep-with-next="always">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    We handle each <dd> element as an indented block
+    beneath the defined term.  If the following 
+    element is another <dd>, that means it's another
+    definition for the same term.  In that case, 
+    we don't put as much vertical space after the 
+    block. 
+    =============================================== -->
+
+  <xsl:template match="dd">
+    <fo:block start-indent="1cm">
+      <xsl:attribute name="space-after">
+        <xsl:choose>
+          <xsl:when test="name(following::*[1]) = 'dd'">
+            <xsl:text>3pt</xsl:text>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>12pt</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    The HTML <em> element is typically rendered in 
+    italics. 
+    =============================================== -->
+
+  <xsl:template match="em">
+    <fo:inline font-style="italic">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    For the <font> element, we handle the color, 
+    face, and size attributes.  Color will work if
+    it's one of the twelve colors supported by XSL-FO
+    or it's a hex value like x0033ff.  (In other words,
+    if you tell FOP to set the color to PapayaWhip, 
+    you're out of luck.)  The face attribute will 
+    work if FOP supports it.  (There are ways to add 
+    fonts to FOP, see the FOP documentation for more 
+    info.)  Size is supported for values like 
+    size="14pt", size="3", and size="+3".
+    =============================================== -->
+
+  <xsl:template match="font">
+    <xsl:variable name="color">
+      <xsl:choose>
+        <xsl:when test="@color">
+          <xsl:value-of select="@color"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>black</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="face">
+      <xsl:choose>
+        <xsl:when test="@face">
+          <xsl:value-of select="@face"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>sans-serif</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="size">
+      <xsl:choose>
+        <xsl:when test="@size">
+          <xsl:choose>
+            <xsl:when test="contains(@size, 'pt')">
+              <xsl:text>@size</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+1'">
+              <xsl:text>110%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+2'">
+              <xsl:text>120%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+3'">
+              <xsl:text>130%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+4'">
+              <xsl:text>140%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+5'">
+              <xsl:text>150%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+6'">
+              <xsl:text>175%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '+7'">
+              <xsl:text>200%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-1'">
+              <xsl:text>90%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-2'">
+              <xsl:text>80%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-3'">
+              <xsl:text>70%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-4'">
+              <xsl:text>60%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-5'">
+              <xsl:text>50%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-6'">
+              <xsl:text>40%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '-7'">
+              <xsl:text>30%</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '1'">
+              <xsl:text>8pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '2'">
+              <xsl:text>10pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '3'">
+              <xsl:text>12pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '4'">
+              <xsl:text>14pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '5'">
+              <xsl:text>18pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '6'">
+              <xsl:text>24pt</xsl:text>
+            </xsl:when>
+            <xsl:when test="@size = '7'">
+              <xsl:text>36pt</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text>12pt</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise> 
+          <xsl:text>12pt</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <fo:inline font-size="{$size}" font-family="{$face}"
+      color="{$color}">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    We render the <h1> by putting a horizontal rule
+    and a page break before it.  We also process 
+    the id attribute; if the <h1> tag has one, we 
+    use it.  If not, we see if the preceding element
+    is a named anchor (<a name="x"/>).  If there is
+    a named anchor before the <h1>, we use the name
+    of the anchor point as the id.
+    =============================================== -->
+
+  <xsl:template match="h1">
+    <fo:block break-before="page">
+      <fo:leader leader-pattern="rule"/>
+    </fo:block>
+    <fo:block font-size="28pt" line-height="32pt"
+      keep-with-next="always"
+      space-after="22pt" font-family="serif">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:when test="name(preceding-sibling::*[1]) = 'a' and
+                          preceding-sibling::*[1][@name]">
+            <xsl:value-of select="preceding-sibling::*[1]/@name"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    <h2> is in a slightly smaller font than an <h1>,
+    and it doesn't have a page break or a line.
+    =============================================== -->
+
+  <xsl:template match="h2">
+    <fo:block font-size="24pt" line-height="28pt"
+      keep-with-next="always" space-after="18pt"
+      font-family="serif">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    <h3> is slightly smaller than <h2>.
+    =============================================== -->
+
+  <xsl:template match="h3">
+    <fo:block font-size="21pt" line-height="24pt"
+      keep-with-next="always" space-after="14pt"
+      font-family="serif">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    <h4> is smaller than <h3>.  For the bookmarks
+    and table of contents, <h4> is the lowest level
+    we include.
+    =============================================== -->
+
+  <xsl:template match="h4">
+    <fo:block font-size="18pt" line-height="21pt"
+      keep-with-next="always" space-after="12pt"
+      font-family="serif">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    <h5> is pretty small, and is underlined to 
+    help it stand out. 
+    =============================================== -->
+
+  <xsl:template match="h5">
+    <fo:block font-size="16pt" line-height="19pt"
+      keep-with-next="always" space-after="12pt"
+      font-family="serif" text-decoration="underline">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    <h6> is the smallest heading of all, and is
+    underlined and italicized.  
+    =============================================== -->
+
+  <xsl:template match="h6">
+    <fo:block font-size="14pt" line-height="17pt"
+      keep-with-next="always" space-after="12pt"
+      font-family="serif" font-style="italic"
+      text-decoration="underline">
+      <xsl:attribute name="id">
+        <xsl:choose>
+          <xsl:when test="@id">
+            <xsl:value-of select="@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="generate-id()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    We render an <hr> with a leader.  Because <hr>
+    is empty, we don't have to process any child
+    elements. 
+    =============================================== -->
+
+  <xsl:template match="hr">
+    <fo:block>
+      <fo:leader leader-pattern="rule"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    Italics.  You can't get much simpler than that.
+    =============================================== -->
+
+  <xsl:template match="i">
+    <fo:inline font-style="italic">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    For the <img> element, we use the src attribute
+    as it comes from HTML.  We also check for any 
+    width and height attributes.  If those attributes
+    are there, we try to use them; height="300px" is
+    used as-is, while height="300" is converted to 
+    the value "300px".
+    =============================================== -->
+
+  <xsl:template match="img">
+    <fo:block space-after="12pt">
+      <fo:external-graphic src="{@src}">
+        <xsl:if test="@width">
+          <xsl:attribute name="width">
+            <xsl:choose>
+              <xsl:when test="contains(@width, 'px')">
+                <xsl:value-of select="@width"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="concat(@width, 'px')"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:attribute>
+        </xsl:if>
+        <xsl:if test="@height">
+          <xsl:attribute name="height">
+            <xsl:choose>
+              <xsl:when test="contains(@height, 'px')">
+                <xsl:value-of select="@height"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="concat(@height, 'px')"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:attribute>
+        </xsl:if>
+      </fo:external-graphic>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    The <kbd> element is in a slightly larger 
+    monospaced text.
+    =============================================== -->
+
+  <xsl:template match="kbd">
+    <fo:inline font-family="monospace" font-size="110%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    We handle the <li> elements under the <ol> and 
+    <ul> elements, so there's no <li> template here.
+    =============================================== -->
+
+  <!-- ============================================
+    For the <nobr> element, we simply turn off the
+    wrap-option. 
+    =============================================== -->
+
+  <xsl:template match="nobr">
+    <fo:inline wrap-option="no-wrap">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    We handle an ordered list with two complications:
+    If the list appears inside another list (either 
+    an <ol> or <ul>), we don't put any vertical space
+    after it.  The other issue is that we indent the
+    list according to how deeply nested the list is. 
+    =============================================== -->
+
+  <xsl:template match="ol">
+    <fo:list-block provisional-distance-between-starts="1cm"
+      provisional-label-separation="0.5cm">
+      <xsl:attribute name="space-after">
+        <xsl:choose>
+          <xsl:when test="ancestor::ul or ancestor::ol">
+            <xsl:text>0pt</xsl:text>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>12pt</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:attribute name="start-indent">
+        <xsl:variable name="ancestors">
+          <xsl:choose>
+            <xsl:when test="count(ancestor::ol) or count(ancestor::ul)">
+              <xsl:value-of select="1 + 
+                                    (count(ancestor::ol) + 
+                                     count(ancestor::ul)) * 
+                                    1.25"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text>1</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <xsl:value-of select="concat($ancestors, 'cm')"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="*"/>
+    </fo:list-block>
+  </xsl:template>
+
+  <!-- ============================================
+    When we handle items in an ordered list, we need
+    to check if the list has a start attribute.  If
+    it does, we change the starting number accordingly.
+    Once we've figured out where to start counting,
+    we check the type attribute to see what format
+    the numbers should use.  
+    =============================================== -->
+
+  <xsl:template match="ol/li">
+    <fo:list-item>
+      <fo:list-item-label end-indent="label-end()">
+        <fo:block>
+          <xsl:variable name="value-attr">
+            <xsl:choose>
+              <xsl:when test="../@start">
+                <xsl:number value="position() + ../@start - 1"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:number value="position()"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:variable>
+          <xsl:choose>
+            <xsl:when test="../@type='i'">
+              <xsl:number value="$value-attr" format="i. "/>
+            </xsl:when>
+            <xsl:when test="../@type='I'">
+              <xsl:number value="$value-attr" format="I. "/>
+            </xsl:when>
+            <xsl:when test="../@type='a'">
+              <xsl:number value="$value-attr" format="a. "/>
+            </xsl:when>
+            <xsl:when test="../@type='A'">
+              <xsl:number value="$value-attr" format="A. "/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:number value="$value-attr" format="1. "/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </fo:block>
+      </fo:list-item-label>
+      <fo:list-item-body start-indent="body-start()">
+        <fo:block>
+          <xsl:apply-templates select="*|text()"/>
+        </fo:block>
+      </fo:list-item-body>
+    </fo:list-item>
+  </xsl:template>
+
+  <!-- ============================================
+    Your basic paragraph.
+    =============================================== -->
+
+  <xsl:template match="p">
+    <fo:block font-size="12pt" line-height="15pt"
+      space-after="12pt">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    Preformatted text is rendered in a monospaced
+    font.  We also have to set the wrap-option
+    and white-space-collapse properties.  
+    =============================================== -->
+
+  <xsl:template match="pre">
+    <fo:block font-family="monospace"
+      white-space-collapse="false" wrap-option="no-wrap">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    Sample text is rendered in a slightly larger
+    monospaced font. 
+    =============================================== -->
+
+  <xsl:template match="samp">
+    <fo:inline font-family="monospace" font-size="110%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    The <small> element is rendered with a relative
+    font size.  That means putting one <small>
+    element inside another creates really small 
+    text.  
+    =============================================== -->
+
+  <xsl:template match="small">
+    <fo:inline font-size="80%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    For strikethrough text, we use the text-decoration
+    property.  
+    =============================================== -->
+
+  <xsl:template match="strike">
+    <fo:inline text-decoration="line-through">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    Strongly emphasized text is simply rendered
+    in bold. 
+    =============================================== -->
+
+  <xsl:template match="strong">
+    <fo:inline font-weight="bold">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    For subscript text, we use the vertical-align
+    property and decrease the font size.  
+    =============================================== -->
+
+  <xsl:template match="sub">
+    <fo:inline vertical-align="sub" font-size="75%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    Superscript text changes the vertical-align
+    property also, and uses a smaller font.
+    =============================================== -->
+
+  <xsl:template match="sup">
+    <fo:inline vertical-align="super" font-size="75%">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    Tables are a hassle.  The main problem we have
+    is converting the cols attribute into some 
+    number of <fo:table-column> elements.  We do 
+    this with a named template called build-columns.
+    Once we've processed the cols attribute, we 
+    invoke all of the templates for the children 
+    of this element. 
+    =============================================== -->
+
+  <xsl:template match="table">
+    <fo:table table-layout="fixed">
+      <xsl:choose>
+        <xsl:when test="@cols">
+         <xsl:call-template name="build-columns">
+           <xsl:with-param name="cols" 
+             select="concat(@cols, ' ')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <fo:table-column column-width="200pt"/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <fo:table-body>
+        <xsl:apply-templates select="*"/>
+      </fo:table-body>
+    </fo:table>
+  </xsl:template>
+
+  <!-- ============================================
+    For a table cell, we put everything inside a
+    <fo:table-cell> element.  We set the padding
+    property correctly, then we set the border 
+    style.  For the border style, we look to see if
+    any of the ancestor elements we care about 
+    specified a solid border.  Next, we check for the 
+    rowspan, colspan, and align attributes.  Notice 
+    that for align, we check this element, then go
+    up the ancestor chain until we find the <table>
+    element or we find something that specifies the 
+    alignment. 
+    =============================================== -->
+
+  <xsl:template match="td">
+    <fo:table-cell 
+      padding-start="3pt" padding-end="3pt"
+      padding-before="3pt" padding-after="3pt">
+      <xsl:if test="@colspan">
+        <xsl:attribute name="number-columns-spanned">
+          <xsl:value-of select="@colspan"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@rowspan">
+        <xsl:attribute name="number-rows-spanned">
+          <xsl:value-of select="@rowspan"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@border='1' or 
+                    ancestor::tr[@border='1'] or
+                    ancestor::thead[@border='1'] or
+                    ancestor::table[@border='1']">
+        <xsl:attribute name="border-style">
+          <xsl:text>solid</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="border-color">
+          <xsl:text>black</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="border-width">
+          <xsl:text>1pt</xsl:text>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:variable name="align">
+        <xsl:choose>
+          <xsl:when test="@align">
+            <xsl:choose>
+              <xsl:when test="@align='center'">
+                <xsl:text>center</xsl:text>
+              </xsl:when>
+              <xsl:when test="@align='right'">
+                <xsl:text>end</xsl:text>
+              </xsl:when>
+              <xsl:when test="@align='justify'">
+                <xsl:text>justify</xsl:text>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:text>start</xsl:text>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="ancestor::tr[@align]">
+            <xsl:choose>
+              <xsl:when test="ancestor::tr/@align='center'">
+                <xsl:text>center</xsl:text>
+              </xsl:when>
+              <xsl:when test="ancestor::tr/@align='right'">
+                <xsl:text>end</xsl:text>
+              </xsl:when>
+              <xsl:when test="ancestor::tr/@align='justify'">
+                <xsl:text>justify</xsl:text>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:text>start</xsl:text>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="ancestor::thead">
+            <xsl:text>center</xsl:text>
+          </xsl:when>
+          <xsl:when test="ancestor::table[@align]">
+            <xsl:choose>
+              <xsl:when test="ancestor::table/@align='center'">
+                <xsl:text>center</xsl:text>
+              </xsl:when>
+              <xsl:when test="ancestor::table/@align='right'">
+                <xsl:text>end</xsl:text>
+              </xsl:when>
+              <xsl:when test="ancestor::table/@align='justify'">
+                <xsl:text>justify</xsl:text>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:text>start</xsl:text>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>start</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <fo:block text-align="{$align}">
+        <xsl:apply-templates select="*|text()"/>
+      </fo:block>
+    </fo:table-cell>
+  </xsl:template>
+
+  <!-- ============================================
+    The rarely-used <tfoot> element contains some
+    number of <tr> elements; we just invoke the 
+    template for <tr> here. 
+    =============================================== -->
+
+  <xsl:template match="tfoot">
+    <xsl:apply-templates select="tr"/>
+  </xsl:template>
+
+  <!-- ============================================
+    If there's a <th> element, we process it just 
+    like a normal <td>, except the font-weight is 
+    always bold and the text-align is always center. 
+    =============================================== -->
+
+  <xsl:template match="th">
+    <fo:table-cell
+      padding-start="3pt" padding-end="3pt"
+      padding-before="3pt" padding-after="3pt">
+      <xsl:if test="@border='1' or 
+                    ancestor::tr[@border='1'] or
+                    ancestor::table[@border='1']">
+        <xsl:attribute name="border-style">
+          <xsl:text>solid</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="border-color">
+          <xsl:text>black</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="border-width">
+          <xsl:text>1pt</xsl:text>
+        </xsl:attribute>
+      </xsl:if>
+      <fo:block font-weight="bold" text-align="center">
+        <xsl:apply-templates select="*|text()"/>
+      </fo:block>
+    </fo:table-cell>
+  </xsl:template>
+
+  <!-- ============================================
+    Just like <tfoot>, the rarely-used <thead> element
+    contains some number of table rows.  We just 
+    invoke the template for <tr> here. 
+    =============================================== -->
+
+  <xsl:template match="thead">
+    <xsl:apply-templates select="tr"/>
+  </xsl:template>
+
+  <!-- ============================================
+    The title of the document is rendered in a large
+    bold font, centered on the page.  This is the 
+    <title> element in the <head> in <html>.
+    =============================================== -->
+
+  <xsl:template match="title">
+    <fo:block space-after="18pt" line-height="27pt" 
+      font-size="24pt" font-weight="bold" text-align="center">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:block>
+  </xsl:template>
+
+  <!-- ============================================
+    For an HTML table row, we create an XSL-FO table
+    row, then invoke the templates for everything 
+    inside it. 
+    =============================================== -->
+
+  <xsl:template match="tr">
+    <fo:table-row>
+      <xsl:apply-templates select="*|text()"/>
+    </fo:table-row>
+  </xsl:template>
+
+  <!-- ============================================
+    Teletype text is rendered in a monospaced font.
+    =============================================== -->
+
+  <xsl:template match="tt">
+    <fo:inline font-family="monospace">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+  
+  <!-- ============================================
+    For underlined text, we use the text-decoration
+    property.
+    =============================================== -->
+
+  <xsl:template match="u">
+    <fo:inline text-decoration="underline">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    The unordered list is pretty straightforward; 
+    the only complication is calculating the space-
+    after and start-indent properties.  If this 
+    list is inside another list, we don't put any 
+    space after this one, and we calculate the 
+    indentation based on the nesting level of this 
+    list. 
+    =============================================== -->
+
+  <xsl:template match="ul">
+    <fo:list-block provisional-distance-between-starts="1cm"
+      provisional-label-separation="0.5cm">
+      <xsl:attribute name="space-after">
+        <xsl:choose>
+          <xsl:when test="ancestor::ul or ancestor::ol">
+            <xsl:text>0pt</xsl:text>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>12pt</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:attribute name="start-indent">
+        <xsl:variable name="ancestors">
+          <xsl:choose>
+            <xsl:when test="count(ancestor::ol) or count(ancestor::ul)">
+              <xsl:value-of select="1 + 
+                                    (count(ancestor::ol) + 
+                                     count(ancestor::ul)) * 
+                                    1.25"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text>1</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <xsl:value-of select="concat($ancestors, 'cm')"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="*"/>
+    </fo:list-block>
+  </xsl:template>
+
+  <!-- ============================================
+    List items inside unordered lists are easy; we
+    just have to use the correct Unicode character
+    for the bullet.  
+    =============================================== -->
+
+  <xsl:template match="ul/li">
+    <fo:list-item>
+      <fo:list-item-label end-indent="label-end()">
+        <fo:block>&#x2022;</fo:block>
+      </fo:list-item-label>
+      <fo:list-item-body start-indent="body-start()">
+        <fo:block>
+          <xsl:apply-templates select="*|text()"/>
+        </fo:block>
+      </fo:list-item-body>
+    </fo:list-item>
+  </xsl:template>
+
+  <!-- ============================================
+    The <var> element is rendered in italics. 
+    =============================================== -->
+
+  <xsl:template match="var">
+    <fo:inline font-style="italic">
+      <xsl:apply-templates select="*|text()"/>
+    </fo:inline>
+  </xsl:template>
+
+  <!-- ============================================
+    Named templates
+    =============================================== -->
+
+  <!-- ============================================
+    This template creates the table of contents.  
+    It indents each entry according to the heading
+    level (<h1> isn't indented, <h2> is indented 
+    1 cm, etc.).  We insert the title of each
+    section as a link, put a leader of dots, then 
+    the page number.  Notice that we generate an
+    id for the heading if it doesn't have one
+    already; this is done with the XSLT generate-id()
+    function. 
+    =============================================== -->
+
+  <xsl:template name="toc">
+    <fo:block>
+      <fo:leader leader-pattern="rule" space-after="18pt"/>
+    </fo:block>
+    <fo:block space-after="12pt" id="TableOfContents" 
+      line-height="21pt" font-size="18pt" text-align="start">
+      Table of Contents
+    </fo:block>
+    <fo:block line-height="11pt" font-size="8pt" 
+      space-after="6pt">
+      If you're viewing this document online, you can 
+      click any of the topics below to link directly to 
+      that section.
+    </fo:block>
+    <xsl:for-each select="/html/body//h1 |
+                          /html/body//h2 | 
+                          /html/body//h3 |
+                          /html/body//h4">
+      <fo:block text-align-last="justify" line-height="17pt"
+        font-size="14pt" space-after="3pt" text-align="start"
+        text-indent="-1cm">
+        <xsl:attribute name="start-indent">
+          <xsl:choose>
+            <xsl:when test="name() = 'h1'">
+              <xsl:text>1cm</xsl:text>
+            </xsl:when>
+            <xsl:when test="name() = 'h2'">
+              <xsl:text>1.5cm</xsl:text>
+            </xsl:when>
+            <xsl:when test="name() = 'h3'">
+              <xsl:text>2cm</xsl:text>
+            </xsl:when>
+            <xsl:when test="name() = 'h4'">
+              <xsl:text>2.5cm</xsl:text>
+            </xsl:when>
+          </xsl:choose>
+        </xsl:attribute>
+        <fo:basic-link color="blue">
+          <xsl:attribute name="internal-destination">
+            <xsl:choose>
+              <xsl:when test="@id">
+                <xsl:value-of select="@id"/>
+              </xsl:when>
+              <xsl:when test="name(preceding-sibling::*[1]) = 'a' and
+                              preceding-sibling::*[1][@name]">
+                <xsl:value-of select="preceding-sibling::*[1]/@name"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="generate-id()"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:attribute>
+          <xsl:apply-templates select="*|text()"/>
+        </fo:basic-link>
+        <fo:leader leader-pattern="dots"
+          leader-pattern-width="5pt"/>
+        <fo:page-number-citation>
+          <xsl:attribute name="ref-id">
+            <xsl:choose>
+              <xsl:when test="@id">
+                <xsl:value-of select="@id"/>
+              </xsl:when>
+              <xsl:when test="name(preceding-sibling::*[1]) = 'a' and
+                              preceding-sibling::*[1][@name]">
+                <xsl:value-of select="preceding-sibling::*[1]/@name"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="generate-id()"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:attribute>
+        </fo:page-number-citation>
+      </fo:block>
+    </xsl:for-each>
+  </xsl:template>
+
+  <!-- ============================================
+    This complicated template creates the PDF bookmarks
+    supported by FOP.  For each <h1> element, it 
+    creates a bookmark for that element, then it
+    looks for all of the <h2> elements beneath it.
+    For each <h2>, it looks for all the <h3> 
+    elements beneath it, etc.  We use generate-id()
+    extensively so we can determine whether a given
+    <h1> or <h2> or <h3> is one we've seen before. 
+    The end result of all this hard work is a set of
+    hierarchical bookmarks that are nested within each 
+    other.
+    =============================================== -->
+
+  <xsl:template name="generate-bookmarks">
+    <fox:outline internal-destination="TableOfContents">
+      <fox:label>Table of Contents</fox:label>
+    </fox:outline>
+    <xsl:for-each select="/html/body//h1">
+      <xsl:variable name="current-h1" select="generate-id()"/>
+      <fox:outline>
+        <xsl:attribute name="internal-destination">
+          <xsl:choose>
+            <xsl:when test="@id">
+              <xsl:value-of select="@id"/>
+            </xsl:when>
+            <xsl:when test="name(preceding-sibling::*[1]) = 'a' and
+                            preceding-sibling::*[1][@name]">
+              <xsl:value-of select="preceding-sibling::*[1]/@name"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="generate-id()"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:attribute>
+        <fox:label>
+          <xsl:value-of select="."/>
+        </fox:label>
+        <xsl:for-each select="following-sibling::h2">
+          <xsl:variable name="current-h2" select="generate-id()"/>
+          <xsl:if 
+            test="generate-id(preceding-sibling::h1[1]) = $current-h1">
+            <fox:outline>
+              <xsl:attribute name="internal-destination">
+                <xsl:choose>
+                  <xsl:when test="@id">
+                    <xsl:value-of select="@id"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$current-h2"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:attribute>
+              <fox:label>
+                <xsl:value-of select="."/>
+              </fox:label>
+              <xsl:for-each select="following-sibling::h3">
+                <xsl:variable name="current-h3" select="generate-id()"/>
+                <xsl:if 
+                  test="generate-id(preceding-sibling::h2[1]) = $current-h2">
+                  <fox:outline>
+                    <xsl:attribute name="internal-destination">
+                      <xsl:choose>
+                        <xsl:when test="@id">
+                          <xsl:value-of select="@id"/>
+                        </xsl:when>
+                        <xsl:otherwise>
+                          <xsl:value-of select="$current-h2"/>
+                        </xsl:otherwise>
+                      </xsl:choose>
+                    </xsl:attribute>
+                    <fox:label>
+                      <xsl:value-of select="."/>
+                    </fox:label>
+                    <xsl:for-each select="following-sibling::h4">
+                      <xsl:if 
+                        test="generate-id(preceding-sibling::h3[1]) = $current-h3">
+                        <fox:outline>
+                          <xsl:attribute name="internal-destination">
+                            <xsl:choose>
+                              <xsl:when test="@id">
+                                <xsl:value-of select="@id"/>
+                              </xsl:when>
+                              <xsl:otherwise>
+                                <xsl:value-of select="$current-h3"/>
+                              </xsl:otherwise>
+                            </xsl:choose>
+                          </xsl:attribute>
+                          <fox:label>
+                            <xsl:value-of select="."/>
+                          </fox:label>
+                        </fox:outline>
+                      </xsl:if>
+                    </xsl:for-each>
+                  </fox:outline>
+                </xsl:if>
+              </xsl:for-each>
+            </fox:outline>
+          </xsl:if>
+        </xsl:for-each>
+      </fox:outline>
+    </xsl:for-each>
+  </xsl:template>
+
+  <!-- ============================================
+    This template generates an <fo:table-column>
+    element for each token in the cols attribute of
+    the HTML <table> tag.  The template processes
+    the first token, then invokes itself with the 
+    rest of the string. 
+    =============================================== -->
+
+  <xsl:template name="build-columns">
+    <xsl:param name="cols"/>
+
+    <xsl:if test="string-length(normalize-space($cols))">
+      <xsl:variable name="next-col">
+        <xsl:value-of select="substring-before($cols, ' ')"/>
+      </xsl:variable>
+      <xsl:variable name="remaining-cols">
+        <xsl:value-of select="substring-after($cols, ' ')"/>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="contains($next-col, 'pt')">
+          <fo:table-column column-width="{$next-col}"/>
+        </xsl:when>
+        <xsl:when test="number($next-col) &gt; 0">
+          <fo:table-column column-width="{concat($next-col, 'pt')}"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <fo:table-column column-width="50pt"/>
+        </xsl:otherwise>
+      </xsl:choose>
+
+      <xsl:call-template name="build-columns">
+        <xsl:with-param name="cols" select="concat($remaining-cols, ' ')"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/futureDev/rest-doc-operation.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,67 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace file = "http://exist-db.org/xquery/file";
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace session="http://exist-db.org/xquery/session";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace xmldb = "http://exist-db.org/xquery/xmldb";
+
+let $login := xmldb:authenticate("xmldb:exist:///db", "admin", "")
+
+let $operation := request:get-parameter("operation", "")
+let $docBase := request:get-parameter("docBase", "")
+let $language := request:get-parameter("language", "")
+let $fileName := request:get-parameter("fileName", "")
+
+let $eSciDocCookieId := request:get-cookie-value("escidocCookie")
+
+let $srcLocalFileName := request:get-uploaded-file-name("srcLocalFileName")
+let $srcExistUploadFileJavaObject := request:get-uploaded-file("srcLocalFileName")
+let $srcExistUploadFileName := string(<b>{$srcExistUploadFileJavaObject}</b>)
+let $srcExistUploadFileUrl := concat("file://", $srcExistUploadFileName)
+
+let $reqSrcUrl := request:get-parameter("srcUrl", "")
+let $srcUrl :=
+  if ($reqSrcUrl = '')
+  then $srcExistUploadFileUrl
+  else $reqSrcUrl
+
+let $error :=
+  if ($eSciDocCookieId = '' or empty($eSciDocCookieId))
+  then <bla>No login context available. Please <a href="login-exist.xql">login</a> before you do an operation</bla>
+  else if(($operation = 'updateExist') and ($srcUrl = ''))
+  then "please specify your source"
+  else if(($operation = 'updateExist' or $operation = 'delete') and ($fileName = ''))
+  then "please specify your destination document name"
+  else "no"
+
+let $jobId := 
+  if($error = 'no' and $operation = 'updateExist')
+  then mpdldoc:do($operation, $srcUrl, $srcLocalFileName, $docBase, $language, $fileName, $eSciDocCookieId)
+  else if($error = 'no' and $operation = 'deleteExist')
+  then mpdldoc:do($operation, 'empty', 'empty', $docBase, $language, $fileName, $eSciDocCookieId)
+  else ()
+let $redirectUrl := <a href="../scheduler/get-jobs.xql?id={$jobId}">here</a>
+let $resultHtml := 
+  if ($error = 'no')
+  then <div>See the status of your document operation {$redirectUrl}</div>
+  else <div><b>Error in your document operation:</b> {$error}</div> 
+
+let $title := "MPDL: eXist document management"
+return
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+  {$resultHtml} 
+  <br/>
+  <br/>{$eSciDocCookieId}
+  <br/>
+  <hr/>
+  Back to <a href="rest-doc-operation.xql">document operation page</a>, see the <a href="rest-doc-operation.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-image-fragment.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,122 @@
+<xsl:stylesheet version="1.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<xsl:output method="html"/>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:variable name="ft-query-name" select="/result/ft-query/name"/>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number"/>
+      <xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
+      <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
+      <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
+      <xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+      <xsl:variable name="ftQueryValue">
+        <xsl:choose>
+          <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
+      <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
+      <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
+      <form action="" method="get"></form>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="70%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          [<a href="?{$textLink}">Text</a>] 
+          [Image] 
+          [<a href="?{$xmlLink}">XML</a>] 
+        </td>
+        <td nowrap="true">
+          <td align="right">
+            <xsl:choose>
+              <xsl:when test="$number &gt; 1">
+                <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeImageValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$imageLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+          </td>
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &lt; $countPages">
+                <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeImageValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$imageLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <input type="hidden" name="document" value="{$documentName}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/>
+            <input type="hidden" name="mode" value="image"/>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>   
+      <xsl:variable name="linkImageEcho" select="/result/page/image-echo"/>
+      <xsl:variable name="linkImageScaler" select="/result/page/image-scaler"/>
+      <table align="middle" width="100%">
+        <colgroup>
+          <col width="10%"/>
+          <col width="60%"/>
+          <col width="30%"/>
+        </colgroup>
+        <tr>
+          <td/>
+          <td align="left" valign="top">
+            <a href="{$linkImageEcho}"><img alt="Page image: {$number}" src="{$linkImageScaler}&amp;dh=600" border="1"/></a>
+          </td>
+          <xsl:if test="$ftQueryValue!=''">
+          <td align="left" valign="top">
+            <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
+            <ol>
+              <xsl:for-each select="/result/ft-query/result/hits/hit">
+              <li>
+                <xsl:variable name="hitPN" select="pn"/>
+                <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeImageValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>
+              </li>
+              </xsl:for-each>
+            </ol>
+          </td>
+          </xsl:if>
+        </tr>
+      </table>
+    </xsl:for-each>
+    <hr/>
+    <xsl:for-each select="document-description">
+      Elapsed time: <xsl:value-of select="performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/xsl/archimedes-image-fragment.xsl?_source=yes">XSL source</a> of this page
+    </xsl:for-each>    
+  </body></html>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-text-fragment.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,281 @@
+<xsl:stylesheet version="1.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<xsl:output method="html"/>
+
+<xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+<xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($ftQueryName) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <!-- Because there are  problems in recognizing words (in mode word) this fake mode is used (same as phrase mode)  -->
+  <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryValue">
+  <xsl:choose>
+  <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number(number)"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
+      <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
+      <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
+      <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
+      <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
+      <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
+      <form action="" method="get"></form>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="70%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          [Text] 
+          [<a href="?{$imageLink}">Image</a>]
+          [<a href="?{$xmlLink}">XML</a>] 
+        </td>
+        <td valign="right" nowrap="true">
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &gt; 1">
+                <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeTextValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$textLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+          </td>
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &lt; $countPages">
+                <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeTextValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$textLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <input type="hidden" name="document" value="{$documentName}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/>
+            <input type="hidden" name="mode" value="text"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>
+      <table align="middle" width="100%">
+        <colgroup>
+          <col width="70%"/>
+          <col width="30%"/>
+        </colgroup>
+        <tr>
+          <td align="left" valign="top">
+            <xsl:for-each select="content">
+              <xsl:apply-templates/>
+            </xsl:for-each>
+          </td>
+          <xsl:if test="$ftQueryValue!=''">
+          <td align="left" valign="top">
+            <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
+            <ol>
+              <xsl:for-each select="/result/ft-query/result/hits/hit">
+              <li>
+                <xsl:variable name="hitPN" select="pn"/>
+                <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeTextValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>
+              </li>
+              </xsl:for-each>
+            </ol>
+          </td>
+          </xsl:if>
+        </tr>
+      </table>
+      <hr/>
+      Elapsed time:  <xsl:value-of select="/result/document-description/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/xsl/archimedes-text-fragment.xsl?_source=yes">XSL source</a> of this page
+      <br/>
+      [<a href="page-query-result.xql?{$textLink}">fast mechanism (file system search)</a>] [<a href="page-query-result-old.xql?{$textLink}">slower mechanism (XQL search)</a>]
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+<xsl:template match="chap|p">
+  <p><xsl:apply-templates/></p>
+</xsl:template>
+
+<xsl:template match="lb">
+  <br/>
+</xsl:template>
+
+<xsl:template match="expan">
+  <xsl:apply-templates/><xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:variable name="firstFigurePosition" select="/result/page/firstFigurePosition"/>
+
+<xsl:template match="figure">
+  <xsl:variable name="figurePos" select="count(preceding::figure)"/>
+  <xsl:variable name="figureId" select="$firstFigurePosition + $figurePos"/>
+  <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+  <!-- delivers all fileds from 021/01/001/1.jpg -->
+  <xsl:variable name="figureLink" select="@xlink:href"/>
+  <xsl:variable name="docId" select="substring-before($figureLink, '/')"/>
+  <xsl:variable name="figureLinkAfter1" select="substring-after($figureLink, '/')"/>
+  <xsl:variable name="docId2" select="substring-before($figureLinkAfter1, '/')"/>
+  <xsl:variable name="figureLinkAfter2" select="substring-after($figureLinkAfter1, '/')"/>
+  <xsl:variable name="page" select="substring-before($figureLinkAfter2, '/')"/>
+  <xsl:variable name="figureFileName" select="substring-after($figureLinkAfter2, '/')"/>
+  <p></p>
+  <a href="http://echo.mpiwg-berlin.mpg.de/zogilib?fn=/permanent/archimedes/{$documentName}/{$docId}-{$docId2}-figures&amp;pn={$figureId}"><img alt="figure: {$figureId}" src="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn=/permanent/archimedes/{$documentName}/{$docId}-{$docId2}-figures&amp;pn={$figureId}&amp;dh=150" align="middle" border="1"/></a>
+  <p></p>
+  Figure: <xsl:value-of select="$figureId"/>
+  <p></p>
+</xsl:template>
+
+<!-- Highlight all term occurrences for the fulltext query. It recognizes all text nodes and then does the highlighting -->
+<xsl:template match="text()">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <xsl:variable name="queryExpr" select="$ftQueryName"/>
+    <xsl:call-template name="highlightQueryTerms">
+    <xsl:with-param name="elemTextContent" select="."/>
+    <xsl:with-param name="queryExprStr" select="$queryExpr"/>
+    <xsl:with-param name="mode" select="$ftQueryMode"/>
+    </xsl:call-template>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Highlight term occurrences in one text node. It recognizes the first occorrence in a text node and then does 
+this template recursive with the first substring before the first term cut off -->
+<xsl:template name="highlightQueryTerms">
+  <xsl:param name="elemTextContent"/>
+  <xsl:param name="queryExprStr"/>
+  <xsl:param name="mode"/>
+  <!-- Translation from Lucene fulltext query to text query  -->  
+  <xsl:variable name="textQuery">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="substring-before(substring-after($queryExprStr, '&quot;'), '&quot;')"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'fakeWord'">
+      <xsl:value-of select="$queryExprStr"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="$queryExprStr"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Word delimiter -->
+  <xsl:variable name="wordDelimRegExpr" select="'[\s,:\.^ ]+'"/>  
+  <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
+  <xsl:variable name="queryRegExprSubstringBefore">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="concat('^.*?', $textQuery)"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'fakeWord'">
+      <xsl:value-of select="concat('^.*?', $textQuery)"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, $textQuery, '(',  $wordDelimRegExpr, ')')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Recognizes the substring after the query term -->
+  <xsl:variable name="queryRegExprSubstringAfter">
+    <xsl:choose>
+    <xsl:when test="$mode = 'phrase'">
+      <xsl:value-of select="concat($textQuery, '.*')"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'fakeWord'">
+      <xsl:value-of select="concat($textQuery, '.*')"/>
+    </xsl:when>
+    <xsl:when test="$mode = 'word'">
+      <xsl:value-of select="concat('(', $wordDelimRegExpr, ')', $textQuery, $wordDelimRegExpr, '.*')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Deletes the substring up to the query term -->
+  <xsl:variable name="substringBefore" select="replace($elemTextContent, $queryRegExprSubstringAfter, '$1', 'i')"/>
+  <!-- Deletes the substring after the query term -->
+  <xsl:variable name="substringAfter" select="replace($elemTextContent, $queryRegExprSubstringBefore, '$1', 'i')"/>
+  <xsl:choose>
+    <xsl:when test="matches($elemTextContent, $queryRegExprSubstringBefore, 'i')">
+      <!-- Prints the original part of the substring up to the first occurrence of the query term -->
+      <xsl:value-of select="$substringBefore"/>
+      <!-- Highlight the query term -->
+      <xsl:variable name="matchQueryTermRegExpr">
+        <xsl:choose>
+        <xsl:when test="$mode = 'phrase'">
+          <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+        </xsl:when>
+        <xsl:when test="$mode = 'fakeWord'">
+          <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+        </xsl:when>
+        <xsl:when test="$mode = 'word'">
+          <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, '(', $textQuery, ')', $wordDelimRegExpr, '.*')"/>
+        </xsl:when>
+        <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="matchQueryTerm" select="replace($elemTextContent, $matchQueryTermRegExpr, '$1', 'i')"/>
+      <span style="background-color: yellow;">
+        <xsl:value-of select="$matchQueryTerm"/>
+      </span>
+      <!-- Recursive call of this template with the substring after the first occurrence of the term: further occurrences of the query 
+      term  -->
+      <xsl:call-template name="highlightQueryTerms">
+        <xsl:with-param name="elemTextContent" select="$substringAfter"/>
+        <xsl:with-param name="queryExprStr" select="$queryExprStr"/>
+        <xsl:with-param name="mode" select="$mode"/>
+      </xsl:call-template>
+    </xsl:when>
+    <!-- if no occurrence of the query term could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:value-of select="$elemTextContent"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-xml-fragment.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,311 @@
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:functx="http://www.functx.com"
+ xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text">
+
+<xsl:output method="html"/>
+
+<!-- siehe unter http://www.xsltfunctions.com     -->
+<xsl:function name="functx:contains-any-of" as="xs:boolean">
+  <xsl:param name="arg" as="xs:string?"/> 
+  <xsl:param name="searchStrings" as="xs:string*"/> 
+  <xsl:sequence select="some $searchString in $searchStrings satisfies contains($arg,$searchString)"/>
+</xsl:function>
+
+<!-- Highlight all term occurrences for the fulltext query. It recognizes the first occorrence and then does 
+this function recursive with the first substring before the first term cut off.
+Result is a sequence of text and highlight nodes:
+Example:
+LE<lb></lb>
+<span ...>MECHANICHE</span>
+...<lb></lb>
+...<lb></lb>
+<span ...>MECHANICHE</span>
+...<lb></lb>
+...<lb></lb>
+...
+ -->
+<xsl:function name="text:highlight">
+  <xsl:param name="inputString" />
+  <xsl:param name="luceneQuery" as="xs:string" />
+  <xsl:param name="mode" as="xs:string" />
+  <!-- Translation from Lucene fulltext query to text query  -->  
+  <xsl:variable name="textQuery">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="substring-before(substring-after($luceneQuery, '&quot;'), '&quot;')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="$luceneQuery"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="$luceneQuery"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Word delimiter: not tested yet -->
+  <xsl:variable name="wordDelimRegExpr" select="'[\s\(\)\[\]\.\\\{\}\$\^\+\?\!\* §%:,;=/]+'"/>   <!-- TODO: bol, eol, ", &, <, >    --> 
+  <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
+  <xsl:variable name="queryRegExprSubstringBefore">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="concat('^.*?', $textQuery)"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="concat('^.*?', $textQuery)"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, $textQuery, '(',  $wordDelimRegExpr, ')')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Recognizes the substring after the query term -->
+  <xsl:variable name="queryRegExprSubstringAfter">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="concat($textQuery, '.*')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="concat($textQuery, '.*')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="concat('(', $wordDelimRegExpr, ')', $textQuery, $wordDelimRegExpr, '.*')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Deletes the substring up to the query term -->
+  <xsl:variable name="substringBefore" select="replace($inputString, $queryRegExprSubstringAfter, '$1', 'i')"/>
+  <!-- Deletes the substring after the query term -->
+  <xsl:variable name="substringAfter" select="replace($inputString, $queryRegExprSubstringBefore, '$1', 'i')"/>
+  <xsl:choose>
+    <xsl:when test="matches($inputString, $queryRegExprSubstringBefore, 'i')">
+      <!-- Prints the original part of the substring up to the first occurrence of the query term -->
+      <xsl:value-of select="$substringBefore"/>
+      <!-- Highlight the query term -->
+      <xsl:variable name="matchQueryTermRegExpr">
+        <xsl:choose>
+          <xsl:when test="$mode = 'phrase'">
+            <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+          </xsl:when>
+          <xsl:when test="$mode = 'fakeWord'">
+            <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+          </xsl:when>
+          <xsl:when test="$mode = 'word'">
+            <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, '(', $textQuery, ')', $wordDelimRegExpr, '.*')"/>
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="matchQueryTerm" select="replace($inputString, $matchQueryTermRegExpr, '$1', 'i')"/>
+      <span style="background-color: yellow;">
+        <xsl:value-of select="$matchQueryTerm"/>
+      </span>
+      <!-- Recursive call of this function with the substring after the first occurrence of the term: further occurrences of the query 
+      term  -->
+      <xsl:sequence select="text:highlight($substringAfter, $luceneQuery, $mode)"/>
+    </xsl:when>
+    <!-- if no occurrence of the query term could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:value-of select="$inputString"/>
+      </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!--
+<xsl:function name="text:limitHighligthedString">
+  <xsl:param name="inputString" />
+  <xsl:param name="countChar" as="xs:integer"/>
+  <xsl:variable name="substringBeforeHighlight" select="substring-before($inputString, '&lt;span')"/>
+  <xsl:variable name="substringAfterHighlight" select="substring-after($inputString, '&lt;span&gt;>')"/>
+  <xsl:variable name="result">
+  ... <xsl:value-of select="substring($substringBeforeHighlight, string-length($substringBeforeHighlight) - $countChar)"/><span style="background-color: yellow;"><xsl:value-of select="' BlaBla '"/></span><xsl:value-of select="substring($substringAfterHighlight, 0, $countChar)"/> ...
+  </xsl:variable>
+  <xsl:sequence select="$result"/>
+</xsl:function>
+-->
+
+<xsl:function name="text:limitHighligthedString">
+  <xsl:param name="inputSequence" as="node()*"/>
+  <xsl:param name="countChar" as="xs:integer"/>
+  <xsl:variable name="before" select="$inputSequence[1]"/>
+  <xsl:variable name="beforeLimited" select="substring($before, string-length($before) - $countChar)"/>  
+  <xsl:variable name="firstSpan" select="$inputSequence[2]"/>
+  <xsl:variable name="after" select="$inputSequence[position() > 2]"/>
+  <xsl:variable name="afterLimited" select="substring($after, 0, $countChar)"/>  
+  <xsl:variable name="result">
+  ... <xsl:sequence select="$before"/><xsl:sequence select="$firstSpan"/><xsl:sequence select="$after"/> ...
+  </xsl:variable>
+  <xsl:sequence select="$result"/>
+</xsl:function>
+
+<xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+<xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($ftQueryName) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <!-- Because there are  problems in recognizing words (in mode word) this fake mode is used (same as phrase mode)  -->
+  <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryValue">
+  <xsl:choose>
+  <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:variable name="ft-query-name" select="/result/ft-query/name"/>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <form action="" method="get"></form>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number(number)"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
+      <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
+      <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
+      <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
+      <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
+      <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="70%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          [<a href="?{$textLink}">Text</a>] 
+          [<a href="?{$imageLink}">Image</a>]
+          [XML] 
+        </td>
+        <td align="right" nowrap="true">
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &gt; 1">
+                <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+          </td>
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &lt; $countPages">
+                <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <input type="hidden" name="document" value="{$documentName}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/> 
+            <input type="hidden" name="mode" value="xml"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>   
+      <table align="middle" width="100%">
+        <colgroup>
+          <col width="70%"/>
+          <col width="30%"/>
+        </colgroup>
+        <tr>
+          <td align="left" valign="top">
+            <xsl:for-each select="content">
+              <xsl:apply-templates/>
+            </xsl:for-each>
+          </td>
+          <xsl:if test="$ftQueryValue!=''">
+          <td align="left" valign="top">
+            <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
+            <ol>
+              <xsl:for-each select="/result/ft-query/result/hits/hit">
+              <li>
+                <xsl:variable name="hitPN" select="pn"/>
+                <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeXmlValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>:<br></br>
+                <!-- Highlight the query terms in each hit  -->
+                <xsl:variable name="highlightedSentenceSeq" select="text:highlight(s, $ftQueryName, $ftQueryMode)"/>
+                <xsl:sequence select="text:limitHighligthedString($highlightedSentenceSeq, 100)"/>
+              </li>
+              </xsl:for-each>
+            </ol>
+          </td>
+          </xsl:if>
+        </tr>
+      </table>
+      <hr/>
+      Elapsed time:  <xsl:value-of select="/result/document-description/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/xsl/archimedes-xml-fragment.xsl?_source=yes">XSL source</a> of this page
+      <br/>
+      [<a href="page-query-result.xql?{$xmlLink}">fast mechanism (file system search)</a>] [<a href="page-query-result-old.xql?{$xmlLink}">slower mechanism (XQL search)</a>]
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|text()|comment()|processing-instruction()">
+  <xsl:variable name="elementName" select="name()"/>
+  <span style="color: brown;">&lt;<xsl:value-of select="$elementName"/><xsl:apply-templates select="attribute()"/>&gt;</span>
+    <xsl:apply-templates select="element()|text()|comment()|processing-instruction()"/>
+  <span style="color: brown;">&lt;/<xsl:value-of select="$elementName"/>&gt;</span>
+  <br/>
+</xsl:template>
+
+<xsl:template match="attribute()">
+  <xsl:variable name="attributeName" select="name()"/>
+  <xsl:text> </xsl:text><xsl:value-of select="$attributeName"/>=<xsl:value-of select="."/>
+    <xsl:apply-templates select="attribute()"/>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences for the fulltext query else show the text -->
+<xsl:template match="text()">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <xsl:sequence select="text:highlight(., $ftQueryName, $ftQueryMode)"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/book-pointer.gif has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/image.jpg has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/imageU.jpg has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/left.gif has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/right.gif has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/text.jpg has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/textU.jpg has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/xml.jpg has changed
Binary file software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/images/xmlU.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/lucene/search.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,40 @@
+xquery version "1.0";
+
+module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search"; 
+
+declare namespace ft = "http://exist-db.org/xquery/lucene";
+
+declare function mpdl-lucene:search($docPath, $ftQuery) as node() {
+  let $document := doc($docPath)
+  (: performance reasons: all hits (not only the first 10! ) are passed through the :)
+  (: for loop: so the overhead in each loop has to be minimized :)
+  let $t := $document//s[ft:query(., $ftQuery)]
+  let $tempQueryResult := 
+    for $ss at $poss in $t
+    (: where $poss > 100 and $poss <= 200  :)
+    return $ss
+  let $queryResult :=
+    for $s at $pos in $tempQueryResult
+      let $pnOfS := count($document//pb[. << $s])    (: faster: comparison only in pb elements of this document :)
+      let $posOfS := count($document//pb[$pnOfS]/following::s[. << $s]) + 1    (: faster: comparisonon only in s elements of this document :)
+      let $resultElem := 
+        <hit>
+          <pos>{$pos}</pos>
+          <pn>{$pnOfS}</pn>
+          <pos-of-s>{$posOfS}</pos-of-s>
+          {$s}
+        </hit>
+    return $resultElem
+  let $resultSize := count($queryResult)
+  let $result := 
+        <ft-query>
+          <name>{$ftQuery}</name>
+          <result>
+            <size>{$resultSize}</size>
+            <hits>
+              {$queryResult}
+            </hits>
+          </result>
+        </ft-query>  
+   return $result
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/monte-page1.xml	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<result xmlns:xlink="http://www.w3.org/1999/xlink">
+  <document-description>
+    <document-name>monte_mecha_037_it_1581</document-name>
+    <author>Monte, Guidobaldo del</author>
+    <title>Le Mechaniche</title>
+    <date>1581</date>
+    <place>Venezia</place>
+    <translator>Pigafetta, Filippo</translator>
+    <lang>it</lang>
+    <cvs_file>monte_mecha_037_it_1581.xml</cvs_file>
+    <cvs_version>2643.17</cvs_version>
+    <locator>037.xml</locator>
+    <count-pages>270</count-pages>
+    <performance>112</performance>
+  </document-description>
+  <page>
+    <number>1</number>
+    <image>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/digilib.jsp?fn=/permanent/archimedes/monte_mecha_037_it_1581/037-01-pageimg&amp;pn=1</image>
+    <image-echo>http://echo.mpiwg-berlin.mpg.de/zogilib?fn=/permanent/archimedes/monte_mecha_037_it_1581/037-01-pageimg&amp;pn=1</image-echo>
+    <image-scaler>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn=/permanent/archimedes/monte_mecha_037_it_1581/037-01-pageimg&amp;pn=1</image-scaler>
+    <xml-url>?document=monte_mecha_037_it_1581&amp;pn=1&amp;mode=xml</xml-url>
+    <firstFigurePosition>1</firstFigurePosition>
+    <content>
+      <archimedes> <text id="id.0.0.0.0.3"> <pb id="p.0001">  </pb>
+      <front id="id.1.0.0.0.0"> <section> <p id="id.2.1.2.0.0" type="head"> <s id="id.2.1.2.1.0">LE <lb> </lb>
+      MECHANICHE <lb> </lb>
+      DELL'ILLVSTRISS SIG. <lb> </lb>
+      GVIDO VBALDO <lb> </lb>
+      DE' MARCHESI DEL <lb> </lb>
+      MONTE: <lb> </lb>
+      </s>
+      <s id="id.2.1.3.1.0">TRADOTTE IN VOLGARE <lb> </lb>
+      DAL SIG. FILIPPO PIGAFETTA: <lb> </lb>
+      Nellequali Å¿i contiene la vera Dottrina di tutti gli IÅ¿trumenti <lb> </lb>
+      principali da mouer peſi grandisſimi con <lb> </lb>
+      picciola forza. <lb> </lb>
+      </s>
+      <s id="id.2.1.4.1.0"> <emph type="italics"> </emph>
+        A beneficio di chi ſi diletta di queſta nobiliſſima scienza; &amp; maſſimamente <lb> </lb>
+        di Capitani di guerra, Ingegnieri, Architetti, &amp; d'ogni <lb> </lb>
+      Artefice, che intenda per via di Machine <lb> </lb>
+      far opre marauiglioſe, e quaſi <lb> </lb>
+      Å¿opra naturali. <emph.end type="italics"> </emph.end>
+      <lb> </lb>
+      </s>
+        <s id="id.2.1.5.1.0">Et ſi dichiarano i vocaboli, &amp; luoghi più difficili. <lb> </lb>
+      </s>
+        <figure id="id.037.01.001.1.jpg" xlink:href="037/01/001/1.jpg"> </figure>
+      <s id="id.2.1.7.1.0"> <emph type="italics"> </emph>
+      In Venetia, Appreſſo Franceſco di Franceſchi Saneſe. </s>
+      <s id="id.2.1.7.2.0">MD LXXXI. <emph.end type="italics"> </emph.end>
+      </s>
+      </p>
+      </section>
+      </front>
+      </text>
+      </archimedes>       
+    </content>
+  </page>
+  <ft-query>
+    <name>Mechaniche</name>
+    <result>
+      <size>2</size>
+      <hits>
+        <hit>
+          <pos>1</pos>
+          <pn>1</pn>
+          <pos-of-s>1</pos-of-s>
+          <s id="id.2.1.2.1.0">LE <lb> </lb>
+            MECHANICHE <lb> </lb>
+            DELL'ILLVSTRISS SIG. <lb> </lb>
+            GVIDO VBALDO <lb> </lb>
+            DE' MARCHESI DEL <lb> </lb>
+            MONTE: <lb> </lb>
+          </s>
+        </hit>
+        <hit>
+          <pos>2</pos>
+          <pn>1</pn>
+          <pos-of-s>3</pos-of-s>
+            <s id="id.2.1.4.1.0"> <emph type="italics"> </emph>
+              A beneficio di chi ſi diletta di queſta nobiliſſima scienza; &amp; maſſimamente <lb> </lb>
+              di Capitani di guerra, Ingegnieri, Architetti, &amp; d'ogni <lb> </lb>
+              Artefice, che intenda per via di Machine <lb> </lb>
+              far opre marauiglioſe, e quaſi <lb> </lb>
+              Å¿opra naturali. <emph.end type="italics"> </emph.end>
+              <lb> </lb>
+            </s>
+        </hit>
+      </hits>
+    </result>
+  </ft-query>  
+</result>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/monte-page1.xpr	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+    <meta>
+        <filters directoryPatterns="" filePatterns=""
+            positiveFilePatterns="" showHiddenFiles="false"/>
+        <options/>
+    </meta>
+    <projectTree name="monte-page1.xpr">
+        <file name="monte-page1.xml"/>
+        <file name="page.xsl"/>
+    </projectTree>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page-query-result.xquery	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,88 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "util/time.xquery";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "lucene/search.xquery";
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "text/all.xquery";
+
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace transform = "http://exist-db.org/xquery/transform";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+
+let $document := request:get-parameter("document", "agric_remet_001_la_1556")
+let $mode := request:get-parameter("mode", "image")
+let $pn := number(request:get-parameter("pn", "1"))
+let $ftQuery := request:get-parameter("ft-query", "")
+let $indexTermsStartStr := request:get-parameter("index-terms-start-str", "")
+
+let $currentTimeBegin := util:system-time()
+let $docPath := concat("/db/archimedes/", $document, ".xml")
+let $docRoot := doc($docPath)
+let $archimedesInfo := $docRoot/archimedes/info
+let $locator := $archimedesInfo/locator
+let $countPages := count($docRoot//pb)
+let $pb1 := $docRoot//pb[$pn]
+let $positionOfFirstFigureAfterPB1 := count($pb1/following::figure[1]/preceding::figure) + 1  (: position der ersten figure nach pb1   :)
+let $pb1ImageRefLeft := substring-before($locator, ".")
+let $pb1ImageRefRight := "01"
+let $pb2 := $docRoot//pb[$pn + 1]
+let $errorCode := 
+  if ($pn < $countPages + 1 and $pn > 0)
+  then 0
+  else 1
+
+let $retPageFragment := 
+  if ($mode = "image" or $errorCode > 0)
+  then ()
+  else util:get-fragment-between($pb1, $pb2, true())
+
+let $returnPageFragment := util:parse($retPageFragment)  (: string2xml: returns a valid xml document for that string   :)
+
+let $ftHits := 
+  if ($ftQuery = "")
+  then ()
+  else mpdl-lucene:search($docPath, $ftQuery)
+
+let $indexTerms :=
+  if($indexTermsStartStr = "")
+  then ()
+  else mpdl-text:indexTerms($docRoot, $indexTermsStartStr, 100)
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode = 0)
+  then 
+    <result>
+    <mode>{$mode}</mode>
+    <document-description>
+      <document-name>{$document}</document-name>
+      {$archimedesInfo}
+      <count-pages>{$countPages}</count-pages>
+      <performance>{$neededTime}</performance>
+    </document-description>
+    <page>
+      <number>{$pn}</number>
+      <image>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/digilib.jsp?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image>
+      <image-echo>http://echo.mpiwg-berlin.mpg.de/zogilib?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image-echo>
+      <image-scaler>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image-scaler>
+      <xml-url>?document={$document}&amp;pn={$pn}&amp;mode=xml</xml-url>
+      <firstFigurePosition>{$positionOfFirstFigureAfterPB1}</firstFigurePosition>
+      <content>{$returnPageFragment}</content>
+    </page>
+    {$ftHits}
+    {$indexTerms}
+    </result>
+  else if ($errorCode = 1)
+  then <error>No result: Page {$pn} not found</error>
+  else <error>undefined error: {$errorCode}</error>  
+
+let $declare := 
+  if ($mode = "text" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=UTF-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=UTF-8")
+
+let $result := transform:transform($xmlResult, doc("/db/xsl/archimedes-page-fragment.xsl"), ())
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page-query-result.xquery.old.xquery	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,151 @@
+xquery version "1.0";
+
+module namespace ft="http://exist-db.org/xquery/lucene";
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace text="http://exist-db.org/xquery/text";
+declare namespace transform="http://exist-db.org/xquery/transform";
+declare namespace util="http://exist-db.org/xquery/util";
+declare namespace docc = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/docc"; 
+declare namespace time-util = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/time-util"; 
+
+declare function time-util:duration-as-ms($t) {
+  round((minutes-from-duration($t) * 60 + seconds-from-duration($t)) * 1000 )
+};
+
+declare function docc:ft-search($docPath, $ftQuery) as node() {
+  let $document := doc($docPath)
+  (: performance reasons: all hits (not only the first 10! ) are passed through the :)
+  (: for loop: so the overhead in each loop has to be minimized :)
+  let $t := $document//s[ft:query(., $ftQuery)]
+  let $tempQueryResult := 
+    for $ss at $poss in $t
+    (: where $poss > 100 and $poss <= 200  :)
+    return $ss
+  let $queryResult :=
+    for $s at $pos in $tempQueryResult
+      let $pnOfS := count($document//pb[. << $s])    (: faster: comparison only in pb elements of this document :)
+      let $posOfS := count($document//pb[$pnOfS]/following::s[. << $s]) + 1    (: faster: comparisonon only in s elements of this document :)
+      let $resultElem := 
+        <hit>
+          <pos>{$pos}</pos>
+          <pn>{$pnOfS}</pn>
+          <pos-of-s>{$posOfS}</pos-of-s>
+          {$s}
+        </hit>
+    return $resultElem
+  let $resultSize := count($queryResult)
+  let $result := 
+        <ft-query>
+          <name>{$ftQuery}</name>
+          <result>
+            <size>{$resultSize}</size>
+            <hits>
+              {$queryResult}
+            </hits>
+          </result>
+        </ft-query>  
+   return $result
+};
+
+declare function docc:termEntries($term as xs:string, $data as xs:int+) {
+  let $result := 
+    <entry>  
+       <term>{$term}</term>  
+       <frequency>{$data[1]}</frequency>  
+       <documents>{$data[2]}</documents>  
+       <position>{$data[3]}</position>  
+       <rank>{$data[4]}</rank>  
+     </entry>  
+  return $result
+};
+
+declare function docc:indexTerms($document, $indexTermsStartStr, $count) as node()* {
+  let $docName := util:document-name($document)
+  let $index := /archimedes/info/cvs_file[contains(., $docName)]/root()/archimedes/text
+  let $callback := util:function(QName("http://www.mpiwg-berlin.mpg.de/ns/mpdl/docc", "docc:termEntries"), 2)
+  let $result := text:index-terms($index, $indexTermsStartStr, $callback, $count)
+  return 
+    <index-terms>
+    <start-string>{$indexTermsStartStr}</start-string>
+    {$result}
+    </index-terms>
+};
+
+
+let $document := request:get-parameter("document", "agric_remet_001_la_1556")
+let $mode := request:get-parameter("mode", "image")
+let $pn := number(request:get-parameter("pn", "1"))
+let $ftQuery := request:get-parameter("ft-query", "")
+let $indexTermsStartStr := request:get-parameter("index-terms-start-str", "")
+
+let $currentTimeBegin := util:system-time()
+let $docPath := concat("/db/archimedes/", $document, ".xml")
+let $docRoot := doc($docPath)
+let $archimedesInfo := $docRoot/archimedes/info
+let $locator := $archimedesInfo/locator
+let $countPages := count($docRoot//pb)
+let $pb1 := $docRoot//pb[$pn]
+let $positionOfFirstFigureAfterPB1 := count($pb1/following::figure[1]/preceding::figure) + 1  (: position der ersten figure nach pb1   :)
+let $pb1ImageRefLeft := substring-before($locator, ".")
+let $pb1ImageRefRight := "01"
+let $pb2 := $docRoot//pb[$pn + 1]
+let $errorCode := 
+  if ($pn < $countPages + 1 and $pn > 0)
+  then 0
+  else 1
+
+let $retPageFragment := 
+  if ($mode = "image" or $errorCode > 0)
+  then ()
+  else util:get-fragment-between($pb1, $pb2, true())
+
+let $returnPageFragment := util:parse($retPageFragment)  (: string2xml: returns a valid xml document for that string   :)
+
+let $ftHits := 
+  if ($ftQuery = "")
+  then ()
+  else docc:ft-search($docPath, $ftQuery)
+
+let $indexTerms :=
+  if($indexTermsStartStr = "")
+  then ()
+  else docc:indexTerms($docRoot, $indexTermsStartStr, 100)
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := time-util:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode = 0)
+  then 
+    <result>
+    <mode>{$mode}</mode>
+    <document-description>
+      <document-name>{$document}</document-name>
+      {$archimedesInfo}
+      <count-pages>{$countPages}</count-pages>
+      <performance>{$neededTime}</performance>
+    </document-description>
+    <page>
+      <number>{$pn}</number>
+      <image>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/digilib.jsp?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image>
+      <image-echo>http://echo.mpiwg-berlin.mpg.de/zogilib?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image-echo>
+      <image-scaler>http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn=/permanent/archimedes/{$document}/{$pb1ImageRefLeft}-{$pb1ImageRefRight}-pageimg&amp;pn={$pn}</image-scaler>
+      <xml-url>?document={$document}&amp;pn={$pn}&amp;mode=xml</xml-url>
+      <firstFigurePosition>{$positionOfFirstFigureAfterPB1}</firstFigurePosition>
+      <content>{$returnPageFragment}</content>
+    </page>
+    {$ftHits}
+    {$indexTerms}
+    </result>
+  else if ($errorCode = 1)
+  then <error>No result: Page {$pn} not found</error>
+  else <error>undefined error: {$errorCode}</error>  
+
+let $declare := 
+  if ($mode = "text" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=UTF-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=UTF-8")
+
+let $result := transform:transform($xmlResult, doc("/db/xsl/archimedes-page-fragment.xsl"), ())
+
+return $result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/page.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,532 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:functx="http://www.functx.com"
+ xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text">
+
+<xsl:output method="html" encoding="utf-8"/>
+
+<!-- see http://www.xsltfunctions.com     -->
+<xsl:function name="functx:contains-any-of" as="xs:boolean">
+  <xsl:param name="arg" as="xs:string?"/> 
+  <xsl:param name="searchStrings" as="xs:string*"/> 
+  <xsl:sequence select="some $searchString in $searchStrings satisfies contains($arg, $searchString)"/>
+</xsl:function>
+
+ <xsl:function name="text:nchars">
+   <xsl:param name="count" as="xs:integer"/>
+   <xsl:param name="char" as="xs:string"/>
+   <xsl:sequence select="if ($count > 0) then concat($char, text:nchars($count - 1, $char)) else $char"/>
+ </xsl:function>
+  
+ <xsl:function name="text:cutStringBefore">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:if test="$length &gt; $cutLength"> (...)</xsl:if>
+  <xsl:value-of select="substring($inputString, $length - $cutLength)"/>  
+</xsl:function>
+
+<xsl:function name="text:cutStringAfter">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:value-of select="substring($inputString, 0, $cutLength)"/>  
+  <xsl:if test="$length &gt; $cutLength">(...) </xsl:if>
+</xsl:function>
+
+
+<!-- Highlight all term occurrences for the Lucene query. 
+Result is a sequence of text and highlighted nodes (with span):
+Example: LE<span ...>MECHANICHE</span>...<span ...>Mechaniche</span>... 
+-->
+<xsl:function name="text:highlight">
+  <xsl:param name="inputStr" as="xs:string" />
+  <xsl:param name="luceneQuery" as="xs:string" />
+  <xsl:param name="clipped" as="xs:string" />
+  <xsl:variable name="terms" select="text:translateLuceneToTerms($luceneQuery)" as="xs:string*"/>
+  <xsl:sequence select="text:highlightTerms($inputStr, $terms, $clipped)" />
+</xsl:function>
+
+
+<!-- Translation of Lucene query to a sequence of terms  -->  
+<xsl:function name="text:translateLuceneToTerms">
+  <xsl:param name="luceneQuery" as="xs:string" />
+  <!-- Escape special chars; Lucene special chars are not handled here: *?-+  -->
+  <xsl:variable name="luceneQueryEscaped" select="replace($luceneQuery, '[.^${}()|\[\]\\]', '\\$0')" /> 
+  <xsl:variable name="luceneQueryWithoutSpaces" select="normalize-space($luceneQueryEscaped)" />
+  <xsl:choose>
+    <!-- phrase  -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('&quot;', '.*', '&quot;'))">
+      <xsl:variable name="queryWithoutQuotes" select="substring-before(substring-after($luceneQueryEscaped, '&quot;'), '&quot;')"/>
+      <xsl:variable name="escapeLuceneChars" select="replace($queryWithoutQuotes, '[*+?]', '\\$0')"/>
+      <xsl:sequence select="$escapeLuceneChars"/>
+    </xsl:when>
+    <!-- single word without star and without quotations -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('^[^', '&quot;' , '*]*$'))">
+      <xsl:sequence select="$luceneQueryEscaped"/>
+    </xsl:when>
+    <!-- single word with star and without quotations -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('^[^', '&quot;' , ']*\*$'))">
+      <xsl:sequence select="substring-before($luceneQueryEscaped, '*')"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:sequence select="''"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:translateLuceneToTermsOld">
+  <xsl:param name="luceneQuery" as="xs:string" />
+  <xsl:variable name="luceneQueryEscaped" select="replace($luceneQuery, '[.^${}()|\[\]\\]', '\\$0')" /> <!-- without *?-+  -->
+  <xsl:variable name="luceneQueryWithoutSpaces" select="normalize-space($luceneQueryEscaped)" />
+  <xsl:choose>
+    <!-- phrase  -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('&quot;', '.*', '&quot;'))">
+      <xsl:variable name="queryWithoutQuotes" select="substring-before(substring-after($luceneQueryEscaped, '&quot;'), '&quot;')"/>
+      <xsl:variable name="escapeLuceneChars" select="replace($queryWithoutQuotes, '[*+?]', '\\$0')"/>
+      <xsl:value-of select="$escapeLuceneChars"/>
+    </xsl:when>
+    <!-- single word without star and without quotations -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('^[^', '&quot;' , '*]*$'))">
+      <xsl:value-of select="$luceneQueryEscaped"/>
+    </xsl:when>
+    <!-- single word with star and without quotations -->
+    <xsl:when test="matches($luceneQueryEscaped, concat('^[^', '&quot;' , ']*\*$'))">
+      <xsl:value-of select="substring-before($luceneQueryEscaped, '*')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:highlightTerms">
+  <xsl:param name="inputStr" as="xs:string" />
+  <xsl:param name="terms" as="xs:string*" />
+  <xsl:param name="clipped" as="xs:string" />
+  <xsl:variable name="term" select="$terms[1]"/>
+  <xsl:variable name="inputString" select="replace($inputStr, '\n', '')"/>
+  <!-- Word delimiter: not tested yet -->
+  <xsl:variable name="wordDelimRegExpr" select="'[\s\(\)\[\]\.\\\{\}\$\^\+\?\!\* §%:,;=/]+'"/>   <!-- TODO: bol, eol, ", &, <, >    --> 
+  <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
+  <xsl:variable name="queryRegExprSubstringBefore">
+    <xsl:value-of select="concat('^.*?', $term)"/>
+  </xsl:variable>
+  <!-- Recognizes the substring after the query term -->
+  <xsl:variable name="queryRegExprSubstringAfter">
+    <xsl:value-of select="concat($term, '.*')"/>
+  </xsl:variable>
+  <!-- Recognizes the query term -->
+  <xsl:variable name="matchQueryTermRegExpr">
+    <xsl:value-of select="concat('^.*?', '(', $term, ')', '.*')"/>
+  </xsl:variable>
+  <!-- Deletes the substring up to the query term -->
+  <xsl:variable name="substringBefore" select="replace($inputString, $queryRegExprSubstringAfter, '$1', 'im')"/>
+  <!-- Deletes the substring after the query term -->
+  <xsl:variable name="substringAfter" select="replace($inputString, $queryRegExprSubstringBefore, '$1', 'im')"/>
+  <xsl:choose>
+    <xsl:when test="matches($inputString, $matchQueryTermRegExpr, 'im')">
+      <!-- Prints the original part of the substring up to the first occurrence of the query term -->
+      <xsl:choose>
+      <xsl:when test="$clipped='true'">
+        <xsl:value-of select="text:cutStringBefore($substringBefore, 70)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$substringBefore"/>
+      </xsl:otherwise>
+      </xsl:choose>
+      <!-- Highlight the query term -->
+      <xsl:variable name="matchQueryTerm" select="replace($inputString, $matchQueryTermRegExpr, '$1', 'im')"/>
+      <span style="background-color: #77DD77;"><!-- pastell green  -->
+        <xsl:value-of select="$matchQueryTerm"/>
+      </span>
+      <!-- Recursive call of this function with the substring after the first occurrence of the term: further occurrences of the query 
+      term  -->
+      <xsl:sequence select="text:highlight($substringAfter, $terms, $clipped)"/>
+    </xsl:when>
+    <!-- if no occurrence of the query term could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:choose>
+      <xsl:when test="$clipped='true'">
+        <xsl:value-of select="text:cutStringAfter($inputString, 70)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$inputString"/>
+      </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+
+
+
+
+
+
+
+<xsl:variable name="mode" select="/result/mode"/>
+<xsl:variable name="language" select="/result/document-description/info/lang"/>
+<xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+<xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($ftQueryName) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <!-- Because there are  problems in recognizing words (in mode word) this fake mode is used (same as phrase mode)  -->
+  <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryValue">
+  <xsl:choose>
+  <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="indexTermsStartStr" select="/result/index-terms/start-string"/>
+<xsl:variable name="indexTermsPN" select="/result/index-terms/pn"/>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentUri" select="/result/document-description/uri"/>
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number(number)"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentUri)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeValue" select="concat('mode=', $mode)"/>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="60%"/>
+          <col width="2%"/>
+          <col width="2%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          <form action="page-query-result.xql" method="get">
+          <input type="hidden" name="document" value="{$documentUri}"/>
+          <xsl:choose>
+          <xsl:when test="$mode = 'text'"><input type="image" src="images/text.jpg" name="mode" value="text"/></xsl:when>
+          <xsl:otherwise><input type="image" src="images/textU.jpg" name="mode" value="text"/></xsl:otherwise>
+          </xsl:choose>
+          <xsl:choose>
+          <xsl:when test="$mode = 'image'"><input type="image" src="images/image.jpg" name="mode" value="image"/></xsl:when>
+          <xsl:otherwise><input type="image" src="images/imageU.jpg" name="mode" value="image"/></xsl:otherwise>
+          </xsl:choose>
+          <xsl:choose>
+          <xsl:when test="$mode = 'xml'"><input type="image" src="images/xml.jpg" name="mode" value="xml"/></xsl:when>
+          <xsl:otherwise><input type="image" src="images/xmlU.jpg" name="mode" value="xml"/></xsl:otherwise>
+          </xsl:choose>
+          <input type="hidden" name="pn" value="{$number}"/>
+          <xsl:if test="/result/ft-query[node()]">
+            <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+          </xsl:if>
+          <xsl:if test="/result/index-terms[node()]">
+            <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+            <input type="hidden" name="index-terms-pn" value="{$indexTermsPN}"/>
+          </xsl:if>
+          </form>
+        </td>
+        <td></td>
+        <td align="right" nowrap="true">
+          <td nowrap="true">
+            <xsl:variable name="leftNumber">
+              <xsl:choose>
+              <xsl:when test="$number &gt; 1"><xsl:value-of select="$number - 1"/></xsl:when>
+              <xsl:otherwise><xsl:value-of select="$number"/></xsl:otherwise>
+              </xsl:choose>
+            </xsl:variable>
+            <form action="page-query-result.xql" method="get">
+            <input type="hidden" name="document" value="{$documentUri}"/>
+            <input type="image" src="images/left.gif" name="pn" value="{$leftNumber}"/> 
+            <input type="hidden" name="mode" value="{$mode}"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+            <xsl:if test="/result/index-terms[node()]">
+              <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+              <input type="hidden" name="index-terms-pn" value="{$indexTermsPN}"/>
+            </xsl:if>
+            </form>
+          </td>
+          <td nowrap="true">
+            <form action="" method="get">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+            </form>
+          </td>
+          <td nowrap="true">
+            <xsl:variable name="rightNumber">
+              <xsl:choose>
+              <xsl:when test="$number &lt; $countPages"><xsl:value-of select="$number + 1"/></xsl:when>
+              <xsl:otherwise><xsl:value-of select="$number"/></xsl:otherwise>
+              </xsl:choose>
+            </xsl:variable>
+            <form action="page-query-result.xql" method="get">
+            <input type="hidden" name="document" value="{$documentUri}"/>
+            <input type="image" src="images/right.gif" name="pn" value="{$rightNumber}"/> 
+            <input type="hidden" name="mode" value="{$mode}"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+            <xsl:if test="/result/index-terms[node()]">
+              <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+              <input type="hidden" name="index-terms-pn" value="{$indexTermsPN}"/>
+            </xsl:if>
+            </form>
+          </td>
+        </td>
+        <td align="right">
+          <td nowrap="true">
+            <form action="page-query-result.xql" method="get">
+            <input type="hidden" name="document" value="{$documentUri}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/> 
+            <input type="hidden" name="mode" value="{$mode}"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+            <xsl:if test="/result/index-terms[node()]">
+              <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+              <input type="hidden" name="index-terms-pn" value="{$indexTermsPN}"/>
+            </xsl:if>
+            </form>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>   
+      <xsl:variable name="tableContent">
+        <colgroup>
+          <col width="65%"/>
+          <col width="35%"/>
+        </colgroup>
+        <tr>
+          <xsl:for-each select="content">
+            <xsl:choose>
+            <xsl:when test="$mode = 'text'"><td align="left" valign="top"><xsl:apply-templates mode="text"/></td></xsl:when>
+            <xsl:when test="$mode = 'xml'"><td align="left" valign="top"><xsl:apply-templates mode="xml"/></td></xsl:when>
+            <xsl:when test="$mode = 'image'">
+              <xsl:variable name="linkImageEcho" select="/result/page/image-echo"/>
+              <xsl:variable name="linkImageScaler" select="/result/page/image-scaler"/>
+              <td align="middle" valign="top">
+                <a href="{$linkImageEcho}"><img alt="Page image: {$number}" src="{$linkImageScaler}&amp;dh=600" border="1"/></a>
+              </td>
+            </xsl:when>
+            <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+          <td align="left" valign="top">
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$number}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              Book contains: <input type="text" size="15" name="ft-query" value="{$ftQueryName}"/>
+              <input type="submit" value="Query"/>
+            </form>
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$number}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              Index terms: <input type="text" size="10" name="index-terms-start-str" value="{$indexTermsStartStr}"/> 
+              <input type="hidden" name="index-terms-pn" value="1"/>
+              <input type="submit" value="Query"/>
+            </form>
+            <xsl:if test="/result/ft-query[node()]">
+              <hr/>
+              <b><xsl:value-of select="/result/ft-query/result/size"/> sentences contain: "<xsl:value-of select="$ftQueryName"/>"</b>
+              <ol>
+                <xsl:for-each select="/result/ft-query/result/hits/hit">
+                <li>
+                  <xsl:variable name="hitPN" select="pn"/>
+                  <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                  <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>:<br></br>
+                  <!-- Highlight the query terms in each hit sentence and clip the result -->
+                  <xsl:sequence select="text:highlight(string(s), $ftQueryName, 'true')"/>
+                </li>
+                </xsl:for-each>
+              </ol>
+            </xsl:if>
+            <xsl:if test="/result/index-terms/pages > 0">
+              <hr/>
+              <xsl:variable name="pn" select="/result/index-terms/pn"/>
+              <xsl:variable name="size" select="/result/index-terms/size"/>
+              <xsl:variable name="pages" select="/result/index-terms/pages"/>
+              <b><xsl:value-of select="$size"/> terms beginning with: "<xsl:value-of select="$indexTermsStartStr"/>"</b><br/>
+              <table width="100%">
+              <colgroup>
+                <col width="90%"/>
+                <col width="10%"/>
+              </colgroup>
+              <tr valign="top">
+              <td>
+              <ol>
+              <xsl:for-each select="/result/index-terms/entry">
+                <xsl:variable name="pos" select="position"/>
+                <xsl:variable name="term" select="term"/>
+                <xsl:variable name="dictionaryLink">
+                  <xsl:choose>
+                  <xsl:when test="$language = 'zh'">
+                  <xsl:variable name="termBig5Encoded" select="/result/index-terms/entry-big5-encoded/term[$pos]"/>
+                  <a href="http://humanum.arts.cuhk.edu.hk/cgi-bin/agrep-lindict?query={$termBig5Encoded}&amp;category=wholerecord">Lin Yutang</a></xsl:when>
+                  <xsl:otherwise><a href="http://archimedes.mpiwg-berlin.mpg.de/cgi-bin/toc/dict?step=table;word={$term};lang={$language};pro=echo">Echo</a></xsl:otherwise>
+                  </xsl:choose>
+                </xsl:variable>
+                <li value="{$pos}">
+                   <xsl:value-of select="$term"/>(<xsl:value-of select="frequency"/>) [<xsl:sequence select="$dictionaryLink"/>]
+                </li>
+              </xsl:for-each>
+              </ol>
+              </td>
+                <td nowrap="true">
+                  <td nowrap="true">
+                  <xsl:variable name="leftNumber">
+                    <xsl:choose>
+                    <xsl:when test="$pn &gt; 1"><xsl:value-of select="$pn - 1"/></xsl:when>
+                    <xsl:otherwise><xsl:value-of select="$pn"/></xsl:otherwise>
+                    </xsl:choose>
+                  </xsl:variable>
+                  <form action="page-query-result.xql" method="get">
+                  <input type="hidden" name="document" value="{$documentUri}"/>
+                  <input type="hidden" name="pn" value="{$number}"/>
+                  <input type="hidden" name="mode" value="{$mode}"/>
+                  <input type="image" src="images/left.gif" name="index-terms-pn" value="{$leftNumber}"/> 
+                  <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+                  </form>
+                  </td>
+                  <td nowrap="true">
+                  <form action="" method="get">
+                  <xsl:value-of select="$pn"/> / <xsl:value-of select="$pages"/>
+                  </form>
+                  </td>
+                  <td nowrap="true">
+                  <xsl:variable name="rightNumber">
+                    <xsl:choose>
+                    <xsl:when test="$pn &lt; $pages"><xsl:value-of select="$pn + 1"/></xsl:when>
+                    <xsl:otherwise><xsl:value-of select="$pn"/></xsl:otherwise>
+                    </xsl:choose>
+                  </xsl:variable>
+                  <form action="page-query-result.xql" method="get">
+                  <input type="hidden" name="document" value="{$documentUri}"/>
+                  <input type="hidden" name="pn" value="{$number}"/>
+                  <input type="hidden" name="mode" value="{$mode}"/>
+                  <input type="image" src="images/right.gif" name="index-terms-pn" value="{$rightNumber}"/> 
+                  <input type="hidden" name="index-terms-start-str" value="{$indexTermsStartStr}"/>
+                  </form>
+                  </td>
+                </td>
+              </tr>
+              </table>
+            </xsl:if>
+            <xsl:if test="/result/index-terms/pages = 0">
+              <hr/>
+              <b>No results</b>
+            </xsl:if>
+          </td>
+        </tr>
+      </xsl:variable>
+      <table align="middle" width="100%" rules="cols" frame="void" cellpadding="5">
+          <xsl:sequence select="$tableContent"/>
+      </table>
+      <hr/>
+      Elapsed time: <xsl:value-of select="text:nchars(6, 'bla')"/>, <xsl:value-of select="/result/document-description/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/mpdl-example/archimedes/xsl/page.xsl?_source=yes">XSL source</a> of this page
+      <br/>
+      <xsl:variable name="thisUrl" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeValue, $ftQueryValue)"/>
+      [<a href="page-query-result-old.xql?{$thisUrl}">slower mechanism (XQL search)</a>]
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()" mode="xml">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|comment()|processing-instruction()" mode="xml">
+  <ul style="margin-left:0px;padding-left:8px">
+    <xsl:variable name="elementName" select="name()"/>&lt;<span style="font-weight:bold;color: purple;"><xsl:value-of select="$elementName"/></span><xsl:apply-templates select="attribute()" mode="xml"/>&gt;<xsl:apply-templates select="element()|text()|comment()|processing-instruction()" mode="xml"/>&lt;/<span style="font-weight:bold;color: purple;"><xsl:value-of select="$elementName"/></span>&gt;
+  </ul>
+</xsl:template>
+
+<xsl:template match="attribute()" mode="xml">
+  <xsl:variable name="attributeName" select="name()"/><xsl:text> </xsl:text><b><xsl:value-of select="$attributeName"/></b>=&quot;<span style="color: blue;"><xsl:value-of select="."/></span>&quot;<xsl:apply-templates select="attribute()" mode="xml"/>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences in each little text piece for the fulltext query -->
+<xsl:template match="text()" mode="xml">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <xsl:sequence select="text:highlight(string(.), $ftQueryName, 'false')"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="chap|p" mode="text">
+  <p><xsl:apply-templates mode="text"/></p>
+</xsl:template>
+
+<xsl:template match="lb" mode="text">
+  <br/>
+</xsl:template>
+
+<xsl:template match="expan" mode="text">
+  <xsl:apply-templates mode="text"/><xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:variable name="firstFigurePosition" select="/result/page/firstFigurePosition"/>
+
+<xsl:template match="figure" mode="text">
+  <xsl:variable name="figurePos" select="count(preceding::figure)"/>
+  <xsl:variable name="figureId" select="$firstFigurePosition + $figurePos"/>
+  <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+  <!-- delivers all fileds from 021/01/001/1.jpg -->
+  <xsl:variable name="figureLink" select="@xlink:href"/>
+  <xsl:variable name="docId" select="substring-before($figureLink, '/')"/>
+  <xsl:variable name="figureLinkAfter1" select="substring-after($figureLink, '/')"/>
+  <xsl:variable name="docId2" select="substring-before($figureLinkAfter1, '/')"/>
+  <xsl:variable name="figureLinkAfter2" select="substring-after($figureLinkAfter1, '/')"/>
+  <xsl:variable name="page" select="substring-before($figureLinkAfter2, '/')"/>
+  <xsl:variable name="figureFileName" select="substring-after($figureLinkAfter2, '/')"/>
+  <p></p>
+  <a href="http://echo.mpiwg-berlin.mpg.de/zogilib?fn=/permanent/archimedes/{$documentName}/{$docId}-{$docId2}-figures&amp;pn={$figureId}"><img alt="figure: {$figureId}" src="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn=/permanent/archimedes/{$documentName}/{$docId}-{$docId2}-figures&amp;pn={$figureId}&amp;dh=150" align="middle" border="1"/></a>
+  <p></p>
+  Figure: <xsl:value-of select="$figureId"/>
+  <p></p>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences in each little text piece for the fulltext query -->
+<xsl:template match="text()" mode="text">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <!-- <xsl:sequence select="text:highlight(string(.), $ftQueryName, $ftQueryMode, 'false')"/>  -->
+    <xsl:sequence select="text:highlight(string(.), $ftQueryName, 'false')"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/text/all.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,48 @@
+xquery version "1.0";
+
+module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"; 
+
+declare namespace text = "http://exist-db.org/xquery/text";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace local = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/local";
+
+declare function mpdl-text:indexTerms($document, $indexTermsStartStr, $pn as xs:int, $pageSize as xs:int) as node()* {
+  let $index := $document/archimedes/text
+  let $language := $document/archimedes/info/lang
+  let $from := ($pn * $pageSize) - $pageSize + 1
+  let $to := $pn * $pageSize
+  let $maxTo := 10000
+  let $callback := util:function(QName("http://www.mpiwg-berlin.mpg.de/ns/mpdl/local", "local:termEntries"), 2)
+  let $indexResult := text:index-terms($index, $indexTermsStartStr, $callback, $maxTo)
+  let $count := count($indexResult)
+  let $pages := 
+    if ($count = 0)
+    then 0
+    else $count idiv $pageSize + 1
+  let $resultEntries := 
+    for $entry at $pos in $indexResult
+    where $pos >= $from and $pos <= $to
+    return $entry
+
+  let $result :=
+      <index-terms>
+        <start-string>{$indexTermsStartStr}</start-string>
+        <size>{$count}</size>
+        <pages>{$pages}</pages>
+        <pn>{$pn}</pn>
+        {$resultEntries}
+      </index-terms>
+  return $result
+};
+
+declare function local:termEntries($term as xs:string, $data as xs:int+) {
+  let $result := 
+    <entry>  
+       <term>{$term}</term>  
+       <frequency>{$data[1]}</frequency>  
+       <documents>{$data[2]}</documents>  
+       <position>{$data[3]}</position>  
+       <rank>{$data[4]}</rank>  
+     </entry>  
+  return $result
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/util/functx.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,20 @@
+xquery version "1.0";
+
+module namespace functx = "http://www.functx.com"; 
+
+declare function functx:substring-before-last( $arg as xs:string?, $delim as xs:string ) as xs:string {
+  if (matches($arg, functx:escape-for-regex($delim)))
+  then replace($arg,
+           concat('^(.*)', functx:escape-for-regex($delim),'.*'),
+           '$1')
+  else ''
+};
+
+declare function functx:substring-after-last( $arg as xs:string?, $delim as xs:string ) as xs:string {
+  replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
+};
+
+declare function functx:escape-for-regex( $arg as xs:string? ) as xs:string {
+  replace($arg,
+           '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/util/time.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,7 @@
+xquery version "1.0";
+
+module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time"; 
+
+declare function mpdl-time:duration-as-ms($t) {
+  round((minutes-from-duration($t) * 60 + seconds-from-duration($t)) * 1000 )
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/xql/xql.xpr	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+    <meta>
+        <filters directoryPatterns="" filePatterns=""
+            positiveFilePatterns="" showHiddenFiles="false"/>
+        <options/>
+    </meta>
+    <projectTree name="xql.xpr"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/archimedes-figures.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,34 @@
+xquery version "1.0";
+
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace exist="http://exist.sourceforge.net/NS/exist";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+
+let $coll := collection('/db/mpdl/documents/standard/archimedes')
+let $tmpResult := $coll//figure
+let $result :=
+  for $figure at $pos in $tmpResult
+    let $collName := util:collection-name($figure)
+    let $shortCollName := substring-after(substring-after(substring-after(substring-after(substring-after($collName, "/"), "/"), "/"), "/"), "/")
+    let $docName := util:document-name($figure)
+    let $mpdlDocUri := concat("/", $shortCollName, "/", $docName)
+    let $fullDocName := concat($collName, "/", $docName)
+    let $document := doc($fullDocName)
+    let $pageBreaks := $document//pb
+    let $pnOfFigure := count($pageBreaks[. << $figure])
+    let $hit := 
+      <li>
+        <a href="http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document={$mpdlDocUri}&amp;pn={$pnOfFigure}&amp;mode=text">{$mpdlDocUri}, Page {$pnOfFigure}</a>
+      </li>
+  order by $fullDocName, $pnOfFigure
+  return $hit
+
+return 
+  <html>
+  <body>
+  <h2>All figures in all Archimedes documents</h2>
+  <ol>{$result}</ol>
+  </body>
+  </html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/controller.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,64 @@
+xquery version "1.0";
+
+(: Controller XQuery for the mpdl application. :)
+
+let $id := "blabla"
+
+return
+if ($exist:path eq '/test.xql') 
+then
+  <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+    <forward url="test2.xql">
+      <add-parameter name="id" value="{$exist:resource}"/>
+    </forward>
+  </dispatch>
+else if (starts-with($exist:path, '/ir/')) then
+  <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+    <forward url="/test">
+      <add-parameter name="doc" value="{$exist:resource}"/>
+    </forward>
+  </dispatch>
+else if ($exist:resource eq 'execute') then
+    let $query := request:get-parameter("qu", ())
+    let $startTime := util:system-time()
+    return
+        <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+			<!-- Query is executed by XQueryServlet -->
+            <forward servlet="XQueryServlet">
+				<!-- Query is passed via the attribute 'xquery.source' -->
+                <set-attribute name="xquery.source" value="{$query}"/>
+				<!-- Results should be written into attribute 'results' -->
+				<set-attribute name="xquery.attribute" value="results"/>
+				<clear-attribute name="results"/>
+				<!-- Errors should be passed through instead of terminating the request -->
+				<set-attribute name="xquery.report-errors" value="yes"/>
+            </forward>
+			<view>
+				<!-- Post process the result: store it into the HTTP session
+					and return the number of hits only. -->
+				<forward url="session.xql">
+					<clear-attribute name="xquery.source"/>
+					<clear-attribute name="xquery.attribute"/>
+					<set-attribute name="elapsed" 
+						value="{string(seconds-from-duration(util:system-time() - $startTime))}"/>
+				</forward>
+			</view>
+        </dispatch>
+(: Retrieve an item from the query results stored in the HTTP session. The
+	format of the URL will be /sandbox/results/X, where X is the number of the
+	item in the result set :)
+else if (starts-with($exist:path, '/results/')) then
+	<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+		<forward url="../session.xql">
+			<add-parameter name="num" value="{$exist:resource}"/>
+		</forward>
+	</dispatch>
+else if (starts-with($exist:path, '/scripts/yui')) then
+    <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+		<forward url="/{replace($exist:path, '(/scripts/yui/.*)$', '$1')}"/>
+	</dispatch>
+else
+    (: everything else is passed through :)
+    <ignore xmlns="http://exist.sourceforge.net/NS/exist">
+        <cache-control cache="yes"/>
+    </ignore>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/doc.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,7 @@
+document {
+  element product {
+    attribute dept { "ACC" },
+    element number { 563 },
+    element name { attribute language {"en"}, "Floppy Sun Hat"}
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/dummy.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,46 @@
+xquery version "1.0";
+
+declare namespace dummy = "http://archimedes.mpiwg-berlin.mpg.de"; 
+declare namespace xlink = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"; 
+
+declare option exist:serialize "method=xml media-type=text/xml omit-xml-declaration=no indent=yes";
+
+declare function dummy:getDummyDocument() as node() {
+  let $bla := 
+    document {
+      element product {
+        attribute dept { "ACC" },
+        element number { 563 },
+        element name { attribute language {"en"}, "Floppy Sun Hat"}
+      },
+      element product {
+        attribute dept { "BCC" },
+        element number { 564 },
+        element name { attribute language {"en"}, "Floppy SBun Iat"}
+      }
+    }
+  return $bla
+};
+
+declare function dummy:milestone-chunk($ms1 as node(), $ms2 as node(), $node as node()) as node()* {
(:
    Version 1.0 -- 7 Feb 2005 -- David Sewell
    Usage: The first two parameters are the starting and ending milestone elements in a
    document or document fragment. Example: $doc//pb[@n='1'], $doc//pb[@n='2'].
    The third parameter should initially be an element that is a parent or
    ancestor of all the milestones, like $doc//body or $doc//text. (This
    parameter is the only one that varies as the function is called
    recursively.)

    The function returns only a single node containing the content between the
    two milestones. To return, for example, all the pages in a book, call the
    function repeatedly by reiterating over every <pb>, where $ms2 will be
    either the following <pb> or, for the last one, the final node() in the
    document or document fragment.

    English-language explanation of the function operation:

    Test for node type. For an element, if it is (1) an ancestor or self of one
    of the two milestones, use the "element" function to return an element of
    the same name, with its content created by recursing over any child nodes. If
    it is (2) an element in between the two milestones, return the element. If
    it is (3) anything else, return null.  For an attribute node, return the
    entire attribute. For a text node, return it if it is between the
    milestones; otherwise return null.
  :) 
  typeswitch ($node)
    case element() return
      if ($node is $ms1) then $node
      else if ( some $n in $node/descendant::* satisfies
                ($n is $ms1 or $n is $ms2) )
      then
        element { name($node) }
                { for $i in ( $node/node() | $node/@* )
                  return dummy:milestone-chunk($ms1, $ms2, $i) }
      else if ( $node >> $ms1 and $node << $ms2 ) then $node
      else ()
    case attribute() return
      attribute { name($node) } { data($node)  }
    default return
      if ( $node >> $ms1 and $node << $ms2 ) then $node
      else ()
}; 
+
+let $dummy := dummy:getDummyDocument()
+
+let $docAchil := /archimedes/info[cvs_file = 'achil_propo_087_la_1545.xml']/fn:root()
+let $pb184 := $docAchil//pb[@n='185']
+let $pb185 := $docAchil//pb[@n='186']
+let $page184 := dummy:milestone-chunk($pb184, $pb185, $docAchil//text)
+
+
+return 
+  (: <?xml-stylesheet type="text/xsl" href="archimedes.xsl" ?>  :)
+  transform:transform($dummy, doc("/db/xsl/archimedes.xsl"), ())
+
+(:
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html>
+   <head>
+     <title>Dummy</title>
+   </head>
+  </html>
+:)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/echo-figures.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,69 @@
+xquery version "1.0";
+
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace exist="http://exist.sourceforge.net/NS/exist";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "../..//text/all.xql";
+
+let $coll := collection('/db/mpdl/documents/standard/echo')
+let $tmpResult := $coll//echo:figure
+let $result :=
+  for $figure at $pos in $tmpResult
+    let $collName := util:collection-name($figure)
+    let $shortCollName := substring-after(substring-after(substring-after(substring-after(substring-after($collName, "/"), "/"), "/"), "/"), "/")
+    let $docName := util:document-name($figure)
+    let $mpdlDocUri := concat("/", $shortCollName, "/", $docName)
+    let $echoArchivePath := mpdl-text:getEchoArchivePath($mpdlDocUri)
+    let $figLabel := string($figure/@xlink:label)
+    let $imageFileName := string($figure/echo:image/@file)
+    let $imageXlinkHref := string($figure/echo:image/@xlink:href)
+    let $fullDocName := concat($collName, "/", $docName)
+    let $document := doc($fullDocName)
+    let $pageBreaks := $document//echo:pb
+    let $pnOfFigure := count($pageBreaks[. << $figure])
+    let $captionStr := 
+      if (not(empty($figure/echo:caption)))
+      then string-join($figure/echo:caption, " ")
+      else ""
+    let $descriptionStr := 
+      if (not(empty($figure/echo:description)))
+      then string-join($figure/echo:description, " ")
+      else ""
+    let $captionElemStr := 
+      if ($captionStr != "")
+      then concat("&#160;&#160;&#160;&#160;&lt;caption&gt;", $captionStr, "&lt;/caption&gt;")
+      else ""
+    let $descriptionElemStr := 
+      if ($descriptionStr != "")
+      then concat("&#160;&#160;&#160;&#160;&lt;description&gt;", $descriptionStr, "&lt;/description&gt;")
+      else ""
+    let $caption := 
+      if ($captionElemStr != "")
+      then <caption>{$captionElemStr}<br/></caption>
+      else ()
+    let $description := 
+      if ($descriptionElemStr != "")
+      then <description>{$descriptionElemStr}<br/></description>
+      else ()
+    let $hit := 
+      <li>
+        <a href="http://mpdl-dev.mpiwg-berlin.mpg.de/ECHOdocuView?url={$echoArchivePath}&amp;pn={$pnOfFigure}&amp;viewMode=images">{$mpdlDocUri}, Page {$pnOfFigure}</a>
+        <br/>
+        &#160;&#160;&lt;figure xlink:label="{$figLabel}"&gt;<br/>
+          &#160;&#160;&#160;&#160;&lt;image file="{$imageFileName}" xlink:href="{$imageXlinkHref}"/&gt; <br/>
+          {$caption}
+          {$description}
+        &#160;&#160;&lt;/figure&gt;
+      </li>
+  order by $fullDocName, $pnOfFigure
+  return $hit
+
+return 
+  <html>
+  <body>
+  <h2>All figures in all Echo documents</h2>
+  <ol>{$result}</ol>
+  </body>
+  </html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/echo-post.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,16 @@
+xquery version "1.0";
+
+(: echo-post.xq: Return all data from an HTTP post to the caller. Test all web forms  :)
+
+declare namespace exist = "http://exist.sourceforge.net/NS/exist";
+declare namespace xmldb="http://exist-db.org/xquery/xmldb";
+declare namespace request="http://exist-db.org/xquery/request";
+
+declare option exist:serialize "method=xml media-type=text/xml indent=yes";
+
+let $post-data := request:get-data()
+
+return
+<post-data>
+   {$post-data}
+</post-data>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/echo.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,7 @@
+xquery version "1.0";
+
+<result>
+<elem>{myecho:myecho("Hello")}</elem>
+<elem>{myecho:myecho("MPDL")}</elem>
+<elem>{mpdltext:getWords("bla blu blub. hh gb-hh", "[,;.\s]+", "i")}</elem>
+</result>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/get-fragment.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,19 @@
+xquery version "1.0";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace exist="http://exist.sourceforge.net/NS/exist";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace foo = "http://exist-db.org/xquery/foo";
+
+
+let $coll := collection("/db/mpdl/documents/standard/archimedes/la")
+let $doc := doc("/db/mpdl/documents/standard/echo/zh/SongYingxing_1637.xml")
+let $pn := 300
+let $xpathQuery := "//place"
+
+
+let $node := <a xmlns="test"><b xmlns="foo"/><bla xmlns="foooo">bla</bla><c/><bla>bla</bla>ggggg</a>
let $nodeTest := <a xmlns="test"><b xmlns="foo"/>bar<c/><bla>bla</bla>ggggg</a>
let $login := xmldb:login('/db/', 'admin', '')
let $store := xmldb:store('/db/', 'test.xml', $node)
let $doc := doc('/db/test.xml')
+let $ms1 := subsequence($doc//*:b, 1, 1)
+let $ms2 := subsequence($doc//*:c, 1, 1)
let $result := util:get-fragment-between($ms1, $ms2, true())
+let $bla := util:parse($result)    
+return $bla
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/kwic.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,174 @@
+(: module namespace kwic="http://exist-db.org/xquery/kwic";    :)
+module namespace kwic="/exist/xquery/archimedes/kwic";
+
+declare variable $kwic:CHARS_SUMMARY := 120;
+declare variable $kwic:CHARS_KWIC := 40;
+
+(:~
+	Retrieve the following and preceding text chunks for a given match.
+
+	@param $match the text node containing the match
+	@param $mode the selection mode: either "previous" or "following"
+:)
+declare function kwic:get-context($match as element(exist:match), $mode as xs:string) as node()* {
+	let $sibs := 
+		if ($mode eq 'previous') then 
+			$match/preceding::text()
+		else
+			$match/text()/following::text()
+	for $sib in $sibs
+	return
+		if ($sib/parent::exist:match) then
+			<span class="hi">{$sib}</span>
+		else
+			$sib
+};
+
+(:~
+	Like fn:substring, but takes a node argument. If the node is an element,
+	a new element is created with the same node-name as the old one and the
+	shortened text content.
+:)
+declare function kwic:substring($node as node(), $start as xs:int, $count as xs:int) as item()? {
+	let $str := substring($node, $start, $count)
+	return
+		if ($node instance of element()) then
+			element { node-name($node) } { $str }
+		else
+			$str
+};
+
+(:~
+	Generate the left-hand context of the match. Returns a sequence of nodes
+	and strings, whose total string length is less than or equal to $max characters.
+
+	Note: this function calls itself recursively until $nodes is empty or
+	the returned sequence has the desired total string length.
+:)
+declare function kwic:truncate-previous($nodes as node()*, $truncated as item()*, 
+	$max as xs:int, $chars as xs:int) {
+	if ($nodes) then
+		let $next := $nodes[last()]
+		return
+			if ($chars + string-length($next) gt $max) then
+				let $remaining := $max - $chars
+				return
+					("...", kwic:substring($next, string-length($next) - $remaining, $remaining), $truncated)
+			else
+				kwic:truncate-previous(subsequence($nodes, 1, count($nodes) - 1), ($next, $truncated),
+					$max, $chars + string-length($next))
+	else
+		$truncated
+};
+
+(:~
+	Generate the right-hand context of the match. Returns a sequence of nodes
+	and strings, whose total string length is less than or equal to $max characters.
+	
+	Note: this function calls itself recursively until $nodes is empty or
+	the returned sequence has the desired total string length.
+:)
+declare function kwic:truncate-following($nodes as node()*, $truncated as item()*, $max as xs:int, $chars as xs:int) {
+	if ($nodes) then
+		let $next := $nodes[1]
+		return
+			if ($chars + string-length($next) gt $max) then
+				let $remaining := $max - $chars
+				return
+					($truncated, kwic:substring($next, 1, $remaining), "...")
+			else
+				kwic:truncate-following(subsequence($nodes, 2), ($truncated, $next),
+					$max, $chars + string-length($next))
+	else
+		$truncated
+};
+
+(:~
+	Computes the total string length of the nodes in the argument sequence
+:)
+declare function kwic:string-length($nodes as item()*) as xs:int {
+	if (exists($nodes)) then
+		sum(for $n in $nodes return string-length($n))
+	else
+		0
+};
+
+(:~
+	Print a summary of the match in $node. Output a predefined amount of text to
+	the left and the right of the match.
+
+	@param $root the root element containing the match. This is the original element
+		   stored in the database.
+	@param $node the exist:match element to process.
+	@param $config configuration element which determines the behaviour of the function
+:)
+declare function kwic:get-summary($root as node(), $node as element(exist:match), $config as element(config)) as element() {
+	let $chars := xs:int($config/@width)
+	let $table := $config/@table = ('yes', 'true')
+	let $prev := kwic:get-context($node, 'previous')
+	let $prevTrunc := kwic:truncate-previous($prev, (), $chars, 0)
+	let $remain := 
+		if (not($table)) then 
+			$chars * 2 - kwic:string-length($prevTrunc)
+		else
+			$chars
+	let $following := kwic:get-context($node, 'following')
+	let $followingTrunc := kwic:truncate-following($following, (), $remain, 0)
+	return
+		if (not($table)) then
+			<p xmlns="http://www.w3.org/1999/xhtml"> 
+				<span class="previous">{$prevTrunc}</span>
+				{
+					if ($config/@link) then
+						<a class="hi" href="{$config/@link}">{ $node/text() }</a>
+					else
+						<span class="hi">{ $node/text() }</span>
+				}
+				<span class="following">{$followingTrunc}</span>
+			</p>
+		else
+			<tr xmlns="http://www.w3.org/1999/xhtml">
+				<td class="previous">{$prevTrunc}</td>
+				<td class="hi">
+				{
+					if ($config/@link) then
+						<a href="{$config/@link}">{$node/text()}</a>
+					else
+						$node/text()
+				}
+				</td>
+				<td class="following">{$followingTrunc}</td>
+			</tr>
+};
+
+(:~
+	Main function of the KWIC module: takes the passed element and returns an 
+	XHTML fragment containing a chunk of text before and after the first full text
+	match in the node.
+
+	The optional config parameter is used to configure the behaviour of the function:
+	
+	&lt;config width="character width" table="yes|no" link="URL to which the match is linked"/&gt;
+
+	By default, kwic:summarize returns an XHTML fragment with the following structure:
+
+	&lt;p xmlns="http://www.w3.org/1999/xhtml"&gt;
+		&lt;span class="previous"&gt;Text before match&lt;/span&gt;
+		&lt;a href="passed URL if any" class="hi"&gt;The highlighted term&lt;/a&gt;
+		&lt;span class="following"&gt;Text after match&lt;/span&gt;
+	&lt;/p&gt;
+
+	If table=yes is passed with the config element, a tr table row will be returned instead
+	of a span (using the same class names).
+
+	@param $hit an arbitrary XML element which has been selected by one of the full text
+		operations or an ngram search.
+	@param $config configuration element to configure the behaviour of the function
+:)
+declare function kwic:summarize($hit as element(), $config as element(config))
+as element()* {
+	let $expanded := util:expand($hit)
+	for $match in $expanded//exist:match[1]
+	return
+		kwic:get-summary($hit, $match, $config)
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/test-trigger.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,25 @@
+xquery version "1.0";  
+  
+(:  
+    A simple XQuery for an XQueryTrigger that  
+    logs all trigger events for which it is executed  
+    in the file /db/triggersLogs.xml  
+:)  
+  
+declare namespace  xmldb="http://exist-db.org/xquery/xmldb";  
+  
+declare variable $local:triggerEvent external;  
+declare variable $local:eventType external;  
+declare variable $local:collectionName external;  
+declare variable $local:documentName external;  
+declare variable $local:document external;  
+  
+declare variable $local:triggersLogFile := "test-trigger-log.xml";  
+
+(: create the log file if it does not exist :)  
+if(not(doc-available($local:triggersLogFile)))
+then (xmldb:store("/db/test", $local:triggersLogFile, <triggers/>))  
+else ()  
+   
+(: log the trigger details to the log file :)  
+update insert <trigger event="{$local:triggerEvent}" eventType="{$local:eventType}" collectionName="{$local:collectionName}" documentName="{$local:documentName}" timestamp="{current-dateTime()}">{$local:document}</trigger>  into doc("/db/test/test-trigger-log.xml")/triggers
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/test2.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,17 @@
+xquery version "1.0";
+
+import module namespace request="http://exist-db.org/xquery/request";
+
+let $id := request:get-parameter("id", ())
+
+return 
+<html>
+<head>
+  <title>Example Web Application</title>
+</head>
+<body>
+  <h1>This is a test</h1>
+  {$id}
+  
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/test3.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,36 @@
+xquery version "1.0";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace exist="http://exist.sourceforge.net/NS/exist";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace ft = "http://exist-db.org/xquery/lucene";
+
+
+let $coll := collection("/db/mpdl/documents/standard/archimedes/la")
+let $doc := doc("/db/mpdl/documents/standard/echo/zh/SongYingxing_1637.xml")
+let $pn := 300
+let $xpathQuery := "//place"
+
+let $pageBreaks := $doc//echo:pb
+let $pb1 := subsequence($pageBreaks, $pn, 1)
+let $pb2 := subsequence($pageBreaks, $pn + 1, 1)
+let $pageFragment := 
+  if ($pn != -1)
+  then util:get-fragment-between($pb1, $pb2, true())
+  else ()
+let $fragmentNode := util:parse($pageFragment)
+
+let $bla := <blu><bla><place>1</place><place>2</place></bla></blu>
+let $tmpFragmentNode := util:eval-inline($fragmentNode, ".")
+
+let $result := util:eval-inline($doc, "let $a := //echo:metadata let $b := for $elem in $a let $bla := $elem return $bla return $b")
+let $result2 := util:eval-inline($bla, "bla/place")
+let $result3 := util:eval-inline($fragmentNode, "let $a := .//place return $a")
+let $result4 := util:eval-inline($tmpFragmentNode, ".//place")
+let $result5 := util:eval-inline($fragmentNode, concat (".", $xpathQuery))
+let $result6 := util:eval-inline($doc, "util:node-id(//echo:metadata)")
+let $result7 := util:eval-inline($bla, "let $a := .//place let $b := for $elem in $a let $bla := $elem return $bla return $b")
+let $result8 := util:eval-inline($doc, "let $a := .//echo:place let $b := for $elem at $i in $a let $bla := concat($i, '. Place: ', $elem, ' (Level: ', util:node-id($elem), ', ', util:node-xpath($elem), ')') return $bla return $b")
+
+
+return $result8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/testDev/testXslFO.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,21 @@
+xquery version "1.0";
+declare namespace fo="http://www.w3.org/1999/XSL/Format";
+declare namespace xslfo="http://exist-db.org/xquery/xslfo";
+ 
+let $fo :=
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+    <fo:layout-master-set>
+        <fo:simple-page-master master-name="my-page">
+            <fo:region-body margin="1in"/>
+        </fo:simple-page-master>
+    </fo:layout-master-set>
+    <fo:page-sequence master-reference="my-page">
+        <fo:flow flow-name="xsl-region-body">
+            <fo:block>Hello World!</fo:block>
+        </fo:flow>
+    </fo:page-sequence>
+</fo:root>
+ 
+let $pdf := xslfo:render($fo, "application/pdf", ())
+
+return response:stream-binary($pdf, "application/pdf", "test-page-1.pdf")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/attribute-query-result.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,335 @@
+xquery version "1.0";
+
+import module namespace functx = "http://www.functx.com" at "util/functx.xql";
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "util/time.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "lucene/search.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace dc="http://purl.org/dc/elements/1.1/";
+declare namespace dct="http://purl.org/dc/terms/1.0/";
+declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+
+let $queryType := request:get-parameter("query-type", "")
+let $docbase := request:get-parameter("docbase", "")
+let $attribute1 := request:get-parameter("attribute1", "")
+let $relOp1 := request:get-parameter("relOp1", "")
+let $attrQuery1 := request:get-parameter("attr-query1", "")
+let $boolOp := request:get-parameter("boolOp", "")
+let $attribute2 := request:get-parameter("attribute2", "")
+let $relOp2 := request:get-parameter("relOp2", "")
+let $attrQuery2 := request:get-parameter("attr-query2", "")
+let $ftQuery := request:get-parameter("ft-query", "")
+let $ftMorphQuery := request:get-parameter("ft-morph-query", "")
+let $orderBy := request:get-parameter("order-by", "")
+let $language := request:get-parameter("language", "")
+let $pn := number(request:get-parameter("pn", ""))
+let $reqPageSize := request:get-parameter("pageSize", "")
+let $pageSize := 
+  if ($reqPageSize = '' or $reqPageSize = '0')
+  then 20
+  else number($reqPageSize)
+
+let $currentTimeBegin := util:system-time()
+
+let $docPathStandard := "/db/mpdl/documents/standard"
+let $docPathMorph := "/db/mpdl/documents/morph"
+let $docPath := 
+  if($queryType = 'fulltextMorph')
+  then $docPathMorph
+  else $docPathStandard
+
+let $docBaseArch := "archimedes"
+let $docBaseEcho := "echo"
+let $fulltextMorphArchDocPath := concat($docPathMorph, "/", $docBaseArch, "/", $language)
+let $fulltextMorphEchoDocPath := concat($docPathMorph, "/", $docBaseEcho, "/", $language)
+let $fulltextMorphCollection := 
+  if(contains($docbase, $docBaseArch) and contains($docbase, $docBaseEcho))
+  then collection($fulltextMorphArchDocPath, $fulltextMorphEchoDocPath)
+  else if(contains($docbase, $docBaseArch) and not(contains($docbase, $docBaseEcho)))
+  then collection($fulltextMorphArchDocPath)
+  else if(not(contains($docbase, $docBaseArch)) and contains($docbase, $docBaseEcho))
+  then collection($fulltextMorphEchoDocPath)
+  else ()
+
+let $fulltextStandardArchDocPath := concat($docPathStandard, "/", $docBaseArch)
+let $fulltextStandardEchoDocPath := concat($docPathStandard, "/", $docBaseEcho)
+let $fulltextStandardCollectionStr := 
+  if(contains($docbase, $docBaseArch) and contains($docbase, $docBaseEcho))
+  then concat("collection('", $fulltextStandardArchDocPath, "', '", $fulltextStandardEchoDocPath, "')")
+  else if(contains($docbase, $docBaseArch) and not(contains($docbase, $docBaseEcho)))
+  then concat("collection('", $fulltextStandardArchDocPath, "')")
+  else if(not(contains($docbase, $docBaseArch)) and contains($docbase, $docBaseEcho))
+  then concat("collection('", $fulltextStandardEchoDocPath, "')")
+  else ""
+let $metadataStr := concat("(", $fulltextStandardCollectionStr, "/archimedes/info", "|" , $fulltextStandardCollectionStr, "/echo:echo/echo:metadata", ")")
+let $fulltextStandardCollection := 
+  if($fulltextStandardCollectionStr != "")
+  then util:eval($fulltextStandardCollectionStr)
+  else ()
+
+let $isAttributeSearch :=
+  if ($queryType = "attribute")
+  then true()
+  else false()
+let $isSimpleAttributeSearch :=
+  if ($queryType = "attribute" and $attrQuery2 = "")
+  then true()
+  else false()
+let $isBooleanAttributeSearch :=
+  if ($queryType = "attribute" and $attrQuery2 != "")
+  then true()
+  else false()
+let $errorAttributeSearch :=
+  if ($docbase = "")
+  then "No document check box is selected. Please select at least one of the document check boxes."
+  else if ($queryType = "attribute" and $attrQuery1 = "" and $attrQuery2 != "")
+  then "Your first attribute field is empty but your second not. Please use the first attribute field for a simple attribute query."
+  else if ($queryType = "attribute" and $attrQuery1 = "" and $attrQuery2 = "")
+  then "Your attribute fields are both empty. Please fill at least one attribute field."
+  else if ($queryType = "fulltext" and $ftQuery = "")
+  then "Your fulltext query field is empty. Please fill this field."
+  else if ($queryType = "fulltextMorph" and $ftMorphQuery = "")
+  then "Your fulltext query field is empty. Please fill this field."
+  else ""
+
+(:  TODO:  performance improvement: at this time the result is fully scanned 3 times (query, ordering, presentation)   :)
+let $attrQueryResult := 
+  if ($queryType = "browse" and $errorAttributeSearch = "")
+  then $fulltextStandardCollection
+  else if ($queryType = "fulltext" and $errorAttributeSearch = "")
+  then mpdl-lucene:search($fulltextStandardCollection, $ftQuery)
+  else if ($queryType = "fulltextMorph" and $errorAttributeSearch = "")
+  then mpdl-lucene:search($fulltextMorphCollection, $ftMorphQuery)
+  else if ($isAttributeSearch and $errorAttributeSearch = "")
+  then mpdl-lucene:attrSearch($metadataStr, $attribute1, $attrQuery1, $boolOp, $attribute2, $attrQuery2)
+  else ()
+  
+let $orderedAttrQueryResult := 
+  if ($queryType = "fulltext" or $queryType = "fulltextMorph")
+  then
+  (for $attrElem in $attrQueryResult
+   order by ft:score($attrElem) descending
+   return $attrElem)
+  else mpdl-lucene:order($attrQueryResult, $orderBy)
+
+let $countResult := count($orderedAttrQueryResult)
+let $countPagesTemp := $countResult idiv $pageSize + 1
+let $countPages :=
+  if((($countResult - 1) idiv $pageSize + 1) = ($countPagesTemp - 1))   
+  then $countPagesTemp - 1   (: if countResult is exactly 10, 20, 30, ... then 1 has to be subtracted   :)
+  else $countPagesTemp
+let $pnLeftNumber :=
+  if ($pn > 1)
+  then $pn - 1
+  else $pn
+let $pnRightNumber :=
+  if ($pn < $countPages)
+  then $pn + 1
+  else $pn
+let $positionFrom := (($pn - 1) * $pageSize) + 1
+let $positionTo := 
+  if ($pn = $countPages)
+  then $countResult
+  else $pn * $pageSize
+
+let $queryUrlPart :=
+  if ($queryType = "fulltext")
+  then concat("&amp;query-type=", $queryType, "&amp;query=", $ftQuery)
+  else if ($queryType = "fulltextMorph")
+  then concat("&amp;query-type=", $queryType, "&amp;query=", $ftMorphQuery)
+  else ""
+
+let $mode :=
+  if ($queryType = "fulltext" or $queryType = "fulltextMorph")
+  then "text"
+  else "image"
+
+let $pageResult := 
+  for $elem at $pos in $orderedAttrQueryResult
+    let $doc := $elem/fn:root()
    let $documentUriOrig := document-uri($doc)
+    let $documentUri := substring-after($documentUriOrig, $docPath)
+    let $documentUriWithoutExtension := substring-before($documentUri, ".")
+    let $docBase := substring-before(substring-after($documentUri, "/"), "/")
+    let $metadata := mpdl-lucene:getMetadata($docBase, $doc)
+    (: Performance: following is slow: why  (would be better structured code) ?
+      let $attrAuthorStr := mpdl-lucene:getElemNameByAttr($docBase, "author")
+      let $author := mpdl-lucene:getElemDynamic($metadataElem, $attrAuthorStr)
+    :)    
+    let $authorElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "author") 
+    let $titleElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "title")
+    let $placeElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "place")
+    let $dateElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "date")
+    let $authors := string-join($authorElems, ', ')
+    let $titles := string-join($titleElems, ', ')
+    let $places := string-join($placeElems, ', ')
+    let $dates := string-join($dateElems, ', ')
+    let $resultElem := 
+      <tr>
+        <td valign="top" style="padding-left:5px;">{$pos}.</td>
+        <td align="middle" valign="top" style="padding-left:7px;"><a href="interface/echo/echoDocuView.xql?document={$documentUri}"><img src="images/book.png" width="15" height="15" border="0"/></a> </td>
+        <td align="middle" valign="top" style="padding-left:7px;"><a href="page-query-result.xql?document={$documentUri}&amp;mode={$mode}{$queryUrlPart}"><img src="images/book.png" width="15" height="15" border="0"/></a> </td>
+        <td align="middle" valign="top"><a href="getDoc?doc={$documentUri}" target="_blank"><img src="images/download.png" width="15" height="15" border="0" alt="Download"/></a></td>
+        <td align="middle" valign="top"><a href="getDoc?doc={$documentUriWithoutExtension}.pdf"><img src="images/download.png" width="15" height="15" border="0" alt="Download"/></a></td>
+        <td align="middle" valign="top"><a href="getDoc?doc={$documentUriWithoutExtension}.html" target="_blank"><img src="images/download.png" width="15" height="15" border="0" alt="Download"/></a></td>
+        <td valign="top" style="padding-left:5px;"><i>{$authors}</i></td>
+        <td valign="top" style="padding-left:5px;">{$titles}</td>
+        <td valign="top" style="padding-left:5px;">{$places}</td>
+        <td valign="top" style="padding-left:5px;">{$dates}</td>
+      </tr>
+  where $pos >= $positionFrom and $pos <= $positionTo
+  return $resultElem
+
+let $docBases := string-join($docbase, ';')
+let $title := 
+  if ($queryType = "browse") 
+  then concat("Result of your query: documentBases=", $docBases, ", browse all, orderBy=", $orderBy)
+  else if ($queryType = "attribute" and $isSimpleAttributeSearch)
+  then concat("Result of your query: documentBases=", $docBases, ', "', $attribute1, '"', " ", $relOp1, " ", '"', $attrQuery1, '"', ", orderBy=", '"', $orderBy, '"')
+  else if ($queryType = "attribute" and $isBooleanAttributeSearch)
+  then concat("Result of your query: documentBases=", $docBases, ', "', $attribute1, '"', " ", $relOp1, " ", '"', $attrQuery1, '"', $boolOp, '"', $attribute2, '"', " ", $relOp2, " ", '"', $attrQuery2, '"', ", orderBy=", '"', $orderBy, '"')
+  else if ($queryType = "fulltext")
+  then concat("Result of your fulltext query: documentBases=", $docBases, '"', $ftQuery, ', "', ", orderBy=", '"', "relevance", '"')
+  else if ($queryType = "fulltextMorph")
+  then concat("Result of your morphological fulltext query: documentBases=", $docBases, ', "', $ftMorphQuery, '"', ", language=", '"', $language, '"', ", orderBy=", '"', "relevance", '"')
+  else ()
+
+let $resultHeaderTable := 
+      <table width="100%">
+        <colgroup>
+          <col width="85%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+        </colgroup>
+        <tr>
+        <td align="left">{$positionFrom} - {$positionTo} of {$countResult} documents</td>
+        <form action="attribute-query-result.xql" method="get">
+          <input type="hidden" name="docbase" value="{$docbase}"/>
+          <input type="hidden" name="query-type" value="{$queryType}"/>
+          <input type="hidden" name="attribute1" value="{$attribute1}"/>
+          <input type="hidden" name="relOp1" value="{$relOp1}"/>
+          <input type="hidden" name="attr-query1" value="{$attrQuery1}"/>
+          <input type="hidden" name="boolOp" value="{$boolOp}"/>
+          <input type="hidden" name="attribute2" value="{$attribute2}"/>
+          <input type="hidden" name="relOp2" value="{$relOp2}"/>
+          <input type="hidden" name="attr-query2" value="{$attrQuery2}"/>
+          <input type="hidden" name="order-by" value="{$orderBy}"/>
+          <input type="hidden" name="ft-query" value="{$ftQuery}"/>
+          <input type="hidden" name="ft-morph-query" value="{$ftMorphQuery}"/>
+          <input type="hidden" name="language" value="{$language}"/>
+          <td><button id="buttonLeftNumber" name="pn" value="{$pnLeftNumber}" style="background:none;border:none;"><img src="images/left.gif"/></button></td>
+          <td nowrap="true">{$pn} / {$countPages}</td>
+          <td><button id="buttonRightNumber" name="pn" value="{$pnRightNumber}" style="background:none;border:none;"><img src="images/right.gif"/></button></td>
+        </form>
+        <form action="attribute-query-result.xql" method="get">
+          <input type="hidden" name="docbase" value="{$docbase}"/>
+          <input type="hidden" name="query-type" value="{$queryType}"/>
+          <input type="hidden" name="attribute1" value="{$attribute1}"/>
+          <input type="hidden" name="relOp1" value="{$relOp1}"/>
+          <input type="hidden" name="attr-query1" value="{$attrQuery1}"/>
+          <input type="hidden" name="boolOp" value="{$boolOp}"/>
+          <input type="hidden" name="attribute2" value="{$attribute2}"/>
+          <input type="hidden" name="relOp2" value="{$relOp2}"/>
+          <input type="hidden" name="attr-query2" value="{$attrQuery2}"/>
+          <input type="hidden" name="order-by" value="{$orderBy}"/>
+          <input type="hidden" name="ft-query" value="{$ftQuery}"/>
+          <input type="hidden" name="ft-morph-query" value="{$ftMorphQuery}"/>
+          <input type="hidden" name="language" value="{$language}"/>
+          <td nowrap="true">Page: <input type="text" size="3" name="pn" value="{$pn}"/></td>
+        </form>
+        </tr>
+      </table>
+
+let $attrQueryResultError := string($attrQueryResult/error)
+let $resultHeader := 
+  if ($attrQueryResultError = '' and $countResult > 0)
+  then $resultHeaderTable
+  else if ($attrQueryResultError != '')
+  then (<b>Your query delivers an error: </b>, $attrQueryResultError)
+  else if ($errorAttributeSearch != '')
+  then (<b>Your query delivers an error: </b>, $errorAttributeSearch)
+  else (<b>Your query delivers no result</b>)
+
+let $resultPageBody := 
+  if ($attrQueryResultError = '' and $countResult > 0)
+  then 
+    <form action="attribute-query-result.xql" method="get">
+      <input type="hidden" name="docbase" value="{$docbase}"/>
+      <input type="hidden" name="query-type" value="{$queryType}"/>
+      <input type="hidden" name="attribute1" value="{$attribute1}"/>
+      <input type="hidden" name="relOp1" value="{$relOp1}"/>
+      <input type="hidden" name="attr-query1" value="{$attrQuery1}"/>
+      <input type="hidden" name="boolOp" value="{$boolOp}"/>
+      <input type="hidden" name="attribute2" value="{$attribute2}"/>
+      <input type="hidden" name="relOp2" value="{$relOp2}"/>
+      <input type="hidden" name="attr-query2" value="{$attrQuery2}"/>
+      <input type="hidden" name="ft-query" value="{$ftQuery}"/>
+      <input type="hidden" name="ft-morph-query" value="{$ftMorphQuery}"/>
+      <input type="hidden" name="language" value="{$language}"/>
+      <input type="hidden" name="pn" value="{$pn}"/>
+    <table width="100%" border="2" rules="groups">
+    <colgroup>
+      <col width="2%"/>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="15%"/>
+      <col width="42%"/>
+      <col width="15%"/>
+      <col width="6%"/>
+    </colgroup>
+    <thead>
+    <tr>
+      <th align="left" valign="top">
+        <button id="dummy" name="order-by" value="{$orderBy}" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">No.</button>
+      </th>
+      <th align="left" valign="top"><button id="dummy" name="order-by" value="{$orderBy}" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Full view</button></th>
+      <th align="left" valign="top"><button id="dummy" name="order-by" value="{$orderBy}" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Lite view</button></th>
+      <th align="left" valign="top"><button id="dummy" name="order-by" value="author" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Xml</button></th>
+      <th align="left" valign="top"><button id="dummy" name="order-by" value="author" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Pdf</button></th>
+      <th align="left" valign="top"><button id="dummy" name="order-by" value="author" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Html</button></th>
+      <th align="left" valign="top">
+        <button name="order-by" value="author" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Author</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="order-by" value="title" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Title</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="order-by" value="place" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Place</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="order-by" value="date" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Year</button>
+      </th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr/>
+      {$pageResult}
+    </tbody>
+    </table>
+    </form>
+  else ()
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+return
+<html>
+ <head>
+  <title>{$title}</title>
+ </head>
+<body>
+  <p style="font-weight:bold;font-size:20px">{$title}</p>
+  {$resultHeader}
+  {$resultPageBody}
+  <p/>
+Elapsed time: {$neededTime} ms, Back to <a href="query.xql">query page</a>, see the <a href="attribute-query-result.xql?_source=yes">XQuery source</a> of this page
+  <p/>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/admin.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,18 @@
+xquery version "1.0";
+
+import module namespace request="http://exist-db.org/xquery/request";
+
+let $operation := request:get-parameter("operation", "")
+let $jobId := mpdldoc:do(string($operation), 'empty', 'empty', 'empty', 'empty', 'empty', 'empty')
+
+return 
+<html>
+<head>
+  <title>Admin</title>
+</head>
+<body>
+  <h1>Admin</h1>
+  <b>JobId of your operation:</b> {$jobId}
+  
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/doc-operation-exist.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,259 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace escidocItem="http://www.escidoc.de/schemas/item/0.9";
+declare namespace container="http://www.escidoc.de/schemas/container/0.8";
+declare namespace escidocMetadataRecords="http://www.escidoc.de/schemas/metadatarecords/0.5";
+declare namespace dc="http://purl.org/dc/elements/1.1/";
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace mpiwg="http://www.mpiwg-berlin.mpg.de/ns/mpiwg";
+
+let $docBaseReq := request:get-parameter("docBase", "")
+let $docBase :=
+  if ($docBaseReq = '')
+  then 'echo'
+  else $docBaseReq
+let $languageReq := request:get-parameter("language", "")
+let $language :=
+  if ($languageReq = '')
+  then 'la'
+  else string($languageReq)
+
+let $docPathStandard := "/db/mpdl/documents/standard"
+let $docPath := concat($docPathStandard, "/", $docBase, "/", $language)
+let $docCollectionStr := concat("collection('", $docPath, "')")
+let $docCollection := util:eval($docCollectionStr)
+let $docFileNames := 
+  for $elem at $pos in $docCollection
+    let $doc := $elem/fn:root()
    let $documentUriOrig := document-uri($doc)
+    let $documentFileName := substring-after(substring-after($documentUriOrig, $docPath), "/")
+  return $documentFileName
+
+let $javascriptHtml :=
+  <script type="text/javascript">
+    <!--
+    function DocumentSelection() {
+      var existIdentifier = document.docBaseList.doc[document.docBaseList.doc.selectedIndex].value;
+      var existLink = "http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=".concat(existIdentifier);
+      var existIdentifierSplit = existIdentifier.split("/");
+      var docBase = existIdentifierSplit[1];
+      var language = existIdentifierSplit[2];
+      var fileName = existIdentifierSplit[3];
+      document.formDocOperation.docBase.value = docBase;
+      document.formDocOperation.language.value = language;
+      document.formDocOperation.fileName.value = fileName;
+      document.getElementById("existLink").href = existLink;
+      document.getElementById("existLink").firstChild.nodeValue = existIdentifier;
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.formDocOperation.srcUrl.value = "";
+    }
+    function OperationSelection() {
+      if (document.formDocOperation.operation.selectedIndex == 1) {
+        document.formDocOperation.srcLocalFileName.value = "";
+        document.formDocOperation.srcUrl.value = "";
+      }
+    }
+    function LocalFileNameSelection() {
+      var srcLocalFileName = document.formDocOperation.srcLocalFileName.value;
+      document.formDocOperation.fileName.value = srcLocalFileName;
+      document.formDocOperation.srcUrl.value = "";
+      document.getElementById("existLink").href = "";
+      document.getElementById("existLink").firstChild.nodeValue = "";
+    }
+    function UrlSelection() {
+      var srcUrl = document.formDocOperation.srcUrl.value;
+      var startPos = srcUrl.lastIndexOf("/");
+      var endPos = srcUrl.length;
+      var fileName = srcUrl.substring(startPos + 1, endPos);
+      document.formDocOperation.fileName.value = fileName;
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.getElementById("existLink").href = "";
+      document.getElementById("existLink").firstChild.nodeValue = "";
+    }
+    function ResetSrcLocalFileName() {
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.formDocOperation.srcUrl.value = "";
+      document.formDocOperation.fileName.value = "";
+    }
+    function DocBaseRefreshDest() {
+      var docBase = document.formDocOperation.docBase[document.formDocOperation.docBase.selectedIndex].value;
+      DocBaseRefresh(docBase);
+    }
+    function DocBaseRefreshList() {
+      var docBase = document.docBaseList.docBase[document.docBaseList.docBase.selectedIndex].value;
+      DocBaseRefresh(docBase);
+    }
+    function DocBaseRefresh(docBase) {
+      document.docBaseList.docBase.value = docBase;
+      for (i = 0; i < document.docBaseList.doc.length; i++)
+        document.docBaseList.doc[i].selected = false;
+      document.docBaseList.submit();
+    }
+    function LanguageRefreshDest() {
+      var lang = document.formDocOperation.language[document.formDocOperation.language.selectedIndex].value;
+      LanguageRefresh(lang);
+    }
+    function LanguageRefreshList() {
+      var lang = document.docBaseList.language[document.docBaseList.language.selectedIndex].value;
+      LanguageRefresh(lang);
+    }
+    function LanguageRefresh(language) {
+      document.docBaseList.language.value = language;
+      for (i = 0; i < document.docBaseList.doc.length; i++)
+        document.docBaseList.doc[i].selected = false;
+      document.docBaseList.submit();
+    }
+    -->
+  </script>
+
+let $eSciDocCookieId := session:get-attribute("eSciDocCookieId")
+
+let $docBaseOptions :=
+          <select>
+            <option value ="archimedes">Archimedes</option>
+            <option value ="echo">Echo</option>
+          </select>
+let $docBaseOptionsSelected :=
+  for $option in $docBaseOptions/option
+    return element { node-name($option)}
+                   { if ($option/@value = $docBase)
+                     then attribute {'selected'}
+                                    {'true'}
+                     else (),
+                     $option/@*,
+                     $option/node() }
+let $docBaseSelectBoxDest :=  
+  <select name="docBase" onchange="DocBaseRefreshDest()">{$docBaseOptionsSelected}</select>
+let $docBaseSelectBoxList :=
+  <select name="docBase" onchange="DocBaseRefreshList()">{$docBaseOptionsSelected}</select>
+
+let $languageOptions :=
+          <select>
+            <option value = "ar">Arabic</option>
+            <option value = "zh">Chinese</option>
+            <option value = "nl">Dutch</option>
+            <option value = "en">English</option>
+            <option value = "fr">French</option>
+            <option value = "de">German</option>
+            <option value = "el">Greek</option>
+            <option value = "it">Italian</option>
+            <option value = "la">Latin</option>
+          </select>
+let $languageOptionsSelected :=
+  for $option in $languageOptions/option
+    return element { node-name($option)}
+                   { if ($option/@value = $language)
+                     then attribute {'selected'}
+                                    {'true'}
+                     else (),
+                     $option/@*,
+                     $option/node() }
+let $languageSelectBoxDest :=  
+  <select name="language" onchange="LanguageRefreshDest()">{$languageOptionsSelected}</select>
+let $languageSelectBoxList :=
+  <select name="language" onchange="LanguageRefreshList()">{$languageOptionsSelected}</select>
+
+let $docsSelectBoxOptions := 
+  for $docFileName at $pos in $docFileNames
+    let $existIdentifier := concat("/", $docBase, "/", $language, "/", $docFileName)
+    let $option := <option value ="{$existIdentifier}">{$docFileName}</option>
+  order by $docFileName
+  return $option
+let $docsSelectBox := 
+  <select name="doc" style="width: 100%;" size="20" onclick="DocumentSelection()">
+    {$docsSelectBoxOptions}
+  </select>
+
+let $error :=
+  if ($eSciDocCookieId = '' or empty($eSciDocCookieId))
+  then <bla>No login context available. Please <a href="login-exist.xql">login</a> before you do an operation</bla>
+  else "no"
+
+let $resultHtml := 
+  if ($error = 'no')
+  then 
+    <div>
+    <table align="middle" width="100%">
+      <colgroup>
+        <col width="50%"/>
+        <col width="50%"/>
+      </colgroup>
+      <tr>
+      <td valign="top">
+        <form name="formDocOperation" action="{session:encode-url(xs:anyURI('doc-operation-result-exist.xql'))}" method="post" enctype="multipart/form-data">
+        <table>
+          <tr><td><b>Operation</b></td></tr>
+          <tr>
+            <td>
+              <select name="operation" onchange="OperationSelection()">
+                <option value ="updateExist" selected="true">Create/Update</option>
+                <option value ="deleteExist">Delete</option>
+              </select>
+              <input type="submit" name="performOperation" value="Execute"/>
+              <a href="../info.xql?info=docInterfaceOperation" onclick="window.open(&quot;../info.xql?info=docInterfaceOperation&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface operation"/></a>
+            </td>
+          </tr>
+          <tr><td><br/></td></tr>
+          <tr><td><b>Source <a href="../info.xql?info=docInterfaceSource" onclick="window.open(&quot;../info.xql?info=docInterfaceSource&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface source"/></a></b></td></tr>
+          <tr><td>Local file: <input type="file" size="40" name="srcLocalFileName" onchange="LocalFileNameSelection()" maxlength="10000000" accept="text/xml" value="srcLocalFileName"/>
+                              <input type="button" name="resetSrcLocalFileName" value="Reset" onclick="ResetSrcLocalFileName()"/></td></tr>
+          <tr><td><text style="margin-left:10px;"></text>or</td></tr>
+          <tr><td>Url: <input type="text" size="40" name="srcUrl" onchange="UrlSelection()" value=""/></td></tr>
+          <tr><td><br/></td></tr>
+          <tr><td><b>Destination</b></td></tr>
+          <tr>
+            <td>Document base: 
+              {$docBaseSelectBoxDest}
+            </td>
+          </tr>
+          <tr>
+            <td>Language: 
+              {$languageSelectBoxDest}
+            </td>
+          </tr>
+          <tr><td>Document name: <input type="text" size="40" name="fileName" value=""/> <a href="../info.xql?info=docInterfaceDestDocName" onclick="window.open(&quot;../info.xql?info=docInterfaceDestDocName&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface source"/></a></td></tr>
+          <tr><td>Document link: <a id="existLink" href=""></a></td></tr>
+        </table>
+        </form>
+      </td>
+      <td valign="top">
+        <form name="docBaseList" action="doc-operation-exist.xql" method="get">
+        <table>
+          <tr>
+            <td>
+              <b>Documents</b><br/>
+              <br/>
+              Document base: 
+              {$docBaseSelectBoxList}
+              Language:
+              {$languageSelectBoxList}
+            </td>
+          </tr>
+          <tr><td>{$docsSelectBox}</td></tr>
+        </table>
+        </form>
+      </td>
+      </tr>
+    </table>
+    </div>
+  else 
+    <div><b>Error in operation:</b> {$error}</div> 
+
+
+
+let $title := "MPDL: eXist document interface"
+return
+<html>
+<head>
+<title>{$title}</title>
+{$javascriptHtml}
+</head>
+<body>
+  <h1>{$title}</h1>
+  {$resultHtml}
+  <hr/>
+  See the <a href="doc-operation-exist.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/doc-operation-result-exist.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,67 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace file = "http://exist-db.org/xquery/file";
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace session="http://exist-db.org/xquery/session";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace xmldb = "http://exist-db.org/xquery/xmldb";
+
+let $login := xmldb:authenticate("xmldb:exist:///db", "admin", "")
+
+let $operation := request:get-parameter("operation", "")
+let $docBase := request:get-parameter("docBase", "")
+let $language := request:get-parameter("language", "")
+let $fileName := request:get-parameter("fileName", "")
+
+let $eSciDocCookieId := session:get-attribute("eSciDocCookieId")
+
+let $srcLocalFileName := request:get-uploaded-file-name("srcLocalFileName")
+let $srcExistUploadFileJavaObject := request:get-uploaded-file("srcLocalFileName")
+let $srcExistUploadFileName := string(<b>{$srcExistUploadFileJavaObject}</b>)
+let $srcExistUploadFileUrl := concat("file://", $srcExistUploadFileName)
+
+let $reqSrcUrl := request:get-parameter("srcUrl", "")
+let $srcUrl :=
+  if ($reqSrcUrl = '')
+  then $srcExistUploadFileUrl
+  else $reqSrcUrl
+
+let $error :=
+  if ($eSciDocCookieId = '' or empty($eSciDocCookieId))
+  then <bla>No login context available. Please <a href="login-exist.xql">login</a> before you do an operation</bla>
+  else if(($operation = 'updateExist') and ($srcUrl = ''))
+  then "please specify your source"
+  else if(($operation = 'updateExist' or $operation = 'delete') and ($fileName = ''))
+  then "please specify your destination document name"
+  else "no"
+
+let $jobId := 
+  if($error = 'no' and $operation = 'updateExist')
+  then mpdldoc:do($operation, $srcUrl, $srcLocalFileName, $docBase, $language, $fileName, $eSciDocCookieId)
+  else if($error = 'no' and $operation = 'deleteExist')
+  then mpdldoc:do($operation, 'empty', 'empty', $docBase, $language, $fileName, $eSciDocCookieId)
+  else ()
+let $redirectUrl := <a href="../scheduler/get-jobs.xql?id={$jobId}">here</a>
+let $resultHtml := 
+  if ($error = 'no')
+  then <div>See the status of your document operation {$redirectUrl}</div>
+  else <div><b>Error in your document operation:</b> {$error}</div> 
+
+let $title := "MPDL: eXist document management"
+return
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+  {$resultHtml} 
+  <br/>
+  <br/>
+  <br/>
+  <hr/>
+  Back to <a href="doc-operation-exist.xql">document operation page</a>, see the <a href="doc-operation-result-exist.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/doc-operation-result.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,67 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace file = "http://exist-db.org/xquery/file";
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace session="http://exist-db.org/xquery/session";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace xmldb = "http://exist-db.org/xquery/xmldb";
+
+let $login := xmldb:authenticate("xmldb:exist:///db", "admin", "")
+
+let $operation := request:get-parameter("operation", "")
+let $docBase := request:get-parameter("docBase", "")
+let $language := request:get-parameter("language", "")
+let $fileName := request:get-parameter("fileName", "")
+
+let $eSciDocCookieId := session:get-attribute("eSciDocCookieId")
+
+let $srcLocalFileName := request:get-uploaded-file-name("srcLocalFileName")
+let $srcExistUploadFileJavaObject := request:get-uploaded-file("srcLocalFileName")
+let $srcExistUploadFileName := string(<b>{$srcExistUploadFileJavaObject}</b>)
+let $srcExistUploadFileUrl := concat("file://", $srcExistUploadFileName)
+
+let $reqSrcUrl := request:get-parameter("srcUrl", "")
+let $srcUrl :=
+  if ($reqSrcUrl = '')
+  then $srcExistUploadFileUrl
+  else $reqSrcUrl
+
+let $error :=
+  if ($eSciDocCookieId = '' or empty($eSciDocCookieId))
+  then <bla>No login context available. Please <a href="login.xql">login</a> before you do an operation</bla>
+  else if(($operation = 'create' or $operation = 'update') and ($srcUrl = ''))
+  then "please specify your source"
+  else if(($operation = 'create' or $operation = 'update' or $operation = 'delete') and ($fileName = ''))
+  then "please specify your destination document name"
+  else "no"
+
+let $jobId := 
+  if($error = 'no' and ($operation = 'create' or $operation = 'update'))
+  then mpdldoc:do($operation, $srcUrl, $srcLocalFileName, $docBase, $language, $fileName, $eSciDocCookieId)
+  else if($error = 'no' and ($operation = 'delete'))
+  then mpdldoc:do($operation, 'empty', 'empty', $docBase, $language, $fileName, $eSciDocCookieId)
+  else ()
+let $redirectUrl := <a href="../scheduler/get-jobs.xql?id={$jobId}">here</a>
+let $resultHtml := 
+  if ($error = 'no')
+  then <div>See the status of your document operation {$redirectUrl}</div>
+  else <div><b>Error in your document operation:</b> {$error}</div> 
+
+let $title := "MPDL: eXist/eSciDoc document management"
+return
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+  {$resultHtml} 
+  <br/>
+  <br/>
+  <br/>
+  <hr/>
+  Back to <a href="doc-operation.xql">document operation page</a>, see the <a href="doc-operation-result.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/doc-operation.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,319 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace escidocItem="http://www.escidoc.de/schemas/item/0.9";
+declare namespace container="http://www.escidoc.de/schemas/container/0.8";
+declare namespace escidocMetadataRecords="http://www.escidoc.de/schemas/metadatarecords/0.5";
+declare namespace dc="http://purl.org/dc/elements/1.1/";
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace mpiwg="http://www.mpiwg-berlin.mpg.de/ns/mpiwg";
+
+let $docBaseReq := request:get-parameter("docBase", "")
+let $docBase :=
+  if ($docBaseReq = '')
+  then 'echo'
+  else $docBaseReq
+let $languageReq := request:get-parameter("language", "")
+let $language :=
+  if ($languageReq = '')
+  then 'la'
+  else string($languageReq)
+
+let $docPathStandard := "/db/mpdl/documents/standard"
+let $docPath := concat($docPathStandard, "/", $docBase, "/", $language)
+let $docCollectionStr := concat("collection('", $docPath, "')")
+let $docCollection := util:eval($docCollectionStr)
+let $docFileNames := 
+  for $elem at $pos in $docCollection
+    let $doc := $elem/fn:root()
    let $documentUriOrig := document-uri($doc)
+    let $documentFileName := substring-after(substring-after($documentUriOrig, $docPath), "/")
+  return $documentFileName
+
+let $javascriptHtml :=
+  <script type="text/javascript">
+    <!--
+    function DocumentSelection() {
+      var existIdentifier = document.docBaseList.doc[document.docBaseList.doc.selectedIndex].value;
+      var eSciDocCookieId = document.docBaseList.eSciDocCookieId.value;
+      var existLink = "http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=".concat(existIdentifier);
+      var existIdentifierSplit = existIdentifier.split("/");
+      var docBase = existIdentifierSplit[1];
+      var language = existIdentifierSplit[2];
+      var fileName = existIdentifierSplit[3];
+      document.formDocOperation.docBase.value = docBase;
+      document.formDocOperation.language.value = language;
+      document.formDocOperation.fileName.value = fileName;
+      document.getElementById("existLink").href = existLink;
+      document.getElementById("existLink").firstChild.nodeValue = existIdentifier;
+      UpdateESciDocLink(existIdentifier, eSciDocCookieId);
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.formDocOperation.srcUrl.value = "";
+    }
+    function OperationSelection() {
+      if (document.formDocOperation.operation.selectedIndex == 1) {
+        document.formDocOperation.srcLocalFileName.value = "";
+        document.formDocOperation.srcUrl.value = "";
+      }
+    }
+    function LocalFileNameSelection() {
+      var srcLocalFileName = document.formDocOperation.srcLocalFileName.value;
+      document.formDocOperation.fileName.value = srcLocalFileName;
+      document.formDocOperation.srcUrl.value = "";
+      document.getElementById("existLink").href = "";
+      document.getElementById("existLink").firstChild.nodeValue = "";
+      document.getElementById("eSciDocLink").href = "";
+      document.getElementById("eSciDocLink").firstChild.nodeValue = "";
+    }
+    function UrlSelection() {
+      var srcUrl = document.formDocOperation.srcUrl.value;
+      var startPos = srcUrl.lastIndexOf("/");
+      var endPos = srcUrl.length;
+      var fileName = srcUrl.substring(startPos + 1, endPos);
+      document.formDocOperation.fileName.value = fileName;
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.getElementById("existLink").href = "";
+      document.getElementById("existLink").firstChild.nodeValue = "";
+      document.getElementById("eSciDocLink").href = "";
+      document.getElementById("eSciDocLink").firstChild.nodeValue = "";
+    }
+    function ResetSrcLocalFileName() {
+      document.formDocOperation.srcLocalFileName.value = "";
+      document.formDocOperation.srcUrl.value = "";
+      document.formDocOperation.fileName.value = "";
+    }
+    function DocBaseRefreshDest() {
+      var docBase = document.formDocOperation.docBase[document.formDocOperation.docBase.selectedIndex].value;
+      DocBaseRefresh(docBase);
+    }
+    function DocBaseRefreshList() {
+      var docBase = document.docBaseList.docBase[document.docBaseList.docBase.selectedIndex].value;
+      DocBaseRefresh(docBase);
+    }
+    function DocBaseRefresh(docBase) {
+      document.docBaseList.docBase.value = docBase;
+      for (i = 0; i < document.docBaseList.doc.length; i++)
+        document.docBaseList.doc[i].selected = false;
+      document.docBaseList.submit();
+    }
+    function LanguageRefreshDest() {
+      var lang = document.formDocOperation.language[document.formDocOperation.language.selectedIndex].value;
+      LanguageRefresh(lang);
+    }
+    function LanguageRefreshList() {
+      var lang = document.docBaseList.language[document.docBaseList.language.selectedIndex].value;
+      LanguageRefresh(lang);
+    }
+    function LanguageRefresh(language) {
+      document.docBaseList.language.value = language;
+      for (i = 0; i < document.docBaseList.doc.length; i++)
+        document.docBaseList.doc[i].selected = false;
+      document.docBaseList.submit();
+    }
+    function UpdateESciDocLinkTemp() {
+      if (http.readyState == 4) {
+      	var eSciDocContainerId = http.responseText.trim();
+        if (eSciDocContainerId != "") {
+          var eSciDocLink = "http://euler.mpiwg-berlin.mpg.de:8080".concat(eSciDocContainerId);
+          document.getElementById("eSciDocLink").href = eSciDocLink;
+          document.getElementById("eSciDocLink").firstChild.nodeValue = eSciDocContainerId;
+        } else {
+          document.getElementById("eSciDocLink").href = "";
+          document.getElementById("eSciDocLink").firstChild.nodeValue = "";
+        }
+        isWorking = false;
+      }
+    }
+    function UpdateESciDocLink(existId, eSciDocCookieId) {
+      if (!isWorking && http) {
+        http.open("GET", "get-escidoc-containerid.xql?existId=" + existId + "&eSciDocCookieId=" + eSciDocCookieId);
+        http.onreadystatechange = UpdateESciDocLinkTemp;  
+        // this sets the call-back function to be invoked when a response from the HTTP request is returned
+        isWorking = true;
+        http.send(null);
+      }
+    }
+    function GetHTTPObject() {
+      var xmlhttp;
+      /*@cc_on
+      @if (@_jscript_version >= 5)
+        try {
+          xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+        } catch (e) {
+          try {
+            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+          } catch (E) {
+            xmlhttp = false;
+          }
+        }
+      @else
+      xmlhttp = false;
+      @end @*/
+      if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
+        try {
+          xmlhttp = new XMLHttpRequest();
+          xmlhttp.overrideMimeType("text/xml"); 
+        } catch (e) {
+          xmlhttp = false;
+        }
+      }
+      return xmlhttp;
+    }
+    var http = GetHTTPObject(); //  create the HTTP Object
+    var isWorking = false;
+    -->
+  </script>
+
+let $eSciDocCookieId := session:get-attribute("eSciDocCookieId")
+
+let $docBaseOptions :=
+          <select>
+            <option value ="archimedes">Archimedes</option>
+            <option value ="echo">Echo</option>
+          </select>
+let $docBaseOptionsSelected :=
+  for $option in $docBaseOptions/option
+    return element { node-name($option)}
+                   { if ($option/@value = $docBase)
+                     then attribute {'selected'}
+                                    {'true'}
+                     else (),
+                     $option/@*,
+                     $option/node() }
+let $docBaseSelectBoxDest :=  
+  <select name="docBase" onchange="DocBaseRefreshDest()">{$docBaseOptionsSelected}</select>
+let $docBaseSelectBoxList :=
+  <select name="docBase" onchange="DocBaseRefreshList()">{$docBaseOptionsSelected}</select>
+
+let $languageOptions :=
+          <select>
+            <option value = "ar">Arabic</option>
+            <option value = "zh">Chinese</option>
+            <option value = "nl">Dutch</option>
+            <option value = "en">English</option>
+            <option value = "fr">French</option>
+            <option value = "de">German</option>
+            <option value = "el">Greek</option>
+            <option value = "it">Italian</option>
+            <option value = "la">Latin</option>
+          </select>
+let $languageOptionsSelected :=
+  for $option in $languageOptions/option
+    return element { node-name($option)}
+                   { if ($option/@value = $language)
+                     then attribute {'selected'}
+                                    {'true'}
+                     else (),
+                     $option/@*,
+                     $option/node() }
+let $languageSelectBoxDest :=  
+  <select name="language" onchange="LanguageRefreshDest()">{$languageOptionsSelected}</select>
+let $languageSelectBoxList :=
+  <select name="language" onchange="LanguageRefreshList()">{$languageOptionsSelected}</select>
+
+let $docsSelectBoxOptions := 
+  for $docFileName at $pos in $docFileNames
+    let $existIdentifier := concat("/", $docBase, "/", $language, "/", $docFileName)
+    let $option := <option value ="{$existIdentifier}">{$docFileName}</option>
+  order by $docFileName
+  return $option
+let $docsSelectBox := 
+  <select name="doc" style="width: 100%;" size="20" onclick="DocumentSelection()">
+    {$docsSelectBoxOptions}
+  </select>
+
+let $error :=
+  if ($eSciDocCookieId = '' or empty($eSciDocCookieId))
+  then <bla>No login context available. Please <a href="login.xql">login</a> before you do an operation</bla>
+  else "no"
+
+let $resultHtml := 
+  if ($error = 'no')
+  then 
+    <div>
+    <table align="middle" width="100%">
+      <colgroup>
+        <col width="50%"/>
+        <col width="50%"/>
+      </colgroup>
+      <tr>
+      <td valign="top">
+        <form name="formDocOperation" action="{session:encode-url(xs:anyURI('doc-operation-result.xql'))}" method="post" enctype="multipart/form-data">
+        <table>
+          <tr><td><b>Operation</b></td></tr>
+          <tr>
+            <td>
+              <select name="operation" onchange="OperationSelection()">
+                <option value ="create" selected="true">Create</option>
+                <option value ="update">Update</option>
+                <option value ="delete">Delete</option>
+              </select>
+              <input type="submit" name="performOperation" value="Execute"/>
+              <a href="../info.xql?info=docInterfaceOperation" onclick="window.open(&quot;../info.xql?info=docInterfaceOperation&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface operation"/></a>
+            </td>
+          </tr>
+          <tr><td><br/></td></tr>
+          <tr><td><b>Source <a href="../info.xql?info=docInterfaceSource" onclick="window.open(&quot;../info.xql?info=docInterfaceSource&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface source"/></a></b></td></tr>
+          <tr><td>Local file: <input type="file" size="40" name="srcLocalFileName" onchange="LocalFileNameSelection()" maxlength="10000000" accept="text/xml" value="srcLocalFileName"/>
+                              <input type="button" name="resetSrcLocalFileName" value="Reset" onclick="ResetSrcLocalFileName()"/></td></tr>
+          <tr><td><text style="margin-left:10px;"></text>or</td></tr>
+          <tr><td>Url: <input type="text" size="40" name="srcUrl" onchange="UrlSelection()" value=""/></td></tr>
+          <tr><td><br/></td></tr>
+          <tr><td><b>Destination</b></td></tr>
+          <tr>
+            <td>Document base: 
+              {$docBaseSelectBoxDest}
+            </td>
+          </tr>
+          <tr>
+            <td>Language: 
+              {$languageSelectBoxDest}
+            </td>
+          </tr>
+          <tr><td>Document name: <input type="text" size="40" name="fileName" value=""/> <a href="../info.xql?info=docInterfaceDestDocName" onclick="window.open(&quot;../info.xql?info=docInterfaceDestDocName&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info document interface source"/></a></td></tr>
+          <tr><td>eXist document link: <a id="existLink" href=""></a></td></tr>
+          <tr><td>eSciDoc document link: <a id="eSciDocLink" href=""></a></td></tr>
+        </table>
+        </form>
+      </td>
+      <td valign="top">
+        <form name="docBaseList" action="doc-operation.xql" method="get">
+        <input type="hidden" name="eSciDocCookieId" value="{$eSciDocCookieId}"/>
+        <table>
+          <tr>
+            <td>
+              <b>Documents</b><br/>
+              <br/>
+              Document base: 
+              {$docBaseSelectBoxList}
+              Language:
+              {$languageSelectBoxList}
+            </td>
+          </tr>
+          <tr><td>{$docsSelectBox}</td></tr>
+        </table>
+        </form>
+      </td>
+      </tr>
+    </table>
+    </div>
+  else 
+    <div><b>Error in operation:</b> {$error}</div> 
+
+
+
+let $title := "MPDL: eXist/eSciDoc document interface"
+return
+<html>
+<head>
+<title>{$title}</title>
+{$javascriptHtml}
+</head>
+<body>
+  <h1>{$title}</h1>
+  {$resultHtml}
+  <hr/>
+  See the <a href="doc-operation.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/get-escidoc-containerid.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,12 @@
+xquery version "1.0";
+
+let $existId := request:get-parameter("existId", "")
+let $eSciDocCookieId := request:get-parameter("eSciDocCookieId", "")
+
+let $eSciDocId := 
+  if ($eSciDocCookieId != '')
+  then mpdldoc:escidoc-get-containerid($existId, $eSciDocCookieId)
+  else ""
+
+return 
+  $eSciDocId
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/index.html	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,20 @@
+<html>
+<head>
+<title>MPDL: document interface</title>
+</head>
+<body>
+<h1>MPDL: document interface</h1>
+<h2>eXist document interface</h2>
+<p>Login to the eXist document interface <a href="login-exist.xql">here</a>.</p>
+<p/><br/>
+If your user account is not active yet, please perform the following steps:
+<ul>
+  <li>Initialize your account: login into eSciDoc with your MPIWG user account (e.g. User-Id: jwillenborg, Password: yourPassword): click <a href="http://euler.mpiwg-berlin.mpg.de:8080/adm">here</a></li>
+  <li>Send an e-mail to <a href="mailto:jwillenborg@mpiwg-berlin.mpg.de">Josef Willenborg</a> with subject &quot;MPDL document interface: get user rights&quot;</li>
+  <li>Wait for an answer mail (this needs normally a few days)</li>
+  <li>Now you have the user rights to read, create, update and delete documents: login into the eXist document interface: click <a href="login-exist.xql">here</a></li>
+</ul>
+<hr/>
+If you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/login-exist.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,61 @@
+xquery version "1.0";
+
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace response="http://exist-db.org/xquery/response";
+declare namespace session="http://exist-db.org/xquery/session";
+
+declare variable $docOperationExistUrlStr { "http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/doc/doc-operation-exist.xql"};
+declare variable $redirect-uri as xs:anyURI { xs:anyURI($docOperationExistUrlStr) };
+
+declare function local:login($userName as xs:string, $password as xs:string) {
+  let $eSciDocCookieId := mpdldoc:escidoc-login($userName, $password)
+  return
+    if ($eSciDocCookieId = '' or empty($eSciDocCookieId)) 
+    then 
+      <p style="color:red">Login failed: User/password is not correct.</p>
+    else if ($eSciDocCookieId = '-10')
+    then
+      <p style="color:red">Login failed: Your user account has not enough user rights for the MPDL document management. Please send an e-mail to <a href="mailto:jwillenborg@mpiwg-berlin.mpg.de">Josef Willenborg</a> with subject &quot;MPDL document interface: get user rights&quot;</p>
+    else
+      (
+        session:set-attribute("userName", $userName),
+        session:set-attribute("eSciDocCookieId", $eSciDocCookieId),
+        response:redirect-to(session:encode-url($redirect-uri))
+      )
+};
+
+declare function local:do-login() {
+  let $userName := request:get-parameter("userName", "")
+  let $password := request:get-parameter("password", "")
+  return
+    if ($userName = '') then
+      ''
+    else
+      local:login($userName, $password)
+};
+
+session:invalidate(),
+session:create(),
+    
+let $title := "MPDL: eXist document management"
+return
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+    <form action="{session:encode-url(request:get-uri())}">
+      <table class="login">
+        <b>User name: </b><input type="text" size="20" name="userName"/><p/>
+        <b>Password: </b><input type="password" size="20" name="password"/><p/>
+        <input type="submit" value="Login"/>
+      </table>
+    </form>
+    { local:do-login() }
+  <hr/>
+  See the <a href="login-exist.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/doc/login.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,61 @@
+xquery version "1.0";
+
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace response="http://exist-db.org/xquery/response";
+declare namespace session="http://exist-db.org/xquery/session";
+
+declare variable $docOperationExistUrlStr { "http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/doc/doc-operation.xql"};
+declare variable $redirect-uri as xs:anyURI { xs:anyURI($docOperationExistUrlStr) };
+
+declare function local:login($userName as xs:string, $password as xs:string) {
+  let $eSciDocCookieId := mpdldoc:escidoc-login($userName, $password)
+  return
+    if ($eSciDocCookieId = '' or empty($eSciDocCookieId)) 
+    then 
+      <p style="color:red">Login failed: User/password is not correct.</p>
+    else if ($eSciDocCookieId = '-10')
+    then
+      <p style="color:red">Login failed: Your user account has not enough user rights for the MPDL document management. Please send an e-mail to <a href="mailto:jwillenborg@mpiwg-berlin.mpg.de">Josef Willenborg</a> with subject &quot;MPDL document interface: get user rights&quot;</p>
+    else
+      (
+        session:set-attribute("userName", $userName),
+        session:set-attribute("eSciDocCookieId", $eSciDocCookieId),
+        response:redirect-to(session:encode-url($redirect-uri))
+      )
+};
+
+declare function local:do-login() {
+  let $userName := request:get-parameter("userName", "")
+  let $password := request:get-parameter("password", "")
+  return
+    if ($userName = '') then
+      ''
+    else
+      local:login($userName, $password)
+};
+
+session:invalidate(),
+session:create(),
+    
+let $title := "MPDL: eXist/eSciDoc document management"
+return
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+    <form action="{session:encode-url(request:get-uri())}">
+      <table class="login">
+        <b>User name: </b><input type="text" size="20" name="userName"/><p/>
+        <b>Password: </b><input type="password" size="20" name="password"/><p/>
+        <input type="submit" value="Login"/>
+      </table>
+    </form>
+    { local:do-login() }
+  <hr/>
+  See the <a href="login.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/escidoc/controller.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,25 @@
+xquery version "1.0";
+
+(: Controller for the eSciDoc REST interface :)
+
+let $bla := ""
+
+return
+if (starts-with($exist:path, '/ir/')) then
+  <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+    <forward url="/mpdl/escidoc/ESciDocRESTServlet">
+      <add-parameter name="escidocUrl" value="{$exist:path}"/>
+    </forward>
+  </dispatch>
+else if (contains($exist:path, '/exist:xquery/execute')) then
+  <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+    <forward url="/mpdl/escidoc/ESciDocRESTServlet">
+      <add-parameter name="escidocUrl" value="{$exist:path}"/>
+    </forward>
+  </dispatch>
+else
+  (: everything else is passed through :)
+  <ignore xmlns="http://exist.sourceforge.net/NS/exist">
+    <cache-control cache="yes"/>
+  </ignore>
+  
\ No newline at end of file
Binary file software/eXist/webapp/mpdl/images/2downarrow.png has changed
Binary file software/eXist/webapp/mpdl/images/2leftarrow.png has changed
Binary file software/eXist/webapp/mpdl/images/2rightarrow.png has changed
Binary file software/eXist/webapp/mpdl/images/2uparrow.png has changed
Binary file software/eXist/webapp/mpdl/images/book-pointer.gif has changed
Binary file software/eXist/webapp/mpdl/images/book.png has changed
Binary file software/eXist/webapp/mpdl/images/camera.png has changed
Binary file software/eXist/webapp/mpdl/images/copyleft.png has changed
Binary file software/eXist/webapp/mpdl/images/dictionary.gif has changed
Binary file software/eXist/webapp/mpdl/images/dictionaryMorph.gif has changed
Binary file software/eXist/webapp/mpdl/images/dot.gif has changed
Binary file software/eXist/webapp/mpdl/images/download.png has changed
Binary file software/eXist/webapp/mpdl/images/echo.gif has changed
Binary file software/eXist/webapp/mpdl/images/figures.png has changed
Binary file software/eXist/webapp/mpdl/images/help.png has changed
Binary file software/eXist/webapp/mpdl/images/image.jpg has changed
Binary file software/eXist/webapp/mpdl/images/imageU.jpg has changed
Binary file software/eXist/webapp/mpdl/images/info.png has changed
Binary file software/eXist/webapp/mpdl/images/left.gif has changed
Binary file software/eXist/webapp/mpdl/images/malcolm.jpg has changed
Binary file software/eXist/webapp/mpdl/images/malcolm.tif has changed
Binary file software/eXist/webapp/mpdl/images/pirate-joey.gif has changed
Binary file software/eXist/webapp/mpdl/images/right.gif has changed
Binary file software/eXist/webapp/mpdl/images/search.gif has changed
Binary file software/eXist/webapp/mpdl/images/searchMorph.gif has changed
Binary file software/eXist/webapp/mpdl/images/searchStructural.gif has changed
Binary file software/eXist/webapp/mpdl/images/searchXPath.gif has changed
Binary file software/eXist/webapp/mpdl/images/text.jpg has changed
Binary file software/eXist/webapp/mpdl/images/textPollux.jpg has changed
Binary file software/eXist/webapp/mpdl/images/textPolluxU.jpg has changed
Binary file software/eXist/webapp/mpdl/images/textU.jpg has changed
Binary file software/eXist/webapp/mpdl/images/toc.gif has changed
Binary file software/eXist/webapp/mpdl/images/xml.jpg has changed
Binary file software/eXist/webapp/mpdl/images/xmlU.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/index.html	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,10 @@
+<html>
+<head>
+<meta name="google-site-verification" content="VZQ3B2hCGA5HPlUJVeYN8ZEhZ0PIC4MeFeKFsknTrWQ" />
+<title>MPDL prototype</title>
+</head>
+<body>
+<h1>MPDL prototype</h1>
+please click <a href="query.xql">here</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/info.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,81 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $info := request:get-parameter("info", "")  (: default: no info  :)
+
+let $infoTitle :=
+  if ($info = '')
+  then ()
+  else if ($info = 'mpdl')
+  then 'MPDL prototype'
+  else if ($info = 'docBases')
+  then 'MPDL documents'
+  else if ($info = 'fulltextMorph')
+  then 'Morphological search'
+  else if ($info = 'fulltext')
+  then 'Fulltext search'
+  else if ($info = 'xpath')
+  then 'Xpath'
+  else if ($info = 'xquery')
+  then 'XQuery'
+  else if ($info = 'pollux')
+  then 'MPDL Pollux service.'
+  else if ($info = 'wordInfo')
+  then 'MPDL language technology: Word information.'
+  else ()
+
+let $infoText := 
+  if ($info = '')
+  then ()
+  else if ($info = 'mpdl')
+  then ('The prototype is based on eXist/Lucene technology. It is implemented in XQuery/XPath, XSL and Java. Also eXist itself is extended a little. All software is open source under the LGPL license ', <img src="images/copyleft.png" width="15" height="15" border="0" alt="lgpl"/>, <p/>, 'The MPDL project is funded by the ', <a href="http://www.mpiwg-berlin.mpg.de">Max Planck Institute for the History of Science</a>, '.', <p/>, 'More information about the MPDL project could be found ', <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software">here</a>, '.', <p/>, 'And that is the guy who is the developer of that stuff: ', <p align="middle"><a href="http://josef-willenborg.de"><img valign="middle" src="images/pirate-joey.gif" width="100" height="100" border="0" alt="pirate"/></a></p>)
+  else if ($info = 'malcolm')
+  then (<h2><img alt="Malcolm Hyman" align="right" src="images/malcolm.jpg" width="30%" height="30%"/>Dr. Malcolm Hyman<br/> † September 4, 2009</h2>, <h3>In memoriam</h3>, 'This software is dedicated to Malcolm Hyman, who was the founder and leader of this project. He died suddenly and unexpectedly. This project owes everything to him.', <h3>His homepages</h3>, <ul><li><a href="http://archimedes.fas.harvard.edu/mdh">Harvard University, Department of the Classics</a></li><li><a href="http://www.mpiwg-berlin.mpg.de/en/staff/members/hyman">Max Planck Institute for the History of Science</a></li><li><a href="http://www.harvardscience.harvard.edu/directory/researchers/malcolm-hyman">HarvardScience</a></li></ul>)
+  else if ($info = 'docBases')
+  then (<b>Archimedes DTD (until 2008): </b>, 'more than 120 documents (4KB - 18MB), coming from Echo collections &quot;Archimedes&quot; and &quot;Historical Travel Guides&quot;, languages: latin, italian, english, german, french, dutch, greek, arabic, chinese', <br/>, <br/>, <b>Echo Schema (since2009): </b>, 'planned more than 100 documents in different languages')
+  else if ($info = 'attr')
+  then ('Attribute search is case sensitive.', <p/>, 'Query syntax see: ', <a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Lucene query syntax</a>, '.')
+  else if ($info = 'fulltextMorph')
+  then ('Morphological index is built up by ', <a href="http://archimedes.fas.harvard.edu/cgi-bin/donatus">Donatus</a>, ' and ', <a href="http://snowball.tartarus.org/">Snowball</a>, '. It is case insensitive.', <p/>, 'Query syntax see: ', <a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Lucene query syntax</a>, '.')
+  else if ($info = 'fulltext')
+  then ('Fulltext index is a case sensitive word index. It should be used especially for wildcard searching (with * and ?).', <p/>, 'Query syntax see: ', <a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Lucene query syntax</a>, '.')
+  else if ($info = 'xpath')
+  then (<p>XPath queries are executed against its context (a path relative to the context). The context is the document from which the XPath query is executed.</p>, <p>Example: /archimedes/info/author finds only the author of the document from which the query is executed (and not of all documents). XPath queries are namespace aware.</p>, <p>References: XPath Language 2.0, see: <a href="http://www.w3.org/TR/xpath20/">here</a>.</p>)
+  else if ($info = 'xquery')
+  then (<p>XQueries are executed against its context (a path relative to the context). The context is the document from which the XQuery is executed. XQueries are namespace aware.</p>, <p>Example 1: return all echo:metadata entries of current document<br/>let $result := //echo:metadata/*<br/>return $result<br/></p>, <p>Example 2: count words of first 3 sentences of current document:<br/>let $s := //echo:s<br/>let $first3s := $s[position() &lt; 4]<br/>let $first3Str := string-join($first3s, ' ')<br/>let $wordCounter := count(tokenize($first3Str, '\W+')[. != ''])<br/>return $wordCounter<br/></p>, <p>If you want to query over many documents you could do this for example by specifying the document collection and using an XPath expression relative from this collection: </p>, <p>Example 3 (XQuery over all documents): return all authors of all archimedes documents ordered<br/>let $coll := collection('/db/mpdl/documents/standard/archimedes')<br/>let $result := $coll/archimedes/info/author<br/>let $orderedResult := <br/>&#160;&#160;for $elem in $result<br/>&#160;&#160;order by $elem<br/>&#160;&#160;return $elem<br/>return $orderedResult<br/></p>, <p>References: XQuery  Language 1.0, see <a href="http://www.w3.org/TR/xquery/">here</a>, <a href="http://de.wikipedia.org/wiki/XQuery">Wikipedia article</a>, eXist functions, see <a href="http://demo.exist-db.org/xquery/transform.xql">here</a></p>)
+  else if ($info = 'pollux')
+  then (<p>MPDL <a href="http://archimedes.fas.harvard.edu/pollux">Pollux</a> service.</p>, <p>Following dictionaries are supported</p>, <ul><li>Autenrieth, a Homeric lexicon (10158 entries)</li><li>Baretti, a dictionary of the English and Italian languages (53555 entries)</li><li>Bonitz, index Aristotelicus (14648 entries)</li><li>Cooper, Thesaurus Linguae Romanae et Brittanicae (33124 entries)</li><li>Florio, a worlde of wordes, or most copious, dictionarie in Italian and English (70091 entries)</li><li>Lewis and Short, Latin dictionary (53500 entries)</li><li>Liddell-Scott-Jones, a Greek-English lexicon (112631 entries)</li><li>Salmoné, an advanced learner's Arabic-English dictionary (6360 entries)</li><li>Webster's revised unabridged dictionary - 1913 (111733 entries)</li></ul>)
+  else if ($info = 'wordInfo')
+  then (<p><b>Morphology information</b>: MPDL <a href="http://archimedes.fas.harvard.edu/cgi-bin/donatus">Donatus</a> and <a href="http://snowball.tartarus.org/">Snowball</a>.</p>, <p>Following morphological data is used and provided</p>, <ul><li>Perseus<ul><li>arabic: 97.249 forms</li><li>greek: 1.020.846 forms</li><li>latin: 710.620 forms</li></ul></li><li>Celex<ul><li>dutch: 381.275 forms and 124.136 lemmas</li><li>english: 160.595 forms and 52.447 lemmas</li><li>german: 365.530 forms and 51.728 lemmas</li></ul></li><li>Lexique<ul><li>french: 306.795 forms</li></ul></li></ul>, <p><b>Dictionary information:</b> MPDL <a href="http://archimedes.fas.harvard.edu/pollux">Pollux</a></p>, <p>Following internal dictionaries are provided</p>, <ul><li>Autenrieth, a Homeric lexicon (10158 entries)</li><li>Baretti, a dictionary of the English and Italian languages (53555 entries)</li><li>Bonitz, index Aristotelicus (14648 entries)</li><li>Cooper, Thesaurus Linguae Romanae et Brittanicae (33124 entries)</li><li>Florio, a worlde of wordes, or most copious, dictionarie in Italian and English (70091 entries)</li><li>Lewis and Short, Latin dictionary (53500 entries)</li><li>Liddell-Scott-Jones, a Greek-English lexicon (112631 entries)</li><li>Salmoné, an advanced learner's Arabic-English dictionary (6360 entries)</li><li>Webster's revised unabridged dictionary - 1913 (111733 entries)</li></ul>, <p>Following external dictionaries are provided</p>, <ul><li>Deutsches Wörterbuch der deutschen Sprache</li><li>William J. Slater, Lexicon to Pindar</li><li>The ARTFL project: Dictionnaires d'autrefois: French dictionaries of the 17th, 18th, 19th and 20th centuries</li><li>The ARTFL project: French - English dictionary</li><li>Charlton T. Lewis, an Elementary Latin Dictionary</li><li>Wiktionary: WikiWoordenboek</li><li>Lin Yutang</li></ul>, <p><b>Wikipedia information:</b> MPDL Wiki</p>, <p>Links to following Wikipedia servers are provided</p>, <ul><li>ar.wikipedia.org</li><li>de.wikipedia.org</li><li>el.wikipedia.org</li><li>en.wikipedia.org</li><li>fr.wikipedia.org</li><li>it.wikipedia.org</li><li>la.wikipedia.org</li><li>nl.wikipedia.org</li><li>zh.wikipedia.org</li></ul>, <p><b>Place information</b></p>, <p>Place links in Echo texts are supported. Place dictionaries are not yet implemented</p>)
+  else if ($info = 'donatus')
+  then (<p>MPDL <a href="http://archimedes.fas.harvard.edu/cgi-bin/donatus">Donatus</a> and <a href="http://snowball.tartarus.org/">Snowball</a> service.</p>, <p>At this time following morphological data is used and provided</p>, <ul><li>Perseus<ul><li>arabic: 97.249 forms</li><li>greek: 1.020.846 forms</li><li>latin: 710.620 forms</li></ul></li><li>Celex<ul><li>dutch: 381.275 forms and 124.136 lemmas</li><li>english: 160.595 forms and 52.447 lemmas</li><li>german: 365.530 forms and 51.728 lemmas</li></ul></li><li>Lexique<ul><li>french: 306.795 forms</li></ul></li></ul>)
+  else if ($info = 'docInterfaceOperation')
+  then (<p><b>MPDL document interface: Operation</b><br/> Please do not overload the system by executing too many document operations at the same time. Please finish one document operation after the other. Look into the status of your document operation (each one has a job id) and see if it is finished (job status finished has a time stamp). Then start another operation.</p>)
+  else if ($info = 'docInterfaceSource')
+  then (<p><b>MPDL document interface: Source document</b><br/> The source document has to be a valid XML-document against either the Echo schema (see the <a href="http://mpdl-proto.mpiwg-berlin.mpg.de/exist/rest/db/mpdl/schema/echo/echo.rnc">Echo Relax NG Schema</a>) or against the Archimedes document format</p>)
+  else if ($info = 'docInterfaceDestDocName')
+  then (<p><b>MPDL document interface: Destination document name</b> <ul><li>has to be unique within a document base and a language. If you use a name which is already used - please look in the documents list (on the right side) - it will be updated (not created).</li> <li>always needs the extension &quot;.xml&quot;.</li><li>example: &quot;Benedetti_1585.xml&quot;</li></ul></p>)
+  else ()
+
+
+return
+<html>
+<head>
+<title>MPDL info</title>
+</head>
+<body>
+<table>
+  <tr>
+    <td>
+    <img src="images/info.png" width="20" height="20" border="0" alt="Info MPDL"/>
+    <span>&#160;&#160;&#160;&#160;&#160;</span>
+    <text style="font-weight:bold;font-size:30px">{$infoTitle}</text>
+    </td>
+  </tr>
+  <tr>
+    <td>{$infoText}</td>
+  </tr>
+</table>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/doc-query.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,150 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "../lucene/search.xql";
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "../text/all.xql";
+
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace transform = "http://exist-db.org/xquery/transform";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace dcterms="http://purl.org/dc/terms";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+let $mpdlDocUri := request:get-parameter("document", "")
+let $mode := request:get-parameter("mode", "image")
+let $queryType := request:get-parameter("queryType", "")
+let $query := request:get-parameter("query", "")
+let $reqQueryResultPageSize := request:get-parameter("queryResultPageSize", "")
+let $queryResultPageSize := 
+  if ($reqQueryResultPageSize = '' or $reqQueryResultPageSize = '0')
+  then 100
+  else number($reqQueryResultPageSize)
+let $reqQueryResultPN := request:get-parameter("queryResultPN", "")
+let $queryResultPN := 
+  if ($reqQueryResultPN = '' or $reqQueryResultPN = '0')
+  then 1
+  else number($reqQueryResultPN)
+
+let $presentationPath := "/db/mpdl/presentation"
+(: e.g. mpdlCollectioName is derived from mpdlDocUri: /archimedes/la/yourDoc.xml  :)
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $language := substring-before(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := 
+  if ($queryType = 'fulltext' or $queryType = 'ftIndex')
+  then concat('/db/mpdl/documents/standard', $mpdlDocUri)
+  else if ($queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma' or $queryType = 'ftIndexMorph')
+  then concat('/db/mpdl/documents/morph', $mpdlDocUri)
+  else concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $currentTimeBegin := util:system-time()
+let $documentAvailable := doc-available($fullDocumentUri)
+let $document := doc($fullDocumentUri)
+let $metadata := 
+  if ($docbase = 'archimedes')
+  then $document/archimedes/info
+  else if ($docbase = 'echo')
+  then $document/echo:echo/echo:metadata
+  else ''
+
+(: xQuery inline execution does not work in module so it has to be done here  :) 
+let $xQueryPageSize := 100
+let $xQueryResultEval := 
+  if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then util:eval-inline($document, $query)
+  else ()
+let $xQueryFrom := ($queryResultPN * $xQueryPageSize) - $xQueryPageSize + 1
+let $xQueryTo := $queryResultPN * $xQueryPageSize
+let $xQueryResultEntries := 
+  for $entry at $pos in $xQueryResultEval
+  where $pos >= $xQueryFrom and $pos <= $xQueryTo
+  return $entry
+let $xQuerySize := count($xQueryResultEval)
+let $xQueryPages := 
+  if ($xQuerySize = 0)
+  then 0
+  else $xQuerySize idiv $xQueryPageSize + 1
+let $xQueryResult := 
+      <result>
+        <size>{$xQuerySize}</size>
+        <page-size>{$xQueryPageSize}</page-size>
+        <pages>{$xQueryPages}</pages>
+        <pn>{$queryResultPN}</pn>
+        <hits>{$xQueryResultEntries}</hits>
+      </result>  
+
+let $queryResult := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $query != "")
+  then mpdl-lucene:search($docbase, $language, $document, $queryType, $query, $queryResultPN, $queryResultPageSize)
+  else if (($queryType = 'ftIndex' or $queryType = 'ftIndexMorph') and $query != "")
+  then mpdl-text:indexTerms($docbase, $language, $document, $query, $queryResultPN, $queryResultPageSize)
+  else if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then $xQueryResult
+  else if ($queryType = 'toc' or $queryType = 'figures')
+  then mpdl-text:get-toc($docbase, $queryType, $document, $queryResultPN, $queryResultPageSize)
+  else if ($query = "")
+  then 
+      <result>
+        <size>0</size>
+        <page-size>0</page-size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>
+  else ()
+
+let $countHits := count($queryResult/result/hits/hit)
+let $firstHit := $queryResult/result/hits/hit[1]
+
+(: 10 or more is an error :)
+let $errorCode := 
+  if (not($documentAvailable))
+  then 10
+  else 0
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode < 10)
+  then 
+    <result>
+      <document-description>
+        <uri>{$mpdlDocUri}</uri>
+        <collection-name>{$docbase}</collection-name>
+        <document-name>{$documentName}</document-name>
+        <language>{$language}</language>
+      </document-description>
+      <page>
+        <mode>{$mode}</mode>
+      </page>
+      <query>
+        <type>{$queryType}</type>
+        <expression>{$query}</expression>
+        {$queryResult}
+      </query>
+      <performance>{$neededTime}</performance>
+    </result>
+  else if ($errorCode = 10)
+  then <error><number>{$errorCode}</number><description>Fulltext document: {$mpdlDocUri} is not available yet</description></error>
+  else <error><number>{$errorCode}</number><description>undefined error: {$errorCode}</description></error>  
+
+let $declare := 
+  if ($mode = "text" or $mode = "textPollux" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+  else if ($mode = "pureXml")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+let $xslFilePath := 
+  if($mode = "text" or $mode = "textPollux" or $mode = "image" or $mode = "xml")
+  then concat($presentationPath, "/queryHtml.xsl")
+  else concat($presentationPath, "/pageXml.xsl")
+let $xslDoc := doc($xslFilePath)
+let $result := 
+  if($errorCode < 10)
+  then transform:transform($xmlResult, $xslDoc, ())
+  else
+    <div>{$xmlResult}</div>  (:  error xml result  :)
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/echo/controller.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,25 @@
+xquery version "1.0";
+
+(: Controller XQuery for the mpdl application. :)
+
+declare namespace dcterms="http://purl.org/dc/terms";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+
+let $mpdlDocUri := "/archimedes/it/borro_fluss_012_it_1561.xml"
+(: let $echoArchivePath := mpdl-text:getEchoArchivePath($mpdlDocUri)  :)
+let $echoURLDocuView := concat("http://echo.mpiwg-berlin.mpg.de/ECHOdocuView?url=", '')
+
+return
+if (starts-with($exist:path, '/docuView.xql')) 
+then
+  <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
+    <redirect url="{$echoURLDocuView}"/>
+  </dispatch>
+(:      <add-parameter name="url" value="{$archivePath}"/>  :)
+(:    </forward>  :)
+else
+    (: everything else is passed through :)
+    <ignore xmlns="http://exist.sourceforge.net/NS/exist">
+        <cache-control cache="yes"/>
+    </ignore>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/echo/echoDocuView.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,35 @@
+xquery version "1.0";
+
+import module namespace request="http://exist-db.org/xquery/request";
+
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "../..//text/all.xql";
+
+let $mpdlDocUri := request:get-parameter("document", ())
+let $echoArchivePath := mpdl-text:getEchoArchivePath($mpdlDocUri)
+let $echoURLDocuView := concat("http://mpdl-dev.mpiwg-berlin.mpg.de/ECHOdocuView?url=", $echoArchivePath)
+let $urlDocuViewer := <a href="{$echoURLDocuView}">redirect to Echo</a>
+let $diglibAvailable := 
+  if ($echoArchivePath = "XXXXDigilibNotAvailableXXXX")
+  then false()
+  else true()
+let $metaRefresh :=
+  if ($diglibAvailable)
+  then <meta http-equiv="Refresh" content="0; url={$echoURLDocuView}"/>
+  else ()
+let $message :=
+  if ($diglibAvailable)
+  then <span><b>Url:</b> {$urlDocuViewer}</span>
+  else <span><b>Could not open Echo Docu Viewer:</b> nausikaa2.rz-berlin.mpg.de does not answer for {$mpdlDocUri}: please try again later</span>
+
+return 
+<html>
+<head>
+  <title>Redirector Echo Docu Viewer</title>
+  {$metaRefresh}
+</head>
+<body>
+  <h1>Redirector Echo Docu Viewer</h1>
+  {$message}
+  
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/external/object.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,19 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace response="http://exist-db.org/xquery/response";
+declare namespace session="http://exist-db.org/xquery/session";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+let $operation := request:get-parameter("operation", "")
+let $type := request:get-parameter("type", "")
+let $uid := request:get-parameter("uid", "")
+let $document := request:get-parameter("document", "")
+let $pn := request:get-parameter("pn", "-1")
+let $xpath := request:get-parameter("xpath", "")
+let $charPosition := request:get-parameter("charPosition", "")
+let $externalObject := request:get-parameter("externalObject", "")
+
+let $result := mpdltext:externalObject($operation, $type, $uid, $document, $pn, $xpath, $charPosition, $externalObject)
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/lt/lemma.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,63 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../../util/time.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $language := request:get-parameter("language", "")
+let $lemmaName := request:get-parameter("lemma", "")
+let $formName := request:get-parameter("form", "")
+let $luceneQuery := request:get-parameter("query", "")
+
+let $currentTimeBegin := util:system-time()
+
+let $lemmas := 
+  if ($formName != '')
+  then mpdltext:get-lemmas-by-form-name($language, $formName)
+  else if ($lemmaName != '')
+  then mpdltext:get-lemma($language, $lemmaName)
+  else mpdltext:get-lemmas-by-lucene-query($language, $luceneQuery)
+let $orderedLemmas := 
+  if (empty($lemmas))
+  then ("no lemmas found for your query")
+  else 
+    for $lemma in $lemmas/lemmas/lemma
+      let $lemmaText := concat($lemma/lemma-name, " (", $lemma/provider, ")")
+      let $orderedForms :=
+        for $form in $lemma/forms/form
+          let $formNameText := $form/form-name
+          let $providerText := $form/provider
+          let $liForm := <li>{$formNameText} ({$providerText})</li>
+        order by $form/form-name
+        return $liForm
+      let $lemmaLi := 
+        <li><b>Lemma: </b>{$lemmaText}
+          <ul>{$orderedForms}</ul>
+        </li>
+    order by $lemma/lemma-name
+    return $lemmaLi
+
+let $queryResultHeaderStr := 
+  if ($formName != '')
+  then <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Form={$formName}</h3>
+  else if ($lemmaName != '')
+  then <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Lemma={$lemmaName}</h3>
+  else <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Query={$luceneQuery}</h3>
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $retHtmlResult :=
+  <html>
+  <head>
+  <title>Lemmas and forms</title>
+  </head>
+  <body>
+  {$queryResultHeaderStr}
+  <p/>
+  {$orderedLemmas} 
+  <p/>
+  </body>
+  </html>
+
+return $retHtmlResult
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/lt/lex.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,42 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $language := request:get-parameter("language", "")
+let $formName := request:get-parameter("form", "")
+let $luceneQuery := request:get-parameter("query", "")
+
+let $lexica := 
+  if ($formName != '')
+  then mpdltext:get-lex-entries-by-form-name($language, $formName)
+  else mpdltext:get-lex-entries-by-lucene-query($language, $luceneQuery)
+let $htmlLexica := 
+  if (empty($lexica))
+  then ("no lexical entries found for your query")
+  else 
+    for $lexicon in $lexica/lexica/lexicon
+      let $lexDescription := $lexicon/description
+      let $lexEntries := $lexicon/entries
+      let $liLexEntryContent :=
+        for $lexEntry in $lexicon/entries/entry
+          let $lexEntryContent := $lexEntry/content
+          let $lexEntryXmlValid := $lexEntryContent/xml-valid
+          let $lexEntryOriginalContent := $lexEntryContent/original-entry
+          let $lexEntryRepairedContent := $lexEntryContent/repaired-entry
+          let $lexEntryContentParsed := 
+            if ($lexEntryXmlValid = "true")
+            then util:parse($lexEntryRepairedContent)
+            else <bla><text>[<i>Remark: lexical entry in lexicon has no valid XML, so only the Betacode text version of the entry could be displayed</i>]</text><p></p>{$lexEntryOriginalContent}</bla>
+        return <li>{($lexEntryContentParsed)}</li>
+      let $lexiconLi := 
+        <li><b>{$lexDescription}</b>
+          <ul>{$liLexEntryContent}</ul>
+        </li>
+    return $lexiconLi
+
+let $retHtmlResult :=
+  <div>
+  {$htmlLexica} 
+  </div>
+
+return $retHtmlResult
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/lt/wordInfo.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,405 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../../util/time.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace xlink="http://www.w3.org/1999/xlink";
+
+(: TODO: Verlinkung von lemma, form, weiteren Einheiten in den Infos auf mpdl-proto (HTML und XML) :)
+
+let $type :=  request:get-parameter("type", "all")
+let $language := request:get-parameter("language", "")
+let $word := request:get-parameter("word", "")
+let $placeHref := request:get-parameter("placeHref", "")
+let $output := request:get-parameter("output", "xml")
+
+let $currentTimeBegin := util:system-time()
+
+let $lemmas := mpdltext:get-lemmas-by-form-name($language, $word)
+let $htmlOrderedLemmas := 
+  if (empty($lemmas))
+  then ("no lemmas found for your query")
+  else 
+    for $lemma in $lemmas/lemmas/lemma
+      let $lemmaText := concat($lemma/lemma-name, " (", $lemma/provider, ")")
+      let $orderedFormsStrTmp :=
+        for $form in $lemma/forms/form
+          let $formStr := concat($form/form-name, " (", $form/provider, ")")
+        order by $form/form-name
+        return $formStr
+      let $orderedFormsStr := string-join($orderedFormsStrTmp, ", ")
+      let $remotePerseusLink :=
+        if ($language = "ar" or $language = "la")
+        then concat("http://www.perseus.tufts.edu/hopper/morph?l=", $lemma/lemma-name, "&amp;la=", $language)
+        else if ($language = "el")
+        then concat("http://www.perseus.tufts.edu/hopper/morph?l=", $lemma/lemma-name, "&amp;la=greek")
+        else ""
+      let $lemmaLi := 
+        if ($language = "ar" or $language = "el" or $language = "la")
+        then 
+          <li><b>Lemma: </b>{$lemmaText} (see this entry in <a href="{$remotePerseusLink}">www.perseus.tufts.edu</a>)
+            <ul>{$orderedFormsStr}</ul>
+          </li>
+        else 
+          <li><b>Lemma: </b>{$lemmaText}
+            <ul>{$orderedFormsStr}</ul>
+          </li>
+    order by $lemma/lemma-name
+    return $lemmaLi
+let $xmlOrderedLemmas := 
+  for $lemma in $lemmas/lemmas/lemma
+    let $orderedForms :=
+      for $form in $lemma/forms/form
+      order by $form/form-name
+      return $form
+    let $retLemma := 
+      <lemma>
+        {$lemma/provider}
+        {$lemma/language}
+        {$lemma/lemma-name}
+        <forms size="{$lemma/forms-size}">{$orderedForms}</forms>
+      </lemma>
+  order by $lemma/lemma-name
+  return $retLemma
+let $lemmasStrTmpTmp := 
+  if (empty($lemmas))
+  then ""
+  else 
+    for $lemma in $lemmas/lemmas/lemma
+      let $lemmaStr := $lemma/lemma-name
+    order by $lemma/lemma-name
+    return $lemmaStr
+let $lemmasStrWithoutWord := string-join($lemmasStrTmpTmp, " ")
+let $lemmasStrTmp := 
+  if (not(contains($lemmasStrWithoutWord, $word)))
+  then concat($word, " ", $lemmasStrWithoutWord)  (: also the form itself is added   :)
+  else $lemmasStrWithoutWord
+let $lemmasStr := 
+  if ($language = "de" and (contains($lemmasStrTmp, "ae") or contains($lemmasStrTmp, "oe") or contains($lemmasStrTmp, "ue") or contains($lemmasStrTmp, "ss")))
+  then replace(replace(replace(replace($lemmasStrTmp, "ae", "ä"), "oe", "ö"), "ue", "ü"), "ss", "ß")
+  else $lemmasStrTmp
+let $lemmasStrTokenized := tokenize($lemmasStr, " ")
+
+let $dictionariesLocal := 
+  if ($type = "all" or $type = "dict")
+  then mpdltext:get-lex-entries-by-lucene-query($language, $lemmasStr)
+  else ()
+let $dictionariesRemoteTmp := 
+  if ($language = "de")
+  then
+    <lexica>
+      <lexicon>
+        <name>dwds</name>
+        <description>Deutsches Wörterbuch der deutschen Sprache</description>
+      </lexicon>
+    </lexica>
+  else if ($language = "el")
+  then
+    <lexica>
+      <lexicon>
+        <name>slater</name>
+        <description>William J. Slater, Lexicon to Pindar</description>
+      </lexicon>
+    </lexica>
+  else if ($language = "fr")
+  then
+    <lexica>
+      <lexicon>
+        <name>artfl-fr</name>
+        <description>The ARTFL project: Dictionnaires d'autrefois: French dictionaries of the 17th, 18th, 19th and 20th centuries</description>
+      </lexicon>
+      <lexicon>
+        <name>artfl-fr-en</name>
+        <description>The ARTFL project: French - English dictionary</description>
+      </lexicon>
+    </lexica>
+  else if ($language = "la")
+  then
+    <lexica>
+      <lexicon>
+        <name>lewis</name>
+        <description>Charlton T. Lewis, an Elementary Latin Dictionary</description>
+      </lexicon>
+    </lexica>
+  else if ($language = "nl")
+  then
+    <lexica>
+      <lexicon>
+        <name>wikiwoordenboek</name>
+        <description>Wiktionary: WikiWoordenboek</description>
+      </lexicon>
+    </lexica>
+  else if ($language = "zh")
+  then
+    <lexica>
+      <lexicon>
+        <name>linyutan</name>
+        <description>Lin Yutang</description>
+      </lexicon>
+    </lexica>
+  else ()
+
+let $dictionariesRemote := 
+  for $lex in $dictionariesRemoteTmp//lexicon
+    let $lexName := $lex/name
+    let $lexEntries :=  
+      for $l in $lemmasStrTokenized
+        let $lLink := 
+          if ($language = "el")
+          then mpdltext:transcode("unicode", "betacode", $l)
+          else if ($language = "zh")
+          then mpdltext:encode-big5($l)
+          else $l
+        let $repairedEntryContentLink :=
+          if ($lexName = "dwds")
+          then concat("http://beta.dwds.de/?qu=", $l)
+          else if ($lexName = "slater")
+          then concat("http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0072:entry=", $lLink)
+          else if ($lexName = "artfl-fr-en")
+          then concat("http://machaut.uchicago.edu/?resource=frengdict&amp;action=search&amp;french=", $l)
+          else if ($lexName = "artfl-fr")
+          then concat("http://artflx.uchicago.edu/cgi-bin/dicos/pubdico1look.pl?strippedhw=", $l)
+          else if ($lexName = "lewis")
+          then concat("http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0060:entry=", $l)
+          else if ($lexName = "wikiwoordenboek")
+          then concat("http://nl.wiktionary.org/wiki/", $l)
+          else if ($lexName = "linyutan")
+          then concat("http://humanum.arts.cuhk.edu.hk/cgi-bin/agrep-lindict?query=", $lLink, "&amp;category=wholerecord")
+          else ""
+        let $lexiconEntry :=
+          <entry>
+            <form>{$l}</form>
+            <content>
+              <xml-valid>true</xml-valid>
+              <original-entry>&lt;original-entry&gt;&lt;/original-entry&gt;</original-entry>
+              <repaired-entry><directLink xlink:type="simple" xlink:href="{$repairedEntryContentLink}">{$l}</directLink></repaired-entry>
+            </content>
+          </entry>
+      return $lexiconEntry
+  return 
+    <lexica>
+      <lexicon>
+        <name>{$lex/name}</name>
+        <description>{$lex/description}</description>
+        <entries>{$lexEntries}</entries>
+      </lexicon>
+    </lexica>
+
+let $dictionaries := 
+    <result>
+    <lexica>
+      {$dictionariesLocal//lexicon}
+      {$dictionariesRemote//lexicon}
+    </lexica>
+    </result>
+let $retDictionaries := 
+  if (empty($dictionaries))
+  then ()
+  else
+    for $dictionary in $dictionaries/lexica/lexicon
+      let $dictName := $dictionary/name
+      let $dictDescription := $dictionary/description
+      let $dictEntries := $dictionary/entries
+      let $entryDictEntryContent :=
+        for $dictEntry in $dictionary/entries/entry
+          let $dictEntryContent := $dictEntry/content
+          let $dictEntryXmlValid := $dictEntryContent/xml-valid
+          let $dictEntryOriginalContent := $dictEntryContent/original-entry
+          let $dictEntryRepairedContent := $dictEntryContent/repaired-entry
+          let $dictEntryRepairedContentLink := $dictEntryRepairedContent/directLink
+          let $dictEntryForm := 
+            if ($language = "el")
+            then mpdltext:transcode("unicode", "betacode", string($dictEntry/form))
+            else if ($language = "ar")
+            then mpdltext:transcode("unicode", "buckwalter", string($dictEntry/form))
+            else $dictEntry/form
+          let $dictEntryContentParsedTmp := 
+            if ($dictEntryXmlValid = "true" and empty($dictEntryRepairedContentLink))
+            then util:parse($dictEntryRepairedContent)
+            else if ($dictEntryXmlValid = "true" and not(empty($dictEntryRepairedContentLink)) and $output = "html")
+            then <div>External link: <a href="{$dictEntryRepairedContentLink/@xlink:href}">{$dictEntryRepairedContentLink}</a></div>
+            else if ($dictEntryXmlValid = "true" and not(empty($dictEntryRepairedContentLink)) and $output = "xml")
+            then <div>{$dictEntryRepairedContentLink}</div>
+            else <bla><text>[<i>Remark: entry in dictionary has no valid XML, so only the Betacode text version of the entry could be displayed</i>]</text><p></p>{$dictEntryOriginalContent}</bla>
+          let $dictEntryContentParsed := 
+            if ($dictionary/name = "ls" and $output = "html")
+            then <div>{$dictEntryContentParsedTmp}<br/>(external link to <a href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0059:entry={$dictEntry/form}">www.perseus.tufts.edu</a>)</div>
+            else if ($dictionary/name = "ls" and $output = "xml")
+            then <div>{$dictEntryContentParsedTmp}<directLink type="simple" xlink:href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0059:entry={$dictEntry/form}">www.perseus.tufts.edu</directLink></div>
+            else if ($dictionary/name = "lsj" and $output = "html")
+            then <div>{$dictEntryContentParsedTmp}<br/>(external link to <a href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0057:entry={$dictEntryForm}">www.perseus.tufts.edu</a>)</div>
+            else if ($dictionary/name = "lsj" and $output = "xml")
+            then <div>{$dictEntryContentParsedTmp}<directLink type="simple" xlink:href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0057:entry={$dictEntryForm}">www.perseus.tufts.edu</directLink></div>
+            else if ($dictionary/name = "autenrieth" and $output = "html")
+            then <div>{$dictEntryContentParsedTmp}<br/>(external link to <a href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0073:entry={$dictEntryForm}">www.perseus.tufts.edu</a>)</div>
+            else if ($dictionary/name = "autenrieth" and $output = "xml")
+            then <div>{$dictEntryContentParsedTmp}<directLink type="simple" xlink:href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0073:entry={$dictEntryForm}">www.perseus.tufts.edu</directLink></div>
+            else if ($dictionary/name = "buckwalter" and $output = "html")
+            then <div>{$dictEntryContentParsedTmp}<br/>(external link to <a href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:2002.02.0014:entry={$dictEntryForm}">www.perseus.tufts.edu</a>)</div>
+            else if ($dictionary/name = "buckwalter" and $output = "xml")
+            then <div>{$dictEntryContentParsedTmp}<directLink type="simple" xlink:href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:2002.02.0014:entry={$dictEntryForm}">www.perseus.tufts.edu</directLink></div>
+            else if ($dictionary/name = "salmone" and $output = "html")
+            then <div>{$dictEntryContentParsedTmp}<br/>(external link to <a href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:2002.02.0005:entry={$dictEntryForm}">www.perseus.tufts.edu</a>)</div>   
+            else if ($dictionary/name = "salmone" and $output = "xml")
+            then <div>{$dictEntryContentParsedTmp}<directLink type="simple" xlink:href="http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:2002.02.0005:entry={$dictEntryForm}">www.perseus.tufts.edu</directLink></div>
+            else $dictEntryContentParsedTmp
+          let $liDictEntryContentParsed := 
+            if ($output = "html")
+            then <li>{($dictEntryContentParsed)}</li>
+            else if ($output = "xml")
+            then <entry>{($dictEntryContentParsed)}</entry>
+            else ()
+        return $liDictEntryContentParsed
+      let $dictLi := 
+        if ($output = "html")
+        then 
+          <li><b>{$dictDescription}</b>
+            <ul>{$entryDictEntryContent}</ul>
+          </li>
+        else if ($output = "xml")
+        then 
+          <dictionaryEntries>
+          <dictionary>
+            <name>{$dictName}</name>
+            <description>{$dictDescription}</description>
+            <entries>{$entryDictEntryContent}</entries>
+          </dictionary>
+          </dictionaryEntries>
+        else ()
+    return $dictLi
+
+let $wikiArticles := 
+  if (empty($lemmas))
+  then ()
+  else 
+    for $l in $lemmasStrTokenized
+      let $wikiHref1 := concat("http://", $language, ".wikipedia.org/wiki/", $l)
+      let $wikiHref2 := concat("http://", $language, ".wikipedia.org/wiki/index.php?search=", $l)
+      let $wikiArticle := 
+        if ($output = "html")
+        then <li><b>Article: </b>External link: <a href="{$wikiHref1}">{$l}</a> (or search for <a href="{$wikiHref2}">{$l})</a></li>
+        else if ($output = "xml")
+        then
+          <article>
+            <name>{$l}</name>
+            <directLink xlink:type="simple" xlink:href="{$wikiHref1}"/>
+            <searchLink xlink:type="simple" xlink:href="{$wikiHref2}"/>
+          </article>
+        else ()
+    return $wikiArticle
+let $places := 
+  if ($placeHref != "" and $output = "html")
+  then <li><b>Place: </b>External link: <a href="{$placeHref}">{$word}</a></li>
+  else if ($placeHref != "" and $output = "html")
+  then
+      <place>
+        <name>{$word}</name>
+        <directLink xlink:type="simple" xlink:href="{$placeHref}"/>
+      </place>
+  else ()
+
+let $dict := 
+  if (not(empty($retDictionaries)) and ($type = "all" or $type = "dict") and $output = "html")
+  then 
+    <p>
+      <h3>Dictionary</h3>
+      <ul>{$retDictionaries}</ul>
+    </p>
+  else if (empty($retDictionaries) and ($type = "all" or $type = "dict") and $output = "html")
+  then
+    <p>
+      <h3>Dictionary</h3>
+      <ul>No information available</ul>
+    </p>
+  else if (not(empty($retDictionaries)) and ($type = "all" or $type = "dict") and $output = "xml")
+  then $retDictionaries
+  else ()
+let $morph := 
+  if (not(empty($htmlOrderedLemmas)) and ($type = "all" or $type = "morph") and $output = "html")
+  then 
+    <p>
+      <h3>Morphology</h3>
+      <ul>{$htmlOrderedLemmas}</ul>
+    </p>
+  else if (empty($htmlOrderedLemmas) and ($type = "all" or $type = "morph") and $output = "html")
+  then
+    <p>
+      <h3>Morphology</h3>
+      <ul>No information available</ul>
+    </p>
+  else if (not(empty($htmlOrderedLemmas)) and ($type = "all" or $type = "morph") and $output = "xml")
+  then <morphologyEntries>{$xmlOrderedLemmas}</morphologyEntries>
+  else if ($type = "morph" and $output = "string")
+  then $lemmasStrWithoutWord
+  else ()
+let $wiki := 
+  if (not(empty($wikiArticles)) and ($type = "all" or $type = "wiki") and $output = "html")
+  then 
+    <p>
+      <h3>Wikipedia</h3>
+      <ul>{$wikiArticles}</ul>
+    </p>
+  else if (not(empty($wikiArticles)) and ($type = "all" or $type = "wiki") and $output = "xml")
+  then <wikiEntries>{$wikiArticles}</wikiEntries>
+  else ()
+let $place := 
+  if (not(empty($places)) and ($type = "all" or $type = "place") and $output = "html")
+  then 
+    <p>
+      <h3>Place</h3>
+      <ul>{$places}</ul>
+    </p>
+  else if (not(empty($places)) and ($type = "all" or $type = "place") and $output = "xml")
+  then <placeEntries>{$places}</placeEntries>
+  else ()
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $declare := 
+  if ($output = "html" or $output = "string")
+  then util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+
+let $queryResultHeaderStr := <h2>Word information for: {$word}</h2>
+let $commentExternalLinks := 
+   "[* no guarantee for external links]"
+
+let $retXmlResult :=
+  <word>
+    <form>{$word}</form>
+    <provider>Max Planck Institute for the History of Science, Berlin</provider>
+    {$morph}
+    {$dict}
+    {$wiki}
+    {$place}
+  </word>
+let $retHtmlResult :=
+  <html>
+  <head>
+  <title>Mpdl: word information</title>
+  </head>
+  <body>
+  <table align="right" valign="top">
+    <td>[<i>This is a MPDL language technology service</i>] <a href="../../info.xql?info=wordInfo" onclick="window.open(&quot;../../info.xql?info=wordInfo&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=800,height=600,toolbar=yes,scrollbars=yes&quot;);return false"><img src="../../images/info.png" valign="bottom" width="15" height="15" border="0" alt="MPDL language technology service"/></a></td>
+  </table>
+  <p/>
+  {$queryResultHeaderStr}
+  {$morph} 
+  {$dict} 
+  {$wiki} 
+  {$place} 
+  {$commentExternalLinks} 
+  <hr/>
+  <p/>
+  Elapsed time: {$neededTime} ms, see the <a href="/exist/xquery.xml">XQuery documentation</a> and the <a href="wordInfo.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+  </body>
+  </html>
+
+let $retResult :=
+  if ($output = "html")
+  then $retHtmlResult 
+  else if ($type = "morph" and $output = "string")
+  then $morph
+  else $retXmlResult
+return $retResult
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/page-fragment.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,401 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "../lucene/search.xql";
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "../text/all.xql";
+
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace transform = "http://exist-db.org/xquery/transform";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace dcterms="http://purl.org/dc/terms";
+declare namespace xhtml="http://www.w3.org/1999/xhtml";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+let $mpdlDocUri := request:get-parameter("document", "")
+let $mode := request:get-parameter("mode", "image")
+
+let $reqPN := number(request:get-parameter("pn", "-1"))
+let $reqPF := request:get-parameter("pf", "")
+let $reqSN := number(request:get-parameter("sn", "-1"))
+let $highlightQuery := request:get-parameter("highlightQuery", "")
+let $regCharNorm := request:get-parameter("characterNormalization", "")
+let $tmpCharNorm := string-join($regCharNorm, ',')
+let $charNorm := 
+  if($tmpCharNorm = "regPlusNorm")
+  then "reg,norm"
+  else $tmpCharNorm
+let $reqExport := request:get-parameter("export", "")
+let $options := string(request:get-parameter("options", ""))
+
+let $presentationPath := "/db/mpdl/presentation"
+(: e.g. mpdlCollectioName is derived from mpdlDocUri: /archimedes/la/yourDoc.xml  :)
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $language := substring-before(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $currentTimeBegin := util:system-time()
+let $documentAvailable := doc-available($fullDocumentUri)
+let $document := doc($fullDocumentUri)
+let $metadata := 
+  if ($docbase = 'archimedes')
+  then $document/archimedes/info
+  else if ($docbase = 'echo')
+  then $document/echo:echo/echo:metadata
+  else ''
+
+let $pageBreaks := 
+  if ($docbase = 'archimedes')
+  then $document//pb
+  else if ($docbase = 'echo')
+  then $document//echo:pb
+  else $document//pb
+let $countPagesTemp := count($pageBreaks)
+let $countPages := 
+  if ($countPagesTemp > 0)
+  then $countPagesTemp
+  else 1
+
+(: for performance reasons: deliver count of gis places and toc/figure entries   :)
+let $gisPlaces := 
+  if ($docbase = 'echo')
+  then $document//echo:place
+  else ()
+let $countGisPlaces := count($gisPlaces)
+let $tocEntries := 
+  if ($docbase = 'echo')
+  then $document//echo:div[@type = 'section' or @type = 'chapter']
+  else ()
+let $figureEntries := 
+  if ($docbase = 'echo')
+  then $document//echo:figure
+  else if ($docbase = 'archimedes') 
+  then $document//figure
+  else ()
+let $countTocEntries := count($tocEntries)
+let $countFigureEntries := count($figureEntries)
+
+(: jump to first pn and sn hit in fulltext mode   :)
+let $pn := 
+    if ($reqPN = -1)
+    then 1
+    else $reqPN
+let $sn := $reqSN
+
+(: 10 or more is an error :)
+let $errorCode := 
+  if (not($documentAvailable))
+  then 10
+  else if ($countPagesTemp != 0 and ($pn > $countPagesTemp or $pn <= 0))
+  then 11 
+  else if ($countPagesTemp = 0) 
+  then 1    (: if no page break is found then the document should have exactly one page   :)
+  else if (not($mode = "text"  or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml" or $mode = "pureXml"))
+  then 12
+  else 0
+
+let $pb1 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 1, 1)
+  else ()
+let $pb2 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn + 1, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 2, 1)
+  else ()
+let $pageHeader := string($pb1/@rhead)
+let $pageNumberOrig := string($pb1/@o)
+
+let $documentIdentifier :=
+  if ($docbase = 'archimedes')
+  then $metadata/locator
+  else if ($docbase = 'echo')
+  then $metadata/dcterms:identifier
+  else $metadata/dcterms:identifier
+let $echoDocIdentifier := 
+  if ($documentIdentifier != '')
+  then substring-before(substring-after($documentIdentifier, "ECHO:"), ".")
+  else ''
+let $echoURLZogilib := "http://echo.mpiwg-berlin.mpg.de/zogilib"
+let $nausikaaURLScaler := "http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler"
+let $nausikaaURLDlInfo := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/dlInfo-xml.jsp"
+let $nausikaaURLTexter := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/servlet/Texter"
+let $echoImageDir := 
+  if ($docbase = 'archimedes')
+  then string($metadata/echodir)
+  else if ($docbase = 'echo')
+  then string($metadata/echo:echodir)
+  else ''
+let $imagesDocDirectory :=
+  if ($echoImageDir != '')
+  then $echoImageDir
+  else if ($docbase = 'archimedes')
+  then concat("/permanent/archimedes/", $documentName)
+  else if ($docbase = 'echo')
+  then concat("/permanent/library/", $echoDocIdentifier)
+  else ''
+let $imagesDocDirectoryIndexMetaUrl := 
+  if ($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis")
+  then concat($nausikaaURLTexter, "?fn=", $imagesDocDirectory, "/index.meta")
+  else ()
+let $digilibAvailable := mpdldoc:check-uri($imagesDocDirectoryIndexMetaUrl, 2000)
+let $imagesDocDirectoryIndexMeta := 
+  if (($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis") and $digilibAvailable)
+  then doc($imagesDocDirectoryIndexMetaUrl)
+  else ()
+let $pageImageDirectory := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/image)
+let $figuresImageDirectoryTemp := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/figures)
+let $figuresImageDirectory := 
+  if ($figuresImageDirectoryTemp != '')
+  then $figuresImageDirectoryTemp
+  else concat(substring-before($pageImageDirectory, "pageimg"), "figures")
+let $pageImageFileNameWithoutExtension := 
+  if ($docbase = 'echo')
+  then concat("/", string($pb1/@file))
+  else ''
+let $imageFileName :=
+  if ($reqPF = '')
+  then concat($imagesDocDirectory, "/", $pageImageDirectory, $pageImageFileNameWithoutExtension)
+  else $reqPF
+let $imageEcho := <image-echo>{$echoURLZogilib}?fn={$imageFileName}&amp;pn={$pn}</image-echo>
+let $imageScaler := <image-scaler>{$nausikaaURLScaler}?fn={$imageFileName}&amp;pn={$pn}</image-scaler>
+
+let $imageFileNameUrl := concat($nausikaaURLDlInfo, "?fn=", $imageFileName)
+let $testImageResult := 
+  if ($mode = 'image' and $digilibAvailable)
+  then doc($imageFileNameUrl)
+  else ()
+let $testImageResultParamImgFn := string($testImageResult//parameter[@name='img.fn']/@value)
+let $imageIsAvailable := 
+  if ($testImageResultParamImgFn = '' and $reqPF = '')
+  then 'false'
+  else 'true'
+  
+let $positionOfFirstFigureAfterPB1 := 
+  if ($docbase = 'archimedes')
+  then count($pb1/following::figure[1]/preceding::figure) + 1
+  else if ($docbase = 'echo')
+  then count($pb1/following::echo:figure[1]/preceding::echo:figure) + 1
+  else ()
+
+let $pageFragmentTmp := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then util:get-fragment-between($pb1, $pb2, true())
+  else ()
+(: replace the soft hyphen (Unicode character for 00AD) just before the line break by a normal hyphen :)
+(: delete the hyphen just before the line break in case of options=withoutLBs :)
+let $pageFragment :=
+  if (($mode = "text" or $mode = "textPollux") and not(contains($options, "withoutLBs")) and contains($pageFragmentTmp, "­<lb"))
+  then replace($pageFragmentTmp, "­<lb", "-<lb")
+  else if (($mode = "text" or $mode = "textPollux") and contains($options, "withoutLBs") and contains($pageFragmentTmp, "-<lb"))
+  then replace($pageFragmentTmp, "-<lb", "<lb")
+  else $pageFragmentTmp
+let $pageFragmentNormalized := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis") and $charNorm = "")
+  then mpdltext:normalizeChars('reg,norm', $language, $pageFragment)
+  else if (($mode = "xml" or $mode = "pureXml") and $charNorm = "")
+  then $pageFragment
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml") and $charNorm != "")
+  then mpdltext:normalizeChars($charNorm, $language, $pageFragment)
+  else ()
+let $retPageFragment := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then $pageFragmentNormalized
+  else if ($mode = "textPollux")
+  then mpdltext:dictionarize($pageFragmentNormalized, $language)
+  else ()
+let $returnPageFragmentTmp := util:parse($retPageFragment)  (: returns a valid xml document for that string   :)  
+
+let $externalElementsTmpTmp := mpdltext:externalObject("read", "element", "", $mpdlDocUri, string($pn), "", "", "")
+let $externalElementsTmp := 
+  if(not($externalElementsTmpTmp = ""))
+  then util:parse($externalElementsTmpTmp)
+  else ()
+let $externalElements := $externalElementsTmp/result/element
+let $containsExternalElements := 
+  if(not(empty($externalElements)))
+  then true()
+  else false()
+let $returnPageFragmentTmpp := 
+  if (contains($options, "withXmlNodeId") or $containsExternalElements)
+  then mpdl-text:insertNodeIdAttribute($returnPageFragmentTmp/*[1])
+  else $returnPageFragmentTmp
+
+let $returnPageFragment := 
+  if($containsExternalElements)
+  then mpdl-text:insert($returnPageFragmentTmpp/*[1], $externalElements) 
+  else $returnPageFragmentTmpp
+
+let $pageFigureAnchors := $returnPageFragment//anchor[@type = 'figure']
+let $pageFigures :=
+    for $pageFigureAnchor in $pageFigureAnchors
+      let $href := string($pageFigureAnchor/@xlink:href)
+      let $pageFigureTmp := $document//echo:figure[@xlink:label = $href]
+      let $pageFigure := subsequence($pageFigureTmp, 1, 1)
+    return 
+      $pageFigure
+let $pageHandwrittenAnchors := $returnPageFragment//anchor[@type = 'handwritten']
+let $pageHandwritten :=
+    for $pageHandwrittenAnchor in $pageHandwrittenAnchors
+      let $handwrittenHref := string($pageHandwrittenAnchor/@xlink:href)
+      let $pageHandwrittenTmp := $document//echo:handwritten[@xlink:label = $handwrittenHref]
+      let $pageHandwritten := subsequence($pageHandwrittenTmp, 1, 1)
+    return 
+      $pageHandwritten
+let $pageTableAnchors := $returnPageFragment//anchor[@type = 'table']
+let $pageTables :=
+    for $pageTableAnchor in $pageTableAnchors
+      let $tableHref := string($pageTableAnchor/@xlink:href)
+      let $pageTableTmp := $document//xhtml:table[@xlink:label = $tableHref]
+      let $pageTable := subsequence($pageTableTmp, 1, 1)
+    return 
+      $pageTable
+let $pageNoteAnchors := $returnPageFragment//anchor[@type = 'note']
+let $pageNotes :=
+  if ($docbase = "echo")
+  then
+    for $pageNoteAnchor in $pageNoteAnchors
+      let $noteHref := string($pageNoteAnchor/@xlink:href)
+      let $pageNoteTmp := $document//echo:note[@xlink:label = $noteHref]
+      let $pageNote := subsequence($pageNoteTmp, 1, 1)
+    return 
+      $pageNote
+  else
+    $returnPageFragment//note
+
+(: Metadata handling: only metadata of the selected document is scanned   :)
+let $identifier := $documentIdentifier
+let $authors := mpdl-lucene:getElementsByAttr($metadata, $docbase, "author")
+let $titles := mpdl-lucene:getElementsByAttr($metadata, $docbase, "title")
+let $places := mpdl-lucene:getElementsByAttr($metadata, $docbase, "place")
+let $date := mpdl-lucene:getElementsByAttr($metadata, $docbase, "date")
+let $rights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "rights")
+let $accessRights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "accessRights")
+let $licenses := mpdl-lucene:getElementsByAttr($metadata, $docbase, "license")
+let $file := mpdl-lucene:getElementsByAttr($metadata, $docbase, "file")
+let $translator := mpdl-lucene:getElementsByAttr($metadata, $docbase, "translator")
+let $version := mpdl-lucene:getElementsByAttr($metadata, $docbase, "version")
+
+let $highlightQueryWordsTemp := 
+  if ($highlightQuery != '')
+  then mpdltext:get-query-morph-forms($language, $highlightQuery)
+  else ''
+let $highlightQueryRegularizations := 
+  if ($highlightQuery != '')
+  then mpdltext:get-query-regularizations($language, $highlightQuery)
+  else ''
+let $highlightQueryWords := 
+  if ($highlightQueryWordsTemp != '' and $highlightQueryRegularizations = '')
+  then $highlightQueryWordsTemp
+  else if ($highlightQueryWordsTemp = '' and $highlightQueryRegularizations != '')
+  then $highlightQueryRegularizations
+  else if ($highlightQueryWordsTemp != '' and $highlightQueryRegularizations != '')
+  then concat($highlightQueryWordsTemp, '|', $highlightQueryRegularizations)
+  else ()
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode < 10)
+  then 
+    <result>
+      <document-description>
+        <uri>{$mpdlDocUri}</uri>
+        <collection-name>{$docbase}</collection-name>
+        <document-name>{$documentName}</document-name>
+        <language>{$language}</language>
+        <authors>{$authors}</authors>
+        <titles>{$titles}</titles>
+        <places>{$places}</places>
+        <date>{$date}</date>
+        <identifier>{$identifier}</identifier>
+        <rights>{$rights}</rights>
+        <accessRights>{$accessRights}</accessRights>
+        <licenses>{$licenses}</licenses>
+        <file>{$file}</file>
+        <translator>{$translator}</translator>
+        <version>{$version}</version>
+        <count-pages>{$countPages}</count-pages>
+        <count-places>{$countGisPlaces}</count-places>
+        <count-toc-entries>{$countTocEntries}</count-toc-entries>
+        <count-figure-entries>{$countFigureEntries}</count-figure-entries>
+      </document-description>
+      <page>
+        <mode>{$mode}</mode>
+        <number>{$pn}</number>
+        <header>{$pageHeader}</header>
+        <number-orig>{$pageNumberOrig}</number-orig>
+        <sentence-number>{$sn}</sentence-number>
+        <digilib-available>{$digilibAvailable}</digilib-available>
+        <image-available>{$imageIsAvailable}</image-available>
+        <image-file-name>{$imageFileName}</image-file-name>
+        {$imageEcho}
+        {$imageScaler}
+        <xml-url>?document={$documentName}&amp;pn={$pn}&amp;mode=xml</xml-url>
+        <page-image-directory>{$imagesDocDirectory}/{$pageImageDirectory}</page-image-directory>
+        <figures-image-directory>{$imagesDocDirectory}/{$figuresImageDirectory}</figures-image-directory>
+        <firstFigurePosition>{$positionOfFirstFigureAfterPB1}</firstFigurePosition>
+        <figures>{$pageFigures}</figures>
+        <handwritten>{$pageHandwritten}</handwritten>
+        <tables>{$pageTables}</tables>
+        <notes>{$pageNotes}</notes>
+        <highlights>
+          <query>{$highlightQuery}</query>
+          <words>{$highlightQueryWords}</words>
+        </highlights>
+        <content>{$returnPageFragment}</content>
+        <character-normalization>{$charNorm}</character-normalization>
+        <options>{$options}</options>
+      </page>
+      <performance>{$neededTime}</performance>
+    </result>
+  else if ($errorCode = 10)
+  then <error><number>{$errorCode}</number><description>Fulltext document: {$mpdlDocUri} is not available yet</description></error>
+  else if ($errorCode = 11)
+  then <error><number>{$errorCode}</number><description>No result: Page {$pn} not found</description></error>
+  else if ($errorCode = 12)
+  then <error><number>{$errorCode}</number><description>View mode {$mode} not available</description></error>
+  else <error><number>{$errorCode}</number><description>undefined error: {$errorCode}</description></error>  
+
+let $declare := 
+  if ($errorCode > 9 or $mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=xhtml media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+  else if ($mode = "pureXml")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+let $xslFilePath := 
+  if($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then concat($presentationPath, "/pageFragmentHtml.xsl")
+  else concat($presentationPath, "/pageXml.xsl")
+  
+let $titleStr := concat(string-join($authors, ', '), ". ", string-join($titles, ', '), ". ", string-join($places, ', '), " ", $date, ".")
+let $tmpResult :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then mpdl-text:html2pdf($language, $xmlResult, $xslFilePath, $titleStr, $pn, $mode) 
+  else if ($errorCode < 10 and not($reqExport = "pdf"))
+  then mpdl-text:transform($xmlResult, $xslFilePath)
+  else 
+    <div>{$xmlResult}</div>  (:  error xml result  :)
+let $result :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then response:stream-binary($tmpResult, "application/pdf", concat($documentName, "-page", $pn, ".pdf"))
+  else $tmpResult
+  
+let $setHeader :=  
+  if ($mode = "pureXml")
+  then response:set-header('Content-Disposition', concat('filename=', $documentName, '-page', $pn)) 
+  else ()
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/queryResult.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,261 @@
+xquery version "1.0";
+
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "../lucene/search.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace dc="http://purl.org/dc/elements/1.1/";
+declare namespace dct="http://purl.org/dc/terms/1.0/";
+declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+
+let $queryType := request:get-parameter("queryType", "")
+let $docbase := request:get-parameter("docbase", "")
+let $output := request:get-parameter("output", "html")
+let $attribute1 := request:get-parameter("attribute1", "")
+let $relOp1 := request:get-parameter("relOp1", "")
+let $attrQuery1 := request:get-parameter("attrQuery1", "")
+let $boolOp := request:get-parameter("boolOp", "")
+let $attribute2 := request:get-parameter("attribute2", "")
+let $relOp2 := request:get-parameter("relOp2", "")
+let $attrQuery2 := request:get-parameter("attrQuery2", "")
+let $ftQuery := request:get-parameter("ftQuery", "")
+let $ftMorphQuery := request:get-parameter("ftMorphQuery", "")
+let $orderBy := request:get-parameter("orderBy", "")
+let $language := request:get-parameter("language", "")
+let $pn := number(request:get-parameter("pn", ""))
+let $reqPageSize := request:get-parameter("pageSize", "")
+let $pageSize := 
+  if ($reqPageSize = '' or $reqPageSize = '0')
+  then 20
+  else number($reqPageSize)
+
+let $docPathStandard := "/db/mpdl/documents/standard"
+let $docPathMorph := "/db/mpdl/documents/morph"
+let $docPath := 
+  if($queryType = 'fulltextMorph')
+  then $docPathMorph
+  else $docPathStandard
+
+let $docBaseArch := "archimedes"
+let $docBaseEcho := "echo"
+let $fulltextMorphArchDocPath := concat($docPathMorph, "/", $docBaseArch, "/", $language)
+let $fulltextMorphEchoDocPath := concat($docPathMorph, "/", $docBaseEcho, "/", $language)
+let $fulltextMorphCollection := 
+  if(contains($docbase, $docBaseArch) and contains($docbase, $docBaseEcho))
+  then collection($fulltextMorphArchDocPath, $fulltextMorphEchoDocPath)
+  else if(contains($docbase, $docBaseArch) and not(contains($docbase, $docBaseEcho)))
+  then collection($fulltextMorphArchDocPath)
+  else if(not(contains($docbase, $docBaseArch)) and contains($docbase, $docBaseEcho))
+  then collection($fulltextMorphEchoDocPath)
+  else ()
+
+let $fulltextStandardArchDocPath := concat($docPathStandard, "/", $docBaseArch)
+let $fulltextStandardEchoDocPath := concat($docPathStandard, "/", $docBaseEcho)
+let $fulltextStandardCollectionStr := 
+  if(contains($docbase, $docBaseArch) and contains($docbase, $docBaseEcho))
+  then concat("collection('", $fulltextStandardArchDocPath, "', '", $fulltextStandardEchoDocPath, "')")
+  else if(contains($docbase, $docBaseArch) and not(contains($docbase, $docBaseEcho)))
+  then concat("collection('", $fulltextStandardArchDocPath, "')")
+  else if(not(contains($docbase, $docBaseArch)) and contains($docbase, $docBaseEcho))
+  then concat("collection('", $fulltextStandardEchoDocPath, "')")
+  else ()
+let $metadataStr := concat("(", $fulltextStandardCollectionStr, "/archimedes/info", "|" , $fulltextStandardCollectionStr, "/echo:echo/echo:metadata", ")")
+let $fulltextStandardCollection := util:eval($fulltextStandardCollectionStr)
+
+let $isAttributeSearch :=
+  if ($queryType = "attribute")
+  then true()
+  else false()
+let $isSimpleAttributeSearch :=
+  if ($queryType = "attribute" and $attrQuery2 = "")
+  then true()
+  else false()
+let $isBooleanAttributeSearch :=
+  if ($queryType = "attribute" and $attrQuery2 != "")
+  then true()
+  else false()
+
+(:  TODO:  performance improvement: at this time the result is fully scanned 3 times (query, ordering, presentation)   :)
+let $attrQueryResult := 
+  if ($queryType = "browse")
+  then $fulltextStandardCollection
+  else if ($queryType = "fulltext")
+  then mpdl-lucene:search($fulltextStandardCollection, $ftQuery)
+  else if ($queryType = "fulltextMorph")
+  then mpdl-lucene:search($fulltextMorphCollection, $ftMorphQuery)
+  else if ($isAttributeSearch)
+  then mpdl-lucene:attrSearch($metadataStr, $attribute1, $attrQuery1, $boolOp, $attribute2, $attrQuery2)
+  else ()
+  
+let $orderedAttrQueryResult := 
+  if ($queryType = "fulltext" or $queryType = "fulltextMorph")
+  then
+  (for $attrElem in $attrQueryResult
+   order by ft:score($attrElem) descending
+   return $attrElem)
+  else mpdl-lucene:order($attrQueryResult, $orderBy)
+
+let $countResult := count($orderedAttrQueryResult)
+let $countPagesTemp := $countResult idiv $pageSize + 1
+let $countPages :=
+  if((($countResult - 1) idiv $pageSize + 1) = ($countPagesTemp - 1))   
+  then $countPagesTemp - 1   (: if countResult is exactly 10, 20, 30, ... then 1 has to be subtracted   :)
+  else $countPagesTemp
+let $pnLeftNumber :=
+  if ($pn > 1)
+  then $pn - 1
+  else $pn
+let $pnRightNumber :=
+  if ($pn < $countPages)
+  then $pn + 1
+  else $pn
+let $positionFrom := (($pn - 1) * $pageSize) + 1
+let $positionTo := 
+  if ($pn = $countPages)
+  then $countResult
+  else $pn * $pageSize
+
+let $mode :=
+  if ($queryType = "fulltext" or $queryType = "fulltextMorph")
+  then "text"
+  else "image"
+
+let $pageResult := 
+  for $elem at $pos in $orderedAttrQueryResult
+    let $doc := $elem/fn:root()
    let $documentUriOrig := document-uri($doc)
+    let $documentUri := substring-after($documentUriOrig, $docPath)
+    let $docBase := substring-before(substring-after($documentUri, "/"), "/")
+    let $metadata := mpdl-lucene:getMetadata($docBase, $doc)
+    (: Performance: following is slow: why  (would be better structured code) ?
+      let $attrAuthorStr := mpdl-lucene:getElemNameByAttr($docBase, "author")
+      let $author := mpdl-lucene:getElemDynamic($metadataElem, $attrAuthorStr)
+    :)    
+    let $authorElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "author") 
+    let $titleElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "title")
+    let $placeElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "place")
+    let $dateElems := mpdl-lucene:getElementsByAttr($metadata, $docBase, "date")
+    let $authors := string-join($authorElems, ', ')
+    let $titles := string-join($titleElems, ', ')
+    let $places := string-join($placeElems, ', ')
+    let $dates := string-join($dateElems, ', ')
+    let $resultElem := 
+      if ($output = "html")
+      then 
+        <tr>
+          <td valign="top" style="padding-left:5px;">{$pos}.</td>
+          <td valign="top" style="padding-left:7px;"><a href="echo/echoDocuView.xql?document={$documentUri}"><img src="../images/book.png" width="15" height="15" border="0"/></a> </td>
+          <td valign="top"><a href="/exist/rest{$docPathStandard}{$documentUri}" target="_blank"><img src="../images/download.png" width="15" height="15" border="0" alt="Download"/></a></td>
+          <td valign="top" style="padding-left:5px;"><i>{$authors}</i></td>
+          <td valign="top" style="padding-left:5px;">{$titles}</td>
+          <td valign="top" style="padding-left:5px;">{$places}</td>
+          <td valign="top" style="padding-left:5px;">{$dates}</td>
+        </tr>
+      else if ($output = "xml")
+      then 
+        <document>
+          <position>{$pos}</position>
+          <uri>{$documentUri}</uri>
+          <author>{$authors}</author>
+          <title>{$titles}</title>
+          <place>{$places}</place>
+          <date>{$dates}</date>
+        </document>
+      else ()
+  where $pos >= $positionFrom and $pos <= $positionTo
+  return $resultElem
+
+let $attrQueryResultError := string($attrQueryResult/error)
+
+let $resultPageBody := 
+  if ($attrQueryResultError = '' and $countResult > 0)
+  then 
+    <form action="queryResult.xql" method="get">
+      <input type="hidden" name="docbase" value="{$docbase}"/>
+      <input type="hidden" name="queryType" value="{$queryType}"/>
+      <input type="hidden" name="attribute1" value="{$attribute1}"/>
+      <input type="hidden" name="relOp1" value="{$relOp1}"/>
+      <input type="hidden" name="attrQuery1" value="{$attrQuery1}"/>
+      <input type="hidden" name="boolOp" value="{$boolOp}"/>
+      <input type="hidden" name="attribute2" value="{$attribute2}"/>
+      <input type="hidden" name="relOp2" value="{$relOp2}"/>
+      <input type="hidden" name="attrQuery2" value="{$attrQuery2}"/>
+      <input type="hidden" name="ftQuery" value="{$ftQuery}"/>
+      <input type="hidden" name="ftMorphQuery" value="{$ftMorphQuery}"/>
+      <input type="hidden" name="language" value="{$language}"/>
+      <input type="hidden" name="pn" value="{$pn}"/>
+      <input type="hidden" name="pageSize" value="{$pageSize}"/>
+    <table width="100%" border="2" rules="groups">
+    <colgroup>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="3%"/>
+      <col width="15%"/>
+      <col width="51%"/>
+      <col width="15%"/>
+      <col width="6%"/>
+    </colgroup>
+    <thead>
+    <tr>
+      <th align="left" valign="top">
+        <button id="dummy" name="orderBy" value="{$orderBy}" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">No.</button>
+      </th>
+      <th align="left" valign="top"><button id="dummy" name="orderBy" value="{$orderBy}" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Echo</button></th>
+      <th></th>
+      <th align="left" valign="top">
+        <button name="orderBy" value="author" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Author</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="orderBy" value="title" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Title</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="orderBy" value="place" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Place</button>
+      </th>
+      <th align="left" valign="top">
+        <button name="orderBy" value="date" style="padding:0px;font-weight:bold;font-size:14px;background:none;border:none;">Year</button>
+      </th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr/>
+      {$pageResult}
+    </tbody>
+    </table>
+    </form>
+  else if ($attrQueryResultError != '')
+  then (<b>Your query delivers an error: </b>, $attrQueryResultError)
+  else (<b>Your query delivers no result</b>)
+
+let $resultPage :=
+  if ($output = "html")
+  then 
+    <div class="queryResult">
+      <div class="queryResultHits" style="visibility:hidden">{$countResult}</div>
+      <div class="queryResultPage">
+        {$resultPageBody}
+      </div>
+    </div>  
+  else if ($output = "xml")
+  then
+    <result>
+      <query>
+        <type>{$queryType}</type>
+        <language>{$language}</language>
+        <docbase>{$docbase}</docbase>
+        <ftQuery>{$ftQuery}</ftQuery>
+        <ftMorphQuery>{$ftMorphQuery}</ftMorphQuery>
+      </query>
+      <queryResult>
+        <size>{$countResult}</size>
+        <page>
+          <size>{$pageSize}</size>
+          <pageNumber>{$pn}</pageNumber>
+          <content>{$pageResult}</content>
+        </page>
+      </queryResult>
+    </result>
+  else ()   
+return $resultPage
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/xpath.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,70 @@
+xquery version "1.0";
+
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+(: ToDo wenn eine pn gegeben ist, wird momentan der namespace ignoriert  :)
+let $mpdlDocUri := request:get-parameter("document", "")
+let $pn := number(request:get-parameter("pn", "-1"))
+let $xpath := request:get-parameter("xpath", "")
+let $output := request:get-parameter("output", "")
+let $resultPageNumber := number(request:get-parameter("resultPN", "1"))
+let $resultPageSize := number(request:get-parameter("resultPageSize", "50"))
+
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $document := doc($fullDocumentUri)
+let $pageBreaks := 
+  if ($docbase = 'archimedes' and $pn != -1)
+  then $document//pb
+  else if ($docbase = 'echo' and $pn != -1)
+  then $document//echo:pb
+  else $document//pb
+let $countPBs := count($pageBreaks)
+let $pb1 := subsequence($pageBreaks, $pn, 1)
+let $pb2 := subsequence($pageBreaks, $pn + 1, 1)
+let $pageFragmentStr := 
+  if ($pn != -1 and $countPBs > 0)
+  then util:get-fragment-between($pb1, $pb2, true())
+  else if ($pn != -1 and $countPBs = 0)
+  then ""
+  else ()
+let $pageFragment := 
+  if ($countPBs > 0)
+  then util:parse($pageFragmentStr)
+  else $document
+let $xPathFragment := concat(".", $xpath)
+let $resultEval :=
+  if ($pn > 0)
+  then util:eval-inline($pageFragment, $xPathFragment)
+  else util:eval-inline($document, $xPathFragment)
+let $from := ($resultPageNumber * $resultPageSize) - $resultPageSize + 1
+let $to := $resultPageNumber * $resultPageSize
+let $resultEvalPage := 
+  for $entry at $pos in $resultEval
+  where $pos >= $from and $pos <= $to
+  return $entry
+let $size := count($resultEval)
+let $pages := 
+  if ($size = 0)
+  then 0
+  else $size idiv $resultPageSize + 1
+let $result := 
+      <result>
+        <document>{$mpdlDocUri}</document>
+        <documentPageNumber>{$pn}</documentPageNumber>
+        <resultSize>{$size}</resultSize>
+        <resultPageSize>{$resultPageSize}</resultPageSize>
+        <countResultPages>{$pages}</countResultPages>
+        <resultPageNumber>{$resultPageNumber}</resultPageNumber>
+        <resultPage>{$resultEvalPage}</resultPage>
+      </result>  
+
+let $declare := 
+  if ($output != "html")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/interface/xquery.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,98 @@
+xquery version "1.0";
+
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+(: ToDo wenn eine pn gegeben ist (also im Fragment untersucht werden soll) geht es momentan nicht s.u. :)
+(: ToDo wenn eine pn gegeben ist, wird momentan der namespace ignoriert wie z.B. xquery=//echo:s&pn=14  :)
+let $xQuery := request:get-parameter("xquery", "")
+let $xQueryPath := request:get-parameter("xqueryPath", "")
+let $mpdlDocUri := request:get-parameter("document", "")
+let $pn := number(request:get-parameter("pn", "-1"))
+let $startRecord := number(request:get-parameter("startRecord", "1"))
+let $maximumRecords := number(request:get-parameter("maximumRecords", "-1"))
+let $output := request:get-parameter("output", "")
+let $options := request:get-parameter("options", "")
+
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $document := doc($fullDocumentUri)
+let $pageBreaks := 
+  if ($docbase = 'archimedes')
+  then $document//pb
+  else if ($docbase = 'echo')
+  then $document//echo:pb
+  else $document//pb
+let $countPBs := count($pageBreaks)
+let $pb1 := subsequence($pageBreaks, $pn, 1)
+let $pb2 := subsequence($pageBreaks, $pn + 1, 1)
+let $pageFragmentStr := 
+  if ($pn != -1 and $countPBs > 0)
+  then util:get-fragment-between($pb1, $pb2, true())
+  else if ($pn != -1 and $countPBs = 0)
+  then ""
+  else ""
+let $pageFragment :=
+  if ($countPBs > 0)
+  then util:parse($pageFragmentStr)
+  else $document
+(: ToDo im Fragment geht es nur mit vorn angehängtem Punkt. Das gibt aber Probleme, wenn es komplizierte XQueries gibt: let $xPathFragment := concat(".", $xpath)  :)
+let $resultEval :=
+  if ($xQueryPath != "" and $document != "" and $pn > 0)
+  then util:eval-inline($pageFragment, $xQueryPath)
+  else if ($xQueryPath != "" and $document != "" and $pn = -1)
+  then util:eval-inline($document, $xQueryPath)
+  else if ($xQueryPath != "" and $mpdlDocUri = "")
+  then util:eval($xQueryPath)
+  else if ($xQueryPath = "" and $document != "" and $pn > 0)
+  then util:eval-inline($pageFragment, $xQuery)
+  else if ($xQueryPath = "" and $document != "" and $pn = -1)
+  then util:eval-inline($document, $xQuery)
+  else if ($xQueryPath = "" and $mpdlDocUri = "")
+  then util:eval($xQuery)
+  else ()
+let $size := count($resultEval)
+let $from := $startRecord
+let $to := 
+  if ($maximumRecords != -1)
+  then $startRecord + $maximumRecords - 1
+  else $size
+let $resultEvalPage := 
+  for $entry at $pos in $resultEval
+  where $pos >= $from and $pos <= $to
+  return 
+    <record>
+      <id>{$pos}</id>
+      <content>{$entry}</content>
+    </record>
+
+let $resDocument := 
+  if ($document != '' and $pn != -1)
+  then <document><id>{$mpdlDocUri}</id><pn>{$pn}</pn></document>
+  else if ($document != '' and $pn = -1)
+  then <document><id>{$mpdlDocUri}</id></document>
+  else ''
+let $result := 
+      <result>
+        <xquery>{$xQuery}</xquery>
+        {$resDocument}
+        <queryResult>
+          <size>{$size}</size>
+          <startRecord>{$startRecord}</startRecord>
+          <maximumRecords>{$maximumRecords}</maximumRecords>
+          <records>
+            {$resultEvalPage}
+          </records>
+        </queryResult>
+      </result>  
+
+
+
+let $declare := 
+  if ($output != "html")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=html media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/lt/encoder.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,48 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $fromCoding := request:get-parameter("from-encoding", "")
+let $toCoding := request:get-parameter("to-encoding", "")
+let $inputString := request:get-parameter("input-string", "")
+
+let $currentTimeBegin := util:system-time()
+
+let $encodedStr := mpdltext:transcode($fromCoding, $toCoding, $inputString)
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $retHtmlResult :=
+  <html>
+  <head>
+  <title>Mpdl language technology</title>
+  </head>
+  <body>
+  <h3>Mpdl language technology: Result of your query: from-encoding={$fromCoding}, to-encoding={$toCoding}</h3>
+  <b>Your input string:</b> 
+  <p/>
+  {$inputString}
+  <p/>
+  <b>Encoded string:</b>
+  <p/>
+  {$encodedStr}  
+  <hr/>
+  <p/>
+  Elapsed time: {$neededTime} ms, see the <a href="/exist/xquery.xml">XQuery documentation</a> and the <a href="encoder.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+  </body>
+  </html>
+
+let $declare := util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+
+
+return
+<result>  
+  <query>
+    <from-encoding>{$fromCoding}</from-encoding>
+    <to-encoding>{$toCoding}</to-encoding>
+    <input-string>{$inputString}</input-string>
+  </query>
+  <encoded-string>{$encodedStr}</encoded-string>
+</result>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/lt/lemma.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,68 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $language := request:get-parameter("language", "")
+let $lemmaName := request:get-parameter("lemma", "")
+let $formName := request:get-parameter("form", "")
+let $luceneQuery := request:get-parameter("query", "")
+
+let $currentTimeBegin := util:system-time()
+
+let $lemmas := 
+  if ($formName != '')
+  then mpdltext:get-lemmas-by-form-name($language, $formName)
+  else if ($lemmaName != '')
+  then mpdltext:get-lemma($language, $lemmaName)
+  else mpdltext:get-lemmas-by-lucene-query($language, $luceneQuery)
+let $orderedLemmas := 
+  if (empty($lemmas))
+  then ("no lemmas found for your query")
+  else 
+    for $lemma in $lemmas/lemmas/lemma
+      let $lemmaText := concat($lemma/lemma-name, " (", $lemma/provider, ")")
+      let $orderedForms :=
+        for $form in $lemma/forms/form
+          let $liForm := <li>{$form/form-name} ({$form/provider})</li>
+        order by $form/form-name
+        return $liForm
+      let $lemmaLi := 
+        <li><b>Lemma: </b>{$lemmaText}
+          <ul>{$orderedForms}</ul>
+        </li>
+    order by $lemma/lemma-name
+    return $lemmaLi
+
+let $queryResultHeaderStr := 
+  if ($formName != '')
+  then <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Form={$formName}</h3>
+  else if ($lemmaName != '')
+  then <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Lemma={$lemmaName}</h3>
+  else <h3>Mpdl-Donatus: Lemmas and forms: Result of your query: Language={$language}, Query={$luceneQuery}</h3>
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $retHtmlResult :=
+  <html>
+  <head>
+  <title>Lemmas and forms</title>
+  </head>
+  <body>
+  {$queryResultHeaderStr}
+  <table align="right">
+    <td align="right">[<i>This is a MPDL <a href="http://archimedes.fas.harvard.edu/cgi-bin/donatus">Donatus</a> and <a href="http://snowball.tartarus.org/">Snowball</a> service</i>] <a href="../info.xql?info=donatus" onclick="window.open(&quot;../info.xql?info=donatus&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="15" height="15" border="0" alt="MPDL Donatus service"/></a></td>
+  </table>
+  <p/>
+  {$orderedLemmas} 
+  <p/>
+  (* in parentheses the data provider of the lemma/form)
+  <hr/>
+  <p/>
+  Elapsed time: {$neededTime} ms, see the <a href="/exist/xquery.xml">XQuery documentation</a> and the <a href="lemma.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+  </body>
+  </html>
+
+return $retHtmlResult
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/lt/lex.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,68 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "../util/time.xql";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $language := request:get-parameter("language", "")
+let $formName := request:get-parameter("form", "")
+let $luceneQuery := request:get-parameter("query", "")
+
+let $currentTimeBegin := util:system-time()
+
+let $lexica := 
+  if ($formName != '')
+  then mpdltext:get-lex-entries-by-form-name($language, $formName)
+  else mpdltext:get-lex-entries-by-lucene-query($language, $luceneQuery)
+let $htmlLexica := 
+  if (empty($lexica))
+  then ("no lexical entries found for your query")
+  else 
+    for $lexicon in $lexica/lexica/lexicon
+      let $lexDescription := $lexicon/description
+      let $lexEntries := $lexicon/entries
+      let $liLexEntryContent :=
+        for $lexEntry in $lexicon/entries/entry
+          let $lexEntryContent := $lexEntry/content
+          let $lexEntryXmlValid := $lexEntryContent/xml-valid
+          let $lexEntryOriginalContent := $lexEntryContent/original-entry
+          let $lexEntryRepairedContent := $lexEntryContent/repaired-entry
+          let $lexEntryContentParsed := 
+            if ($lexEntryXmlValid = "true")
+            then util:parse($lexEntryRepairedContent)
+            else <bla><text>[<i>Remark: lexical entry in lexicon has no valid XML, so only the Betacode text version of the entry could be displayed</i>]</text><p></p>{$lexEntryOriginalContent}</bla>
+        return <li>{($lexEntryContentParsed)}</li>
+      let $lexiconLi := 
+        <li><b>{$lexDescription}</b>
+          <ul>{$liLexEntryContent}</ul>
+        </li>
+    return $lexiconLi
+
+let $queryResultHeaderStr := 
+  if ($formName != '')
+  then <h3>Mpdl-Pollux: Result of your query: Language={$language}, Form={$formName}</h3>
+  else <h3>Mpdl-Pollux: Result of your query: Language={$language}, Query={$luceneQuery}</h3>
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $retHtmlResult :=
+  <html>
+  <head>
+  <title>Mpdl-Pollux</title>
+  </head>
+  <body>
+  {$queryResultHeaderStr}
+  <table align="right">
+    <td align="right">[<i>This is a MPDL <a href="http://archimedes.fas.harvard.edu/pollux">Pollux</a> service</i>] <a href="../info.xql?info=pollux" onclick="window.open(&quot;../info.xql?info=pollux&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="../images/info.png" valign="bottom" width="15" height="15" border="0" alt="MPDL Pollux service"/></a></td>
+  </table>
+  <text>  </text>
+  <p/>
+  {$htmlLexica} 
+  <hr/>
+  <p/>
+  Elapsed time: {$neededTime} ms, see the <a href="/exist/xquery.xml">XQuery documentation</a> and the <a href="lex.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+  </body>
+  </html>
+
+return $retHtmlResult
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/lucene/search.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,385 @@
+xquery version "1.0";
+
+module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search"; 
+
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+
+declare namespace ft = "http://exist-db.org/xquery/lucene";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+declare namespace dc="http://purl.org/dc/elements/1.1/";
+declare namespace dcterms="http://purl.org/dc/terms";
+
+declare function mpdl-lucene:search($mpdlCollection, $queryStr) {
+  let $luceneParseResult := mpdltext:lucene-parse-query($queryStr)
+  let $result := 
+    if ($luceneParseResult = '')
+    then $mpdlCollection/.[ft:query(archimedes/text, $queryStr) or ft:query(echo:echo/echo:text, $queryStr)]
+    else
+      <result>
+        <error>{$luceneParseResult}</error>
+        <size>0</size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>    
+  return $result
+};
+
+declare function mpdl-lucene:search($mpdlCollectionName, $language, $document, $queryType, $queryStr, $pn as xs:int, $pageSize as xs:int) as node() {
+  (: performance reasons: all hits (not only the first 10! ) are passed through the :)
+  (: for loop: so the overhead in each loop has to be minimized :)
+  let $query := 
+    if ($queryType = 'fulltext' or $queryType = 'fulltextMorph')
+    then $queryStr
+    else if ($queryType = 'fulltextMorphLemma')
+    then concat('lemmalemma', $queryStr)
+    else ()
+  let $pageBreaks := 
+    if ($mpdlCollectionName = 'archimedes')
+    then $document//pb
+    else if ($mpdlCollectionName = 'echo') 
+    then $document//echo:pb
+    else $document//pb
+  let $luceneParseResult := mpdltext:lucene-parse-query($queryStr)
+  let $t := 
+    if ($luceneParseResult != '')
+    then ()
+    else if ($mpdlCollectionName = 'archimedes')
+    then $document//s[ft:query(., $query)]
+    else if ($mpdlCollectionName = 'echo')
+    then $document//echo:s[ft:query(., $query)]
+    else $document//s[ft:query(., $query)]
+  let $from := ($pn * $pageSize) - $pageSize + 1
+  let $to := $pn * $pageSize
+  (: performance improvements: result set of 500 needs 3 sec., result set of 10 needs 0,7 sec.:)
+  let $tempQueryResult := 
+    for $ss at $poss in $t
+    where $poss >= $from and $poss <= $to
+    return $ss
+  let $queryResult :=
+    for $s at $pos in $tempQueryResult
+      let $pnOfS := count($pageBreaks[. << $s])        (: faster: comparison only in pb elements of this document :)
+      let $pb := subsequence($pageBreaks, $pnOfS, 1)
+      (: test if sentence surrounds page break; costs 0,1 sec performance :)
+      let $pbPlus1 := subsequence($pageBreaks, $pnOfS + 1, 1)
+      let $sSurroundsPB := 
+        if ($pbPlus1/parent::node() = $s and $pbPlus1 intersect $s/descendant::node())
+        then true()
+        else false()
+      let $posOfS :=                           (: faster: comparison only in s elements of this document :)
+        if ($mpdlCollectionName = 'archimedes')
+        then count($pb/following::s[. << $s]) + 1
+        else if ($mpdlCollectionName = 'echo')
+        then count($pb/following::echo:s[. << $s]) + 1
+        else count($pb/following::s[. << $s]) + 1
+      let $position := $from - 1 + $pos
+      let $resultElem := 
+        <hit>
+          <pos>{$position}</pos>
+          <pn>{$pnOfS}</pn>
+          <pos-of-s>{$posOfS}</pos-of-s>
+          <s>{string($s)}</s>
+          <s-surrounds-pb>{$sSurroundsPB}</s-surrounds-pb>
+        </hit>
+    return $resultElem
+  let $resultSize := count($t)
+  let $pages := 
+    if ($resultSize = 0)
+    then 0
+    else $resultSize idiv $pageSize + 1
+  let $queryForms := 
+    if ($queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma')
+    then mpdltext:get-query-morph-forms($language, $queryStr)
+    else ()
+  let $queryRegularizations := 
+    if ($queryType = 'fulltextMorph')
+    then mpdltext:get-query-regularizations($language, $queryStr)
+    else ()
+
+  let $encodedQueryTerms := 
+    if ($language = "zh")
+    then 
+      mpdltext:get-big5-encoded-terms($query)
+    else ()
+
+  let $result := 
+    if ($luceneParseResult != '')
+    then
+      <result>
+        <error>{$luceneParseResult}</error>
+        <size>0</size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>    
+    else
+      <result>
+        <size>{$resultSize}</size>
+        <page-size>{$pageSize}</page-size>
+        <pages>{$pages}</pages>
+        <pn>{$pn}</pn>
+        <hits>
+          {$queryResult}
+        </hits>
+        <query-forms>{$queryForms}</query-forms>
+        <query-regularizations>{$queryRegularizations}</query-regularizations>
+        {$encodedQueryTerms}
+      </result>
+   
+   return $result
+};
+
+declare function mpdl-lucene:attrSearch($metadataStr, $attribute1, $attrValue1, $boolOp, $attribute2, $attrValue2) {
+  let $attrFtQueryStr1 := mpdl-lucene:getAttrQueryStr($attribute1, $attrValue1)
+  let $attrFtQueryStr2 := mpdl-lucene:getAttrQueryStr($attribute2, $attrValue2)
+  let $booleanQueryStr := 
+    if ($attrValue2 = "")
+    then $attrFtQueryStr1
+    else if ($attrValue2 != "" and $boolOp = "or")
+    then concat($attrFtQueryStr1, " or ", $attrFtQueryStr2)
+    else if ($attrValue2 != "" and $boolOp = "and")
+    then concat("(", $attrFtQueryStr1, ") and (", $attrFtQueryStr2, ")")
+    else if ($attrValue2 != "" and $boolOp = "andNot")
+    then concat("(", $attrFtQueryStr1, ") and not(", $attrFtQueryStr2, ")")
+    else ()
+  let $attrQuery := concat($metadataStr, "/.[", $booleanQueryStr, "]")
+  let $luceneParseResult1 := mpdltext:lucene-parse-query($attrValue1)
+  let $luceneParseResult2 := mpdltext:lucene-parse-query($attrValue2)
+  let $luceneParseResult :=
+    if ($luceneParseResult1 = '' and $luceneParseResult2 = '')
+    then ''
+    else if ($luceneParseResult1 != '' and $luceneParseResult2 = '')
+    then concat("attribute ", $attribute1, " with value: ", $attrValue1, ": ", $luceneParseResult1)
+    else if ($luceneParseResult1 = '' and $luceneParseResult2 != '')
+    then concat("attribute ", $attribute2, " with value: ", $attrValue2, ": ", $luceneParseResult2)
+    else if ($luceneParseResult1 != '' and $luceneParseResult2 != '')
+    then concat("attribute ", $attribute1, " with value: ", $attrValue1, ": ", $luceneParseResult1, ", attribute ", $attribute2, " with value: ", $attrValue2, ": ", $luceneParseResult2)
+    else ()    
+  let $result := 
+    if ($luceneParseResult = '')
+    then util:eval($attrQuery)
+    else
+      <result>
+        <error>{$luceneParseResult}</error>
+        <size>0</size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>    
+  
+  return $result
+};
+
+declare function mpdl-lucene:order($metadata, $orderBy) {
+  let $result := 
+  (for $attrElem in $metadata
+     let $doc := $attrElem/fn:root()
+     let $documentUri := document-uri($doc)
+     let $docBase := functx:substring-after-last(functx:substring-before-last(functx:substring-before-last($documentUri, "/"), "/"), "/")
+     let $metadataElem := mpdl-lucene:getMetadata($docBase, $doc)
+     let $attrElemName := mpdl-lucene:getElemNameByAttr($docBase, $orderBy)
+     let $orderByElem := mpdl-lucene:getElemDynamic($metadataElem, $attrElemName)  (: this costs performance for many result elements   :)
+     let $orderByTemp := lower-case(string-join($orderByElem, ', '))
   order by $orderByTemp
+   return $attrElem)
+
+  return $result
+
+  (: performance improvement (?):
+     let $result := 
+       for $x in doc(/db/doc1.xml) 
+       order by $x
+       if ($sortOrder eq "asc")
+       then ( "ascending" ) 
+       else ( "descending" ) 
+  :)
+};
+
+declare function mpdl-lucene:getMetadata($docBase, $doc) {
+  let $result :=
+    if ($docBase = 'archimedes')
+    then $doc/archimedes/info
+    else if ($docBase = 'echo')
+    then $doc/echo:echo/echo:metadata
+    else ()
+  return $result	
+};
+
+declare function mpdl-lucene:getText($docBase, $doc) {
+  let $result :=
+    if ($docBase = 'archimedes')
+    then $doc/archimedes/text
+    else if ($docBase = 'echo')
+    then $doc/echo:echo/echo:text
+    else ()
+  return $result	
+};
+
+
+(: TODO: performance improvement: each time util:eval is executed   :)
+declare function mpdl-lucene:getElemDynamic($path, $elemStr) {
+  let $evalExpr :=
+    if($elemStr != "")
+    then concat("$path/", $elemStr)
+    else ""
+  let $result := util:eval($evalExpr)
+  return $result	
+};
+
+declare function mpdl-lucene:getAttrQueryStr($attribute, $attrValue) {
+  let $attrArch := mpdl-lucene:getElemNameByAttr("archimedes", $attribute)
+  let $attrEcho := mpdl-lucene:getElemNameByAttr("echo", $attribute)
+  let $attrArchRelQueryStr :=
+    if ($attribute = "date")
+    then concat($attrArch, " = '", $attrValue, "'")
+    else concat("ft:query(", $attrArch, ", '", $attrValue, "')")
+  let $attrEchoRelQueryStr :=
+    if ($attribute = "date")
+    then concat($attrEcho, " = '", $attrValue, "'")
+    else concat("ft:query(", $attrEcho, ", '", $attrValue, "')")
+  let $result := 
+    if ($attrArch != "" and $attrEcho != "")
+    then concat($attrArchRelQueryStr, " or ",  $attrEchoRelQueryStr)
+    else if ($attrArch = "" and $attrEcho != "")
+    then $attrEchoRelQueryStr
+    else if ($attrArch != "" and $attrEcho = "")
+    then $attrArchRelQueryStr
+    else ""
+  return $result
+};
+
+declare function mpdl-lucene:getElemNameByAttr($docBase, $attribute) {
+  let $docBaseArch := "archimedes"
+  let $docBaseEcho := "echo"
+  let $result :=
+    if ($docBase = $docBaseArch and $attribute = "author")
+    then "author"
+    else if ($docBase = $docBaseEcho and $attribute = "author")
+    then "dcterms:creator"
+    else if ($docBase = $docBaseArch and $attribute = "title")
+    then "title"
+    else if ($docBase = $docBaseEcho and $attribute = "title")
+    then "dcterms:title"
+    else if ($docBase = $docBaseArch and $attribute = "place")
+    then "place"
+    else if ($docBase = $docBaseEcho and $attribute = "place")
+    then ""
+    else if ($docBase = $docBaseArch and $attribute = "date")
+    then "date"
+    else if ($docBase = $docBaseEcho and $attribute = "date")
+    then "dcterms:date"
+    else if ($docBase = $docBaseArch and $attribute = "language")
+    then "lang"
+    else if ($docBase = $docBaseEcho and $attribute = "language")
+    then "dcterms:language"
+    else if ($docBase = $docBaseArch and $attribute = "identifier")
+    then "locator"
+    else if ($docBase = $docBaseEcho and $attribute = "identifier")
+    then "dcterms:identifier"
+    else if ($docBase = $docBaseArch and $attribute = "rights")
+    then ""
+    else if ($docBase = $docBaseEcho and $attribute = "rights")
+    then "dcterms:rights"
+    else if ($docBase = $docBaseArch and $attribute = "license")
+    then ""
+    else if ($docBase = $docBaseEcho and $attribute = "license")
+    then "dcterms:license"
+    else if ($docBase = $docBaseArch and $attribute = "accessRights")
+    then ""
+    else if ($docBase = $docBaseEcho and $attribute = "accessRights")
+    then "dcterms:accessRights"
+    else if ($docBase = $docBaseArch and $attribute = "file")
+    then "cvs_file"
+    else if ($docBase = $docBaseEcho and $attribute = "file")
+    then ""
+    else if ($docBase = $docBaseArch and $attribute = "translator")
+    then "translator"
+    else if ($docBase = $docBaseEcho and $attribute = "translator")
+    then ""
+    else if ($docBase = $docBaseArch and $attribute = "version")
+    then "cvs_version"
+    else if ($docBase = $docBaseEcho and $attribute = "version")
+    then ""
+    else ""
+    
+  return $result
+};
+
+declare function mpdl-lucene:getElementsByAttr($metadata, $docBase, $attribute) {
+  let $docBaseArch := "archimedes"
+  let $docBaseEcho := "echo"
+  let $result :=
+    if ($docBase = $docBaseArch and $attribute = "author")
+    then 
+      for $elem in $metadata/author
+      return <author>{$elem}</author>
+    else if ($docBase = $docBaseEcho and $attribute = "author")
+    then 
+      for $elem in $metadata/dcterms:creator
+      return <author>{$elem}</author>
+    else if ($docBase = $docBaseArch and $attribute = "title")
+    then 
+      for $elem in $metadata/title
+      return <title>{$elem}</title>
+    else if ($docBase = $docBaseEcho and $attribute = "title")
+    then 
+      for $elem in $metadata/dcterms:title
+      return <title>{$elem}</title>
+    else if ($docBase = $docBaseArch and $attribute = "place")
+    then 
+      for $elem in $metadata/place
+      return <place>{$elem}</place>
+    else if ($docBase = $docBaseEcho and $attribute = "place")
+    then ()
+    else if ($docBase = $docBaseArch and $attribute = "date")
+    then 
+      for $elem in $metadata/date
+      return <date>{$elem}</date>
+    else if ($docBase = $docBaseEcho and $attribute = "date")
+    then 
+      for $elem in $metadata/dcterms:date
+      return <date>{$elem}</date>
+    else if ($docBase = $docBaseArch and $attribute = "language")
+    then $metadata/lang
+    else if ($docBase = $docBaseEcho and $attribute = "language")
+    then $metadata/dcterms:language
+    else if ($docBase = $docBaseArch and $attribute = "identifier")
+    then $metadata/locator
+    else if ($docBase = $docBaseEcho and $attribute = "identifier")
+    then $metadata/dcterms:identifier
+    else if ($docBase = $docBaseArch and $attribute = "rights")
+    then ()
+    else if ($docBase = $docBaseEcho and $attribute = "rights")
+    then 
+      for $elem in $metadata/dcterms:rights
+      return <rights>{$elem}</rights>
+    else if ($docBase = $docBaseArch and $attribute = "accessRights")
+    then ()
+    else if ($docBase = $docBaseEcho and $attribute = "accessRights")
+    then 
+      for $elem in $metadata/dcterms:accessRights
+      return <rights>{$elem}</rights>
+    else if ($docBase = $docBaseArch and $attribute = "license")
+    then ()
+    else if ($docBase = $docBaseEcho and $attribute = "license")
+    then 
+      for $elem in $metadata/dcterms:license
+      return <license>{$elem}</license>
+    else if ($docBase = $docBaseArch and $attribute = "file")
+    then $metadata/cvs_file
+    else if ($docBase = $docBaseEcho and $attribute = "file")
+    then ()
+    else if ($docBase = $docBaseArch and $attribute = "translator")
+    then $metadata/translator
+    else if ($docBase = $docBaseEcho and $attribute = "translator")
+    then ()
+    else if ($docBase = $docBaseArch and $attribute = "version")
+    then $metadata/cvs_version
+    else if ($docBase = $docBaseEcho and $attribute = "version")
+    then ()
+    else ()
+    
+  return $result
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/page-query-result.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,431 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "util/time.xql";
+import module namespace functx = "http://www.functx.com" at "util/functx.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "lucene/search.xql";
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "text/all.xql";
+
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace transform = "http://exist-db.org/xquery/transform";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace dcterms="http://purl.org/dc/terms";
+declare namespace xhtml="http://www.w3.org/1999/xhtml";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+let $mpdlDocUri := request:get-parameter("document", "")
+let $queryType := request:get-parameter("query-type", "")
+let $mode := request:get-parameter("mode", "image")
+let $reqPN := number(request:get-parameter("pn", "-1"))
+let $reqPF := request:get-parameter("pf", "")
+let $reqSN := number(request:get-parameter("sn", "-1"))
+let $query := request:get-parameter("query", "")
+let $reqQueryResultPN := request:get-parameter("query-result-pn", "")
+let $queryResultPN := 
+  if ($reqQueryResultPN = '' or $reqQueryResultPN = '0')
+  then 1
+  else number($reqQueryResultPN)
+let $regCharNorm := request:get-parameter("characterNormalization", "")
+let $tmpCharNorm := string-join($regCharNorm, ',')
+let $charNorm := 
+  if($tmpCharNorm = "regPlusNorm")
+  then "reg,norm"
+  else $tmpCharNorm
+let $reqExport := request:get-parameter("export", "")
+let $options := string(request:get-parameter("options", ""))
+
+let $presentationPath := "/db/mpdl/presentation"
+(: e.g. mpdlCollectioName is derived from mpdlDocUri: /archimedes/la/yourDoc.xml  :)
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $language := substring-before(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := 
+  if ($queryType = 'fulltext' or $queryType = 'ftIndex')
+  then concat('/db/mpdl/documents/standard', $mpdlDocUri)
+  else if ($queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma' or $queryType = 'ftIndexMorph')
+  then concat('/db/mpdl/documents/morph', $mpdlDocUri)
+  else concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $currentTimeBegin := util:system-time()
+let $documentAvailable := doc-available($fullDocumentUri)
+let $document := doc($fullDocumentUri)
+let $metadata := 
+  if ($docbase = 'archimedes')
+  then $document/archimedes/info
+  else if ($docbase = 'echo')
+  then $document/echo:echo/echo:metadata
+  else ''
+
+let $pageBreaks := 
+  if ($docbase = 'archimedes')
+  then $document//pb
+  else if ($docbase = 'echo')
+  then $document//echo:pb
+  else $document//pb
+let $countPagesTemp := count($pageBreaks)
+let $countPages := 
+  if ($countPagesTemp > 0)
+  then $countPagesTemp
+  else 1
+
+(: xQuery inline execution does not work in module so it has to be done here  :) 
+let $xQueryPageSize := 100
+let $xQueryResultEval := 
+  if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then util:eval-inline($document, $query)
+  else ()
+let $xQueryFrom := ($queryResultPN * $xQueryPageSize) - $xQueryPageSize + 1
+let $xQueryTo := $queryResultPN * $xQueryPageSize
+let $xQueryResultEntries := 
+  for $entry at $pos in $xQueryResultEval
+  where $pos >= $xQueryFrom and $pos <= $xQueryTo
+  return $entry
+let $xQuerySize := count($xQueryResultEval)
+let $xQueryPages := 
+  if ($xQuerySize = 0)
+  then 0
+  else $xQuerySize idiv $xQueryPageSize + 1
+let $xQueryResult := 
+      <result>
+        <size>{$xQuerySize}</size>
+        <page-size>{$xQueryPageSize}</page-size>
+        <pages>{$xQueryPages}</pages>
+        <pn>{$queryResultPN}</pn>
+        <hits>{$xQueryResultEntries}</hits>
+      </result>  
+
+let $queryResult := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $query != "")
+  then mpdl-lucene:search($docbase, $language, $document, $queryType, $query, $queryResultPN, 10)
+  else if (($queryType = 'ftIndex' or $queryType = 'ftIndexMorph') and $query != "")
+  then mpdl-text:indexTerms($docbase, $language, $document, $query, $queryResultPN, 100)
+  else if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then $xQueryResult
+  else if ($queryType = 'toc' or $queryType = 'figures')
+  then mpdl-text:get-toc($docbase, $queryType, $document, $queryResultPN, 100)
+  else if ($query = "")
+  then 
+      <result>
+        <size>0</size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>
+  else ()
+
+let $countHits := count($queryResult/result/hits/hit)
+let $firstHit := $queryResult/result/hits/hit[1]
+(: jump to first pn and sn hit in fulltext mode   :)
+let $pn := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $countHits > 0 and $reqPN <= 0)
+  then number($firstHit/pn)
+  else if ($reqPN = -1)
+  then 1
+  else $reqPN
+let $sn := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $countHits > 0 and $reqPN <= 0 and $reqSN < 0)
+  then number($firstHit/pos-of-s)
+  else $reqSN
+
+(: 10 or more is an error :)
+let $errorCode := 
+  if (not($documentAvailable))
+  then 10
+  else if ($countPagesTemp != 0 and ($pn > $countPagesTemp or $pn <= 0))
+  then 11 
+  else if ($countPagesTemp = 0) 
+  then 1    (: if no page break is found then the document should have exactly one page   :)
+  else if (not($mode = "text"  or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml" or $mode = "pureXml"))
+  then 12
+  else 0
+
+let $pb1 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 1, 1)
+  else ()
+let $pb2 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn + 1, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 2, 1)
+  else ()
+let $pageHeader := string($pb1/@rhead)
+let $pageNumberOrig := string($pb1/@o)
+
+let $documentIdentifier :=
+  if ($docbase = 'archimedes')
+  then $metadata/locator
+  else if ($docbase = 'echo')
+  then $metadata/dcterms:identifier
+  else $metadata/dcterms:identifier
+let $echoDocIdentifier := 
+  if ($documentIdentifier != '')
+  then substring-before(substring-after($documentIdentifier, "ECHO:"), ".")
+  else ''
+let $echoURLZogilib := "http://echo.mpiwg-berlin.mpg.de/zogilib"
+let $nausikaaURLScaler := "http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler"
+let $nausikaaURLDlInfo := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/dlInfo-xml.jsp"
+let $nausikaaURLTexter := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/servlet/Texter"
+let $echoImageDir := 
+  if ($docbase = 'archimedes')
+  then string($metadata/echodir)
+  else if ($docbase = 'echo')
+  then string($metadata/echo:echodir)
+  else ''
+let $imagesDocDirectory :=
+  if ($echoImageDir != '')
+  then $echoImageDir
+  else if ($docbase = 'archimedes')
+  then concat("/permanent/archimedes/", $documentName)
+  else if ($docbase = 'echo')
+  then concat("/permanent/library/", $echoDocIdentifier)
+  else ''
+let $imagesDocDirectoryIndexMetaUrl := 
+  if ($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis")
+  then concat($nausikaaURLTexter, "?fn=", $imagesDocDirectory, "/index.meta")
+  else ()
+let $digilibAvailable := mpdldoc:check-uri($imagesDocDirectoryIndexMetaUrl, ())
+let $imagesDocDirectoryIndexMeta := 
+  if (($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis") and $digilibAvailable)
+  then doc($imagesDocDirectoryIndexMetaUrl)
+  else ()
+let $pageImageDirectory := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/image)
+let $figuresImageDirectoryTemp := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/figures)
+let $figuresImageDirectory := 
+  if ($figuresImageDirectoryTemp != '')
+  then $figuresImageDirectoryTemp
+  else concat(substring-before($pageImageDirectory, "pageimg"), "figures")
+let $pageImageFileNameWithoutExtension := 
+  if ($docbase = 'echo')
+  then concat("/", string($pb1/@file))
+  else ''
+let $imageFileName :=
+  if ($reqPF = '')
+  then concat($imagesDocDirectory, "/", $pageImageDirectory, $pageImageFileNameWithoutExtension)
+  else $reqPF
+let $imageEcho := <image-echo>{$echoURLZogilib}?fn={$imageFileName}&amp;pn={$pn}</image-echo>
+let $imageScaler := <image-scaler>{$nausikaaURLScaler}?fn={$imageFileName}&amp;pn={$pn}</image-scaler>
+
+let $imageFileNameUrl := concat($nausikaaURLDlInfo, "?fn=", $imageFileName)
+let $testImageResult := 
+  if ($mode = 'image' and $digilibAvailable)
+  then doc($imageFileNameUrl)
+  else ()
+let $testImageResultParamImgFn := string($testImageResult//parameter[@name='img.fn']/@value)
+let $imageIsAvailable := 
+  if ($testImageResultParamImgFn = '' and $reqPF = '')
+  then 'false'
+  else 'true'
+
+let $positionOfFirstFigureAfterPB1 := 
+  if ($docbase = 'archimedes')
+  then count($pb1/following::figure[1]/preceding::figure) + 1
+  else if ($docbase = 'echo')
+  then count($pb1/following::echo:figure[1]/preceding::echo:figure) + 1
+  else ()
+
+let $pageFragmentTmp := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then util:get-fragment-between($pb1, $pb2, true())
+  else ()
+(: replace the soft hyphen (Unicode character for 00AD) just before the line break by a normal hyphen :)
+(: delete the hyphen just before the line break in case of options=withoutLBs :)
+let $pageFragment :=
+  if (($mode = "text" or $mode = "textPollux") and not(contains($options, "withoutLBs")) and contains($pageFragmentTmp, "­<lb"))
+  then replace($pageFragmentTmp, "­<lb", "-<lb")
+  else if (($mode = "text" or $mode = "textPollux") and contains($options, "withoutLBs") and contains($pageFragmentTmp, "-<lb"))
+  then replace($pageFragmentTmp, "-<lb", "<lb")
+  else $pageFragmentTmp
+let $pageFragmentNormalized := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis") and $charNorm = "")
+  then mpdltext:normalizeChars('reg,norm', $language, $pageFragment)
+  else if (($mode = "xml" or $mode = "pureXml") and $charNorm = "")
+  then $pageFragment
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml") and $charNorm != "")
+  then mpdltext:normalizeChars($charNorm, $language, $pageFragment)
+  else ()
+let $retPageFragment := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then $pageFragmentNormalized
+  else if ($mode = "textPollux")
+  then mpdltext:dictionarize($pageFragmentNormalized, $language)
+  else ()
+let $returnPageFragmentTmp := util:parse($retPageFragment)  (: returns a valid xml document for that string   :)  
+
+let $externalElementsTmpTmp := mpdltext:externalObject("read", "element", "<object uid='joe' documentId='/archimedes/it/l223.xml' pageNumber='17'></object>")
+let $externalElementsTmp := 
+  if(not($externalElementsTmpTmp = ""))
+  then util:parse($externalElementsTmpTmp)
+  else ()
+let $externalElements := $externalElementsTmp/result/object
+let $containsExternalElements := 
+  if(not(empty($externalElements)))
+  then true()
+  else false()
+let $returnPageFragmentTmpp := 
+  if (contains($options, "withXmlNodeId") or $containsExternalElements)
+  then mpdl-text:insertNodeIdAttribute($returnPageFragmentTmp/*[1])
+  else $returnPageFragmentTmp
+
+let $returnPageFragment := 
+  if($containsExternalElements)
+  then mpdl-text:insert($returnPageFragmentTmpp/*[1], $externalElements) 
+  else $returnPageFragmentTmpp
+
+let $pageFigureAnchors := $returnPageFragment//anchor[@type = 'figure']
+let $pageFigures :=
+    for $pageFigureAnchor in $pageFigureAnchors
+      let $figureHref := string($pageFigureAnchor/@xlink:href)
+      let $pageFigureTmp := $document//echo:figure[@xlink:label = $figureHref]
+      let $pageFigure := subsequence($pageFigureTmp, 1, 1)
+    return 
+      $pageFigure
+let $pageHandwrittenAnchors := $returnPageFragment//anchor[@type = 'handwritten']
+let $pageHandwritten :=
+    for $pageHandwrittenAnchor in $pageHandwrittenAnchors
+      let $handwrittenHref := string($pageHandwrittenAnchor/@xlink:href)
+      let $pageHandwrittenTmp := $document//echo:handwritten[@xlink:label = $handwrittenHref]
+      let $pageHandwritten := subsequence($pageHandwrittenTmp, 1, 1)
+    return 
+      $pageHandwritten
+let $pageTableAnchors := $returnPageFragment//anchor[@type = 'table']
+let $pageTables :=
+    for $pageTableAnchor in $pageTableAnchors
+      let $tableHref := string($pageTableAnchor/@xlink:href)
+      let $pageTableTmp := $document//xhtml:table[@xlink:label = $tableHref]
+      let $pageTable := subsequence($pageTableTmp, 1, 1)
+    return 
+      $pageTable
+let $pageNoteAnchors := $returnPageFragment//anchor[@type = 'note']
+let $pageNotes :=
+  if ($docbase = "echo")
+  then
+    for $pageNoteAnchor in $pageNoteAnchors
+      let $noteHref := string($pageNoteAnchor/@xlink:href)
+      let $pageNoteTmp := $document//echo:note[@xlink:label = $noteHref]
+      let $pageNote := subsequence($pageNoteTmp, 1, 1)
+    return 
+      $pageNote
+  else
+    $returnPageFragment//note
+
+(: Metadata handling: only metadata of the selected document is scanned   :)
+let $identifier := $documentIdentifier
+let $authors := mpdl-lucene:getElementsByAttr($metadata, $docbase, "author")
+let $titles := mpdl-lucene:getElementsByAttr($metadata, $docbase, "title")
+let $places := mpdl-lucene:getElementsByAttr($metadata, $docbase, "place")
+let $date := mpdl-lucene:getElementsByAttr($metadata, $docbase, "date")
+let $rights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "rights")
+let $accessRights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "accessRights")
+let $licenses := mpdl-lucene:getElementsByAttr($metadata, $docbase, "license")
+let $file := mpdl-lucene:getElementsByAttr($metadata, $docbase, "file")
+let $translator := mpdl-lucene:getElementsByAttr($metadata, $docbase, "translator")
+let $version := mpdl-lucene:getElementsByAttr($metadata, $docbase, "version")
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode < 10)
+  then 
+    <result>
+      <document-description>
+        <uri>{$mpdlDocUri}</uri>
+        <collection-name>{$docbase}</collection-name>
+        <document-name>{$documentName}</document-name>
+        <language>{$language}</language>
+        <authors>{$authors}</authors>
+        <titles>{$titles}</titles>
+        <places>{$places}</places>
+        <date>{$date}</date>
+        <identifier>{$identifier}</identifier>
+        <rights>{$rights}</rights>
+        <accessRights>{$accessRights}</accessRights>
+        <licenses>{$licenses}</licenses>
+        <file>{$file}</file>
+        <translator>{$translator}</translator>
+        <version>{$version}</version>
+        <count-pages>{$countPages}</count-pages>
+      </document-description>
+      <page>
+        <mode>{$mode}</mode>
+        <number>{$pn}</number>
+        <sentence-number>{$sn}</sentence-number>
+        <header>{$pageHeader}</header>
+        <number-orig>{$pageNumberOrig}</number-orig>
+        <digilib-available>{$digilibAvailable}</digilib-available>
+        <image-available>{$imageIsAvailable}</image-available>
+        <image-file-name>{$imageFileName}</image-file-name>
+        {$imageEcho}
+        {$imageScaler}
+        <xml-url>?document={$documentName}&amp;pn={$pn}&amp;mode=xml</xml-url>
+        <page-image-directory>{$imagesDocDirectory}/{$pageImageDirectory}</page-image-directory>
+        <figures-image-directory>{$imagesDocDirectory}/{$figuresImageDirectory}</figures-image-directory>
+        <firstFigurePosition>{$positionOfFirstFigureAfterPB1}</firstFigurePosition>
+        <figures>{$pageFigures}</figures>
+        <handwritten>{$pageHandwritten}</handwritten>
+        <tables>{$pageTables}</tables>
+        <notes>{$pageNotes}</notes>
+        <content>{$returnPageFragment}</content>
+        <character-normalization>{$charNorm}</character-normalization>
+        <options>{$options}</options>
+      </page>
+      <query>
+        <type>{$queryType}</type>
+        <expression>{$query}</expression>
+        {$queryResult}
+      </query>
+      <performance>{$neededTime}</performance>
+    </result>
+  else if ($errorCode = 10)
+  then <error><number>{$errorCode}</number><description>Fulltext document: {$mpdlDocUri} is not available yet</description></error>
+  else if ($errorCode = 11)
+  then <error><number>{$errorCode}</number><description>No result: Page {$pn} not found</description></error>
+  else if ($errorCode = 12)
+  then <error><number>{$errorCode}</number><description>View mode {$mode} not available</description></error>
+  else <error><number>{$errorCode}</number><description>undefined error: {$errorCode}</description></error>  
+
+let $declare := 
+  if ($errorCode > 9 or $mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=xhtml media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+  else if ($mode = "pureXml")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+let $xslFilePath := 
+  if($reqExport = "pdf")
+  then concat($presentationPath, "/pageFragmentHtml.xsl")
+  else if($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then concat($presentationPath, "/pageHtml.xsl")
+  else concat($presentationPath, "/pageXml.xsl")
+
+let $titleStr := concat(string-join($authors, ', '), ". ", string-join($titles, ', '), ". ", string-join($places, ', '), " ", $date, ".")
+let $tmpResult :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then mpdl-text:html2pdf($language, $xmlResult, $xslFilePath, $titleStr, $pn, $mode) 
+  else if ($errorCode < 10 and not($reqExport = "pdf"))
+  then mpdl-text:transform($xmlResult, $xslFilePath)
+  else 
+    <div>{$xmlResult}</div>  (:  error xml result  :)
+let $result :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then response:stream-binary($tmpResult, "application/pdf", concat($documentName, "-page", $pn, ".pdf"))
+  else $tmpResult
+  
+let $setHeaderXmlFilename := 
+  if ($mode = "pureXml" and $queryType = "xpath" and $query != "")
+  then response:set-header('Content-Disposition', concat('filename=', $documentName, '-xpath-result--', $query, '--'))
+  else if ($mode = "pureXml" and $queryType = "xquery" and $query != "")
+  then response:set-header('Content-Disposition', concat('filename=', 'xquery-result'))
+  else if ($mode = "pureXml") 
+  then response:set-header('Content-Disposition', concat('filename=', $documentName, '-page', $pn)) 
+  else ()
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/pq.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,439 @@
+xquery version "1.0";
+
+import module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time" at "util/time.xql";
+import module namespace functx = "http://www.functx.com" at "util/functx.xql";
+import module namespace mpdl-lucene = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/lucene/search" at "lucene/search.xql";
+import module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text" at "text/all.xql";
+
+declare namespace xlink="http://www.w3.org/1999/xlink";
+declare namespace request = "http://exist-db.org/xquery/request";
+declare namespace transform = "http://exist-db.org/xquery/transform";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+declare namespace dcterms="http://purl.org/dc/terms";
+declare namespace xhtml="http://www.w3.org/1999/xhtml";
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+
+
+let $mpdlDocUri := request:get-parameter("document", "")
+let $queryType := request:get-parameter("query-type", "")
+let $mode := request:get-parameter("mode", "image")
+let $reqPN := number(request:get-parameter("pn", "-1"))
+let $reqPF := request:get-parameter("pf", "")
+let $reqSN := number(request:get-parameter("sn", "-1"))
+let $query := request:get-parameter("query", "")
+let $reqQueryResultPN := request:get-parameter("query-result-pn", "")
+let $queryResultPN := 
+  if ($reqQueryResultPN = '' or $reqQueryResultPN = '0')
+  then 1
+  else number($reqQueryResultPN)
+let $regCharNorm := request:get-parameter("characterNormalization", "")
+let $tmpCharNorm := string-join($regCharNorm, ',')
+let $charNorm := 
+  if($tmpCharNorm = "regPlusNorm")
+  then "reg,norm"
+  else $tmpCharNorm
+let $reqExport := request:get-parameter("export", "")
+let $options := string(request:get-parameter("options", ""))
+
+let $presentationPath := "/db/mpdl/presentation"
+(: e.g. mpdlCollectioName is derived from mpdlDocUri: /archimedes/la/yourDoc.xml  :)
+let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+let $language := substring-before(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/")
+let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+let $fullDocumentUri := 
+  if ($queryType = 'fulltext' or $queryType = 'ftIndex')
+  then concat('/db/mpdl/documents/standard', $mpdlDocUri)
+  else if ($queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma' or $queryType = 'ftIndexMorph')
+  then concat('/db/mpdl/documents/morph', $mpdlDocUri)
+  else concat('/db/mpdl/documents/morph', $mpdlDocUri)
+let $currentTimeBegin := util:system-time()
+let $documentAvailable := doc-available($fullDocumentUri)
+let $document := doc($fullDocumentUri)
+let $metadata := 
+  if ($docbase = 'archimedes')
+  then $document/archimedes/info
+  else if ($docbase = 'echo')
+  then $document/echo:echo/echo:metadata
+  else ''
+
+let $pageBreaks := 
+  if ($docbase = 'archimedes')
+  then $document//pb
+  else if ($docbase = 'echo')
+  then $document//echo:pb
+  else $document//pb
+let $countPagesTemp := count($pageBreaks)
+let $countPages := 
+  if ($countPagesTemp > 0)
+  then $countPagesTemp
+  else 1
+
+(: xQuery inline execution does not work in module so it has to be done here  :) 
+let $xQueryPageSize := 100
+let $xQueryResultEval := 
+  if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then util:eval-inline($document, $query)
+  else ()
+let $xQueryFrom := ($queryResultPN * $xQueryPageSize) - $xQueryPageSize + 1
+let $xQueryTo := $queryResultPN * $xQueryPageSize
+let $xQueryResultEntries := 
+  for $entry at $pos in $xQueryResultEval
+  where $pos >= $xQueryFrom and $pos <= $xQueryTo
+  return $entry
+let $xQuerySize := count($xQueryResultEval)
+let $xQueryPages := 
+  if ($xQuerySize = 0)
+  then 0
+  else $xQuerySize idiv $xQueryPageSize + 1
+let $xQueryResult := 
+      <result>
+        <size>{$xQuerySize}</size>
+        <page-size>{$xQueryPageSize}</page-size>
+        <pages>{$xQueryPages}</pages>
+        <pn>{$queryResultPN}</pn>
+        <hits>{$xQueryResultEntries}</hits>
+      </result>  
+
+let $queryResult := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $query != "")
+  then mpdl-lucene:search($docbase, $language, $document, $queryType, $query, $queryResultPN, 10)
+  else if (($queryType = 'ftIndex' or $queryType = 'ftIndexMorph') and $query != "")
+  then mpdl-text:indexTerms($docbase, $language, $document, $query, $queryResultPN, 100)
+  else if ($queryType = 'xpath' or $queryType = 'xquery' and $query != "")
+  then $xQueryResult
+  else if ($queryType = 'toc' or $queryType = 'figures')
+  then mpdl-text:get-toc($docbase, $queryType, $document, $queryResultPN, 100)
+  else if ($query = "")
+  then 
+      <result>
+        <size>0</size>
+        <pages>0</pages>
+        <pn>0</pn>
+        <hits/>
+      </result>
+  else ()
+
+let $countHits := count($queryResult/result/hits/hit)
+let $firstHit := $queryResult/result/hits/hit[1]
+(: jump to first pn and sn hit in fulltext mode   :)
+let $pn := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $countHits > 0 and $reqPN <= 0)
+  then number($firstHit/pn)
+  else if ($reqPN = -1)
+  then 1
+  else $reqPN
+let $sn := 
+  if (($queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma') and $countHits > 0 and $reqPN <= 0 and $reqSN < 0)
+  then number($firstHit/pos-of-s)
+  else $reqSN
+
+(: 10 or more is an error :)
+let $errorCode := 
+  if (not($documentAvailable))
+  then 10
+  else if ($countPagesTemp != 0 and ($pn > $countPagesTemp or $pn <= 0))
+  then 11 
+  else if ($countPagesTemp = 0) 
+  then 1    (: if no page break is found then the document should have exactly one page   :)
+  else if (not($mode = "text"  or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml" or $mode = "pureXml"))
+  then 12
+  else 0
+
+let $pb1 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 1, 1)
+  else ()
+let $pb2 := 
+  if ($errorCode = 0)
+  then subsequence($pageBreaks, $pn + 1, 1)
+  else if ($errorCode = 1)
+  then subsequence(mpdl-lucene:getText($docbase, $document), 2, 1)
+  else ()
+let $pageHeader := string($pb1/@rhead)
+let $pageNumberOrig := string($pb1/@o)
+
+let $documentIdentifier :=
+  if ($docbase = 'archimedes')
+  then $metadata/locator
+  else if ($docbase = 'echo')
+  then $metadata/dcterms:identifier
+  else $metadata/dcterms:identifier
+let $echoDocIdentifier := 
+  if ($documentIdentifier != '')
+  then substring-before(substring-after($documentIdentifier, "ECHO:"), ".")
+  else ''
+let $echoURLZogilib := "http://echo.mpiwg-berlin.mpg.de/zogilib"
+let $nausikaaURLScaler := "http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler"
+let $nausikaaURLDlInfo := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/dlInfo-xml.jsp"
+let $nausikaaURLTexter := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/servlet/Texter"
+let $echoImageDir := 
+  if ($docbase = 'archimedes')
+  then string($metadata/echodir)
+  else if ($docbase = 'echo')
+  then string($metadata/echo:echodir)
+  else ''
+let $imagesDocDirectory :=
+  if ($echoImageDir != '')
+  then $echoImageDir
+  else if ($docbase = 'archimedes')
+  then concat("/permanent/archimedes/", $documentName)
+  else if ($docbase = 'echo')
+  then concat("/permanent/library/", $echoDocIdentifier)
+  else ''
+let $imagesDocDirectoryIndexMetaUrl := 
+  if ($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis")
+  then concat($nausikaaURLTexter, "?fn=", $imagesDocDirectory, "/index.meta")
+  else ()
+let $digilibAvailable := mpdldoc:check-uri($imagesDocDirectoryIndexMetaUrl, ())
+let $imagesDocDirectoryIndexMeta := 
+  if (($mode = "image" or $mode = "text" or $mode = "textPollux" or $mode = "gis") and $digilibAvailable)
+  then doc($imagesDocDirectoryIndexMetaUrl)
+  else ()
+let $pageImageDirectory := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/image)
+let $figuresImageDirectoryTemp := string($imagesDocDirectoryIndexMeta/resource/meta/texttool/figures)
+let $figuresImageDirectory := 
+  if ($figuresImageDirectoryTemp != '')
+  then $figuresImageDirectoryTemp
+  else concat(substring-before($pageImageDirectory, "pageimg"), "figures")
+let $pageImageFileNameWithoutExtension := 
+  if ($docbase = 'echo')
+  then concat("/", string($pb1/@file))
+  else ''
+let $imageFileName :=
+  if ($reqPF = '')
+  then concat($imagesDocDirectory, "/", $pageImageDirectory, $pageImageFileNameWithoutExtension)
+  else $reqPF
+let $imageEcho := <image-echo>{$echoURLZogilib}?fn={$imageFileName}&amp;pn={$pn}</image-echo>
+let $imageScaler := <image-scaler>{$nausikaaURLScaler}?fn={$imageFileName}&amp;pn={$pn}</image-scaler>
+
+let $imageFileNameUrl := concat($nausikaaURLDlInfo, "?fn=", $imageFileName)
+let $testImageResult := 
+  if ($mode = 'image' and $digilibAvailable)
+  then doc($imageFileNameUrl)
+  else ()
+let $testImageResultParamImgFn := string($testImageResult//parameter[@name='img.fn']/@value)
+let $imageIsAvailable := 
+  if ($testImageResultParamImgFn = '' and $reqPF = '')
+  then 'false'
+  else 'true'
+
+let $positionOfFirstFigureAfterPB1 := 
+  if ($docbase = 'archimedes')
+  then count($pb1/following::figure[1]/preceding::figure) + 1
+  else if ($docbase = 'echo')
+  then count($pb1/following::echo:figure[1]/preceding::echo:figure) + 1
+  else ()
+
+let $pageFragmentTmp := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then util:get-fragment-between($pb1, $pb2, true())
+  else ()
+(: replace the soft hyphen (Unicode character for 00AD) just before the line break by a normal hyphen :)
+(: delete the hyphen just before the line break in case of options=withoutLBs :)
+let $pageFragment :=
+  if (($mode = "text" or $mode = "textPollux") and not(contains($options, "withoutLBs")) and contains($pageFragmentTmp, "­<lb"))
+  then replace($pageFragmentTmp, "­<lb", "-<lb")
+  else if (($mode = "text" or $mode = "textPollux") and contains($options, "withoutLBs") and contains($pageFragmentTmp, "-<lb"))
+  then replace($pageFragmentTmp, "-<lb", "<lb")
+  else $pageFragmentTmp
+let $pageFragmentNormalized := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis") and $charNorm = "")
+  then mpdltext:normalizeChars('reg,norm', $language, $pageFragment)
+  else if (($mode = "xml" or $mode = "pureXml") and $charNorm = "")
+  then $pageFragment
+  else if (($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "xml" or $mode = "pureXml") and $charNorm != "")
+  then mpdltext:normalizeChars($charNorm, $language, $pageFragment)
+  else ()
+let $retPageFragment := 
+  if ($mode = "image" or $errorCode > 9)
+  then ()
+  else if ($mode = "text" or $mode = "gis" or $mode = "xml" or $mode = "pureXml")
+  then $pageFragmentNormalized
+  else if ($mode = "textPollux")
+  then mpdltext:dictionarize($pageFragmentNormalized, $language)
+  else ()
+let $returnPageFragmentTmp := util:parse($retPageFragment)  (: returns a valid xml document for that string   :)  
+
+let $externalElementsTmpTmp := mpdltext:externalObject("read", "element", "", $mpdlDocUri, string($pn), "", "", "")
+let $externalElementsTmp := 
+  if(not($externalElementsTmpTmp = ""))
+  then util:parse($externalElementsTmpTmp)
+  else ()
+let $externalElements := $externalElementsTmp/result/element
+let $containsExternalElements := 
+  if(not(empty($externalElements)))
+  then true()
+  else false()
+(: let $bla := error(QName("Bla", "Bla"), util:serialize($externalElementsTmp, ())) :)
+let $returnPageFragmentTmpp := 
+  if (contains($options, "withXmlNodeId") or $containsExternalElements)
+  then mpdl-text:insertNodeIdAttribute($returnPageFragmentTmp/*[1])
+  else $returnPageFragmentTmp
+let $sentences := util:eval-inline($returnPageFragmentTmpp, ".//s")
+let $s4NodeId := subsequence($sentences, 4, 1)/@xmlNodeId
+let $s5NodeId := subsequence($sentences, 5, 1)/@xmlNodeId
+let $testExternalObjects :=
+  (<element uid="joe" documentId="{$mpdlDocUri}" pageNumber="14" xmlNodeId="{$s4NodeId}" before="true" charPos="10"><content><note>This is a first test note</note></content></element>, 
+   <element uid="joe" documentId="{$mpdlDocUri}" pageNumber="14" xmlNodeId="{$s5NodeId}" before="false" charPos="-1"><content><note>This is a second test note</note></content></element>) 
+
+let $returnPageFragment := 
+  if($containsExternalElements)
+  then mpdl-text:insert($returnPageFragmentTmpp/*[1], $externalElements) 
+  else $returnPageFragmentTmpp
+
+let $pageFigureAnchors := $returnPageFragment//anchor[@type = 'figure']
+let $pageFigures :=
+    for $pageFigureAnchor in $pageFigureAnchors
+      let $figureHref := string($pageFigureAnchor/@xlink:href)
+      let $pageFigureTmp := $document//echo:figure[@xlink:label = $figureHref]
+      let $pageFigure := subsequence($pageFigureTmp, 1, 1)
+    return 
+      $pageFigure
+let $pageHandwrittenAnchors := $returnPageFragment//anchor[@type = 'handwritten']
+let $pageHandwritten :=
+    for $pageHandwrittenAnchor in $pageHandwrittenAnchors
+      let $handwrittenHref := string($pageHandwrittenAnchor/@xlink:href)
+      let $pageHandwrittenTmp := $document//echo:handwritten[@xlink:label = $handwrittenHref]
+      let $pageHandwritten := subsequence($pageHandwrittenTmp, 1, 1)
+    return 
+      $pageHandwritten
+let $pageTableAnchors := $returnPageFragment//anchor[@type = 'table']
+let $pageTables :=
+    for $pageTableAnchor in $pageTableAnchors
+      let $tableHref := string($pageTableAnchor/@xlink:href)
+      let $pageTableTmp := $document//xhtml:table[@xlink:label = $tableHref]
+      let $pageTable := subsequence($pageTableTmp, 1, 1)
+    return 
+      $pageTable
+let $pageNoteAnchors := $returnPageFragment//anchor[@type = 'note']
+let $pageNotes :=
+  if ($docbase = "echo")
+  then
+    for $pageNoteAnchor in $pageNoteAnchors
+      let $noteHref := string($pageNoteAnchor/@xlink:href)
+      let $pageNoteTmp := $document//echo:note[@xlink:label = $noteHref]
+      let $pageNote := subsequence($pageNoteTmp, 1, 1)
+    return 
+      $pageNote
+  else
+    $returnPageFragment//note
+
+(: Metadata handling: only metadata of the selected document is scanned   :)
+let $identifier := $documentIdentifier
+let $authors := mpdl-lucene:getElementsByAttr($metadata, $docbase, "author")
+let $titles := mpdl-lucene:getElementsByAttr($metadata, $docbase, "title")
+let $places := mpdl-lucene:getElementsByAttr($metadata, $docbase, "place")
+let $date := mpdl-lucene:getElementsByAttr($metadata, $docbase, "date")
+let $rights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "rights")
+let $accessRights := mpdl-lucene:getElementsByAttr($metadata, $docbase, "accessRights")
+let $licenses := mpdl-lucene:getElementsByAttr($metadata, $docbase, "license")
+let $file := mpdl-lucene:getElementsByAttr($metadata, $docbase, "file")
+let $translator := mpdl-lucene:getElementsByAttr($metadata, $docbase, "translator")
+let $version := mpdl-lucene:getElementsByAttr($metadata, $docbase, "version")
+
+let $currentTimeEnd := util:system-time()
+let $neededTime := mpdl-time:duration-as-ms($currentTimeEnd - $currentTimeBegin)
+
+let $xmlResult := 
+  if ($errorCode < 10)
+  then 
+    <result>
+      <document-description>
+        <uri>{$mpdlDocUri}</uri>
+        <collection-name>{$docbase}</collection-name>
+        <document-name>{$documentName}</document-name>
+        <language>{$language}</language>
+        <authors>{$authors}</authors>
+        <titles>{$titles}</titles>
+        <places>{$places}</places>
+        <date>{$date}</date>
+        <identifier>{$identifier}</identifier>
+        <rights>{$rights}</rights>
+        <accessRights>{$accessRights}</accessRights>
+        <licenses>{$licenses}</licenses>
+        <file>{$file}</file>
+        <translator>{$translator}</translator>
+        <version>{$version}</version>
+        <count-pages>{$countPages}</count-pages>
+      </document-description>
+      <page>
+        <mode>{$mode}</mode>
+        <number>{$pn}</number>
+        <sentence-number>{$sn}</sentence-number>
+        <header>{$pageHeader}</header>
+        <number-orig>{$pageNumberOrig}</number-orig>
+        <digilib-available>{$digilibAvailable}</digilib-available>
+        <image-available>{$imageIsAvailable}</image-available>
+        <image-file-name>{$imageFileName}</image-file-name>
+        {$imageEcho}
+        {$imageScaler}
+        <xml-url>?document={$documentName}&amp;pn={$pn}&amp;mode=xml</xml-url>
+        <page-image-directory>{$imagesDocDirectory}/{$pageImageDirectory}</page-image-directory>
+        <figures-image-directory>{$imagesDocDirectory}/{$figuresImageDirectory}</figures-image-directory>
+        <firstFigurePosition>{$positionOfFirstFigureAfterPB1}</firstFigurePosition>
+        <figures>{$pageFigures}</figures>
+        <handwritten>{$pageHandwritten}</handwritten>
+        <tables>{$pageTables}</tables>
+        <notes>{$pageNotes}</notes>
+        <content>{$returnPageFragment}</content>
+        <character-normalization>{$charNorm}</character-normalization>
+        <options>{$options}</options>
+      </page>
+      <query>
+        <type>{$queryType}</type>
+        <expression>{$query}</expression>
+        {$queryResult}
+      </query>
+      <performance>{$neededTime}</performance>
+    </result>
+  else if ($errorCode = 10)
+  then <error><number>{$errorCode}</number><description>Fulltext document: {$mpdlDocUri} is not available yet</description></error>
+  else if ($errorCode = 11)
+  then <error><number>{$errorCode}</number><description>No result: Page {$pn} not found</description></error>
+  else if ($errorCode = 12)
+  then <error><number>{$errorCode}</number><description>View mode {$mode} not available</description></error>
+  else <error><number>{$errorCode}</number><description>undefined error: {$errorCode}</description></error>  
+
+let $declare := 
+  if ($errorCode > 9 or $mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then util:declare-option("exist:serialize", "method=xhtml media-type=text/html omit-xml-declaration=no indent=yes encoding=utf-8")
+  else if ($mode = "pureXml")
+  then util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+  else util:declare-option("exist:serialize", "method=xml media-type=text/xml omit-xml-declaration=no indent=yes encoding=utf-8")
+let $xslFilePath := 
+  if($reqExport = "pdf")
+  then concat($presentationPath, "/pageFragmentHtml.xsl")
+  else if($mode = "text" or $mode = "textPollux" or $mode = "gis" or $mode = "image" or $mode = "xml")
+  then concat($presentationPath, "/pageHtml.xsl")
+  else concat($presentationPath, "/pageXml.xsl")
+
+let $titleStr := concat(string-join($authors, ', '), ". ", string-join($titles, ', '), ". ", string-join($places, ', '), " ", $date, ".")
+let $tmpResult :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then mpdl-text:html2pdf($language, $xmlResult, $xslFilePath, $titleStr, $pn, $mode) 
+  else if ($errorCode < 10 and not($reqExport = "pdf"))
+  then mpdl-text:transform($xmlResult, $xslFilePath)
+  else 
+    <div>{$xmlResult}</div>  (:  error xml result  :)
+let $result :=
+  if ($errorCode < 10 and $reqExport = "pdf")
+  then response:stream-binary($tmpResult, "application/pdf", concat($documentName, "-page", $pn, ".pdf"))
+  else $tmpResult
+  
+let $setHeaderXmlFilename := 
+  if ($mode = "pureXml" and $queryType = "xpath" and $query != "")
+  then response:set-header('Content-Disposition', concat('filename=', $documentName, '-xpath-result--', $query, '--'))
+  else if ($mode = "pureXml" and $queryType = "xquery" and $query != "")
+  then response:set-header('Content-Disposition', concat('filename=', 'xquery-result'))
+  else if ($mode = "pureXml") 
+  then response:set-header('Content-Disposition', concat('filename=', $documentName, '-page', $pn)) 
+  else ()
+
+return $result
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/functions-functx.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:functx="http://www.functx.com"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<!-- see http://www.xsltfunctions.com     -->
+<xsl:function name="functx:contains-any-of" as="xs:boolean">
+  <xsl:param name="arg" as="xs:string?"/> 
+  <xsl:param name="searchStrings" as="xs:string*"/> 
+  <xsl:sequence select="some $searchString in $searchStrings satisfies contains($arg,$searchString)"/>
+</xsl:function>
+
+<xsl:function name="functx:cutStringBefore">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:if test="$length &gt; $cutLength"> (...)</xsl:if>
+  <xsl:value-of select="substring($inputString, $length - $cutLength)"/>  
+</xsl:function>
+
+<xsl:function name="functx:cutStringAfter">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:value-of select="substring($inputString, 0, $cutLength)"/>  
+  <xsl:if test="$length &gt; $cutLength">(...) </xsl:if>
+</xsl:function>
+
+<xsl:function name="functx:sort" as="item()*">
+  <xsl:param name="seq" as="item()*"/> 
+  <xsl:for-each select="$seq">
+    <xsl:sort select="."/>
+    <xsl:copy-of select="."/>
+   </xsl:for-each>
+</xsl:function>   
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/functions-mpdl.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:mpdl="http://www.mpiwg-berlin.mpg.de/ns/mpdl">
+
+<xsl:function name="mpdl:showFigure">
+  <xsl:param name="digilibAvailable"/>
+  <xsl:param name="figureFileName"/>
+  <xsl:param name="figureNumber"/>
+  <xsl:param name="figureCaption"/>
+  <xsl:param name="figureDescription"/>
+  <xsl:param name="figureVariables"/>
+  <xsl:param name="class"/>
+  <xsl:variable name="fullFigureFileName">
+    <xsl:choose>
+      <xsl:when test="$figureFileName != ''"><xsl:value-of select="concat($figuresImageDirectory, '/', $figureFileName)"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="$figuresImageDirectory"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="nausikaaURLDlInfo" select="concat('http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/dlInfo-xml.jsp?fn=', $fullFigureFileName)"/>
+  <xsl:variable name="testFigureResult">
+    <xsl:choose>
+      <xsl:when test="$digilibAvailable = 'true'"><xsl:value-of select="unparsed-text($nausikaaURLDlInfo)"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="testFigureResultParamImgFn" select="substring-before(substring-after($testFigureResult, 'parameter name=&quot;img.fn&quot; value=&quot;'), '&quot;')"/>
+  <xsl:variable name="figureIsAvailable">
+    <xsl:choose>
+      <xsl:when test="$testFigureResultParamImgFn = ''"><xsl:value-of select="'false'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'true'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="figureWidth">
+    <xsl:choose>
+      <xsl:when test="$collectionName = 'archimedes' or contains($class, 'float none')"><xsl:value-of select="'400'"/></xsl:when>
+      <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="'200'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'200'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="figureHeight">
+    <xsl:choose>
+      <xsl:when test="$collectionName = 'archimedes' or contains($class, 'float none')"><xsl:value-of select="'400'"/></xsl:when>
+      <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="'200'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'200'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="figureBorder" select="'border:1px;'"/>
+  <xsl:variable name="style">
+    <xsl:choose>
+      <xsl:when test="$figureIsAvailable = 'true'"><xsl:value-of select="$figureBorder"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="concat($figureBorder, 'width:', $figureWidth, ';')"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:if test="$collectionName = 'archimedes'"><br/></xsl:if>
+  <xsl:variable name="figureContent">
+    <xsl:choose>
+      <xsl:when test="$digilibAvailable = 'false'">
+        <img title="Could not fetch figure by nausikaa2.rz-berlin.mpg.de: please try again later" alt="Could not fetch figure by nausikaa2.rz-berlin.mpg.de: please try again later" src="images/camera.png" width="30" height="30" border="0"/>
+      </xsl:when>
+      <xsl:when test="$figureIsAvailable = 'true' and $figureFileName != ''">
+        <a href="http://echo.mpiwg-berlin.mpg.de/zogilib?fn={$fullFigureFileName}"><img alt="figure: {$figureNumber}" src="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn={$fullFigureFileName}&amp;dh={$figureHeight}&amp;dw={$figureWidth}"/></a>
+      </xsl:when>
+      <xsl:when test="$figureIsAvailable = 'true' and $figureFileName = ''">
+        <a href="http://echo.mpiwg-berlin.mpg.de/zogilib?fn={$fullFigureFileName}&amp;pn={$figureNumber}"><img alt="figure: {$figureNumber}" src="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler?fn={$fullFigureFileName}&amp;pn={$figureNumber}&amp;dh={$figureHeight}&amp;dw={$figureWidth}"/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <img title="Figure: {$fullFigureFileName} not scanned" alt="Figure: {$fullFigureFileName} not scanned" src="images/camera.png" width="30" height="30" border="0"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="figureText" select="concat('[Figure: ', $figureNumber, ']')"/>
+  <div class="{$class}" style="{$style}">
+    <xsl:if test="not(empty($figureCaption))"><xsl:sequence select="$figureCaption"/><br/></xsl:if>
+    <xsl:sequence select="$figureContent"/>
+    <br/>
+    <xsl:value-of select="$figureText"/>
+    <xsl:if test="not(empty($figureDescription))"><xsl:value-of select="': '"/><xsl:sequence select="$figureDescription"/></xsl:if>
+    <xsl:if test="not(empty($figureVariables))"><xsl:value-of select="'(Variables: '"/><xsl:sequence select="$figureVariables"/><xsl:value-of select="')'"/></xsl:if>
+  </div>
+</xsl:function>
+
+<xsl:function name="mpdl:showHandwritten">
+  <xsl:param name="fileName"/>
+  <xsl:param name="href"/>
+  <xsl:variable name="handwrittenText" select="'[Handwritten]'"/>
+  <div class="handwritten">
+    <img title="Handwritten: {$href} not scanned" alt="Handwritten: {$href} not scanned" src="images/camera.png" width="30" height="30" border="0"/>
+    <br/>
+    <xsl:value-of select="$handwrittenText"/>
+    <p/>
+  </div>
+</xsl:function>
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/functions-text.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,354 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:saxon="http://saxon.sf.net/"
+ xmlns:functx="http://www.functx.com"
+ xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<xsl:import href="/db/mpdl/presentation/functions-functx.xsl" />
+
+<!-- delivers a concatenation of n chars of the given char -->   
+<xsl:function name="text:nchars">
+  <xsl:param name="count" as="xs:integer"/>
+  <xsl:param name="char" as="xs:string"/>
+  <xsl:sequence select="if ($count > 1) then concat($char, text:nchars($count - 1, $char)) else $char"/>
+</xsl:function>
+
+<xsl:function name="text:sortWithComma">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:variable name="inputStrings" select="tokenize($inputString, '\|')"/>
+  <xsl:variable name="sortedInputStrings" select="functx:sort($inputStrings)"/>
+  <xsl:variable name="result">
+    <xsl:for-each select="$sortedInputStrings">
+      <xsl:value-of select="concat(., ', ')"/>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:variable name="length" select="string-length($result)"/>  
+  <xsl:choose>
+    <xsl:when test="$length > 0">
+      <xsl:value-of select="substring($result, 0, $length - 1)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="''"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!-- Compares inputString1 and inputString2 and removes the duplicates in     -->
+<!-- inputString1 and gives them back -->
+<!-- inputString1 and inputString2 contain a list of strings separated by "|" -->
+<xsl:function name="text:removeDuplicates">
+  <xsl:param name="inputString1" as="xs:string"/>
+  <xsl:param name="inputString2" as="xs:string"/>
+  <xsl:variable name="inputStrings1" select="tokenize($inputString1, '\|')"/>  
+  <xsl:variable name="inputStrings2" select="tokenize($inputString2, '\|')"/>
+  <xsl:variable name="result">
+    <xsl:for-each select="$inputStrings1">
+      <xsl:variable name="str" select="."/>  
+      <xsl:if test="not(text:contained($str, $inputStrings2))"><xsl:value-of select="concat($str, '|')"/></xsl:if>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:variable name="length" select="string-length($result)"/>  
+  <xsl:choose>
+    <xsl:when test="$length > 0">
+      <xsl:value-of select="substring($result, 0, $length)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="''"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:contained" as="xs:boolean">
+  <xsl:param name="arg" as="xs:string?"/> 
+  <xsl:param name="searchStrings" as="xs:string*"/> 
+  <xsl:sequence select="some $searchString in $searchStrings satisfies compare($arg, $searchString) = 0"/>
+</xsl:function>
+
+<xsl:function name="text:cutStringBefore">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:variable name="cutString" select="substring($inputString, $length - $cutLength)"/>
+  <xsl:choose>
+    <xsl:when test="$length &gt; $cutLength">
+       (...)
+      <xsl:value-of select="text:cutFirstWord($cutString)"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="$cutString"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:cutStringAfter">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:param name="cutLength" as="xs:integer"/>
+  <xsl:variable name="length" select="string-length($inputString)"/>  
+  <xsl:variable name="cutString" select="substring($inputString, 0, $cutLength)"/>  
+  <xsl:choose>
+    <xsl:when test="$length &gt; $cutLength">
+      <xsl:value-of select="text:cutLastWord($cutString)"/>
+      (...) 
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="$cutString"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:cutFirstWord">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:value-of select="replace($inputString, '^.*?[\s:.,;!_]', ' ', 'im')"/>  
+</xsl:function>
+
+<xsl:function name="text:cutLastWord">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:value-of select="replace($inputString, '(.*)[\s:.,;!_].*$', '$1 ', 'im')"/>  
+</xsl:function>
+
+<xsl:function name="text:trim">
+  <xsl:param name="inputString" as="xs:string"/>
+  <xsl:variable name="trimBefore" select="replace($inputString, '^\s+(.*?)', '$1')"/>  
+  <xsl:value-of select="replace($trimBefore, '(.*?)\s+$', '$1')"/>  
+</xsl:function>
+
+<!-- Word delimiter: not tested yet -->
+<!-- TODO: bol, eol, ", &, <, >    -->
+<!-- <xsl:variable name="wordDelimRegExpr" select="'[\s\(\)\[\]\.\\\{\}\$\^\+\?\!\* §%:,;=/]+'"/>  -->  
+
+<!-- Tokenization of a Lucene query with phrases and words to a list of query terms separated with | -->  
+<xsl:function name="text:translateLuceneToTerms">
+  <xsl:param name="inputLuceneQuery" as="xs:string" />
+  <!-- Delete all parantheses outside quotes: (a AND b) OR c   ->  a AND b OR c -->
+  <xsl:variable name="luceneQueryWithoutParantheses1" select="replace($inputLuceneQuery, '([^\\])[()]', '$1')" /> 
+  <xsl:variable name="luceneQueryWithoutParantheses2" select="replace($luceneQueryWithoutParantheses1, '^[()]', '')" /> 
+  <!-- Unescape special chars in Lucene query  -->
+  <xsl:variable name="luceneQueryUnescaped" select="replace($luceneQueryWithoutParantheses2, '\\([-\+&amp;|!(){}\[\]\^&quot;~*?:\\])', '$1')" /> 
+  <!-- Escape special chars which have a meta meaning in regular expressions  -->
+  <xsl:variable name="luceneQueryRegExprEscaped1" select="replace($luceneQueryUnescaped, '[*]', '###Star###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped2" select="replace($luceneQueryRegExprEscaped1, '[\+]', '###Plus###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped3" select="replace($luceneQueryRegExprEscaped2, '[?]', '###QM###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped4" select="replace($luceneQueryRegExprEscaped3, '[\.]', '###Dot###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped5" select="replace($luceneQueryRegExprEscaped4, '[\^]', '###BeginLine###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped6" select="replace($luceneQueryRegExprEscaped5, '[$]', '###EndLine###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped7" select="replace($luceneQueryRegExprEscaped6, '[|]', '###Or###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped8" select="replace($luceneQueryRegExprEscaped7, '[(]', '###Paranthes1Open###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped9" select="replace($luceneQueryRegExprEscaped8, '[)]', '###Paranthes1Close###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped10" select="replace($luceneQueryRegExprEscaped9, '[{]', '###Paranthes2Open###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped11" select="replace($luceneQueryRegExprEscaped10, '[}]', '###Paranthes2Close###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped12" select="replace($luceneQueryRegExprEscaped11, '[\[]', '###Paranthes3Open###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped13" select="replace($luceneQueryRegExprEscaped12, '[\]]', '###Paranthes3Close###')" /> 
+  <xsl:variable name="luceneQueryRegExprEscaped14" select="replace($luceneQueryRegExprEscaped13, '~[0123456789,]*', '###Tilde###')" /> 
+  <xsl:value-of select="text:translateLuceneQueryToTermsMain($luceneQueryRegExprEscaped14, 'DUMMYDUMMYSTART')" />
+</xsl:function>
+
+<!-- Tokenization of a Lucene query with phrases and words to a list of query terms separated with | -->  
+<xsl:function name="text:translateLuceneQueryToTermsMain">
+  <xsl:param name="inputString" as="xs:string" />
+  <!-- last term in previous step: used for Lucene operator NOT)  -->
+  <xsl:param name="lastFetchedTerm" as="xs:string" />
+  <xsl:choose>
+    <!-- single phrase: phrase is appended -->
+    <xsl:when test="matches($inputString, '^&quot;[^&quot;]*?&quot;$')">
+      <xsl:variable name="withoutSurroundingQuotes" select="substring-before(substring-after($inputString, '&quot;'), '&quot;')"/>
+      <xsl:variable name="termEscaped" select="text:escapeLucenePhraseForRegExpr($withoutSurroundingQuotes)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($termEscaped, $lastFetchedTerm)" />
+      <xsl:value-of select="$term" />
+    </xsl:when>
+    <!-- "+" followd by a single phrase: phrase is appended -->
+    <xsl:when test="matches($inputString, '^###Plus###&quot;[^&quot;]*?&quot;$')">
+      <xsl:variable name="length" select="string-length($inputString)"/>
+      <xsl:variable name="withoutSurroundingQuotes" select="substring($inputString, 12, $length - 12)"/>
+      <xsl:variable name="termEscaped" select="text:escapeLucenePhraseForRegExpr($withoutSurroundingQuotes)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($termEscaped, $lastFetchedTerm)" />
+      <xsl:value-of select="$term" />
+    </xsl:when>
+    <!-- "-" followd by a single phrase: phrase is not appended -->
+    <xsl:when test="matches($inputString, '^-&quot;[^&quot;]*?&quot;$')">
+      <xsl:value-of select="'DUMMYDUMMYMINUS'" />
+    </xsl:when>
+    <!-- TODO: single phrase followed by near operator (~[0123456789]+): determine distance between -->
+    <xsl:when test="matches($inputString, '^&quot;[^&quot;]*?&quot;~[0123456789]+$')">
+      <xsl:value-of select="$inputString" />
+    </xsl:when>
+    <!-- phrase followed by something: phrase is appended  -->
+    <xsl:when test="matches($inputString, '^&quot;.*?&quot;\s')"> 
+      <xsl:variable name="afterFirstTerm" select="replace($inputString, '^&quot;.*?&quot;\s', '')"/>
+      <xsl:variable name="length" select="string-length($inputString)"/>
+      <xsl:variable name="afterFirstTermLength" select="string-length($afterFirstTerm)"/>
+      <xsl:variable name="firstTerm" select="substring($inputString, 1, $length - $afterFirstTermLength)"/>
+      <xsl:variable name="afterFirstTermTrimmed" select="text:trim($afterFirstTerm)"/>
+      <xsl:variable name="firstTermWithoutSurroundingQuotes" select="substring-before(substring-after($firstTerm, '&quot;'), '&quot;')"/>
+      <xsl:variable name="firstTermEscaped" select="text:escapeLucenePhraseForRegExpr($firstTermWithoutSurroundingQuotes)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($firstTermEscaped, $lastFetchedTerm)" />
+      <xsl:value-of select="concat($term, '|')" />
+      <!-- Recursive call of this function with the substring after the first term -->
+      <xsl:value-of select="text:translateLuceneQueryToTermsMain($afterFirstTermTrimmed, $term)"/>
+    </xsl:when>
+    <!--  + sign followd by phrase followed by something: phrase is appended -->
+    <xsl:when test="matches($inputString, '^###Plus###&quot;.*?&quot;\s')"> 
+      <xsl:variable name="afterFirstTerm" select="replace($inputString, '^###Plus###&quot;.*?&quot;\s', '')"/>
+      <xsl:variable name="length" select="string-length($inputString)"/>
+      <xsl:variable name="afterFirstTermLength" select="string-length($afterFirstTerm)"/>
+      <xsl:variable name="firstTerm" select="substring($inputString, 1, $length - $afterFirstTermLength)"/>
+      <xsl:variable name="afterFirstTermTrimmed" select="text:trim($afterFirstTerm)"/>
+      <xsl:variable name="firstTermWithoutSurroundingQuotes" select="substring-before(substring-after($firstTerm, '&quot;'), '&quot;')"/>
+      <xsl:variable name="firstTermEscaped" select="text:escapeLucenePhraseForRegExpr($firstTermWithoutSurroundingQuotes)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($firstTermEscaped, $lastFetchedTerm)" />
+      <xsl:value-of select="concat($term, '|')" />
+      <!-- Recursive call of this function with the substring after the first term -->
+      <xsl:value-of select="text:translateLuceneQueryToTermsMain($afterFirstTermTrimmed, $term)"/>
+    </xsl:when>
+    <!-- "-" followd by phrase followed by something: phrase is not appended -->
+    <xsl:when test="matches($inputString, '^-&quot;.*?&quot;\s')"> 
+      <xsl:variable name="afterFirstTerm" select="replace($inputString, '^-&quot;.*?&quot;\s', '')"/>
+      <xsl:variable name="afterFirstTermTrimmed" select="text:trim($afterFirstTerm)"/>
+      <!-- Recursive call of this function with the substring after the first term -->
+      <xsl:value-of select="text:translateLuceneQueryToTermsMain($afterFirstTermTrimmed, 'DUMMYDUMMYMINUS')"/>
+    </xsl:when>
+    <!-- single word: without quotes and spaces: word is appended -->
+    <xsl:when test="matches($inputString, '^[^&quot;\s]*$')">
+      <xsl:variable name="termEscaped" select="text:escapeLuceneTermForRegExpr($inputString)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($termEscaped, $lastFetchedTerm)"/>
+      <xsl:value-of select="$term" />
+    </xsl:when>
+    <!-- word followed by something: word is appended -->
+    <xsl:when test="matches($inputString, '^[^&quot;\s]*?\s')">
+      <xsl:variable name="afterFirstTerm" select="replace($inputString, '^[^&quot;\s]*?\s', '')"/>
+      <xsl:variable name="length" select="string-length($inputString)"/>
+      <xsl:variable name="afterFirstTermLength" select="string-length($afterFirstTerm)"/>
+      <xsl:variable name="firstTerm" select="substring($inputString, 1, $length - $afterFirstTermLength)"/>
+      <xsl:variable name="firstTermTrimmed" select="text:trim($firstTerm)"/>
+      <xsl:variable name="afterFirstTermTrimmed" select="text:trim($afterFirstTerm)"/>
+      <!-- treat single Lucene term: special Lucene characters in query term ("*", "+", ".", "-")  -->
+      <xsl:variable name="termEscaped" select="text:escapeLuceneTermForRegExpr($firstTermTrimmed)" />
+      <xsl:variable name="term" select="text:translateLuceneQueryTermToTerm($termEscaped, $lastFetchedTerm)" />
+      <xsl:value-of select="concat($term, '|')" />
+      <!-- Recursive call of this function with the substring after the first term -->
+      <xsl:value-of select="text:translateLuceneQueryToTermsMain($afterFirstTermTrimmed, $term)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="''"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="text:escapeLuceneTermForRegExpr">
+  <xsl:param name="inputString" as="xs:string" />
+  <!-- replace special Lucene characters: "*", "+", "~" were escaped for regular expression  -->
+  <xsl:variable name="termWithoutLuceneSymbols1" select="replace($inputString, '###Star###', '')" />
+  <xsl:variable name="termWithoutLuceneSymbols2" select="replace($termWithoutLuceneSymbols1, '###Plus###', '')" />
+  <xsl:variable name="termWithoutLuceneSymbols3" select="replace($termWithoutLuceneSymbols2, '###Tilde###', '')" />
+  <!-- Lucene mask symbol "?" is replaced with regular expression symbol "." -->
+  <xsl:variable name="term" select="replace($termWithoutLuceneSymbols3, '###QM###', '.')" />
+  <xsl:value-of select="$term" />
+</xsl:function>
+
+<xsl:function name="text:escapeLucenePhraseForRegExpr">
+  <xsl:param name="inputString" as="xs:string" />
+  <!-- replace special Lucene characters: "*" and "+" were escaped for regular expression  -->
+  <xsl:variable name="termWithoutLuceneSymbols1" select="replace($inputString, '###Star###', '\\*')" />
+  <xsl:variable name="termWithoutLuceneSymbols2" select="replace($termWithoutLuceneSymbols1, '###Plus###', '')" />
+  <!-- Lucene mask symbol "?" is replaced with regular expression symbol "." -->
+  <xsl:variable name="term" select="replace($termWithoutLuceneSymbols2, '###QM###', '\\?')" />
+  <xsl:value-of select="$term" />
+</xsl:function>
+
+<!-- last special char replacements and logical operator handling   -->
+<xsl:function name="text:translateLuceneQueryTermToTerm">
+  <xsl:param name="inputString" as="xs:string" />
+  <!-- last term in previous step: used for Lucene operator NOT)  -->
+  <xsl:param name="lastFetchedTerm" as="xs:string" />
+  <xsl:variable name="termEscaped1" select="replace($inputString, '###Dot###', '\\.')" />
+  <xsl:variable name="termEscaped2" select="replace($termEscaped1, '###BeginLine###', '\\^')" />
+  <xsl:variable name="termEscaped3" select="replace($termEscaped2, '###EndLine###', '\\DollarSign')" />  <!-- TODO  -->
+  <xsl:variable name="termEscaped4" select="replace($termEscaped3, '###Or###', '\\|')" />
+  <xsl:variable name="termEscaped5" select="replace($termEscaped4, '###Paranthes1Open###', '\\(')" />
+  <xsl:variable name="termEscaped6" select="replace($termEscaped5, '###Paranthes1Close###', '\\)')" />
+  <xsl:variable name="termEscaped7" select="replace($termEscaped6, '###Paranthes2Open###', '\\{')" />
+  <xsl:variable name="termEscaped8" select="replace($termEscaped7, '###Paranthes1Close###', '\\}')" />
+  <xsl:variable name="termEscaped9" select="replace($termEscaped8, '###Paranthes3Open###', '\\[')" />
+  <xsl:variable name="term" select="replace($termEscaped9, '###Paranthes3Close###', '\\]')" />
+  <xsl:choose>
+    <xsl:when test="($term != 'AND') and ($term != 'OR') and ($term != 'NOT') and (substring($term, 1, 1) != '-') and (($lastFetchedTerm = 'DUMMYDUMMYSTART') or ($lastFetchedTerm != 'DUMMYDUMMYNOT'))">
+      <xsl:value-of select="$term" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="concat('DUMMYDUMMY', $term)"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!-- Highlight all term occurrences. Result is a sequence of text and highlighted nodes (with span).
+Example: LE<span ...>MECHANICHE</span>...<span ...>Mechaniche</span>...   -->
+<xsl:function name="text:highlight">
+  <xsl:param name="inputStr" as="xs:string" />
+  <xsl:param name="terms" as="xs:string" />
+  <xsl:param name="words" as="xs:string" />
+  <xsl:param name="clipped" as="xs:string" />
+  <xsl:variable name="hitBeginStr" select="'XXhitStartXX'"/>
+  <xsl:variable name="hitEndStr" select="'XXhitEndXX'"/>
+  <xsl:variable name="inputStringTemp" select="replace($inputStr, '\n', '')"/>
+  <!-- replace all term or word occurences with surrounding begin and end marks (string operation) --> 
+  <xsl:choose>
+    <xsl:when test="$terms != '' and $words != ''">
+      <xsl:variable name="inputStringWithMarksForTerms" select="replace($inputStringTemp, concat('(', $terms, ')'), concat($hitBeginStr, '$1', $hitEndStr), 'im')"/>
+      <xsl:variable name="inputStringWithMarksForWords" select="replace($inputStringWithMarksForTerms, concat('([\s:.,;!_]+|^)', '(', $words, ')', '([\s:.,;!_]+|$)'), concat('$1', $hitBeginStr, '$2', $hitEndStr, '$3'), 'im')"/>
+      <xsl:sequence select="text:highlightTerms($inputStringWithMarksForWords, $clipped, $hitBeginStr, $hitEndStr)" />
+    </xsl:when>
+    <xsl:when test="$terms != '' and $words = ''">
+      <xsl:variable name="inputStringWithMarksForTerms" select="replace($inputStringTemp, concat('(', $terms, ')'), concat($hitBeginStr, '$1', $hitEndStr), 'im')"/>
+      <xsl:sequence select="text:highlightTerms($inputStringWithMarksForTerms, $clipped, $hitBeginStr, $hitEndStr)" />
+    </xsl:when>
+    <xsl:when test="$terms = '' and $words != ''">
+      <xsl:variable name="inputStringWithMarksForWords" select="replace($inputStringTemp, concat('([\s:.,;!_]+|^)', '(', $words, ')', '([\s:.,;!_]+)'), concat('$1', $hitBeginStr, '$2', $hitEndStr, '$3'), 'im')"/>
+      <xsl:sequence select="text:highlightTerms($inputStringWithMarksForWords, $clipped, $hitBeginStr, $hitEndStr)" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:sequence select="$inputStr"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!-- Convert an input string with hits (marked with begin and end marks) to a sequence of text nodes with highlight span nodes  -->
+<xsl:function name="text:highlightTerms">
+  <xsl:param name="inputString" as="xs:string" />
+  <xsl:param name="clipped" as="xs:string" />
+  <xsl:param name="hitBeginStr" />
+  <xsl:param name="hitEndStr" />
+  <xsl:variable name="substringBefore" select="substring-before($inputString, $hitEndStr)"/>
+  <xsl:variable name="substringAfter" select="substring-after($inputString, $hitEndStr)"/>
+  <xsl:variable name="beforeHitBeginString" select="substring-before($substringBefore, $hitBeginStr)"/>
+  <xsl:variable name="hitTerm" select="substring-after($substringBefore, $hitBeginStr)"/>
+  <xsl:choose>
+    <xsl:when test="contains($inputString, $hitEndStr)">
+      <!-- Prints the original part of the substring up to the first occurrence of a hit -->
+      <xsl:choose>
+      <xsl:when test="$clipped='true'">
+        <xsl:value-of select="text:cutStringBefore($beforeHitBeginString, 70)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$beforeHitBeginString"/>
+      </xsl:otherwise>
+      </xsl:choose>
+      <!-- Highlight the hit -->
+      <span class="hit highlight">
+        <xsl:value-of select="$hitTerm"/>
+      </span>
+      <!-- Recursive call of this function with the substring after the first occurrence of the hit: further occurrences of hits -->
+      <xsl:sequence select="text:highlightTerms($substringAfter, $clipped, $hitBeginStr, $hitEndStr)"/>
+    </xsl:when>
+    <!-- if no occurrence of a hit could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:choose>
+      <xsl:when test="$clipped='true'">
+        <xsl:value-of select="text:cutStringAfter($inputString, 70)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$inputString"/>
+      </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/functions-util.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:mpdl-util="http://www.mpiwg-berlin.mpg.de/ns/mpdl/util">
+
+<xsl:function name="mpdl-util:copyWithoutNamespace">
+  <xsl:param name="myElem"/>
+  <xsl:for-each select="$myElem">
+    <xsl:choose>
+      <xsl:when test="self::*">  <!--myElem is an element-->
+        <xsl:element name="{$myElem/name()}" namespace="">
+          <xsl:copy-of select="$myElem/@*"/>   <!-- attributes -->
+          <xsl:for-each select="$myElem/* | $myElem/text()">    <!-- element and text child nodes of the node -->
+            <xsl:sequence select="mpdl-util:copyWithoutNamespace(.)"/>
+          </xsl:for-each>
+        </xsl:element>
+      </xsl:when>
+      <xsl:when test="self::text()">    <!-- text -->
+        <xsl:text></xsl:text><xsl:value-of select="."/> 
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:for-each>
+</xsl:function>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/pageFragmentHtml.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,693 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:functx="http://www.functx.com"
+  xmlns:saxon="http://saxon.sf.net/"
+  xmlns:mpdl="http://www.mpiwg-berlin.mpg.de/ns/mpdl"
+  xmlns:mpdl-util="http://www.mpiwg-berlin.mpg.de/ns/mpdl/util"
+  xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"
+  xmlns:dc="http://purl.org/dc/elements/1.1/" 
+  xmlns:dcterms="http://purl.org/dc/terms"
+  xmlns:echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/" 
+  xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+  xmlns:xhtml="http://www.w3.org/1999/xhtml">
+
+<xsl:import href="/db/mpdl/presentation/functions-mpdl.xsl" />
+<xsl:import href="/db/mpdl/presentation/functions-text.xsl" />
+<xsl:import href="/db/mpdl/presentation/functions-util.xsl" />
+
+<xsl:output method="xhtml" encoding="utf-8"/>
+
+<xsl:variable name="mode" select="/result/page/mode"/>
+<xsl:variable name="language" select="/result/document-description/language"/>
+<xsl:variable name="sn" select="number(/result/page/sentence-number)"/>
+<xsl:variable name="digilibAvailable" select="/result/page/digilib-available"/>
+<xsl:variable name="options" select="/result/page/options"/>
+<xsl:variable name="topPB" select="subsequence(//pb, 1, 1)"/>
+<xsl:variable name="firstSentence" select="subsequence(//s, 1, 1)"/>
+<xsl:variable name="highlightQuery" select="string(/result/page/highlights/query)"/>
+<xsl:variable name="highlightQueryTermsTemp" select="string-join(text:translateLuceneToTerms($highlightQuery), '')" as="xs:string"/>
+<xsl:variable name="highlightQueryWords" select="string(/result/page/highlights/words)"/>
+<xsl:variable name="highlightQueryTerms" select="text:removeDuplicates($highlightQueryTermsTemp, $highlightQueryWords)"/> 
+
+<xsl:template match="result">
+  <xsl:for-each select="page">
+    <xsl:variable name="documentUri" select="/result/document-description/uri"/>
+    <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+    <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+    <xsl:variable name="countPlaces" select="/result/document-description/count-places"/>
+    <xsl:variable name="countTocEntries" select="/result/document-description/count-toc-entries"/>
+    <xsl:variable name="countFigureEntries" select="/result/document-description/count-figure-entries"/>
+    <xsl:variable name="pageHeader" select="header"/>
+    <xsl:variable name="pageNumber" select="number(number)"/>
+    <xsl:variable name="pageNumberOrig" select="number-orig"/>
+    <xsl:variable name="documentValue" select="concat('document=', $documentUri)"/>
+    <xsl:variable name="pnValue" select="concat('pn=', $pageNumber)"/>
+    <xsl:variable name="modeValue" select="concat('mode=', $mode)"/>
+	<div class="page">
+	<div class="pageMeta">
+	  <div class="countPages"><xsl:value-of select="$countPages"/></div>
+	  <div class="countPlaces"><xsl:value-of select="$countPlaces"/></div>
+	  <div class="countTocEntries"><xsl:value-of select="$countTocEntries"/></div>
+	  <div class="countFigureEntries"><xsl:value-of select="$countFigureEntries"/></div>
+	  <div class="pageNumber"><xsl:value-of select="$pageNumber"/></div>
+      <!-- test ob die Zahl gerade oder ungerade ist     -->
+      <xsl:choose>
+        <xsl:when test="$pageNumberOrig = ''"></xsl:when>
+        <xsl:otherwise><div class="pageNumberOrig"><xsl:value-of select="$pageNumberOrig"/></div></xsl:otherwise>
+      </xsl:choose>
+      <xsl:if test="$pageHeader != ''">
+        <div class="pageHeaderTitle"><xsl:value-of select="$pageHeader"/></div>
+      </xsl:if>
+	</div>
+    <div class="pageContent">
+       <xsl:for-each select="content">
+         <xsl:variable name="contentStr" select="normalize-space(string(.))"/>
+         <xsl:variable name="figures" select=".//figure|.//handwritten"/>
+         <xsl:if test="$contentStr = '' and empty($figures)">
+           <div class="emptyPage"><xsl:value-of select="'[Empty page]'"/></div>
+         </xsl:if>
+         <xsl:choose>
+         <xsl:when test="$mode = 'text' or $mode = 'textPollux' or $mode = 'gis'">
+             <xsl:apply-templates mode="text"/>
+         </xsl:when>
+         <xsl:when test="$mode = 'xml'">
+             <xsl:apply-templates mode="xml"/>
+         </xsl:when>
+         <xsl:when test="$mode = 'image'">
+           <xsl:variable name="imageAvailable" select="/result/page/image-available"/>
+           <xsl:variable name="imageFileName" select="/result/page/image-file-name"/>
+           <xsl:variable name="linkImageEcho" select="/result/page/image-echo"/>
+           <xsl:variable name="linkImageScaler" select="/result/page/image-scaler"/>
+           <xsl:variable name="imageHeight" select="600"/>
+           <xsl:choose>
+             <xsl:when test="$digilibAvailable = 'true' and $imageAvailable = 'true'">
+               <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border: 1px;">
+                 <a href="{$linkImageEcho}"><img alt="Page image: {$linkImageScaler}" src="{$linkImageScaler}&amp;dh={$imageHeight}"/></a>
+               </div>
+             </xsl:when>
+             <xsl:when test="$digilibAvailable = 'true' and $imageAvailable = 'false'">
+               <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border:1px dashed;">
+                 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+                 Page image: <br/>
+                 <br/>
+                 <xsl:value-of select="$imageFileName"/> , page <xsl:value-of select="$pageNumber"/>
+                 <br/><br/>
+                 not scanned
+               </div>
+             </xsl:when>
+             <xsl:when test="$digilibAvailable = 'false'">
+               <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border:1px dashed;">
+               <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+               Could not fetch: <br/>
+               <br/>
+               <xsl:value-of select="$imageFileName"/> , page <xsl:value-of select="$pageNumber"/>
+               <br/><br/>
+               from nausikaa2.rz-berlin.mpg.de: please try again later
+               </div>
+             </xsl:when>
+             <xsl:otherwise></xsl:otherwise>
+           </xsl:choose>
+         </xsl:when>
+         <xsl:otherwise></xsl:otherwise>
+         </xsl:choose>
+       </xsl:for-each>
+    </div>
+    </div>
+  </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()" mode="xml">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|comment()|processing-instruction()" mode="xml">
+  <xsl:variable name="elementName" select="name()"/>
+  <xsl:variable name="elementPresentation">
+    <xsl:choose>
+    <xsl:when test="element() = node() or text() != '' or self::comment() or self::processing-instruction()">
+      <xsl:value-of select="'&lt;'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:apply-templates select="attribute()" mode="xml"/>
+      <xsl:value-of select="'&gt;'"/>
+      <xsl:apply-templates select="element()|text()|comment()|processing-instruction()" mode="xml"/>
+      <xsl:value-of select="'&lt;/'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:value-of select="'&gt;'"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="'&lt;'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:apply-templates select="attribute()" mode="xml"/>
+      <xsl:value-of select="'/&gt;'"/>
+    </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+    <!-- Show the sentence in color light grey if it is given as sn -->
+    <xsl:when test="$elementName = 's' and $sn >= 0 and $sn = $actualSN">
+      <ul class="xml element highlight">
+        <a name="sn{$actualSN}"></a><xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:when>
+    <xsl:when test="$elementName = 's' and $sn != $actualSN">
+      <ul class="xml element">
+        <a name="sn{$actualSN}"></a><xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:when>
+    <xsl:otherwise>
+      <ul class="xml element">
+        <xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="attribute()" mode="xml">
+  <xsl:variable name="attributeName" select="name()"/>
+  <span class="xml attributeName">
+    <xsl:value-of select="' '"/>
+    <xsl:value-of select="$attributeName"/>
+  </span>
+  <xsl:value-of select="'=&quot;'"/>
+  <span class="xml attributeValue"><xsl:value-of select="."/></span><xsl:value-of select="'&quot;'"/>
+  <xsl:apply-templates select="attribute()" mode="xml"/>
+</xsl:template>
+
+<xsl:template match="text()" mode="xml">
+  <xsl:variable name="parentS" select="./ancestor::s"/>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test="$parentS = $firstSentence and ($topPB >> $parentS)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$highlightQuery != '' and $sn >= 0 and $sn = $actualSN">
+      <xsl:sequence select="text:highlight(string(.), $highlightQueryTerms, $highlightQueryWords, 'false')"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="."/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- variables used by templates in mode "text" -->
+<xsl:variable name="collectionName" select="/result/document-description/collection-name"/>
+<xsl:variable name="documentUri" select="/result/document-description/uri"/>
+<xsl:variable name="documentIdentifier" select="/result/document-description/identifier"/>
+<xsl:variable name="pageNumber" select="/result/page/number"/>
+<xsl:variable name="firstFigurePosition" select="/result/page/firstFigurePosition"/>
+<xsl:variable name="figuresImageDirectory" select="/result/page/figures-image-directory"/>
+<xsl:variable name="figures" select="/result/page/figures"/>
+<xsl:variable name="handwritten" select="/result/page/handwritten"/>
+<xsl:variable name="tables" select="/result/page/tables"/>
+<xsl:variable name="notes" select="/result/page/notes"/>
+<xsl:variable name="charNorm" select="/result/page/character-normalization"/>
+
+<xsl:template match="text" mode="text">
+  <xsl:apply-templates mode="text"/>
+  <!--   Notes                      -->
+  <xsl:if test="$collectionName = 'archimedes' and count($notes/*) > 0">
+    <div>
+      <hr class="notesBottom"/>
+      <xsl:for-each select="$notes/note">
+        <xsl:variable name="notePos" select="position()"/>
+        <xsl:variable name="label" select="$notePos"/>
+        <xsl:variable name="uid" select="@uid"/>
+        <xsl:variable name="modificationDate" select="@modificationDate"/>
+        <xsl:variable name="noteWithoutNamespace" select="mpdl-util:copyWithoutNamespace(.)"/>
+        <p>
+          <a>
+            <xsl:attribute name="name"><xsl:value-of select="concat('note-', $pageNumber, '-', $label)"/></xsl:attribute>
+            <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', 'note-', $pageNumber, '-', $label, 'ref')"/></xsl:attribute>
+            <xsl:value-of select="concat('[↑ note-', $pageNumber, '-', $label, ']')"/>
+          </a>
+          <xsl:value-of select="': '"/>
+          <xsl:choose>
+            <xsl:when test="$uid = '' or empty($uid)">
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+            </xsl:when>
+            <xsl:otherwise>
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+              <xsl:value-of select="concat(' [external note, ', $uid, ', ', $modificationDate, ']')"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </p>
+      </xsl:for-each>
+    </div>
+  </xsl:if>
+  <xsl:if test="$collectionName = 'echo' and count($notes/*) > 0">
+    <div>
+      <hr class="notesBottom"/>
+      <xsl:for-each select="$notes/echo:note">
+        <xsl:variable name="label" select="string(@xlink:label)"/>
+        <xsl:variable name="uid" select="@uid"/>
+        <xsl:variable name="modificationDate" select="@modificationDate"/>
+        <xsl:variable name="noteWithoutNamespace" select="mpdl-util:copyWithoutNamespace(.)"/>
+        <p>
+          <a>
+            <xsl:attribute name="name"><xsl:value-of select="$label"/></xsl:attribute>
+            <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $label, 'ref')"/></xsl:attribute>
+            <xsl:value-of select="concat('[↑ ', $label, ']')"/>
+          </a>
+          <xsl:value-of select="': '"/>
+          <xsl:choose>
+            <xsl:when test="$uid = '' or empty($uid)">
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+            </xsl:when>
+            <xsl:otherwise>
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+              <xsl:value-of select="concat(' [external note, ', $uid, ', ', $modificationDate, ']')"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </p>
+      </xsl:for-each>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="head" mode="text">
+  <p class="bf center"><xsl:apply-templates mode="text"/></p>
+</xsl:template>
+
+<xsl:template match="div" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="level" select="@level"/>
+  <xsl:variable name="style" select="@style"/>
+  <xsl:variable name="border" select="@border"/>
+  <xsl:variable name="width" select="@width"/>
+  <xsl:variable name="note" select="note"/>
+  <xsl:variable name="figure" select="figure"/>
+  <xsl:variable name="floatClassValue">
+    <xsl:choose>
+      <xsl:when test="not(empty($note))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="not(empty($figure))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="$type = 'float'"><xsl:value-of select="'float left'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'float left'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="levelClassValue">
+    <xsl:choose>
+      <xsl:when test="not(empty($note))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="$level = '1'"><xsl:value-of select="'level one'"/></xsl:when>
+      <xsl:when test="$level = '2'"><xsl:value-of select="'level two'"/></xsl:when>
+      <xsl:when test="$level = '3'"><xsl:value-of select="'level three'"/></xsl:when>
+      <xsl:when test="$level = '4'"><xsl:value-of select="'level four'"/></xsl:when>
+      <xsl:when test="$level = '5'"><xsl:value-of select="'level five'"/></xsl:when>
+      <xsl:when test="$level = '6'"><xsl:value-of select="'level six'"/></xsl:when>
+      <xsl:when test="$level = '7'"><xsl:value-of select="'level seven'"/></xsl:when>
+      <xsl:when test="$level = '8'"><xsl:value-of select="'level eight'"/></xsl:when>
+      <xsl:when test="$level = '9'"><xsl:value-of select="'level nine'"/></xsl:when>
+      <xsl:when test="empty($level)"><xsl:value-of select="''"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'level n'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <div>
+    <xsl:if test="not(empty($style))"><xsl:attribute name="style"><xsl:value-of select="$style"/></xsl:attribute></xsl:if>
+    <xsl:attribute name="class"><xsl:value-of select="concat($floatClassValue, ' ', $levelClassValue)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="p" mode="text">
+  <xsl:variable name="style" select="@style"/>
+  <p>
+    <xsl:if test="not(empty($style))">
+      <xsl:attribute name="class"><xsl:value-of select="$style"/></xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates mode="text"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="lb" mode="text">
+  <xsl:variable name="withoutLBs">
+    <xsl:choose>
+      <xsl:when test="contains($options, 'withoutLBs')"><xsl:value-of select="'true'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'false'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>  
+  <xsl:if test="$withoutLBs = 'false'"><br/></xsl:if>
+  <xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="cb" mode="text">
+  <br/><xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="expan" mode="text">
+  <xsl:apply-templates mode="text"/><xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="note" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:variable name="notePos" select="count(preceding::note[. >> $topPB]) + 1"/>
+  <xsl:variable name="href" select="concat('note-', $pageNumber, '-', $notePos)"/>
+  <xsl:choose>
+    <xsl:when test="$collectionName = 'archimedes'">
+      <a>
+        <xsl:attribute name="name"><xsl:value-of select="concat($href, 'ref')"/></xsl:attribute>
+        <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $href)"/></xsl:attribute>
+        <xsl:attribute name="class"><xsl:value-of select="'super'"/></xsl:attribute>
+        <xsl:value-of select="concat(' ↓ (', $href, ') ')"/>
+      </a>
+    </xsl:when>
+    <xsl:when test="$collectionName = 'echo' and not($hasLabel)">
+      <p>
+        <xsl:value-of select="'[Note]: '"/>
+        <span class="note"><xsl:apply-templates mode="text"/></span>
+      </p>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="emph" mode="text">
+  <xsl:variable name="class" select="@class"/>
+  <xsl:variable name="style" select="@style"/>
+  <xsl:variable name="text" select="string-join(., '')"/>
+  <xsl:variable name="length" select="string-length($text)"/>
+  <xsl:variable name="firstChar" select="substring($text, 1, 1)"/>
+  <xsl:variable name="first2Chars" select="substring($text, 1, 2)"/>
+  <xsl:variable name="restChars" select="substring($text, 2, $length)"/>
+  <xsl:variable name="first2CharsAreUppercase" select="upper-case($first2Chars) = $first2Chars"/>
+  <xsl:variable name="rest">
+    <xsl:choose>
+      <xsl:when test="$length &lt; 2 or empty($length)"><xsl:value-of select="''"/></xsl:when>
+      <xsl:otherwise>
+        <xsl:choose>
+          <xsl:when test="not(empty(w))">
+            <a class="textPollux" href="lt/wordInfo.xql?language={w/@lang}&amp;word={w/@form}&amp;output=html"><xsl:value-of select="$restChars"/></a>
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$restChars"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:if test="$collectionName = 'echo' and not(contains($class, 'sc'))"><span class="{$class} {$style}"><xsl:apply-templates mode="text"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'echo' and contains($class, 'sc') and $first2CharsAreUppercase"><span class="dc {$style}"><xsl:value-of select="$firstChar"/></span><span class="{$class} {$style}"><xsl:sequence select="$rest"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'echo' and contains($class, 'sc') and not($first2CharsAreUppercase)"><span class="{$class} {$style}"><xsl:apply-templates mode="text"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'archimedes'"><xsl:apply-templates mode="text"/></xsl:if>
+</xsl:template>
+
+<xsl:template match="ref" mode="text">
+  <span class="ref"><xsl:apply-templates mode="text"/></span>
+</xsl:template>
+
+<xsl:template match="foreign" mode="text">
+  <xsl:variable name="lang" select="@lang"/>
+  <xsl:variable name="xmllang" select="@xml:lang"/>
+  <xsl:variable name="language">
+    <xsl:choose>
+      <xsl:when test="not(empty($xmllang))"><xsl:value-of select="$xmllang"/></xsl:when>
+      <xsl:when test="not(empty($lang))"><xsl:value-of select="$lang"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>  
+  <span>
+    <xsl:attribute name="class"><xsl:value-of select="concat('foreign ', $language)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="q" mode="text">
+  <div class="q"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="quote" mode="text">
+  <div class="quote"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="blockquote" mode="text">
+  <div class="blockquote"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="set-off" mode="text">
+  <div class="set-off"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="reg" mode="text">
+  <span class="reg">   
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="var" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <span class="var">
+    <xsl:attribute name="class"><xsl:value-of select="concat('var ', $type)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="num" mode="text">
+  <span class="num"><xsl:apply-templates mode="text"/></span>
+</xsl:template>
+
+<xsl:template match="gap" mode="text">
+  <xsl:variable name="extent" select="@extent"/>
+  <xsl:variable name="count">
+    <xsl:choose>
+      <xsl:when test="empty($extent)"><xsl:value-of select="number(3)"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="number($extent)"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="gapChars" select="text:nchars($count, '.')"/>
+  <xsl:value-of select="concat('[', $gapChars, ']')"/><xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="anchor" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="href" select="@xlink:href"/>
+  <xsl:choose>
+    <xsl:when test="$type = 'figure'">
+      <xsl:variable name="figure" select="$figures/echo:figure[@xlink:label = $href]"/>
+      <xsl:variable name="figureFileName">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="replace($figure/@xlink:href, '/', '.')"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$figure/echo:image/@file"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$figure/echo:image/@file"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureNumber">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="$firstFigurePosition + count($figure/preceding::figure)"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$firstFigurePosition + count(./preceding::echo:figure[empty(@xlink:label)]) + count(./preceding::echo:anchor[@type = 'figure'])"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureCaption" select="string-join($figure/echo:caption/text(), ' ')"/>
+      <xsl:variable name="figureDescription" select="string-join($figure/echo:description/text(), ' ')"/>
+      <xsl:variable name="figureVariables" select="string-join($figure/echo:variables/text(), ' ')"/>
+      <xsl:sequence select="mpdl:showFigure($digilibAvailable, $figureFileName, $figureNumber, $figureCaption, $figureDescription, $figureVariables, 'float right')"/>
+    </xsl:when>
+    <xsl:when test="$type = 'handwritten'">
+      <xsl:variable name="hw" select="$handwritten/echo:handwritten[@xlink:label = $href]"/>
+      <xsl:variable name="hwFileName" select="$hw/@file"/>
+      <xsl:variable name="hwHref" select="$hw/@xlink:href"/>
+      <xsl:sequence select="mpdl:showHandwritten($hwFileName, $hwHref)"/>
+    </xsl:when>
+    <xsl:when test="$type = 'table'">
+      <xsl:variable name="table" select="$tables/xhtml:table[@xlink:label = $href]"/>
+      <xsl:sequence select="mpdl-util:copyWithoutNamespace($table)"/>
+    </xsl:when>
+    <xsl:when test="$type = 'note'">
+      <a>
+        <xsl:attribute name="name"><xsl:value-of select="concat($href, 'ref')"/></xsl:attribute>
+        <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $href)"/></xsl:attribute>
+        <xsl:attribute name="class"><xsl:value-of select="'super'"/></xsl:attribute>
+        <xsl:value-of select="concat('↓ (', $href, ')')"/>
+      </a>
+    </xsl:when>
+    <xsl:otherwise><a><xsl:attribute name="href"><xsl:value-of select="@xlink:href"/></xsl:attribute>Anchor of type: <xsl:value-of select="@type"/>, href: <xsl:value-of select="@xlink:href"/></a></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- GIS Elements   -->
+<xsl:template match="place" mode="text">
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="id" select="@id"/>
+  <xsl:variable name="echoDocDir" select="replace($figuresImageDirectory, '(.*)/.*$', '$1')"/>
+  <xsl:variable name="echoDocDirTokenized" select="tokenize($echoDocDir, '/')"/>
+  <xsl:variable name="echoDocDirNameSize" select="count($echoDocDirTokenized)"/>
+  <xsl:variable name="echoDoc" select="string(subsequence($echoDocDirTokenized, $echoDocDirNameSize))"/>
+  <xsl:variable name="docStrOld" select="concat('http://echo.mpiwg-berlin.mpg.de/ECHOdocuView?url=', $echoDocDir, '&amp;pn=', $pageNumber, '&amp;sn=', $actualSN, '&amp;viewMode=gis')"/>
+  <xsl:variable name="docStr" select="concat('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=', $documentUri, '&amp;mode=gis', '&amp;pn=', $pageNumber, '&amp;sn=', $actualSN)"/>
+  <xsl:variable name="docBase64Coded" select="saxon:string-to-base64Binary($docStr, 'utf8')"/>
+  <xsl:variable name="href" select="concat('http://chinagis.mpiwg-berlin.mpg.de/chinagis/REST/db/mpdl/', $echoDoc, '?id=', $id, '&amp;doc=', $docBase64Coded, '&amp;format=gis')"/>
+  <xsl:choose>
+    <xsl:when test="$mode = 'textPollux'">
+      <xsl:variable name="baseUrlLex" select="'http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/interface/'"/>
+      <xsl:variable name="wordLanguage" select="string-join(w[1]/@lang, '')"/>
+      <xsl:variable name="form" select="string-join(w/@form, '')"/>
+      <xsl:variable name="wordStr" select="string-join(w, '')"/>
+      <xsl:variable name="lexHref">
+        <xsl:if test="not(empty(w))">
+          <xsl:value-of select="concat($baseUrlLex, 'lt/wordInfo.xql?language=', $wordLanguage, '&amp;word=', $form, '&amp;output=html', '&amp;placeHref=', encode-for-uri($href))"/>
+        </xsl:if>
+        <xsl:if test="empty(w)">
+          <xsl:value-of select="concat($baseUrlLex, 'lt/wordInfo.xql?type=place', '&amp;output=html', '&amp;placeHref=', encode-for-uri($href))"/>
+        </xsl:if>
+      </xsl:variable>
+      <span class="place">
+        <a class="textPollux"><xsl:attribute name="href"><xsl:value-of select="$lexHref"/></xsl:attribute><xsl:value-of select="$wordStr"/></a>
+      </span>
+    </xsl:when>
+    <xsl:otherwise>
+      <span class="place">
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="time" mode="text">
+  <span class="time">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="person" mode="text">
+  <span class="person">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="event" mode="text">
+  <span class="event">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<!-- MML   -->
+<xsl:template match="mml:*" mode="text">
+  <xsl:copy-of select="."/>
+</xsl:template>
+    
+<!-- XHTML: remove the xhtml namespace   -->
+<xsl:template match="xhtml:*" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:variable name="isTable" select="name() = 'table'"/>
+  <xsl:choose>
+    <xsl:when test="(not($hasLabel)) or ($isTable and $hasLabel)">
+      <xsl:element name="{name()}" namespace="">
+        <xsl:copy-of select="@*"/>
+        <xsl:apply-templates mode="text"/>
+      </xsl:element>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="figure" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:choose>
+    <xsl:when test="not($hasLabel)">
+      <xsl:variable name="figureFileName">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="replace(./@xlink:href, '/', '.')"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="./image/@file"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="./image/@file"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureNumber">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure)"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureCaption" select="./caption/text()"/>
+      <xsl:variable name="figureDescription" select="./description/text()"/>
+      <xsl:variable name="figureVariables" select="./variables/text()"/>
+      <xsl:sequence select="mpdl:showFigure($digilibAvailable, $figureFileName, $figureNumber, $figureCaption, $figureDescription, $figureVariables, 'float none')"/>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="handwritten" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:choose>
+    <xsl:when test="not($hasLabel)">
+      <xsl:variable name="fileName" select="@file"/>
+      <xsl:variable name="href" select="@xlink:href"/>
+      <xsl:sequence select="mpdl:showHandwritten($fileName, $href)"/>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- textPollux links                           -->
+<xsl:template match="w" mode="text">
+  <xsl:variable name="baseUrlLex" select="'http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/interface/'"/>
+  <xsl:variable name="wordLanguage" select="@lang"/>
+  <xsl:variable name="form" select="@form"/>
+  <a class="textPollux">
+    <xsl:attribute name="href"><xsl:value-of select="concat($baseUrlLex, 'lt/wordInfo.xql?language=', $wordLanguage, '&amp;word=', $form, '&amp;output=html')"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </a>
+</xsl:template>
+
+<xsl:template match="s" mode="text">
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <a name="sn{$actualSN}"></a>
+  <xsl:choose>
+    <!-- Show the sentence in color light grey if it is given as sn -->
+    <xsl:when test="$sn >= 0 and $sn = $actualSN">
+      <span class="s highlight">
+        <xsl:if test="contains($options, 'withXmlNodeId')"><xsl:attribute name="xmlNodeId"><xsl:value-of select="@xmlNodeId"/></xsl:attribute></xsl:if>
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:when>
+    <xsl:otherwise>
+      <span class="s">
+        <xsl:if test="contains($options, 'withXmlNodeId')"><xsl:attribute name="xmlNodeId"><xsl:value-of select="@xmlNodeId"/></xsl:attribute></xsl:if>
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="text()" mode="text">
+  <xsl:variable name="parentS" select="./ancestor::s"/>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test="$parentS = $firstSentence and ($topPB >> $parentS)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+  <xsl:when test="$highlightQuery != '' and $sn >= 0 and $sn = $actualSN">
+    <xsl:sequence select="text:highlight(string(.), $highlightQueryTerms, $highlightQueryWords, 'false')"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/pageHtml.css	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,245 @@
+/* general */
+.it        { font-style:italic }                    /* DESpecs: _ _ and attribute "it" */
+.it span.it { font-style:normal }                   /* DESpecs: _ _ within a paragraph already in italics */
+.bf        { font-weight:bold }                     /* DESpecs: <bf> */
+.sc        { font-variant:small-caps }              /* DESpecs: <sc> */
+.sub       { vertical-align:sub; font-size:.8em }   /* DESpecs: <_>  */ /* line-height:1em; ? */
+.super     { vertical-align:super; font-size:.8em } /* DESpecs: <^> */
+.sm        { font-size:smaller }                    /* DESpecs: <sm>, if within <p> */
+.ul        { text-decoration:underline }            /* DESpecs: <ul> */
+.ol        { text-decoration:overline }             /* DESpecs: <ol> */
+.st        { text-decoration:line-through }         /* DESpecs: <st> */
+.red       { color:red }                            /* DESpecs: <red> */
+.sp        { letter-spacing:0.3em }                 /* DESpecs: <sp> */  /* "font-stretch:wider;" is deprecated */
+.center    { text-align:center }
+.fr        { font-family:'Lucida blackletter'}     /* preliminary representation of Fraktur */
+
+/* unused */
+.setoff    { margin-left:2cm; margin-right:2cm }
+
+/* xml presentation    */
+span.xml.elementName { font-weight:bold;color:purple; }
+span.xml.attributeName { font-weight:bold; }
+span.xml.attributeValue { color:blue; }
+ul.xml.element { margin-left:0px;padding-left:8px }
+ul.xml.element.highlight { background-color:#D3D3D3; }      /* LightGrey    */
+
+/* drop cap (Initiale)     */
+span.dc {
+   float: left;
+   font-family: Georgia;
+   font-size: 250%;
+   line-height: 0.8em; 
+   text-transform: uppercase; /* immer als Großbuchstabe */
+   margin-right: 10px;
+   padding-top: 1px;
+}
+
+/* variables and numbers */
+span.var { font-style:italic; }
+span.var.segment { font-style:italic; text-decoration:overline; }
+span.var.line    { font-style:italic; text-decoration:underline; }
+span.var.gnomon  { font-style:italic; text-decoration:line-through; }
+span.num   { color:maroon }
+
+/* foreign languages     */
+span.foreign { color:green; }
+span.foreign a:link { color:green; }
+span.foreign a:visited { color:green; }
+span.foreign.el span.foreign.grc span.foreign.greek { color:green; } 
+span.foreign.en span.foreign.english { color:green; }  
+span.foreign.fr span.foreign.french { color:green; } 
+span.foreign.la span.foreign.latin { color:green; } 
+/*  .....    */
+
+
+/* indentation at the beginning of a paragraph: <emph class="sc it"> */
+span.sc { font-weight:bold; }
+span.sc.it {font-weight:bold; font-style:italic; }
+
+/* regularized words */
+span.reg { color:purple; }
+
+/* ref               */
+span.ref { font-style:italic; } 
+
+/* quotes */
+div.q     { margin-left:10px; font-style:italic; }
+div.quote { margin-left:10px; font-style:italic; }
+div.blockquote { margin-left:10px; font-style:normal; }
+div.set-off { margin-left:10px; font-style:italic; }
+
+/* notes     */
+span.note { font-style:italic; }
+
+/* GIS elements    */
+span.place { background-color:#87F717; color:black; }  /* Lawn green   */
+span.person  { background-color:#87F717; color:black; }  /* Lawn green   */
+span.time  { background-color:#87F717; color:black; }  /* Lawn green   */
+span.event  { background-color:#87F717; color:black; }  /* Lawn green   */
+
+/* preliminary representations of single/double/wavy/circled lines in Chinese text */
+span.sl { text-decoration:underline; }        /* DESpecs for Chinese: <sl> */
+span.dl { text-decoration:underline; }        /* DESpecs for Chinese: <dl> */
+span.wl { text-decoration:underline; }        /* DESpecs for Chinese: <wl> */
+span.cl { text-decoration:underline; }        /* DESpecs for Chinese: <cl> */
+
+/* sentence    */
+span.s.highlight { background-color:#D3D3D3; }  /* LightGrey    */
+span.s:hover { background-color:#D3D3D3; }      /* LightGrey    */
+
+/* highlighting    */
+span.hit.highlight { background-color:#77DD77; }  /* pastell green  */
+
+/* Links 
+a:link {text-decoration: none;}
+a:visited {text-decoration: none}
+a:active {text-decoration: none}
+a:hover {text-decoration: underline; color: red;}
+ */
+
+/* table     */
+table { margin-left:30px; }
+
+table.toc { width:100%; margin-left:1px; }
+
+/* page splittings: hr etc.   */
+hr.notesBottom {
+  border:none; 
+  border-top:2px dashed black; 
+  height:2px; 
+  color:#000000; 
+  background:transparent;
+}
+
+div.handwritten {
+  margin-left:10%; 
+} 
+
+/* divs */
+div.float.none {
+	margin-left:10%; 
+} 
+div.float.right {
+	float:right;
+	clear:both;
+	margin-right:10%
+}
+
+/* toc elements    */
+div.toc.float.right {
+    text-align:center;
+    vertical-align:top;
+	top:10%;
+	clear:right;
+	font-style:normal; 
+}
+div.toc.float.right a:link, a:visited {
+    text-decoration: none;
+    font-style: normal; 
+}
+div.toc.one   { 
+    clear: left;
+    text-align: left;
+    vertical-align:top;
+	float:left; 
+	margin-left:2%; 
+    width:75%;        
+}
+div.toc.two  { 
+    clear:left;
+    text-align: left;
+    vertical-align:top;
+	float:left; 
+	margin-left:2%; 
+    width:75%;        
+}
+div.toc.three { 
+    clear:left;
+    text-align: left;
+    vertical-align:top;
+	float:left; 
+	margin-left:2%; 
+    width:75%;        
+}
+div.toc.four div.toc.five div.toc.six div.toc.seven { 	
+    clear:left;
+    text-align: left;
+    vertical-align:top;
+	float:left; 
+	margin-left:2%; 
+    width:75%;        
+}
+
+
+/* page styling for generating PDF documents with Flying Saucer */
+div.pageNumber {
+	display:none;
+}
+div.pageNumberOrig {
+	display:none;
+}
+div.countPages {
+	display:none;
+}
+div.countPlaces {
+	display:none;
+}
+div.countTocEntries {
+	display:none;
+}
+div.countFigureEntries {
+	display:none;
+}
+div.pageHeaderTitle {
+	font-weight:bold;
+	text-align:center;
+}
+body {
+    counter-reset: pn; 
+}
+div.page:before {
+	float:right;
+	font:11pt sans-serif;
+	font-weight:bold;
+	content:"[Page " counter(pn) "]";
+	counter-increment:pn;
+	page:pdfPage;
+	clear:both;
+}
+div.page {
+	page-break-after:always;
+	page:pdfPage;
+	clear:both;
+}
+@page pdfPage {
+	size:A4;
+	margin-top:0.7cm;
+	margin-bottom:0.7cm;
+	margin-left:0.7cm;
+	margin-right:0.7cm;
+	padding:0.2cm;
+	border:thin solid #808080;
+    @top-left { font: 11pt sans-serif; padding-left: 0.2cm; padding-right: 1cm; font-weight:bold;};
+    @top-right { font: 11pt sans-serif;  white-space: nowrap; font-weight:bold;};
+    @bottom-left { font: 11pt sans-serif;  white-space: nowrap; font-weight:bold;};
+    @bottom-right { font: 11pt sans-serif;  white-space: nowrap; content: counter(page);};
+}
+
+div.tocPage {
+	page-break-after:always;
+	page:tocPage;
+}
+@page tocPage {
+	size:A4;
+	margin-top:0.7cm;
+	margin-bottom:0.7cm;
+	margin-left:0.7cm;
+	margin-right:0.7cm;
+	padding:0.2cm;
+	border:thin solid #808080;
+    @top-left { font: 11pt sans-serif; padding-left: 0.2cm; padding-right: 1cm; font-weight:bold;};
+    @top-right { font: 11pt sans-serif;  white-space: nowrap; font-weight:bold;};
+    @bottom-left { font: 11pt sans-serif;  white-space: nowrap; font-weight:bold;};
+    @bottom-right { font: 11pt sans-serif;  white-space: nowrap; content: counter(page);};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/pageHtml.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,1223 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:functx="http://www.functx.com"
+  xmlns:saxon="http://saxon.sf.net/"
+  xmlns:mpdl="http://www.mpiwg-berlin.mpg.de/ns/mpdl"
+  xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"
+  xmlns:mpdl-util="http://www.mpiwg-berlin.mpg.de/ns/mpdl/util"
+  xmlns:dc="http://purl.org/dc/elements/1.1/" 
+  xmlns:dcterms="http://purl.org/dc/terms"
+  xmlns:echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/" 
+  xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+  xmlns:xhtml="http://www.w3.org/1999/xhtml">
+
+<xsl:import href="/db/mpdl/presentation/functions-mpdl.xsl" />
+<xsl:import href="/db/mpdl/presentation/functions-text.xsl" />
+<xsl:import href="/db/mpdl/presentation/functions-util.xsl" />
+
+<xsl:output method="xhtml" encoding="utf-8"/>
+
+<xsl:variable name="errorMessage" select="string(/result/query/result/error)"/>
+<xsl:variable name="mode" select="/result/page/mode"/>
+<xsl:variable name="queryType" select="/result/query/type"/>
+<xsl:variable name="query" select="text:trim(string(/result/query/expression))"/>
+<xsl:variable name="queryResultPages" select="number(/result/query/result/pages)"/>
+<xsl:variable name="queryResultPN" select="/result/query/result/pn"/>
+<xsl:variable name="language" select="/result/document-description/language"/>
+<xsl:variable name="sn" select="number(/result/page/sentence-number)"/>
+<xsl:variable name="digilibAvailable" select="/result/page/digilib-available"/>
+<xsl:variable name="options" select="/result/page/options"/>
+<xsl:variable name="topPB" select="subsequence(//pb, 1, 1)"/>
+<xsl:variable name="firstSentence" select="subsequence(//s, 1, 1)"/>
+<xsl:variable name="ftQueryTermsTemp" select="string-join(text:translateLuceneToTerms($query), '')" as="xs:string"/>
+<xsl:variable name="ftQueryMorphForms" select="string(/result/query/result/query-forms)"/>
+<!-- Removes the duplicates between ftQueryMorphForms and ftQueryTerms for highlighting them semantically correct: -->
+<!-- Morphological forms are hightlighted as whole words but query terms are highlighted also as partly strings -->
+<xsl:variable name="ftQueryTerms" select="text:removeDuplicates($ftQueryTermsTemp, $ftQueryMorphForms)"/> 
+<xsl:variable name="ftQueryRegularizations" select="string(/result/query/result/query-regularizations)"/>
+<xsl:variable name="ftQueryHighlightWords">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMorphForms != '' and $ftQueryRegularizations = ''"><xsl:value-of select="$ftQueryMorphForms"/></xsl:when>
+  <xsl:when test="$ftQueryMorphForms = '' and $ftQueryRegularizations != ''"><xsl:value-of select="$ftQueryRegularizations"/></xsl:when>
+  <xsl:when test="$ftQueryMorphForms != '' and $ftQueryRegularizations != ''"><xsl:value-of select="concat($ftQueryMorphForms, '|', $ftQueryRegularizations)"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="$ftQueryMorphForms"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<!-- used in module: functions-text: highlight  -->
+<xsl:variable name="ftQueryEncodeBig5" select="/result/query/result/big5-mappings"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($query, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($query) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <!-- Because there are  problems in recognizing words (in mode word) this fake mode is used (same as phrase mode)  -->
+  <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="result">
+  <xsl:variable name="author" select="string-join(/result/document-description/authors/author, ', ')"/>
+  <xsl:variable name="title" select="string-join(/result/document-description/titles/title, ', ')"/>
+  <xsl:variable name="place" select="string-join(/result/document-description/places/place, ', ')"/>
+  <xsl:variable name="date" select="/result/document-description/date"/>
+  <xsl:variable name="bookTitle">
+    <xsl:value-of select="$author"/>.
+    <xsl:value-of select="$title"/>.
+    <xsl:value-of select="$place"/><xsl:if test="$place != ''">, </xsl:if>
+    <xsl:value-of select="$date"/>.
+  </xsl:variable>
+  <html>
+  <head>
+    <title><xsl:value-of select="$bookTitle"/></title>
+    <link rel="stylesheet" type="text/css" href="presentation/pageHtml.css"/>
+  </head>
+  <body>
+    <text style="font-weight:bold;font-size:20px"><xsl:value-of select="$bookTitle"/></text>
+    <p/>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentUri" select="/result/document-description/uri"/>
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="pageHeader" select="header"/>
+      <xsl:variable name="pageNumber" select="number(number)"/>
+      <xsl:variable name="pageNumberOrig" select="number-orig"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentUri)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $pageNumber)"/>
+      <xsl:variable name="modeValue" select="concat('mode=', $mode)"/>
+      <table cellspacing="1" cellpadding="1">
+        <colgroup>
+          <col width="5%"/>
+          <col width="5%"/>
+          <col width="5%"/>
+          <col width="5%"/>
+          <col width="33%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="3%"/>
+          <col width="10%"/>          
+          <col width="3%"/>
+          <col width="5%"/>
+          <col width="3%"/>
+          <col width="5%"/>
+        </colgroup>
+        <tr>
+        <form action="page-query-result.xql" method="get">
+        <input type="hidden" name="document" value="{$documentUri}"/>
+        <td>
+          <xsl:choose>
+          <xsl:when test="$mode = 'text'"><button id="buttonModeText" name="mode" value="text" style="background:none;border:none;"><img src="images/text.jpg" height="18"/></button></xsl:when>
+          <xsl:otherwise><button id="buttonModeUText" name="mode" value="text" style="background:none;border:none;"><img src="images/textU.jpg" height="18"/></button></xsl:otherwise>
+          </xsl:choose>
+        </td>
+        <td>
+          <xsl:choose>
+          <xsl:when test="$mode = 'textPollux'"><button id="buttonModeTextPollux" name="mode" value="textPollux" style="background:none;border:none;"><img src="images/textPollux.jpg" height="18"/></button></xsl:when>
+          <xsl:otherwise><button id="buttonModeUTextPollux" name="mode" value="textPollux" style="background:none;border:none;"><img src="images/textPolluxU.jpg" height="18"/></button></xsl:otherwise>
+          </xsl:choose>
+        </td>
+        <td>
+          <xsl:choose>
+          <xsl:when test="$mode = 'image'"><button id="buttonModeImage" name="mode" value="image" style="background:none;border:none;"><img src="images/image.jpg" height="18"/></button></xsl:when>
+          <xsl:otherwise><button id="buttonModeUImage" name="mode" value="image" style="background: none;border:none;"><img src="images/imageU.jpg" height="18"/></button></xsl:otherwise>
+          </xsl:choose>
+        </td>
+        <td>
+          <xsl:choose>
+          <xsl:when test="$mode = 'xml'"><button id="buttonModeXml" name="mode" value="xml" style="background:none;border:none;"><img src="images/xml.jpg" height="18"/></button></xsl:when>
+          <xsl:otherwise><button id="buttonModeUXml" name="mode" value="xml" style="background:none;border:none;"><img src="images/xmlU.jpg" height="18"/></button></xsl:otherwise>
+          </xsl:choose>
+        </td>
+        <input type="hidden" name="pn" value="{$pageNumber}"/>
+        <xsl:if test="/result/page/sentence-number[node()]">
+          <input type="hidden" name="sn" value="{$sn}"/>
+        </xsl:if>
+        <input type="hidden" name="query-type" value="{$queryType}"/>
+        <xsl:if test="/result/query/result[node()]">
+          <input type="hidden" name="query" value="{$query}"/>
+          <input type="hidden" name="query-result-pn" value="{$queryResultPN}"/>
+        </xsl:if>
+        </form>
+        <td/>
+        <!-- toc, fulltext, fulltextMorph, structural, ftIndex and ftIndexMorph buttons      -->
+        <form action="page-query-result.xql" method="get">
+        <input type="hidden" name="document" value="{$documentUri}"/>
+        <input type="hidden" name="mode" value="{$mode}"/>
+        <input type="hidden" name="pn" value="{$pageNumber}"/>
+        <xsl:if test="/result/page/sentence-number[node()]">
+          <input type="hidden" name="sn" value="-1"/>
+        </xsl:if>
+        <td><button id="bToc" name="query-type" value="toc" style="background: none; border: none;"><img src="images/toc.gif" width="24" height="24"/></button></td>
+        <td><button id="bFulltext" name="query-type" value="fulltext" style="background: none; border: none;"><img src="images/search.gif" width="24" height="24"/></button></td>
+        <td><button id="bFulltextMorph" name="query-type" value="fulltextMorph" style="background: none; border: none;"><img src="images/searchMorph.gif" width="24" height="24"/></button></td>
+        <td><button id="bStructural" name="query-type" value="xpath" style="background: none; border: none;"><img src="images/searchStructural.gif" width="24" height="24"/></button></td>
+        <td><button id="bFtIndex" name="query-type" value="ftIndex" style="background: none; border: none;"><img src="images/dictionary.gif" width="24" height="24"/></button></td>
+        <td><button id="bftIndexMorph" name="query-type" value="ftIndexMorph" style="background: none; border: none;"><img src="images/dictionaryMorph.gif" width="24" height="24"/></button></td>
+        <td><button id="bFigures" name="query-type" value="figures" style="background: none; border: none;"><img src="images/figures.png" width="24" height="24"/></button></td>
+        <xsl:choose>
+          <xsl:when test="/result/query/result[node()] and not($queryType = 'toc')">
+            <input type="hidden" name="query" value=""/>
+            <input type="hidden" name="query-result-pn" value="{$queryResultPN}"/>
+          </xsl:when>
+          <xsl:when test="/result/query/result[node()] and $queryType = 'toc'">
+            <input type="hidden" name="query-result-pn" value="1"/>
+          </xsl:when>
+          <xsl:otherwise>
+          </xsl:otherwise>
+        </xsl:choose>
+        </form>
+        <td/>
+        <xsl:variable name="leftNumber">
+          <xsl:choose>
+          <xsl:when test="$pageNumber &gt; 1"><xsl:value-of select="$pageNumber - 1"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$pageNumber"/></xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <xsl:variable name="rightNumber">
+          <xsl:choose>
+          <xsl:when test="$pageNumber &lt; $countPages"><xsl:value-of select="$pageNumber + 1"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$pageNumber"/></xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <form action="page-query-result.xql" method="get">
+        <input type="hidden" name="document" value="{$documentUri}"/>
+        <input type="hidden" name="mode" value="{$mode}"/>
+        <td><button id="buttonLeftNumber" name="pn" value="{$leftNumber}" style="background:none;border:none;"><img src="images/left.gif"/></button></td>
+        <td nowrap="true"><xsl:value-of select="$pageNumber"/> / <xsl:value-of select="$countPages"/></td>
+        <td><button id="buttonRightNumber" name="pn" value="{$rightNumber}" style="background:none;border:none;"><img src="images/right.gif"/></button></td>
+        <input type="hidden" name="query-type" value="{$queryType}"/>
+        <xsl:if test="/result/query/result[node()]">
+          <input type="hidden" name="query" value="{$query}"/>
+          <input type="hidden" name="query-result-pn" value="{$queryResultPN}"/>
+        </xsl:if>
+        </form>
+        <form action="page-query-result.xql" method="get">
+        <input type="hidden" name="document" value="{$documentUri}"/>
+        <input type="hidden" name="mode" value="{$mode}"/>
+        <td nowrap="true">Page: <input type="text" size="2" name="pn" value="{$pageNumber}"/></td> 
+        <input type="hidden" name="query-type" value="{$queryType}"/>
+        <xsl:if test="/result/query/result[node()]">
+          <input type="hidden" name="query" value="{$query}"/>
+          <input type="hidden" name="query-result-pn" value="{$queryResultPN}"/>
+        </xsl:if>
+        </form>
+        </tr>
+      </table>
+      <hr/>
+      <table align="middle" width="100%" rules="cols" frame="void" cellpadding="7">
+        <colgroup>
+          <col width="65%"/>
+          <col width="35%"/>
+        </colgroup>
+        <tr>
+          <xsl:for-each select="content">
+            <xsl:choose>
+            <xsl:when test="$mode = 'text' or $mode = 'textPollux' or $mode = 'gis'">
+              <td align="left" valign="top">
+                <xsl:if test="$pageHeader != '' or $pageNumberOrig != ''">
+                  <table width="100%" cellspacing="1" cellpadding="1">
+                    <colgroup>
+                      <col width="10%"/>
+                      <col width="70%"/>
+                      <col width="20%"/>
+                    </colgroup>
+                    <tr>
+                      <td align="left"><b><xsl:value-of select="$pageNumberOrig"/></b></td>
+                      <td align="center"><b><xsl:value-of select="$pageHeader"/></b></td>
+                    </tr>
+                  </table>
+                </xsl:if>
+                <table>
+                <colgroup>
+                  <col width="90%"/>
+                  <col width="10%"/>
+                </colgroup>
+                <tr>
+                <td>
+                  <xsl:variable name="contentStr" select="normalize-space(string(.))"/>
+                  <xsl:variable name="figures" select=".//figure|.//handwritten"/>
+                  <xsl:if test="$contentStr = '' and empty($figures)">
+                    <div class="emptyPage"><xsl:value-of select="'[Empty page]'"/></div>
+                  </xsl:if>
+                  <xsl:apply-templates mode="text"/>
+                </td>
+                <td align="middle" valign="top"><p><a href="?{$documentValue}&amp;mode={$mode}&amp;pn={$pageNumber}&amp;sn={$sn}&amp;export=pdf&amp;options={$options}"><img src="images/download.png" width="24" height="24" border="0" alt="Download"/></a><br/>Download PDF</p></td>
+                </tr>
+                </table>
+              </td>
+            </xsl:when>
+            <xsl:when test="$mode = 'xml'">
+              <td align="left" valign="top">
+                <table>
+                <colgroup>
+                  <col width="90%"/>
+                  <col width="10%"/>
+                </colgroup>
+                <tr>
+                <td><xsl:apply-templates mode="xml"/></td>
+                <td align="middle" valign="top"><p><a target="_blank" href="?{$documentValue}&amp;mode=pureXml&amp;pn={$pageNumber}"><img src="images/download.png" width="24" height="24" border="0" alt="Download"/></a><br/>Download XML</p></td>
+                <td align="middle" valign="top"><p><a href="?{$documentValue}&amp;mode={$mode}&amp;pn={$pageNumber}&amp;sn={$sn}&amp;export=pdf"><img src="images/download.png" width="24" height="24" border="0" alt="Download"/></a><br/>Download PDF</p></td>
+                </tr>
+                </table>
+              </td>
+            </xsl:when>
+            <xsl:when test="$mode = 'image'">
+              <xsl:variable name="imageAvailable" select="/result/page/image-available"/>
+              <xsl:variable name="imageFileName" select="/result/page/image-file-name"/>
+              <xsl:variable name="linkImageEcho" select="/result/page/image-echo"/>
+              <xsl:variable name="linkImageScaler" select="/result/page/image-scaler"/>
+              <xsl:variable name="imageHeight" select="600"/>
+              <td align="middle" valign="top">
+                <xsl:choose>
+                  <xsl:when test="$digilibAvailable = 'true' and $imageAvailable = 'true'">
+                    <table>
+                      <colgroup>
+                        <col width="90%"/>
+                        <col width="10%"/>
+                      </colgroup>
+                      <tr>
+                      <td>
+                        <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border: 1px;">
+                          <a href="{$linkImageEcho}"><img alt="Page image: {$linkImageScaler}" src="{$linkImageScaler}&amp;dh={$imageHeight}"/></a>
+                        </div>
+                      </td>
+                      <td align="middle" valign="top"><p><a href="?{$documentValue}&amp;mode={$mode}&amp;pn={$pageNumber}&amp;sn={$sn}&amp;export=pdf"><img src="images/download.png" width="24" height="24" border="0" alt="Download"/></a><br/>Download PDF</p></td>
+                      </tr>
+                    </table>
+                  </xsl:when>
+                  <xsl:when test="$digilibAvailable = 'true' and $imageAvailable = 'false'">
+                    <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border:1px dashed;">
+                      <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+                      Page image: <br/>
+                      <br/>
+                      <xsl:value-of select="$imageFileName"/> , page <xsl:value-of select="$pageNumber"/>
+                      <br/><br/>
+                      not scanned
+                    </div>
+                  </xsl:when>
+                  <xsl:when test="$digilibAvailable = 'false'">
+                    <div style="height:{$imageHeight}px; margin-left:10px; margin-right:10px; border:1px dashed;">
+                      <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+                      Could not fetch: <br/>
+                      <br/>
+                      <xsl:value-of select="$imageFileName"/> , page <xsl:value-of select="$pageNumber"/>
+                      <br/><br/>
+                      from nausikaa2.rz-berlin.mpg.de: please try again later
+                    </div>
+                  </xsl:when>
+                  <xsl:otherwise></xsl:otherwise>
+                </xsl:choose>
+              </td>
+            </xsl:when>
+            <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+          <td align="left" valign="top" style="padding-right: 25px;">
+            <xsl:if test="$queryType = 'toc'">
+              <b>Table of contents</b>
+            </xsl:if>
+            <xsl:if test="$queryType = 'figures'">
+              <b>Figures</b>
+            </xsl:if>
+            <xsl:if test="$queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma'">
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <input type="hidden" name="query-type" value="{$queryType}"/>
+              <xsl:if test="$queryType = 'fulltext'">
+                <xsl:value-of select="'Contains: '"/>
+              </xsl:if>
+              <xsl:if test="$queryType = 'fulltextMorph'">
+                <xsl:value-of select="'Contains morphological: '"/>
+              </xsl:if>
+              <xsl:if test="$queryType = 'fulltextMorphLemma'">
+                <xsl:value-of select="'Contains lemma: '"/>
+              </xsl:if>
+              <input type="text" size="15" name="query" value="{$query}"/>
+              <input type="hidden" name="query-result-pn" value="1"/>
+              <input type="submit" value="Query"/>
+            </form>
+            </xsl:if>
+            <xsl:if test="$queryType = 'xpath' or $queryType = 'xquery'">
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <table cellspacing="1" cellpadding="1">
+              <colgroup>
+                <col width="70%"/>
+                <col width="15%"/>
+                <col width="15%"/>
+              </colgroup>
+              <tr>
+                <td>
+                  <xsl:if test="$queryType = 'xpath'"><b><xsl:value-of select="'XPath query '"/></b></xsl:if>
+                  <xsl:if test="$queryType = 'xquery'"><b><xsl:value-of select="'XQuery '"/></b></xsl:if>
+                  <a href="info.xql?info={$queryType}" onclick="window.open(&quot;info.xql?info={$queryType}&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" width="15" height="15" border="0" alt="Info"/></a>
+                </td>
+                <td><button id="bXPath" name="query-type" value="xpath" style="background:none"><text style="font-weight:bold;font-size:12px">XPath</text></button></td>
+                <td><button id="bXQuery" name="query-type" value="xquery" style="background:none"><text style="font-weight:bold;font-size:12px">XQuery</text></button></td>
+              </tr>
+              </table>
+              <input type="hidden" name="query" value=""/>
+            </form>
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <xsl:if test="$queryType = 'xpath'">
+                <input type="hidden" name="query-type" value="xpath"/>
+                <table>
+                <tr><td><input type="text" size="50" name="query" value="{$query}"/></td></tr>
+                <tr><td><input type="submit" value="Query"/></td></tr>
+                </table>
+              </xsl:if>
+              <xsl:if test="$queryType = 'xquery'">
+                <input type="hidden" name="query-type" value="xquery"/>
+                <table>
+                  <tr>
+                    <td>
+                    <textarea name="query" cols="45" rows="10">
+                      <xsl:choose>
+                      <xsl:when test="$query = ''"><xsl:value-of select="' '" /></xsl:when>
+                      <xsl:otherwise><xsl:value-of select="$query"/></xsl:otherwise>
+                      </xsl:choose>
+                    </textarea>
+                    </td>
+                  </tr>
+                  <tr><td><input type="submit" value="Query"/></td></tr>
+                </table>
+              </xsl:if>
+            </form>
+            </xsl:if>
+            <xsl:if test="$queryType = 'ftIndex' or $queryType = 'ftIndexMorph'">
+            <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <input type="hidden" name="query-type" value="{$queryType}"/>
+              <xsl:if test="$queryType = 'ftIndex'"><xsl:value-of select="'Fulltext index: '"/></xsl:if>
+              <xsl:if test="$queryType = 'ftIndexMorph'"><xsl:value-of select="'Morphological index: '"/></xsl:if>
+              <input type="text" size="10" name="query" value="{$query}"/> 
+              <input type="hidden" name="query-result-pn" value="1"/>
+              <input type="submit" value="Query"/>
+            </form>
+            </xsl:if>
+            <xsl:if test="(($query != '' or $queryType = 'toc' or $queryType = 'figures') and $queryResultPages &gt; 0)">
+              <hr/>
+              <table>
+              <colgroup>
+                <col width="81%"/>
+                <col width="3%"/>
+                <col width="5%"/>
+                <col width="3%"/>
+                <col width="5%"/>
+              </colgroup>
+              <tr>
+              <td>
+                <xsl:variable name="resultSize" select="/result/query/result/size"/>
+                <xsl:if test="$queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma'">
+                  <b><xsl:value-of select="$resultSize"/> sentence hits</b>
+                </xsl:if>
+                <xsl:if test="$queryType = 'ftIndex' or $queryType = 'ftIndexMorph'">
+                  <b><xsl:value-of select="$resultSize"/> entries beginning with: "<xsl:value-of select="$query"/>"<br/></b>
+                </xsl:if>
+                <xsl:if test="$queryType = 'xpath' or $queryType = 'xquery'">
+                  <b><xsl:value-of select="$resultSize"/> element hits</b>
+                </xsl:if>
+              </td>
+              <xsl:variable name="leftNumber">
+                <xsl:choose>
+                <xsl:when test="$queryResultPN &gt; 1"><xsl:value-of select="$queryResultPN - 1"/></xsl:when>
+                <xsl:otherwise><xsl:value-of select="$queryResultPN"/></xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:variable name="rightNumber">
+                <xsl:choose>
+                <xsl:when test="$queryResultPN &lt; $queryResultPages"><xsl:value-of select="$queryResultPN + 1"/></xsl:when>
+                <xsl:otherwise><xsl:value-of select="$queryResultPN"/></xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <input type="hidden" name="query-type" value="{$queryType}"/>
+              <input type="hidden" name="query" value="{$query}"/>
+              <td><button id="buttonLeftNumber" name="query-result-pn" value="{$leftNumber}" style="background:none;border:none;"><img src="images/left.gif"/></button></td>
+              <td nowrap="true"><xsl:value-of select="$queryResultPN"/> / <xsl:value-of select="$queryResultPages"/></td>
+              <td><button id="buttonRightNumber" name="query-result-pn" value="{$rightNumber}" style="background:none;border:none;"><img src="images/right.gif"/></button></td>
+              </form>
+              <form action="page-query-result.xql" method="get">
+              <input type="hidden" name="document" value="{$documentUri}"/>
+              <input type="hidden" name="pn" value="{$pageNumber}"/>
+              <input type="hidden" name="mode" value="{$mode}"/>
+              <input type="hidden" name="query-type" value="{$queryType}"/>
+              <input type="hidden" name="query" value="{$query}"/>
+              <td nowrap="true">Page: <input type="text" size="2" name="query-result-pn" value="{$queryResultPN}"/></td>
+              </form>
+              </tr>
+              </table>
+              <xsl:if test="$ftQueryMorphForms != ''">
+                <table>
+                  <colgroup>
+                    <col width="40%"/>
+                    <col width="60%"/>
+                  </colgroup>
+                  <td/>
+                  <xsl:if test="$queryType = 'fulltextMorph'">
+                    <td align="right" nowrap="true">Morphological expansion: <a href="lt/lemma.xql?language={$language}&amp;query={$query}">see here</a></td>
+                  </xsl:if>
+                  <xsl:if test="$queryType = 'fulltextMorphLemma'">
+                    <td align="right" nowrap="true">Morphological expansion: <a href="lt/lemma.xql?language={$language}&amp;lemma={$query}">see here</a></td>
+                  </xsl:if>
+                </table>
+              </xsl:if>
+              <hr/>
+              <xsl:if test="$queryType = 'toc' or $queryType = 'figures'">
+                <table class="toc" cellspacing="1" cellpadding="1">
+                  <colgroup>
+                    <col width="70%"/>
+                    <col width="20%"/>
+                  </colgroup>
+                <xsl:for-each select="/result/query/result/hits/toc-entry">
+                  <xsl:variable name="page" select="page"/>
+                  <xsl:variable name="level">
+                    <xsl:choose>
+                      <xsl:when test="real-level = '1'"><xsl:value-of select="'one'"/></xsl:when>
+                      <xsl:when test="real-level = '2'"><xsl:value-of select="'two'"/></xsl:when>
+                      <xsl:when test="real-level = '3'"><xsl:value-of select="'three'"/></xsl:when>
+                      <xsl:when test="real-level = '4'"><xsl:value-of select="'four'"/></xsl:when>
+                      <xsl:when test="real-level = '5'"><xsl:value-of select="'five'"/></xsl:when>
+                      <xsl:when test="real-level = '6'"><xsl:value-of select="'six'"/></xsl:when>
+                      <xsl:when test="real-level = '7'"><xsl:value-of select="'seven'"/></xsl:when>
+                      <xsl:otherwise><xsl:value-of select="'one'"/></xsl:otherwise>
+                    </xsl:choose>
+                  </xsl:variable>
+                  <tr>
+                  <td align="left" valign="top">
+                    <div class="toc {$level}">
+                      <xsl:value-of select="'['"/>
+                      <xsl:value-of select="concat(level-string, ' ')"/>
+                      <xsl:value-of select="content"/>
+                      <xsl:value-of select="']'"/>
+                    </div>
+                  </td>
+                  <td align="center" valign="top">
+                    <div class="toc float right">
+                      <a href="?{$documentValue}&amp;pn={$page}&amp;{$modeValue}&amp;query-type={$queryType}&amp;query-result-pn={$queryResultPN}">
+                        <xsl:value-of select="concat('Page: ', $page)"/>
+                      </a>
+                    </div>
+                  </td>
+                  </tr>
+                </xsl:for-each>
+                </table>
+              </xsl:if>
+              <xsl:if test="$queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma'">
+              <table cellspacing="1" cellpadding="1">
+              <xsl:for-each select="/result/query/result/hits/hit">
+                <tr valign="top">
+                <xsl:variable name="pos" select="pos"/>
+                <xsl:variable name="term" select="term"/>
+                <td><xsl:value-of select="$pos"/>.</td>
+                <td align="left">
+                  <xsl:variable name="hitPN" select="pn"/>
+                  <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                  <xsl:variable name="sSurroundsPB" select="s-surrounds-pb"/>
+                  <xsl:variable name="queryValue" select="concat('&amp;', 'query=', $query)"/>
+                  <xsl:variable name="queryValueEscaped1" select="replace($queryValue, '\+', '%2B')"/>
+                  <xsl:variable name="queryValueEscaped2" select="replace($queryValueEscaped1, ' ', '+')"/>
+                  <xsl:choose>
+                  <!-- if a found sentence surrounds a page break then a special presentation of the hit is done -->
+                  <xsl:when test="$sSurroundsPB = 'false'">
+                    <a href="?{$documentValue}&amp;pn={$hitPN}&amp;sn={$hitPosOfS}&amp;{$modeValue}&amp;query-type={$queryType}{$queryValueEscaped2}&amp;query-result-pn={$queryResultPN}#sn{$hitPosOfS}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <a href="?{$documentValue}&amp;pn={$hitPN}&amp;sn={$hitPosOfS}&amp;{$modeValue}&amp;query-type={$queryType}{$queryValueEscaped2}&amp;query-result-pn={$queryResultPN}#sn{$hitPosOfS}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a> / <a href="?{$documentValue}&amp;pn={$hitPN + 1}&amp;sn=0&amp;{$modeValue}&amp;query-type={$queryType}{$queryValueEscaped2}&amp;query-result-pn={$queryResultPN}#sn0">Page <xsl:value-of select="$hitPN + 1"/>, continuation of the sentence</a>
+                  </xsl:otherwise>
+                  </xsl:choose>
+                  :<br/>
+                  <!-- Highlight the query terms in each hit sentence and clip the result -->
+                  <xsl:sequence select="text:highlight(s, $ftQueryTerms, $ftQueryHighlightWords, 'true')"/>
+                </td>
+                </tr>
+              </xsl:for-each>
+              </table>
+              </xsl:if>
+              <xsl:if test="$queryType = 'ftIndex' or $queryType = 'ftIndexMorph'">
+              <table cellspacing="1" cellpadding="1">
+              <xsl:for-each select="/result/query/result/hits/entry">
+                <tr valign="top">
+                <xsl:variable name="pos" select="position"/>
+                <xsl:variable name="term" select="term"/>
+                <xsl:variable name="polluxKeys" select="pollux-keys"/>
+                <xsl:variable name="lemmasWithOR" select="lemmas-with-or"/>
+                <xsl:variable name="dictionaryLink">
+                  <xsl:choose>
+                  <xsl:when test="$language = 'zh'">
+                    <xsl:variable name="termBig5Encoded" select="/result/query/result/big5-hits/entry-big5-encoded/term[$pos]"/>
+                    <a href="http://humanum.arts.cuhk.edu.hk/cgi-bin/agrep-lindict?query={$termBig5Encoded}&amp;category=wholerecord">Lin Yutang</a>
+                    <!-- TODO: replace Java based function by XSL-function like the following, but that does not work yet cause termHexBin is not the same than by Java) also in query.xsl and functions-text.xsl -->
+                    <xsl:variable name="termHexBin"><xsl:value-of select="saxon:string-to-hexBinary($term, 'utf8')"/></xsl:variable>
+                    <xsl:variable name="termHexBinStr" select="string($termHexBin)"/>
+                    <xsl:variable name="termBig5EncodedNew">
+                      <xsl:for-each select="string-to-codepoints($termHexBinStr)">
+                        <xsl:variable name="pos" select="position()"/>
+                        <xsl:variable name="posIDiv" select="$pos idiv 2"/>
+                        <xsl:variable name="posPlus1IDiv" select="($pos + 1) idiv 2"/>
+                        <xsl:if test="$posIDiv != $posPlus1IDiv">
+                          <xsl:variable name="charStr" select="substring($termHexBinStr, $pos, 2)"/>
+                          <xsl:value-of select="encode-for-uri(concat('%', $charStr))"/>
+                        </xsl:if>
+                      </xsl:for-each>
+                    </xsl:variable>
+                  </xsl:when>
+                  <xsl:otherwise><a href="http://archimedes.mpiwg-berlin.mpg.de/cgi-bin/toc/dict?step=table;word={$term};lang={$language};pro=echo">Echo</a></xsl:otherwise>
+                  </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="polluxLink">
+                  <xsl:choose>
+                  <xsl:when test="$polluxKeys = ''">Pollux</xsl:when>
+                  <xsl:otherwise><a href="lt/lex.xql?language={$language}&amp;query={$polluxKeys}">Pollux</a></xsl:otherwise>
+                  </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="wikipediaLink">
+                  <xsl:choose>
+                  <xsl:when test="$lemmasWithOR = ''">Wiki</xsl:when>
+                  <xsl:otherwise><a href="http://{$language}.wikipedia.org/wiki/index.php?search={$lemmasWithOR}">Wiki</a></xsl:otherwise>
+                  </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="ftSearchQueryType">
+                  <xsl:choose>
+                  <xsl:when test="$queryType = 'ftIndex'"><xsl:value-of select="'fulltext'"/></xsl:when>
+                  <xsl:when test="$queryType = 'ftIndexMorph'"><xsl:value-of select="'fulltextMorphLemma'"/></xsl:when>
+                  <xsl:otherwise></xsl:otherwise>
+                  </xsl:choose>
+                </xsl:variable>
+                <td><xsl:value-of select="$pos"/>.</td>
+                <td align="left">
+                  <a href="lt/lemma.xql?language={$language}&amp;lemma={$term}"><xsl:value-of select="$term"/></a>(<a href="?{$documentValue}&amp;{$modeValue}&amp;query-type={$ftSearchQueryType}&amp;query={$term}"><xsl:value-of select="frequency"/></a>) [<xsl:sequence select="$polluxLink"/>][<xsl:sequence select="$wikipediaLink"/>][<xsl:sequence select="$dictionaryLink"/>]
+                </td>
+                </tr>
+              </xsl:for-each>
+              </table>
+              </xsl:if>
+              <xsl:if test="$queryType = 'xpath' or $queryType = 'xquery'">
+                <xsl:for-each select="/result/query/result/hits">
+                  <table>
+                  <colgroup>
+                    <col width="90%"/>
+                    <col width="10%"/>
+                  </colgroup>
+                  <tr>
+                  <td><xsl:apply-templates mode="xml"/></td>
+                  <xsl:variable name="queryWithoutCRLF" select="replace($query, '\r\n', ' ')"/>
+                  <td align="middle" valign="top"><p><a target="_blank" href="?{$documentValue}&amp;mode=pureXml&amp;query-type={$queryType}&amp;query={$queryWithoutCRLF}&amp;query-result-pn={$queryResultPN}"><img src="images/download.png" width="24" height="24" border="0" alt="Download"/></a><br/>Download</p></td>
+                  </tr>
+                  </table>
+                </xsl:for-each>
+              </xsl:if>
+            </xsl:if>
+            <xsl:choose>
+              <xsl:when test="$errorMessage != ''">
+                <hr/>
+                <b>Your query delivers an error: </b>
+                <xsl:value-of select="$errorMessage"/>
+              </xsl:when>
+              <xsl:when test="$errorMessage = '' and $query != '' and $queryResultPages = 0">
+                <hr/>
+                <b>No results</b>
+              </xsl:when>
+            </xsl:choose>
+          </td>
+        </tr>
+      </table>
+      <hr/>
+      Elapsed time: <xsl:value-of select="/result/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/mpdl/presentation/pageHtml.xsl?_source=yes">XSL source</a> of this page
+      <br/>
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()" mode="xml">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|comment()|processing-instruction()" mode="xml">
+  <xsl:variable name="elementName" select="name()"/>
+  <xsl:variable name="elementPresentation">
+    <xsl:choose>
+    <xsl:when test="element() = node() or text() != '' or self::comment() or self::processing-instruction()">
+      <xsl:value-of select="'&lt;'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:apply-templates select="attribute()" mode="xml"/>
+      <xsl:value-of select="'&gt;'"/>
+      <xsl:apply-templates select="element()|text()|comment()|processing-instruction()" mode="xml"/>
+      <xsl:value-of select="'&lt;/'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:value-of select="'&gt;'"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="'&lt;'"/>
+      <span class="xml elementName"><xsl:value-of select="$elementName"/></span>
+      <xsl:apply-templates select="attribute()" mode="xml"/>
+      <xsl:value-of select="'/&gt;'"/>
+    </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+    <!-- Show the sentence in color light grey if it is given as sn -->
+    <xsl:when test="$elementName = 's' and $sn >= 0 and $sn = $actualSN">
+      <ul class="xml element highlight">
+        <a name="sn{$actualSN}"></a><xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:when>
+    <xsl:when test="$elementName = 's' and $sn != $actualSN">
+      <ul class="xml element">
+        <a name="sn{$actualSN}"></a><xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:when>
+    <xsl:otherwise>
+      <ul class="xml element">
+        <xsl:sequence select="$elementPresentation"/>
+      </ul>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="attribute()" mode="xml">
+  <xsl:variable name="attributeName" select="name()"/>
+  <span class="xml attributeName">
+    <xsl:value-of select="' '"/>
+    <xsl:value-of select="$attributeName"/>
+  </span>
+  <xsl:value-of select="'=&quot;'"/>
+  <span class="xml attributeValue"><xsl:value-of select="."/></span><xsl:value-of select="'&quot;'"/>
+  <xsl:apply-templates select="attribute()" mode="xml"/>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences in each little text piece for the fulltext query -->
+<xsl:template match="text()" mode="xml">
+  <xsl:variable name="parentS" select="./ancestor::s"/>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test="$parentS = $firstSentence and ($topPB >> $parentS)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$ftQueryMode != 'false' and $sn >= 0 and $sn = $actualSN">
+      <xsl:sequence select="text:highlight(string(.), $ftQueryTerms, $ftQueryHighlightWords, 'false')"/>
+    </xsl:when>
+    <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- variables used by templates in mode "text" -->
+<xsl:variable name="collectionName" select="/result/document-description/collection-name"/>
+<xsl:variable name="documentUri" select="/result/document-description/uri"/>
+<xsl:variable name="documentName" select="/result/document-description/document-name"/>
+<xsl:variable name="documentIdentifier" select="/result/document-description/identifier"/>
+<xsl:variable name="pageNumber" select="/result/page/number"/>
+<xsl:variable name="firstFigurePosition" select="/result/page/firstFigurePosition"/>
+<xsl:variable name="figuresImageDirectory" select="/result/page/figures-image-directory"/>
+<xsl:variable name="figures" select="/result/page/figures"/>
+<xsl:variable name="handwritten" select="/result/page/handwritten"/>
+<xsl:variable name="tables" select="/result/page/tables"/>
+<xsl:variable name="notes" select="/result/page/notes"/>
+<xsl:variable name="charNorm" select="/result/page/character-normalization"/>
+
+<xsl:template match="text" mode="text">
+  <xsl:apply-templates mode="text"/>
+  <!--   Notes                      -->
+  <xsl:if test="$collectionName = 'archimedes' and count($notes/*) > 0">
+    <div>
+      <hr class="notesBottom"/>
+      <xsl:for-each select="$notes/note">
+        <xsl:variable name="notePos" select="position()"/>
+        <xsl:variable name="label" select="$notePos"/>
+        <xsl:variable name="uid" select="@uid"/>
+        <xsl:variable name="modificationDate" select="@modificationDate"/>
+        <xsl:variable name="noteWithoutNamespace" select="mpdl-util:copyWithoutNamespace(.)"/>
+        <p>
+          <a>
+            <xsl:attribute name="name"><xsl:value-of select="concat('note-', $pageNumber, '-', $label)"/></xsl:attribute>
+            <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', 'note-', $pageNumber, '-', $label, 'ref')"/></xsl:attribute>
+            <xsl:value-of select="concat('[↑ note-', $pageNumber, '-', $label, ']')"/>
+          </a>
+          <xsl:value-of select="': '"/>
+          <xsl:choose>
+            <xsl:when test="$uid = '' or empty($uid)">
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+            </xsl:when>
+            <xsl:otherwise>
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+              <xsl:value-of select="concat(' [external note, ', $uid, ', ', $modificationDate, ']')"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </p>
+      </xsl:for-each>
+    </div>
+  </xsl:if>
+  <xsl:if test="$collectionName = 'echo' and count($notes/*) > 0">
+    <div>
+      <hr class="notesBottom"/>
+      <xsl:for-each select="$notes/echo:note">
+        <xsl:variable name="label" select="string(@xlink:label)"/>
+        <xsl:variable name="uid" select="@uid"/>
+        <xsl:variable name="modificationDate" select="@modificationDate"/>
+        <xsl:variable name="noteWithoutNamespace" select="mpdl-util:copyWithoutNamespace(.)"/>
+        <p>
+          <a>
+            <xsl:attribute name="name"><xsl:value-of select="$label"/></xsl:attribute>
+            <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $label, 'ref')"/></xsl:attribute>
+            <xsl:value-of select="concat('[↑ ', $label, ']')"/>
+          </a>
+          <xsl:value-of select="': '"/>
+          <xsl:choose>
+            <xsl:when test="$uid = '' or empty($uid)">
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+            </xsl:when>
+            <xsl:otherwise>
+              <span class="note"><xsl:apply-templates select="$noteWithoutNamespace/node()" mode="text"/></span>
+              <xsl:value-of select="concat(' [external note, ', $uid, ', ', $modificationDate, ']')"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </p>
+      </xsl:for-each>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="head" mode="text">
+  <p class="bf center"><xsl:apply-templates mode="text"/></p>
+</xsl:template>
+
+<xsl:template match="div" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="level" select="@level"/>
+  <xsl:variable name="style" select="@style"/>
+  <xsl:variable name="border" select="@border"/>
+  <xsl:variable name="width" select="@width"/>
+  <xsl:variable name="note" select="note"/>
+  <xsl:variable name="figure" select="figure"/>
+  <xsl:variable name="floatClassValue">
+    <xsl:choose>
+      <xsl:when test="not(empty($note))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="not(empty($figure))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="$type = 'float'"><xsl:value-of select="'float left'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'float left'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="levelClassValue">
+    <xsl:choose>
+      <xsl:when test="not(empty($note))"><xsl:value-of select="''"/></xsl:when>
+      <xsl:when test="$level = '1'"><xsl:value-of select="'level one'"/></xsl:when>
+      <xsl:when test="$level = '2'"><xsl:value-of select="'level two'"/></xsl:when>
+      <xsl:when test="$level = '3'"><xsl:value-of select="'level three'"/></xsl:when>
+      <xsl:when test="$level = '4'"><xsl:value-of select="'level four'"/></xsl:when>
+      <xsl:when test="$level = '5'"><xsl:value-of select="'level five'"/></xsl:when>
+      <xsl:when test="$level = '6'"><xsl:value-of select="'level six'"/></xsl:when>
+      <xsl:when test="$level = '7'"><xsl:value-of select="'level seven'"/></xsl:when>
+      <xsl:when test="$level = '8'"><xsl:value-of select="'level eight'"/></xsl:when>
+      <xsl:when test="$level = '9'"><xsl:value-of select="'level nine'"/></xsl:when>
+      <xsl:when test="empty($level)"><xsl:value-of select="''"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'level n'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <div>
+    <xsl:if test="not(empty($style))"><xsl:attribute name="style"><xsl:value-of select="$style"/></xsl:attribute></xsl:if>
+    <xsl:attribute name="class"><xsl:value-of select="concat($floatClassValue, ' ', $levelClassValue)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="p" mode="text">
+  <xsl:variable name="style" select="@style"/>
+  <p>
+    <xsl:if test="not(empty($style))">
+      <xsl:attribute name="class"><xsl:value-of select="$style"/></xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates mode="text"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="lb" mode="text">
+  <xsl:variable name="withoutLBs">
+    <xsl:choose>
+      <xsl:when test="contains($options, 'withoutLBs')"><xsl:value-of select="'true'"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="'false'"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>  
+  <xsl:if test="$withoutLBs = 'false'"><br/></xsl:if>
+  <xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="cb" mode="text">
+  <br/><xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="expan" mode="text">
+  <xsl:apply-templates mode="text"/><xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="note" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:variable name="notePos" select="count(preceding::note[. >> $topPB]) + 1"/>
+  <xsl:variable name="href" select="concat('note-', $pageNumber, '-', $notePos)"/>
+  <xsl:choose>
+    <xsl:when test="$collectionName = 'archimedes'">
+      <a>
+        <xsl:attribute name="name"><xsl:value-of select="concat($href, 'ref')"/></xsl:attribute>
+        <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $href)"/></xsl:attribute>
+        <xsl:attribute name="class"><xsl:value-of select="'super'"/></xsl:attribute>
+        <xsl:value-of select="concat(' ↓ (', $href, ') ')"/>
+      </a>
+    </xsl:when>
+    <xsl:when test="$collectionName = 'echo' and not($hasLabel)">
+      <p>
+        <xsl:value-of select="'[Note]: '"/>
+        <span class="note"><xsl:apply-templates mode="text"/></span>
+      </p>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="emph" mode="text">
+  <xsl:variable name="class" select="@class"/>
+  <xsl:variable name="style" select="@style"/>
+  <xsl:variable name="text" select="string-join(., '')"/>
+  <xsl:variable name="length" select="string-length($text)"/>
+  <xsl:variable name="firstChar" select="substring($text, 1, 1)"/>
+  <xsl:variable name="first2Chars" select="substring($text, 1, 2)"/>
+  <xsl:variable name="restChars" select="substring($text, 2, $length)"/>
+  <xsl:variable name="first2CharsAreUppercase" select="upper-case($first2Chars) = $first2Chars"/>
+  <xsl:variable name="rest">
+    <xsl:choose>
+      <xsl:when test="$length &lt; 2 or empty($length)"><xsl:value-of select="''"/></xsl:when>
+      <xsl:otherwise>
+        <xsl:choose>
+          <xsl:when test="not(empty(w))">
+            <a class="textPollux" href="interface/lt/wordInfo.xql?language={w/@lang}&amp;word={w/@form}&amp;output=html"><xsl:value-of select="$restChars"/></a>
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$restChars"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:if test="$collectionName = 'echo' and not(contains($class, 'sc'))"><span class="{$class} {$style}"><xsl:apply-templates mode="text"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'echo' and contains($class, 'sc') and $first2CharsAreUppercase"><span class="dc {$style}"><xsl:value-of select="$firstChar"/></span><span class="{$class} {$style}"><xsl:sequence select="$rest"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'echo' and contains($class, 'sc') and not($first2CharsAreUppercase)"><span class="{$class} {$style}"><xsl:apply-templates mode="text"/></span></xsl:if>
+  <xsl:if test="$collectionName = 'archimedes'"><xsl:apply-templates mode="text"/></xsl:if>
+</xsl:template>
+
+<xsl:template match="ref" mode="text">
+  <span class="ref"><xsl:apply-templates mode="text"/></span>
+</xsl:template>
+
+<xsl:template match="foreign" mode="text">
+  <xsl:variable name="lang" select="@lang"/>
+  <xsl:variable name="xmllang" select="@xml:lang"/>
+  <xsl:variable name="language">
+    <xsl:choose>
+      <xsl:when test="not(empty($xmllang))"><xsl:value-of select="$xmllang"/></xsl:when>
+      <xsl:when test="not(empty($lang))"><xsl:value-of select="$lang"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>  
+  <span>
+    <xsl:attribute name="class"><xsl:value-of select="concat('foreign ', $language)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="q" mode="text">
+  <div class="q"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="quote" mode="text">
+  <div class="quote"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="blockquote" mode="text">
+  <div class="blockquote"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="set-off" mode="text">
+  <div class="set-off"><xsl:apply-templates mode="text"/></div>
+</xsl:template>
+
+<xsl:template match="reg" mode="text">
+  <span class="reg">   
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="var" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <span class="var">
+    <xsl:attribute name="class"><xsl:value-of select="concat('var ', $type)"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="num" mode="text">
+  <span class="num"><xsl:apply-templates mode="text"/></span>
+</xsl:template>
+
+<xsl:template match="gap" mode="text">
+  <xsl:variable name="extent" select="@extent"/>
+  <xsl:variable name="count">
+    <xsl:choose>
+      <xsl:when test="empty($extent)"><xsl:value-of select="number(3)"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="number($extent)"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="gapChars" select="text:nchars($count, '.')"/>
+  <xsl:value-of select="concat('[', $gapChars, ']')"/><xsl:apply-templates mode="text"/>
+</xsl:template>
+
+<xsl:template match="anchor" mode="text">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="href" select="@xlink:href"/>
+  <xsl:choose>
+    <xsl:when test="$type = 'figure'">
+      <xsl:variable name="figure" select="$figures/echo:figure[@xlink:label = $href]"/>
+      <xsl:variable name="figureFileName">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="replace($figure/@xlink:href, '/', '.')"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$figure/echo:image/@file"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$figure/echo:image/@file"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureNumber">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="$firstFigurePosition + count($figure/preceding::figure)"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$firstFigurePosition + count(./preceding::echo:figure[empty(@xlink:label)]) + count(./preceding::echo:anchor[@type = 'figure'])"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureCaption" select="string-join($figure/echo:caption/text(), ' ')"/>
+      <xsl:variable name="figureDescription" select="string-join($figure/echo:description/text(), ' ')"/>
+      <xsl:variable name="figureVariables" select="string-join($figure/echo:variables/text(), ' ')"/>
+      <xsl:sequence select="mpdl:showFigure($digilibAvailable, $figureFileName, $figureNumber, $figureCaption, $figureDescription, $figureVariables, 'float right')"/>
+    </xsl:when>
+    <xsl:when test="$type = 'handwritten'">
+      <xsl:variable name="hw" select="$handwritten/echo:handwritten[@xlink:label = $href]"/>
+      <xsl:variable name="hwFileName" select="$hw/@file"/>
+      <xsl:variable name="hwHref" select="$hw/@xlink:href"/>
+      <xsl:sequence select="mpdl:showHandwritten($hwFileName, $hwHref)"/>
+    </xsl:when>
+    <xsl:when test="$type = 'table'">
+      <xsl:variable name="table" select="$tables/xhtml:table[@xlink:label = $href]"/>
+      <xsl:sequence select="mpdl-util:copyWithoutNamespace($table)"/>
+    </xsl:when>
+    <xsl:when test="$type = 'note'">
+      <a>
+        <xsl:attribute name="name"><xsl:value-of select="concat($href, 'ref')"/></xsl:attribute>
+        <xsl:attribute name="href"><xsl:value-of select="concat(urlBase, '#', $href)"/></xsl:attribute>
+        <xsl:attribute name="class"><xsl:value-of select="'super'"/></xsl:attribute>
+        <xsl:value-of select="concat('↓ (', $href, ')')"/>
+      </a>
+    </xsl:when>
+    <xsl:otherwise><a><xsl:attribute name="href"><xsl:value-of select="$href"/></xsl:attribute>Anchor of type: <xsl:value-of select="$type"/>, href: <xsl:value-of select="$href"/></a></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- GIS Elements   -->
+<xsl:template match="place" mode="text">
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="id" select="@id"/>
+  <xsl:variable name="echoDocDir" select="replace($figuresImageDirectory, '(.*)/.*$', '$1')"/>
+  <xsl:variable name="echoDocDirTokenized" select="tokenize($echoDocDir, '/')"/>
+  <xsl:variable name="echoDocDirNameSize" select="count($echoDocDirTokenized)"/>
+  <xsl:variable name="echoDoc" select="string(subsequence($echoDocDirTokenized, $echoDocDirNameSize))"/>
+  <xsl:variable name="docStrOld" select="concat('http://echo.mpiwg-berlin.mpg.de/ECHOdocuView?url=', $echoDocDir, '&amp;pn=', $pageNumber, '&amp;sn=', $actualSN, '&amp;viewMode=gis')"/>
+  <xsl:variable name="docStr" select="concat('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=', $documentUri, '&amp;mode=gis', '&amp;pn=', $pageNumber, '&amp;sn=', $actualSN)"/>
+  <xsl:variable name="docBase64Coded" select="saxon:string-to-base64Binary($docStr, 'utf8')"/>
+  <xsl:variable name="href" select="concat('http://chinagis.mpiwg-berlin.mpg.de/chinagis/REST/db/mpdl/', $echoDoc, '?id=', $id, '&amp;doc=', $docBase64Coded, '&amp;format=gis')"/>
+  <xsl:choose>
+    <xsl:when test="$mode = 'textPollux'">
+      <xsl:variable name="wordLanguage" select="string-join(w[1]/@lang, '')"/>
+      <xsl:variable name="form" select="string-join(w/@form, '')"/>
+      <xsl:variable name="wordStr" select="string-join(w, '')"/>
+      <xsl:variable name="lexHref">
+        <xsl:if test="not(empty(w))">
+          <xsl:value-of select="concat('interface/lt/wordInfo.xql?language=', $wordLanguage, '&amp;word=', $form, '&amp;output=html', '&amp;placeHref=', encode-for-uri($href))"/>
+        </xsl:if>
+        <xsl:if test="empty(w)">
+          <xsl:value-of select="concat('interface/lt/wordInfo.xql?type=place', '&amp;output=html', '&amp;placeHref=', encode-for-uri($href))"/>
+        </xsl:if>
+      </xsl:variable>
+      <span class="place">
+        <a class="textPollux"><xsl:attribute name="href"><xsl:value-of select="$lexHref"/></xsl:attribute><xsl:value-of select="$wordStr"/></a>
+      </span>
+    </xsl:when>
+    <xsl:otherwise>
+      <span class="place">
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="time" mode="text">
+  <span class="time">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="person" mode="text">
+  <span class="person">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="event" mode="text">
+  <span class="event">
+    <xsl:apply-templates mode="text"/>
+  </span>
+</xsl:template>
+
+<!-- MML   -->
+<xsl:template match="mml:*" mode="text">
+  <xsl:copy-of select="."/>
+</xsl:template>
+    
+<!-- XHTML: remove the xhtml namespace   -->
+<xsl:template match="xhtml:*" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:variable name="isTable" select="name() = 'table'"/>
+  <xsl:choose>
+    <xsl:when test="(not($hasLabel)) or ($isTable and $hasLabel)">
+      <xsl:element name="{name()}" namespace="">
+        <xsl:copy-of select="@*"/>
+        <xsl:apply-templates mode="text"/>
+      </xsl:element>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="figure" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:choose>
+    <xsl:when test="not($hasLabel)">
+      <xsl:variable name="figureFileName">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="replace(./@xlink:href, '/', '.')"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="./image/@file"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="./image/@file"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureNumber">
+        <xsl:choose>
+          <xsl:when test="$collectionName = 'archimedes'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure)"/></xsl:when>
+          <xsl:when test="$collectionName = 'echo'"><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$firstFigurePosition + count(./preceding::figure[empty(@xlink:label)]) + count(./preceding::anchor[@type = 'figure'])"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="figureCaption" select="./caption/text()"/>
+      <xsl:variable name="figureDescription" select="./description/text()"/>
+      <xsl:variable name="figureVariables" select="./variables/text()"/>
+      <xsl:sequence select="mpdl:showFigure($digilibAvailable, $figureFileName, $figureNumber, $figureCaption, $figureDescription, $figureVariables, 'float none')"/>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="handwritten" mode="text">
+  <xsl:variable name="hasLabel" select="string(@xlink:label) != ''"/>
+  <xsl:choose>
+    <xsl:when test="not($hasLabel)">
+      <xsl:variable name="fileName" select="@file"/>
+      <xsl:variable name="href" select="@xlink:href"/>
+      <xsl:sequence select="mpdl:showHandwritten($fileName, $href)"/>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+
+<!-- textPollux links                           -->
+<xsl:template match="w" mode="text">
+  <xsl:variable name="wordLanguage" select="@lang"/>
+  <xsl:variable name="form" select="@form"/>
+  <a class="textPollux">
+    <xsl:attribute name="href"><xsl:value-of select="concat('interface/lt/wordInfo.xql?language=', $wordLanguage, '&amp;word=', $form, '&amp;output=html')"/></xsl:attribute>
+    <xsl:apply-templates mode="text"/>
+  </a>
+</xsl:template>
+
+<xsl:template match="s" mode="text">
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test=". = $firstSentence and ($topPB >> .)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <a name="sn{$actualSN}"></a>
+  <xsl:choose>
+    <!-- Show the sentence in color light grey if it is given as sn -->
+    <xsl:when test="$sn >= 0 and $sn = $actualSN">
+      <span class="s highlight">
+        <xsl:if test="contains($options, 'withXmlNodeId')"><xsl:attribute name="xmlNodeId"><xsl:value-of select="@xmlNodeId"/></xsl:attribute></xsl:if>
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:when>
+    <xsl:otherwise>
+      <span class="s">
+        <xsl:if test="contains($options, 'withXmlNodeId')"><xsl:attribute name="xmlNodeId"><xsl:value-of select="@xmlNodeId"/></xsl:attribute></xsl:if>
+        <xsl:apply-templates mode="text"/>
+      </span>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences in each little text piece for the fulltext query -->
+<xsl:template match="text()" mode="text">
+  <xsl:variable name="parentS" select="./ancestor::s"/>
+  <xsl:variable name="actualSN">
+    <xsl:choose>
+      <xsl:when test="$parentS = $firstSentence and ($topPB >> $parentS)">0</xsl:when>
+      <xsl:otherwise><xsl:value-of select="count(preceding::s[. >> $topPB]) + 1"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false' and $sn >= 0 and $sn = $actualSN">
+    <xsl:sequence select="text:highlight(string(.), $ftQueryTerms, $ftQueryHighlightWords, 'false')"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/pageXml.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:functx="http://www.functx.com"
+  xmlns:saxon="http://saxon.sf.net/"
+  xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"
+  xmlns:de="http://www.mpiwg-berlin.mpg.de/ns/de/1.0/" 
+  xmlns:dc="http://purl.org/dc/elements/1.1/" 
+  xmlns:dcq="http://purl.org/dc/qualifiers/1.0/" 
+  xmlns:dct="http://purl.org/dc/terms/1.0/" 
+  xmlns:echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/" 
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+  xmlns:xhtml="http://www.w3.org/1999/xhtml">
+
+<xsl:output method="xml" encoding="utf-8"/>
+
+<xsl:variable name="mode" select="/result/page/mode"/>
+<xsl:variable name="queryType" select="/result/query/type"/>
+
+<xsl:template match="result">
+  <xsl:choose>
+  <xsl:when test="$mode = 'pureXml' and ($queryType = 'xpath' or $queryType = 'xquery')">
+    <query-result>
+      <xsl:sequence select="/result/query/result/hits/*"/>
+    </query-result>
+  </xsl:when>
+  <xsl:otherwise><xsl:sequence select="/result/page/content/*"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/presentation/queryHtml.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,220 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:saxon="http://saxon.sf.net/"
+  xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"
+  xmlns:dc="http://purl.org/dc/elements/1.1/" 
+  xmlns:dcterms="http://purl.org/dc/terms"
+  xmlns:echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/" 
+  xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+  xmlns:xhtml="http://www.w3.org/1999/xhtml"
+  xmlns:functx="http://www.functx.com">
+
+<xsl:import href="/db/mpdl/presentation/functions-functx.xsl"/>
+<xsl:import href="/db/mpdl/presentation/functions-text.xsl"/>
+
+<xsl:output method="html" encoding="utf-8"/>
+
+<xsl:variable name="errorMessage" select="string(/result/query/result/error)"/>
+<xsl:variable name="documentUri" select="/result/document-description/uri"/>
+<xsl:variable name="documentName" select="/result/document-description/document-name"/>
+<xsl:variable name="documentValue" select="concat('document=', $documentUri)"/>
+<xsl:variable name="mode" select="/result/page/mode"/>
+<xsl:variable name="modeValue" select="concat('mode=', $mode)"/>
+<xsl:variable name="queryType" select="/result/query/type"/>
+<xsl:variable name="query" select="text:trim(string(/result/query/expression))"/>
+<xsl:variable name="queryResultPages" select="number(/result/query/result/pages)"/>
+<xsl:variable name="queryResultSize" select="number(/result/query/result/size)"/>
+<xsl:variable name="queryResultPN" select="/result/query/result/pn"/>
+<xsl:variable name="language" select="/result/document-description/language"/>
+<xsl:variable name="ftQueryTermsTemp" select="string-join(text:translateLuceneToTerms($query), '')" as="xs:string"/>
+<xsl:variable name="ftQueryMorphForms" select="string(/result/query/result/query-forms)"/>
+<!-- Removes the duplicates between ftQueryMorphForms and ftQueryTerms for highlighting them semantically correct: -->
+<!-- Morphological forms are hightlighted as whole words but query terms are highlighted also as partly strings -->
+<xsl:variable name="ftQueryTerms" select="text:removeDuplicates($ftQueryTermsTemp, $ftQueryMorphForms)"/> 
+<xsl:variable name="ftQueryRegularizations" select="string(/result/query/result/query-regularizations)"/>
+<xsl:variable name="ftQueryHighlightWords">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMorphForms != '' and $ftQueryRegularizations = ''"><xsl:value-of select="$ftQueryMorphForms"/></xsl:when>
+  <xsl:when test="$ftQueryMorphForms = '' and $ftQueryRegularizations != ''"><xsl:value-of select="$ftQueryRegularizations"/></xsl:when>
+  <xsl:when test="$ftQueryMorphForms != '' and $ftQueryRegularizations != ''"><xsl:value-of select="concat($ftQueryMorphForms, '|', $ftQueryRegularizations)"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="$ftQueryMorphForms"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryEncodeBig5" select="/result/query/result/big5-mappings"/>
+
+<xsl:template match="result">
+  <div class="queryResult">
+    <div class="queryResultHits" style="visibility:hidden">
+      <xsl:value-of  select="$queryResultSize"/>
+	</div>
+	<xsl:if test="(($query != '' or $queryType = 'toc' or $queryType = 'figures') and $queryResultPages &gt; 0)">
+      <xsl:if test="$ftQueryMorphForms != ''">
+        <div class="queryResultMorphExpansion">
+	      <xsl:if test="$queryType = 'fulltextMorph'">
+	        Morphological expansion: <a href="../lt/lemma.xql?language={$language}&amp;query={$query}">see here</a>
+	      </xsl:if>
+	      <xsl:if test="$queryType = 'fulltextMorphLemma'">
+	        Morphological expansion: <a href="../lt/lemma.xql?language={$language}&amp;lemma={$query}">see here</a>
+	      </xsl:if>
+	    </div>
+	  </xsl:if>
+      <div class="queryResultPage">
+	  <xsl:if test="$queryType = 'toc' or $queryType = 'figures'">
+	    <xsl:for-each select="/result/query/result/hits/toc-entry">
+	      <xsl:variable name="page" select="page"/>
+	      <xsl:variable name="level">
+	        <xsl:choose>
+	          <xsl:when test="real-level = '1'"><xsl:value-of select="'one'"/></xsl:when>
+	          <xsl:when test="real-level = '2'"><xsl:value-of select="'two'"/></xsl:when>
+	          <xsl:when test="real-level = '3'"><xsl:value-of select="'three'"/></xsl:when>
+	          <xsl:when test="real-level = '4'"><xsl:value-of select="'four'"/></xsl:when>
+	          <xsl:when test="real-level = '5'"><xsl:value-of select="'five'"/></xsl:when>
+	          <xsl:when test="real-level = '6'"><xsl:value-of select="'six'"/></xsl:when>
+	          <xsl:when test="real-level = '7'"><xsl:value-of select="'seven'"/></xsl:when>
+	          <xsl:otherwise><xsl:value-of select="'one'"/></xsl:otherwise>
+	        </xsl:choose>
+	      </xsl:variable>
+          <div class="toc {$level}">
+            <xsl:value-of select="'['"/>
+	        <xsl:value-of select="concat(level-string, ' ')"/>
+	        <xsl:value-of select="content"/>
+            <xsl:value-of select="']'"/>
+	      </div>
+	      <div class="toc float right">
+	        <a href="page-fragment.xql?{$documentValue}&amp;mode={$mode}&amp;pn={$page}">
+	          <xsl:value-of select="concat('Page: ', $page)"/>
+	        </a>
+	      </div>
+	    </xsl:for-each>
+	  </xsl:if>
+	  <xsl:if test="$queryType = 'fulltext' or $queryType = 'fulltextMorph' or $queryType = 'fulltextMorphLemma'">
+	  <xsl:for-each select="/result/query/result/hits/hit">
+	    <xsl:variable name="pos" select="pos"/>
+	    <xsl:variable name="term" select="term"/>
+	    <div class="queryResultPageHit">
+          <div class="queryResultPageHitLink">
+	        <xsl:value-of select="concat($pos, '.')"/>
+	        <xsl:variable name="hitPN" select="pn"/>
+	        <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+	        <xsl:variable name="sSurroundsPB" select="s-surrounds-pb"/>
+	        <xsl:variable name="queryValue" select="concat('&amp;', 'query=', $query)"/>
+	        <xsl:variable name="queryValueEscaped1" select="replace($queryValue, '\+', '%2B')"/>
+	        <xsl:variable name="queryValueEscaped2" select="replace($queryValueEscaped1, ' ', '+')"/>
+	        <xsl:choose>
+	        <!-- if a found sentence surrounds a page break then a special presentation of the hit is done -->
+	          <xsl:when test="$sSurroundsPB = 'false'">
+	            <a href="page-fragment.xql?{$documentValue}&amp;pn={$hitPN}&amp;sn={$hitPosOfS}&amp;{$modeValue}&amp;highlightQuery={$query}#sn{$hitPosOfS}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>
+	          </xsl:when>
+	          <xsl:otherwise>
+	            <a href="page-fragment.xql?{$documentValue}&amp;pn={$hitPN}&amp;sn={$hitPosOfS}&amp;{$modeValue}&amp;highlightQuery={$query}#sn{$hitPosOfS}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a> / <a href="page-fragment.xql?{$documentValue}&amp;pn={$hitPN + 1}&amp;sn=0&amp;{$modeValue}&amp;highlightQuery={$query}#sn0">Page <xsl:value-of select="$hitPN + 1"/>, continuation of the sentence</a>
+	          </xsl:otherwise>
+	        </xsl:choose>
+	        <xsl:value-of select="':'"/>
+	      </div>
+          <div class="queryResultPageHitContent">
+	        <!-- Highlight the query terms in each hit sentence and clip the result -->
+	        <xsl:sequence select="text:highlight(s, $ftQueryTerms, $ftQueryHighlightWords, 'true')"/>
+	      </div>
+	    </div>
+	  </xsl:for-each>
+	  </xsl:if>
+	  <xsl:if test="$queryType = 'ftIndex' or $queryType = 'ftIndexMorph'">
+	  <xsl:for-each select="/result/query/result/hits/entry">
+	    <xsl:variable name="pos" select="position"/>
+	    <xsl:variable name="term" select="term"/>
+	    <xsl:variable name="polluxKeys" select="pollux-keys"/>
+	    <xsl:variable name="lemmasWithOR" select="lemmas-with-or"/>
+	    <xsl:variable name="dictionaryLink">
+          <xsl:choose>
+	      <xsl:when test="$language = 'zh'">
+	      <xsl:variable name="termBig5Encoded" select="/result/query/result/big5-hits/entry-big5-encoded/term[$pos]"/>
+	      <a href="http://humanum.arts.cuhk.edu.hk/cgi-bin/agrep-lindict?query={$termBig5Encoded}&amp;category=wholerecord">Lin Yutang</a>
+	      </xsl:when>
+	      <xsl:otherwise><a href="http://archimedes.mpiwg-berlin.mpg.de/cgi-bin/toc/dict?step=table;word={$term};lang={$language};pro=echo">Echo</a></xsl:otherwise>
+	      </xsl:choose>
+	    </xsl:variable>
+	    <xsl:variable name="polluxLink">
+	      <xsl:choose>
+	      <xsl:when test="$polluxKeys = ''">Pollux</xsl:when>
+	      <xsl:otherwise><a href="../lt/lex.xql?language={$language}&amp;query={$polluxKeys}">Pollux</a></xsl:otherwise>
+	      </xsl:choose>
+	    </xsl:variable>
+	    <xsl:variable name="wikipediaLink">
+	      <xsl:choose>
+	      <xsl:when test="$lemmasWithOR = ''">Wiki</xsl:when>
+	      <xsl:otherwise><a href="http://{$language}.wikipedia.org/wiki/index.php?search={$lemmasWithOR}">Wiki</a></xsl:otherwise>
+	      </xsl:choose>
+	    </xsl:variable>
+	    <xsl:variable name="ftSearchQueryType">
+	      <xsl:choose>
+	      <xsl:when test="$queryType = 'ftIndex'"><xsl:value-of select="'fulltext'"/></xsl:when>
+	      <xsl:when test="$queryType = 'ftIndexMorph'"><xsl:value-of select="'fulltextMorphLemma'"/></xsl:when>
+	      <xsl:otherwise></xsl:otherwise>
+	      </xsl:choose>
+	    </xsl:variable>
+	    <div class="queryResultPageHit">
+          <xsl:value-of select="concat($pos, '.')"/>
+          <a href="../lt/lemma.xql?language={$language}&amp;lemma={$term}"><xsl:value-of select="$term"/></a>(<a href="?{$documentValue}&amp;{$modeValue}&amp;queryType={$ftSearchQueryType}&amp;query={$term}"><xsl:value-of select="frequency"/></a>) [<xsl:sequence select="$polluxLink"/>][<xsl:sequence select="$wikipediaLink"/>][<xsl:sequence select="$dictionaryLink"/>]
+        </div>    
+	  </xsl:for-each>
+	  </xsl:if>
+	  <xsl:if test="$queryType = 'xpath' or $queryType = 'xquery'">
+	    <xsl:for-each select="/result/query/result/hits">
+          <div class="queryResultPageHit">
+            <div class="queryResultPageHitContent">
+	          <xsl:apply-templates mode="xml"/>
+	        </div>
+            <div class="queryResultPageHitDownload">
+              <xsl:variable name="queryWithoutCRLF" select="replace($query, '\r\n', ' ')"/>
+              <a target="_blank" href="?{$documentValue}&amp;mode=pureXml&amp;queryType={$queryType}&amp;query={$queryWithoutCRLF}&amp;queryResultPN={$queryResultPN}"><img src="../images/download.png" width="24" height="24" border="0" alt="Download"/></a><xsl:value-of select="'Download'"/>
+            </div>
+          </div>
+	    </xsl:for-each>
+	  </xsl:if>
+	  </div>
+	</xsl:if>
+    <xsl:choose>
+      <xsl:when test="$errorMessage != ''">
+        <div class="query-result-page">
+          <b>Your query delivers an error: </b>
+          <xsl:value-of select="$errorMessage"/>
+        </div>
+      </xsl:when>
+      <xsl:when test="$errorMessage = '' and $query != '' and $queryResultPages = 0">
+        <div class="query-result-page">
+          <b>No results</b>
+        </div>
+      </xsl:when>
+    </xsl:choose>
+  </div>
+</xsl:template>
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()" mode="xml">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|comment()|processing-instruction()" mode="xml">
+  <xsl:variable name="elementName" select="name()"/>
+  <xsl:variable name="elementPresentation">
+    <xsl:choose>
+    <xsl:when test="element() = node() or text() != '' or self::comment() or self::processing-instruction()">
+      &lt;<span style="font-weight:bold;color:purple;"><xsl:value-of select="$elementName"/></span><xsl:apply-templates select="attribute()" mode="xml"/>&gt;<xsl:apply-templates select="element()|text()|comment()|processing-instruction()" mode="xml"/>&lt;/<span style="font-weight:bold;color:purple;"><xsl:value-of select="$elementName"/></span>&gt;
+    </xsl:when>
+    <xsl:otherwise>
+      &lt;<span style="font-weight:bold;color:purple;"><xsl:value-of select="$elementName"/></span><xsl:apply-templates select="attribute()" mode="xml"/>/&gt;
+    </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <ul style="margin-left:0px;padding-left:8px"><xsl:sequence select="$elementPresentation"/></ul>
+</xsl:template>
+
+<xsl:template match="attribute()" mode="xml">
+  <xsl:variable name="attributeName" select="name()"/><xsl:text> </xsl:text><b><xsl:value-of select="$attributeName"/></b>=&quot;<span style="color:blue;"><xsl:value-of select="."/></span>&quot;<xsl:apply-templates select="attribute()" mode="xml"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/query.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,241 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+
+let $attrQueryAuthor := "Monte"
+let $attrQueryTitle := "Mech*"
+let $ftQuery := "quantitas"
+let $ftMorphQuery := "quantitas"
+
+return
+<html>
+<head>
+<title>MPDL project</title>
+<script type="text/javascript">
+<!--
+function DateSelection() {
+  if (document.formAttrQueryResult.attribute1.selectedIndex == 3)
+    document.formAttrQueryResult.relOp1.selectedIndex = 0;
+  else 
+    document.formAttrQueryResult.relOp1.selectedIndex = 1;
+  if (document.formAttrQueryResult.attribute2.selectedIndex == 3)
+    document.formAttrQueryResult.relOp2.selectedIndex = 0;
+  else 
+    document.formAttrQueryResult.relOp2.selectedIndex = 1;
+}
+function EqualSelection() {
+  if (document.formAttrQueryResult.relOp1.selectedIndex == 0)
+    document.formAttrQueryResult.attribute1.selectedIndex = 3;
+  if (document.formAttrQueryResult.relOp1.selectedIndex == 1 && document.formAttrQueryResult.attribute1.selectedIndex == 3)
+    document.formAttrQueryResult.attribute1.selectedIndex = 0;
+  if (document.formAttrQueryResult.relOp2.selectedIndex == 0)
+    document.formAttrQueryResult.attribute2.selectedIndex = 3;
+  if (document.formAttrQueryResult.relOp2.selectedIndex == 1 && document.formAttrQueryResult.attribute2.selectedIndex == 3)
+    document.formAttrQueryResult.attribute2.selectedIndex = 0;
+}
+function checkCR(event) {
+  var keyCode = event.keyCode
+  if (keyCode == 13)
+    return false;
+}
+
+-->
+</script>
+</head>
+<body>
+  <form name="formAttrQueryResult" action="attribute-query-result.xql" method="get">
+  <input type="hidden" name="query-type" value="none" id="ietype"/>
+  <table height="60px">
+    <colgroup>
+      <col width="50%"/>
+      <col width="30%"/>
+      <col width="10%"/>
+      <col width="10%"/>
+    </colgroup>
+    <tr>
+    <td align="left" valign="top">
+      <text style="font-weight:bold;font-size:30px">MPDL prototype <a href="info.xql?info=mpdl" onclick="window.open(&quot;info.xql?info=mpdl&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" valign="bottom" width="18" height="18" border="0" alt="Info MPDL"/></a></text>
+    </td>
+    <td align="left" valign="top">
+      <a href="info.xql?info=malcolm" onclick="window.open(&quot;info.xql?info=malcolm&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false">Dedicated to Dr. Malcolm Hyman</a><br/><text style="margin-left:20px;"></text>† September 4, 2009
+    </td>
+    <td align="left" valign="top">
+      <a href="http://exist-db.org"><img alt="powered by eXist" align="right" border="0" src="/resources/powered.gif"/></a>
+    </td>
+    <td align="left" valign="top">
+      <a href="http://atomic.exist-db.org/blogs/eXist/?id=urn:uuid:e17b7bb6-596e-4d8b-ab35-90bf5fef8884">Release 1.4<br/>
+      Nov, 2009</a>
+    </td>
+    </tr>
+  </table>
+  <hr/>
+  <table>
+    <tr>
+    <td valign="top" height="60px">
+      <table>
+      <tr>
+        <td valign="top"><b>Documents:</b></td>
+        <td>
+          <text style="margin-left:15px;">Archimedes DTD</text><br/>
+          <text style="margin-left:15px;">(until 2008)</text>
+        </td>
+        <td valign="top">
+          <text style="margin-left:1px;"></text><input type="checkbox" name="docbase" value="archimedes" checked="checked"/>
+        </td>
+        <td>
+          <text style="margin-left:20px;">Echo Schema</text><br/>
+          <text style="margin-left:20px;">(since 2009)</text>
+        </td>
+        <td valign="top">
+          <text style="margin-left:1px;"></text><input type="checkbox" name="docbase" value="echo" checked="checked"/>
+        </td>
+        <td valign="top"><text style="margin-left:40px;"></text><button type="submit" name="browseQuery" onclick="document.getElementById('ietype').value='browse';">Browse</button></td>
+        <td valign="top"><a href="info.xql?info=docBases" onclick="window.open(&quot;info.xql?info=docBases&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" valign="bottom" width="15" height="15" border="0" alt="Info Document bases"/></a></td>
+      </tr>
+      <tr>
+      </tr>
+      </table> 
+    </td>
+    </tr>
+
+    <tr>
+    <td valign="top" height="110px">
+      <table>
+      <tr>
+      <td>
+      <select name="attribute1" onchange="DateSelection()">
+      <option value ="author" selected="true">Author</option>
+      <option value ="title">Title</option>
+      <option value ="place">Place</option>
+      <option value ="date">Year</option>
+      <option value ="language">Language</option>
+      <option value ="identifier">Identifier/Locator</option>
+      <option disabled="disabled">--Echo--</option>
+      <option value ="rights">Rights</option>
+      <option value ="license">License</option>
+      <option value ="accessRights">Access rights</option>
+      <option disabled="disabled">--Archimedes--</option>
+      <option value ="file">File name</option>
+      <option value ="translator">Translator</option>
+      <option value ="version">Version</option>
+      </select>          
+      </td>
+      <td>
+      <select name="relOp1" onchange="EqualSelection()">
+      <option value ="equal"> = </option>
+      <option value ="contains" selected="true">contains</option>
+      </select>          
+      </td>
+      <td>
+      <input type="text" size="40" name="attr-query1" value="{$attrQueryAuthor}" onkeypress="return checkCR(event)"/>
+      <button type="submit" name="attributeQuery" onclick="document.getElementById('ietype').value='attribute';">Query</button>
+      <a href="info.xql?info=attr" onclick="window.open(&quot;info.xql?info=attr&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" valign="bottom" width="15" height="15" border="0" alt="Info Attribute search"/></a>
+      </td>
+      </tr>
+
+      <tr>
+      <td>
+      <table>
+      <tr>
+      <td>
+      <text style="margin-left:10px;"></text>
+      </td>
+      <td>
+      <select name="boolOp">
+      <option value ="and" selected="true">and</option>
+      <option value ="or">or</option>
+      <option value ="andNot">and not</option>
+      </select>          
+      </td>
+      </tr>
+      </table>
+      </td>
+      </tr>
+
+      <tr>
+      <td>
+      <select name="attribute2" onchange="DateSelection()">
+      <option value ="author">Author</option>
+      <option value ="title" selected="true">Title</option>
+      <option value ="place">Place</option>
+      <option value ="date">Year</option>
+      <option value ="language">Language</option>
+      <option value ="identifier">Identifier/Locator</option>
+      <option disabled="disabled">--Echo--</option>
+      <option value ="rights">Rights</option>
+      <option value ="license">License</option>
+      <option value ="accessRights">Access rights</option>
+      <option disabled="disabled">--Archimedes--</option>
+      <option value ="file">File name</option>
+      <option value ="translator">Translator</option>
+      <option value ="version">Version</option>
+      </select>          
+      </td>
+      <td>
+      <select name="relOp2" onchange="EqualSelection()">
+      <option value ="equal"> = </option>
+      <option value ="contains" selected="true">contains</option>
+      </select>          
+      </td>
+      <td>
+      <input type="text" size="40" name="attr-query2" value="{$attrQueryTitle}" onkeypress="return checkCR(event)"/>
+      </td>
+      </tr>
+      </table>
+    </td>
+    <td/>
+    </tr>
+    
+    <tr>
+    <td valign="top" height="50px">
+      <table>
+        <tr>
+        <td>
+        Document contains <input type="text" size="40" name="ft-query" value="{$ftQuery}" onkeypress="return checkCR(event)"/>
+        <button type="submit" name="fulltextQuery" onclick="document.getElementById('ietype').value='fulltext';">Query</button>
+        </td>
+        <td>
+        <a href="info.xql?info=fulltext" onclick="window.open(&quot;info.xql?info=fulltext&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" valign="bottom" width="15" height="15" border="0" alt="Info fulltext search"/></a>
+        </td>
+        </tr>
+      </table>
+    </td>
+    </tr>
+    
+    <tr>
+    <td valign="top" height="50px">
+      <table>
+        <tr>
+        <td>
+        Document contains morphological <input type="text" size="40" name="ft-morph-query" value="{$ftMorphQuery}" onkeypress="return checkCR(event)"/>
+        <select name="language">
+        <option value ="ar">Arabic</option>
+        <option value ="zh">Chinese</option>
+        <option value ="nl">Dutch</option>
+        <option value ="en">English</option>
+        <option value ="fr">French</option>
+        <option value ="de">German</option>
+        <option value ="el">Greek</option>
+        <option value ="it">Italian</option>
+        <option value ="la" selected="true">Latin</option>
+        </select>
+        <button type="submit" name="fulltextMorphQuery" onclick="document.getElementById('ietype').value='fulltextMorph';">Query</button>
+        </td>
+        <td valign="bottom">
+        <a href="info.xql?info=fulltextMorph" onclick="window.open(&quot;info.xql?info=fulltextMorph&quot;, &quot;InfoWindow&quot;, &quot;menubar=no,width=500,height=500,toolbar=no&quot;);return false"><img src="images/info.png" width="15" height="15" border="0" alt="Info morphological search"/></a>
+        </td>
+        </tr>
+        <input type="hidden" name="order-by" value="author"/>
+        <input type="hidden" name="pn" value="1"/>
+      </table>
+    </td>
+    </tr>
+
+  </table> 
+  <hr/>
+  <p/>
+  See the <a href="/exist/xquery.xml">eXist XQuery documentation</a> and the <a href="query.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+  <br/>Last MPDL software update: January, 2011
+</form>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/scheduler/get-jobs.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,91 @@
+xquery version "1.0";
+
+declare namespace request="http://exist-db.org/xquery/request";
+declare namespace util = "http://exist-db.org/xquery/util";
+
+let $jobId := request:get-parameter("id", "all")
+
+let $result := mpdldoc:get-jobs($jobId)
+
+let $resultHtml := 
+  for $operation in $result//mpdl-doc-operation
+    let $operationName := $operation/name
+    let $jobId := $operation/job-id
+    let $srcUrl := $operation/src/url
+    let $source :=
+      if ($operationName = 'delete')
+      then ()
+      else if (starts-with($srcUrl, 'file:'))
+      then
+        <bla> 
+          <b>Source</b>
+          <ul>
+            <li><b>Upload file name:</b> {$operation/src/upload-file-name}</li>
+          </ul>
+        </bla>
+      else
+        <bla> 
+          <b>Source</b>
+          <ul>
+            <li><b>Url:</b> {$operation/src/url}</li>
+          </ul>
+        </bla>
+    let $destUrl :=
+      if ($operationName = 'create' or $operationName = 'update')
+      then
+        <bla>
+        <li><b>Link to eSciDoc:</b> <a href="{$operation/dest/escidoc-url}">{$operation/dest/escidoc-url}</a></li>
+        <li><b>Link to eXist:</b> <a href="{$operation/dest/exist-url}">{$operation/dest/exist-url}</a></li>
+        </bla>
+      else if ($operationName = 'updateExist')
+      then
+        <bla>
+        <li><b>Link to eXist:</b> <a href="{$operation/dest/exist-url}">{$operation/dest/exist-url}</a></li>
+        </bla>
+      else ()
+    let $errorMessage := $operation/status/error-message
+    let $errorLIEntry := 
+      if ($errorMessage = 'no error')
+      then <li><b>Error:</b> {$errorMessage}</li>
+      else <li><font color="#FF0000"><b>Error:</b></font> {$errorMessage}</li>
+    let $operationHtmlTableData :=
+      <bla>
+        <tr><td>
+        <b>Refresh:</b> <a href="?id={$jobId}">operation status</a><p/>
+        <b>Operation:</b> {$operation/name}<p/>
+        <b>Job-Id:</b> {$operation/job-id}<p/>
+        <b>Job status</b>
+          <ul>
+          <li><b>Started:</b> {$operation/status/started}</li>
+          <li><b>Finished:</b> {$operation/status/finished}</li>
+          <li><b>Description:</b> {$operation/status/description}</li>
+          {$errorLIEntry}
+        </ul>
+        {$source}
+        <b>Destination</b>
+          <ul>
+            <li><b>Document base:</b> {$operation/dest/doc-base}</li>
+            <li><b>Language:</b> {$operation/dest/language}</li>
+            <li><b>Document name:</b> {$operation/dest/file-name}</li>
+            {$destUrl}
+          </ul>
+        <b>Description:</b> {$operation/description}<p/>
+        <hr/>
+        </td></tr>
+      </bla>  
+  return <bla>{$operationHtmlTableData}</bla>
+
+let $title := "Document operation status"
+return 
+<html>
+<head>
+<title>{$title}</title>
+</head>
+<body>
+  <h1>{$title}</h1>
+  <table>
+  {$resultHtml}
+  </table>
+  See the <a href="get-jobs.xql?_source=yes">XQuery source</a> of this page, if you find a bug <a href="https://itgroup.mpiwg-berlin.mpg.de:8080/tracs/mpdl-project-software/newticket">let us know</a>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/sitemap.xml	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=1</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=2</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=3</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=4</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=5</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=6</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=7</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=8</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=9</loc></url>
+<url><loc>http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/page-query-result.xql?document=/echo/la/Alvarus_1509.xml&amp;mode=text&amp;pn=10</loc></url>
+</urlset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/text/all.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,333 @@
+xquery version "1.0";
+
+module namespace mpdl-text = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/text"; 
+
+import module namespace functx = "http://www.functx.com" at "../util/functx.xql";
+
+declare namespace text = "http://exist-db.org/xquery/text";
+declare namespace util = "http://exist-db.org/xquery/util";
+declare namespace local = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/local";
+
+declare namespace echo="http://www.mpiwg-berlin.mpg.de/ns/echo/1.0/";
+declare namespace dcterms="http://purl.org/dc/terms";
+
+declare function mpdl-text:insertNodeIdAttribute($element as element()) {
+  element {node-name($element)}
+    {$element/@*, attribute { "xmlNodeId" } { util:node-id($element) },
+     for $child at $pos in $element/node()
+        return if ($child instance of element())
+          then mpdl-text:insertNodeIdAttribute($child)
+          else $child
+    }
+};
+
+declare function mpdl-text:insertMyNodeIdAttribute($element as element()) {
+  mpdl-text:insertMyNodeIdAttribute($element, "1")
+};
+declare function mpdl-text:insertMyNodeIdAttribute($element as element(), $myNodeId as xs:string) {
+  element {node-name($element)}
+    {$element/@*, attribute { "xmlNodeId" } { $myNodeId },
+     for $child at $pos in $element/node()
+        return 
+          if ($child instance of element())
+          then mpdl-text:insertMyNodeIdAttribute($child, concat($myNodeId, ".", $pos))
+          else $child
+    }
+};
+
+declare function mpdl-text:insert($fragment as element(), $externalObjects as element()*) {
+  let $firstObject := $externalObjects[1]
+  let $xmlNodeId := $firstObject/@xmlNodeId
+  let $posNode := $fragment//*[@xmlNodeId = $xmlNodeId]
+  let $before := $firstObject/@before
+  let $boolBefore := 
+    if ($before = "true")
+    then true()
+    else false()
+  let $charPosStr := $firstObject/@charPos
+  let $charPos := 
+    if($charPosStr != "" and not(empty($charPosStr)))
+    then number($charPosStr)
+    else -1
+  let $newNode := $firstObject/content
+  let $size := count($externalObjects)
+  let $otherObjects := 
+    if ($size > 1) 
+    then subsequence($externalObjects, 2, $size)
+    else ()
+  let $insertedFragment := mpdl-text:insert($fragment, $posNode, $boolBefore, $charPos, $newNode)
+  let $result :=
+    if ($size >= 1)
+    then
+      mpdl-text:insert($insertedFragment, $otherObjects)
+    else
+      $fragment
+    return $result
+};
+
+declare function mpdl-text:insert($element as element(), $node, $before, $charPos, $newNode) {
+  if ($element = $node and $before and $charPos = -1)
+  then
+  ($newNode,
+  element {node-name($node)}
+    {$node/@*,
+     for $child in $node/node()
+        return if ($child instance of element())
+          then mpdl-text:insert($child, $node, $before, $charPos, $newNode)
+          else $child
+    })
+  else if ($element = $node and not($before) and $charPos = -1)
+  then
+  (element {node-name($node)}
+    {$node/@*,
+     for $child in $node/node()
+        return if ($child instance of element())
+          then mpdl-text:insert($child, $node, $before, $charPos, $newNode)
+          else $child
+    }, $newNode)
+  else if ($element = $node and $charPos >= 0)
+  then
+    util:parse(mpdltext:insertAtCharPos(util:serialize($node, ()), util:serialize($newNode, ()), $charPos))
+  else
+  element {node-name($element)}
+    {$element/@*,
+     for $child in $element/node()
+        return if ($child instance of element())
+          then mpdl-text:insert($child, $node, $before, $charPos, $newNode)
+          else $child
+    }
+};
+
+declare function mpdl-text:indexTerms($mpdlCollectionName, $language, $document, $indexTermsStartStr, $pn as xs:int, $pageSize as xs:int) as node()* {
+  let $index := 
+    if ($mpdlCollectionName = 'archimedes')
+    then $document/archimedes/text
+    else if ($mpdlCollectionName = 'echo') 
+    then $document/echo:echo/echo:text 
+    else $document/archimedes/text
+  let $from := ($pn * $pageSize) - $pageSize + 1
+  let $to := $pn * $pageSize
+  let $maxTo := 10000
+  let $callback := util:function(QName("http://www.mpiwg-berlin.mpg.de/ns/mpdl/local", "local:termEntries"), 2)
+  let $indexResult := text:index-terms($index, $indexTermsStartStr, $callback, $maxTo)
+  let $count := count($indexResult)
+  let $pages := 
+    if ($count = 0)
+    then 0
+    else $count idiv $pageSize + 1
+  let $withPolluxKeys := 'true'
+  let $resultEntries := 
+    for $entry at $pos in $indexResult
+      let $term := $entry/term
+      let $lexEntryKeys := 
+        if ($withPolluxKeys = 'true')
+        then mpdltext:get-lex-entry-keys-by-form-name($language, $term)
+        else ''
+      let $lemmasWithOR := mpdltext:get-lemmasstr-by-form-name($language, $term)
+    where $pos >= $from and $pos <= $to
+    return 
+      <entry>
+        <term>{$entry/term}</term>
+        <pollux-keys>{$lexEntryKeys}</pollux-keys>
+        <lemmas-with-or>{$lemmasWithOR}</lemmas-with-or>
+        <frequency>{$entry/frequency}</frequency>  
+        <documents>{$entry/documents}</documents>  
+        <position>{$entry/position}</position>  
+        <rank>{$entry/rank}</rank>  
+      </entry>
+  let $callbackBig5 := 
+    if ($language = "zh")
+    then util:function(QName("http://www.mpiwg-berlin.mpg.de/ns/mpdl/local", "local:termEntriesInBig5"), 2)
+    else ()
+  let $indexResultBig5 := 
+    if ($language = "zh")
+    then text:index-terms($index, $indexTermsStartStr, $callbackBig5, $maxTo)
+    else ()
+  let $resultEntriesBig5 := 
+    if ($language = "zh")
+    then 
+      for $entry at $pos in $indexResultBig5
+      where $pos >= $from and $pos <= $to
+      return $entry
+    else ()
+
+  let $result :=
+      <result>
+        <size>{$count}</size>
+        <page-size>{$pageSize}</page-size>
+        <pages>{$pages}</pages>
+        <pn>{$pn}</pn>
+        <hits>{$resultEntries}</hits>
+        <big5-hits>{$resultEntriesBig5}</big5-hits>
+      </result>
+  return $result
+};
+
+declare function local:termEntries($term as xs:string, $data as xs:int+) {
+  let $result := 
+    <entry>  
+       <term>{$term}</term>  
+       <frequency>{$data[1]}</frequency>  
+       <documents>{$data[2]}</documents>  
+       <position>{$data[3]}</position>  
+       <rank>{$data[4]}</rank>  
+     </entry>  
+  return $result
+};
+
+declare function local:termEntriesInBig5($term as xs:string, $data as xs:int+) {
+  let $encodedTerm := mpdltext:encode-big5($term)
+  let $result := 
+    <entry-big5-encoded>  
+       <term>{$encodedTerm}</term>  
+     </entry-big5-encoded>  
+  return $result
+};
+
+declare function mpdl-text:get-toc($docBase, $queryType, $document, $pn as xs:int, $pageSize as xs:int) {
+  let $from := ($pn * $pageSize) - $pageSize + 1
+  let $to := $pn * $pageSize
+  let $tocEntriesAll := 
+    if ($docBase = 'echo' and $queryType = 'toc')
+    then $document//echo:div[@type = 'section' or @type = 'chapter']
+    else if ($docBase = 'echo' and $queryType = 'figures')
+    then $document//echo:figure
+    else if ($docBase = 'archimedes' and $queryType = 'figures') 
+    then $document//figure
+    else ()
+  let $tocEntriesAllTmp := 
+    for $entry at $pos in $tocEntriesAll
+      let $pb := 
+        if ($docBase = 'echo')
+        then $entry/preceding::echo:pb[1]
+        else $entry/preceding::pb[1]
+      let $pageNum := 
+        if ($docBase = 'echo')
+        then count($pb/preceding::echo:pb) + 1
+        else count($pb/preceding::pb) + 1
+      let $level := 
+        if ($queryType = 'toc')
+        then number($entry/@level)
+        else 1
+      let $figureCaption := 
+        if ($docBase = 'echo' and $queryType = 'figures' and not(empty($entry/echo:caption)))
+        then concat(': ', string-join($entry/echo:caption/text(), ' '))
+        else ''
+      let $figureDescription := 
+        if ($docBase = 'echo' and $queryType = 'figures' and not(empty($entry/echo:description)))
+        then concat(': ', string-join($entry/echo:description/text(), ' '))
+        else ''
+      let $figureVariables := 
+        if ($docBase = 'echo' and $queryType = 'figures' and not(empty($entry/echo:variables)))
+        then concat(' (Variables: ', string-join($entry/echo:variables/text(), ' '), ')')
+        else ''
+      let $figureAllDesc :=
+        if ($docBase = 'echo' and $queryType = 'figures')
+        then concat($figureCaption, $figureDescription, $figureVariables)
+        else ''
+      let $content := 
+        if ($docBase = 'echo' and $queryType = 'toc')
+        then string-join($entry/echo:head, ' ')
+        else if ($queryType = 'figures')
+        then concat('Figure', $figureAllDesc)
+        else ()
+    return
+      <toc-entry> 
+        <page>{$pageNum}</page>
+        <level>{$level}</level>
+        <content>{$content}</content>
+      </toc-entry>
+  let $tocEntriesAllTmpWithLevels := mpdltext:generate-toc-levels($tocEntriesAllTmp)/toc-entries/toc-entry
+  let $tocEntries := 
+    for $entry at $pos in $tocEntriesAllTmpWithLevels
+    where $pos >= $from and $pos <= $to
+    return $entry
+  let $size := count($tocEntriesAll)
+  let $pages := 
+    if ($size = 0)
+    then 0
+    else $size idiv $pageSize + 1
+  let $result := 
+      <result>
+        <size>{$size}</size>
+        <page-size>{$pageSize}</page-size>
+        <pages>{$pages}</pages>
+        <pn>{$pn}</pn>
+        <hits>{$tocEntries}</hits>
+      </result>  
+  return $result
+};
+
+declare function mpdl-text:getEchoArchivePath($mpdlDocUri) {
+  let $documentName := substring-before(substring-after(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/"), ".")
+  let $language := substring-before(substring-after(substring-after($mpdlDocUri, "/"), "/"), "/")
+  let $docbase := substring-before(substring-after($mpdlDocUri, "/"), "/")
+  let $fullDocumentUri := concat('/db/mpdl/documents/standard', $mpdlDocUri)
+  let $document := doc($fullDocumentUri)
+  let $metadata := 
+    if ($docbase = 'archimedes')
+    then $document/archimedes/info
+    else if ($docbase = 'echo')
+    then $document/echo:echo/echo:metadata
+    else ''
+  let $documentIdentifier :=
+    if ($docbase = 'archimedes')
+    then $metadata/locator
+    else if ($docbase = 'echo')
+    then $metadata/dcterms:identifier
+    else $metadata/dcterms:identifier
+  let $echoDocIdentifier := 
+    if ($documentIdentifier != '') 
+    then substring-before(substring-after($documentIdentifier, "ECHO:"), ".")
+    else ''
+  let $nausikaaURLTexter := "http://nausikaa2.mpiwg-berlin.mpg.de/digitallibrary/servlet/Texter"
+  let $echoImageDir := 
+    if ($docbase = 'archimedes')
+    then string($metadata/echodir)
+    else if ($docbase = 'echo')
+    then string($metadata/echo:echodir)
+    else ''
+  let $imagesDocDirectory :=
+    if ($echoImageDir != '')
+    then $echoImageDir
+    else if ($docbase = 'archimedes')
+    then concat("/permanent/archimedes/", $documentName)
+    else if ($docbase = 'echo')
+    then concat("/permanent/library/", $echoDocIdentifier)
+    else ''
+  let $imagesDocDirectoryIndexMetaUrl  := concat($nausikaaURLTexter, "?fn=", $imagesDocDirectory, "/index.meta")
+  let $digilibAvailable := mpdldoc:check-uri($imagesDocDirectoryIndexMetaUrl, 2000)
+  let $imagesDocDirectoryIndexMeta := 
+    if ($digilibAvailable)
+    then doc($imagesDocDirectoryIndexMetaUrl)
+    else "XXXXDigilibNotAvailableXXXX"
+  let $archivePath := 
+    if ($digilibAvailable)
+    then string($imagesDocDirectoryIndexMeta/resource/archive-path)
+    else $imagesDocDirectoryIndexMeta
+  return $archivePath
+};
+
+declare function mpdl-text:transform($inputXml, $xslFileName) {
+  let $pageXslDoc := doc($xslFileName)
+  let $result := transform:transform($inputXml, $pageXslDoc, ())
+  return $result
+};
+
+declare function mpdl-text:html2pdf($language, $inputXml, $xslFileName, $title, $pageNumber, $mode) {
+  let $pageXslDoc := doc($xslFileName)
+  let $htmlPageFragment := transform:transform($inputXml, $pageXslDoc, ())
+  let $topLeftStr := $title
+  let $topRightStr := concat("Page ", $pageNumber, " (&quot; counter(page) &quot;)")
+  let $bottomLeftStr := concat("View mode: ", $mode)
+  let $currentTime := current-dateTime()
+  let $year := year-from-dateTime($currentTime)
+  let $month := month-from-dateTime($currentTime)
+  let $day := day-from-dateTime($currentTime)
+  let $hours := hours-from-dateTime($currentTime)
+  let $minutes := minutes-from-dateTime($currentTime)
+  let $dateStr := concat("", $day, ".", $month, ".", $year, " ", $hours, ":", $minutes)
+  let $bottomRightStr := $dateStr
+  let $pdfResult := mpdldoc:html2pdf($htmlPageFragment, $language, $topLeftStr, $topRightStr, $bottomLeftStr, $bottomRightStr) 
+  return $pdfResult	
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/util/functx.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,62 @@
+xquery version "1.0";
+
+module namespace functx = "http://www.functx.com"; 
+
+declare function functx:path-to-node-with-pos( $node as node()? )  as xs:string {
+  string-join(
+    for $ancestor in $node/ancestor-or-self::*
+      let $sibsOfSameName := $ancestor/../*[name() = name($ancestor)]
+    return 
+      concat(name($ancestor),
+        if (count($sibsOfSameName) <= 1)
+        then ''
+        else concat('[', functx:index-of-node($sibsOfSameName, $ancestor),']'))
+      , '/')
+ };
+ 
+declare function functx:index-of-node( $nodes as node()*, $nodeToFind as node() ) as xs:integer* {
+  for $seq in (1 to count($nodes))
+  return $seq[$nodes[$seq] is $nodeToFind]
+};
+ 
+declare function functx:substring-before-last( $arg as xs:string?, $delim as xs:string ) as xs:string {
+  if (matches($arg, functx:escape-for-regex($delim)))
+  then replace($arg,
+           concat('^(.*)', functx:escape-for-regex($delim),'.*'),
+           '$1')
+  else ''
+};
+
+declare function functx:substring-after-last( $arg as xs:string?, $delim as xs:string ) as xs:string {
+  replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
+};
+
+declare function functx:escape-for-regex( $arg as xs:string? ) as xs:string {
+  replace($arg,
+           '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
+};
+
+declare function functx:trim($arg as xs:string?) as xs:string {
+  replace(replace($arg,'\s+$',''),'^\s+','')
+};
+ 
+ declare function functx:value-intersect 
+  ( $arg1 as xs:anyAtomicType* ,
+    $arg2 as xs:anyAtomicType* )  as xs:anyAtomicType* {
+       
+  distinct-values($arg1[.=$arg2])
+};
+
+declare function functx:value-except 
+  ( $arg1 as xs:anyAtomicType* ,
+    $arg2 as xs:anyAtomicType* )  as xs:anyAtomicType* {
+       
+  distinct-values($arg1[not(.=$arg2)])
+};
+
+declare function functx:value-union 
+  ( $arg1 as xs:anyAtomicType* ,
+    $arg2 as xs:anyAtomicType* )  as xs:anyAtomicType* {
+       
+  distinct-values(($arg1, $arg2))
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/util/time.xql	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,7 @@
+xquery version "1.0";
+
+module namespace mpdl-time = "http://www.mpiwg-berlin.mpg.de/ns/mpdl/util/time"; 
+
+declare function mpdl-time:duration-as-ms($t) {
+  round((minutes-from-duration($t) * 60 + seconds-from-duration($t)) * 1000 )
+};