跳轉到內容

XQuery/幻燈片

來自華夏公益教科書

儘管微軟 PowerPoint 已經存在 20 年,並且多年來不斷改進,但它仍然是普遍使用的簡報軟體。它提供了廣泛的功能,但我們大多數人只是用它來製作簡單的文字幻燈片,也許還會新增一些動畫。

但是,Powerpoint 並沒有將簡報的內容與其演示方式(如幻燈片、列印形式以及索引)和外觀(樣式、顏色)乾淨地分離,它是一個昂貴的專有產品,並且對於許多工來說過於臃腫。因此,使用簡單的 XML 工具來提供類似的功能具有價值。

現有技術

[編輯 | 編輯原始碼]

使用 XML 技術提供輕量級、非專有的簡報軟體有很多方法。這些方法通常依賴於 Web 瀏覽器作為渲染引擎(這是一個在 1984 年 Richard Gaskins 無法選擇的設計選擇)。核心問題是將簡報劃分為單獨的幻燈片以及支援幻燈片序列中的導航。

  • Slidy by Dave Raggett - SlidyXML, XSLT, Javascript
  • S5 by Eric Meyer
  • DocBook by Norman Walsh - DocBook, XSLT
  • [1] DocBook, CSS, Opera 演示模式

該專案使用 XQuery 作為伺服器端語言。

演示格式

[編輯 | 編輯原始碼]

其他方法使用定義的詞彙表,但這裡選擇使用 XHTML 以及一些額外的標記來定義幻燈片邊界和幻燈片放映屬性。這提供了廣泛的功能,例如格式化、連結、影像、嵌入式影片。

<ss:slideshow xmlns="http://www.w3.org/1999/xhtml" xmlns:ss="http://www.cems.uwe.ac.uk/xmlwiki/slideshow">
    <ss:css>
        <ss:slide>slide.css</ss:slide>
        <ss:print/>
    </ss:css>
    <ss:header>DSA 2008 - Lecture 1 - Chris Wallace</ss:header>
    <ss:footer/>  
    <ss:slide>
        <h1>Teaching approach</h1>
        <ul>
            <li>1 lecture a week 
                <ul>
                    <li>Interaction using SMS whiteboard and Multi-choice cube</li>
                </ul>
            </li>
            <li>1 2-hour workshop every 2 weeks - write down the weeks you have been allocated</li>
            <li>2 hour Research time every 2 weeks (alternating with the workshops) - independent
                    study with tutor support </li>
            <li>Teaching resources in UWEOnline and in the <a href="https://www.cems.uwe.ac.uk/studentwiki/index.php/UFIEKG-20-2/2008">studentWiki</a>
            </li>
        </ul>
    </ss:slide>
...

在這裡,我使用了兩個名稱空間:預設的是幻燈片主體中使用的 XHTML,ss 名稱空間用於幻燈片放映元素,這些元素定義了幻燈片放映屬性、母版幻燈片和幻燈片邊界。

這是一個非常簡化的格式,將來會擴充套件。

指令碼

[編輯 | 編輯原始碼]

定義幻燈片放映內容的 XML 文件需要被轉換為投影的幻燈片以及列印格式。在此實現中,這兩個版本都是從同一個指令碼生成的。

名稱空間

[編輯 | 編輯原始碼]

必須宣告兩個名稱空間 - 用於預設 XHTML 名稱空間的任意字首。

declare namespace ss= "http://www.cems.uwe.ac.uk/xmlwiki/slideshow";
declare namespace h = "http://www.w3.org/1999/xhtml" ;

幻燈片引數是幻燈片放映文件的 URI(無論是資料庫文件還是外部文件)、幻燈片編號以及模式 - 幻燈片或列印。引數透過分號分隔的查詢字串傳遞,而不是更常見的鍵=值形式,因為我無法在 Javascript 中使 & 分隔符工作(??)

declare variable $params := tokenize(request:get-query-string(),";");
declare variable $uri := $params[1];
declare variable $n := xs:integer(($params[2],1)[1]);
declare variable $mode :=($params[3],"slide")[1];

獲取 XML

[編輯 | 編輯原始碼]

獲取幻燈片放映 - 如果儲存在資料庫中,這會更快,但也可以是外部檔案。

declare variable $slideshow := doc($uri)/ss:slideshow;
declare variable $slides := $slideshow/ss:slide;
declare variable $count := count($slides);

幻燈片放映

[編輯 | 編輯原始碼]

顯示幻燈片

[編輯 | 編輯原始碼]

一個函式生成包含幻燈片的 div。全域性變數定義了常見的幻燈片放映屬性。

