跳转到内容

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>
华夏公益教科书