XQuery/Alphabet Poster

This toy programme creates alphabet posters using images from Wikipedia, located via dbpedia.

It is described in a blog entry

Script

edit
(:  
  This script  creates a picture alphabet based on a list of words.  
  The pictures are from wikipedia, found via dbpedia.
  
  This was created for  Charlie Taylor (age 5 ) for his animal alphabet.
  
  @parameter  title - The title string for the poster 
  @parameter  alphabet - list of comma-separated word , unordered
  @parameter cols - the number of columns in the table layout
  @parameter  action : poster - generate the poster, editor generate the editor for the data
  @author Chris Wallace
  @date 2008-10-22
  
:)
declare namespace r = "http://www.w3.org/2005/sparql-results#";

declare variable $alphabet := request:get-parameter("alphabet","Ant,Bat");
declare variable $words := tokenize(normalize-space($alphabet)," *, *");
declare variable $title := request:get-parameter("title","Charlie's Animal  Alphabet");
declare variable $cols := xs:integer(request:get-parameter("cols",4));
declare variable $action := request:get-parameter("action","edit");

declare variable  $query := "
PREFIX : <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE { 
      :Hedgehog  foaf:depiction ?img.
   }
";

declare function local:execute-sparql($query as xs:string)  {
  let $sparql := concat("http://dbpedia.org/sparql?format=xml&amp;default-graph-uri=http://dbpedia.org&amp;query=",
                               encode-for-uri($query)
                           )
  return  doc($sparql)
};


declare function local:picture($animal as xs:string )  as xs:string {
 let $queryx := replace($query,"Hedgehog",replace($animal," ","_"))
 let $result:= local:execute-sparql($queryx)
 return string($result//r:result[1]//r:uri)
};

declare function local:cell ($animal as xs:string , $picture as xs:string) as element(td) {
 let $letter := substring($animal,1,1)
 return 
     <td class="cell" valign="top">
            <span class="letter">{$letter} </span>
             is for 
              <div>
            <a href="http://en.wikipedia.org/wiki/{$animal}">
           <img src="{$picture}"  
                alt="{$animal}" 
                title="{$animal}" 
                border="0"
            />   
           </a>
           </div>
           <span class="word">
                {$animal}
            </span>
      </td>

};

declare function local:poster() as element(div) {
    <div>
      <h1>{$title}  </h1>
      {let $letters := 
         for $animal in $words
         let $picture := local:picture($animal)
         order by $animal
         return 
             local:cell($animal,$picture)
       let $nrows := xs:integer(ceiling(count($letters) div $cols))
       return
         <table>
           {for $row in (1 to $nrows)
            return
             <tr>
                {for $col in (1 to $cols)
                 let $letter := $letters[position()= ($row - 1 ) * $cols + $col]
                 return
                   if ($letter) 
                   then $letter
                   else <td> </td>
                }
             </tr>
            }
         </table>
       }
    </div>
  };
  
declare function local:editor() as element(form) {
<form action="alphabet.xq" method="get">
   <input type="hidden" name="action" value="poster"/>
   <div> <label for="title">Title of Alphabet</label><input type="text" name="title" value="{$title}"size="50"/></div>
   <div> <label for="cols">Number of Columns</label><input type="text" name="cols" value="{$cols}"size="2"/></div>
   <div> <label for="alphabet">Alphabet words, unordered, separated by  ,  </label>
   <br/>
   <textarea name="alphabet" cols="80" rows="5">
   {$alphabet}
   </textarea>
   </div>
   <input type="submit" value="Create Alphabet Poster"/>
</form>
};

declare option exist:serialize "method=xhtml media-type=text/html";

<html>
   <head>
       <title>Alphabet Poster - {$action}</title>
       <style>
        <![CDATA[
         body {font-family:Comic Sans MS;}
         div.cell {margin: 0 5px 10px 0; }
         span.letter  {font-size:200%;}
         span.word {display:none;}
         ]]>
       </style>
       <style media="print">
       <![CDATA[
         .nav {display:none}
         span.word {display:block; font-size:120%;font-family:Comic Sans MS; }
         ]]>
       </style>
   </head>
   <body>
  {
if ($action = "poster")
then (<span class="nav"><a href="alphabet.xq?alphabet={string-join($words,", ")}&amp;title={$title}&amp;cols={$cols}&amp;action=edit"> [edit]</a></span> ,
           local:poster()
          )
else  if ($action="edit")
then local:editor()
else ()
 }
  </body>
</html>