declare function local:show-slide($slide as element(ss:slide) ) as element(div) {
<div class="slide">
        <span class="header">{$slideshow/ss:master/ss:header/node()}</span>
              {$slide}
         <span class="footer">{$n}/{$count} &#160; {$slideshow/ss:footer/node()}  </span>
 </div>
};

內容幻燈片

[編輯 | 編輯原始碼]

每個幻燈片中的 <h1> 元素用於生成內容幻燈片,編號為 0。

declare function local:show-contents() as element(div) {
<div class="contents">
   <span class="header">{$slideshow/ss:header/node()}</span>
   <h1>Contents</h1>
   <ul>
     {for $slide at $i in $slides
      return 
         <li>{$i} &#160;<a href="slide.xql?{$uri};{$i}">{string($slide/h:h1)}</a> </li>
     }
    </ul>
    <span class="footer">0/{$count} &#160; {$slideshow/ss:footer/node()}  </span>
</div>
};

導航由一個 JavaScript 函式處理,該函式處理按鍵事件並附加到頁面主體。此程式碼對於每個幻燈片都不同,因此會為每個幻燈片生成。按鍵對映部分基於常見無線演示器生成的程式碼,即 Labtec 筆記本演示器,它專為與 PowerPoint 一起使用而設計。該裝置的文件很難找到,因此按鍵對映是透過捕獲簡單 javascript 觀察到的按鍵來分析的。

  • 左右按鈕:PageUp 和 PageDown 用於向前和向後翻頁
  • 底部鍵:'b' 用於使螢幕空白
  • 頂部按鈕:在 F5 到全屏模式和 Esc 到編輯模式之間切換

添加了其他按鍵對映,允許使用游標鍵並進入列印模式。

請注意,在生成此 Javascript 程式碼時,{ } 括號需要加倍。

declare function local:keypress-script() as element(script) {
let $prev := if ($n > 0) then $n - 1 else 1
let $next := if ($n < $count) then $n + 1 else $count
return
 <script type="text/javascript">                     
        function keypress(e) {{
            var code=e.keyCode
            if (code==34 || code== 39) document.location = "slide.xql?{$uri};{$next}"  //Page UP or forward : next
            if (code==33 || code== 37) document.location = "slide.xql?{$uri};{$prev}"  //Page Down or back  : previous     
            if (code==66 || code==38 ) document.location = "slide.xql?{$uri};0"            //b or up  : index
            if (code==36) document.location ="slide.xql?{$uri};1"               //Home : first
            if (code==35) document.location ="slide.xql?{$uri};{$count}"    //End : last
            if (code==80 || code==40 ) document.location ="slide.xql?{$uri};0;print"    //p :  print
         }}       
    </script> 
};
declare option exist:serialize "method=xhtml media-type=text/html";

if ($mode="slide")
then
<html>
<head>
  <title>{string($slideshow/ss:title)} - Slides</title>
  <link rel="stylesheet" type="text/css"  href="{$slideshow/ss:css/ss:slide}"/>
   {local:keypress-script()}
</head>
<body onkeydown="keypress(event)">
    { if ($n=0) 
      then   local:show-contents() 
      else  local:show-slide($slides[$n])       
    }
  </body>
</html>
else ...
[編輯 | 編輯原始碼]

其他函式生成幻燈片放映的可列印版本。它包括:

目錄頁

[編輯 | 編輯原始碼]
declare function local:print-contents() as element(div) {
<div class="contents">
   <h2>Contents</h2>
   <ul>
     {for $slide at $i in $slides
      return 
         <li>{$i} . <a href="slide.xql?{$uri};{$i}">{string($slide/h:h1)}</a> </li>
     }
    </ul>
</div>
};

幻燈片

[編輯 | 編輯原始碼]
declare function local:print-slides() as element(div)* {
  for $slide at $i in $slides
  return 
         $slide 
};

連結的 URI 在列印的幻燈片中不可見,因此新增一個包含所有出現在幻燈片中的連結的最後頁面非常有用。

declare function local:print-links() as element(div) {
  <div class="links">
    <h1>Links</h1>
    <ul>
    {for $slide at $i in $slides
     for $link in $slide//h:a
     order by upper-case($link)
     return 
      <li>{string($link)} :<em>{string($link/@href)}</em> </li>
    }
    </ul>
  </div>
  };

生成列印檢視

[編輯 | 編輯原始碼]

如果模式為“列印”,則生成列印格式

..
else
<html>
   <head>
      <title>{string($slideshow/ss:title)} - Print</title>
      <link rel="stylesheet" type="text/css"  href="{$slideshow/ss:css/ss:print}"/>
   </head>
   <body>
       
     {local:print-contents()}
     {local:print-slides()}  
     {local:print-links()}
   </body>
</html>
華夏公益教科書