add presentation files from ipw 2009
Matt S Trout [Fri, 23 Oct 2009 13:40:31 +0000 (14:40 +0100)]
docs/antiquated-perl.xul [new file with mode: 0644]
docs/takahashi.css [new file with mode: 0755]
docs/takahashi.js [new file with mode: 0755]

diff --git a/docs/antiquated-perl.xul b/docs/antiquated-perl.xul
new file mode 100644 (file)
index 0000000..cc110bb
--- /dev/null
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="takahashi.css" type="text/css"?><page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="presentation" xmlns:html="http:/www.w3.org/1999/xhtml" orient="vertical" onkeypress="Presentation.onKeyPress(event);">\r
+<html:textarea id="builtinCode" style="visibility: collapse"><![CDATA[\r
+Antiquated
+Perl
+----
+Modern
+Perl?
+----
+Post
+Modern
+Perl
+----
+Enlightened
+Perl
+----
+everybody
+knows
+----
+Catalyst
+Moose
+DBIx::Class
+----
+Modern
+Perl?
+----
+perl5
+v10
+----
+  given ($x) {
+    when (3) {
+  ...
+----
+~~
+----
+what's the
+opposite?
+----
+Old
+Perl?
+----
+if it 
+works
+----
+Legacy
+Perl?
+----
+not
+interesting
+----
+Stupid
+Perl
+----
+*$&^*(^
+FormMail.PL
+----
+Antiquated
+Perl
+----
+Antique
+----
+Old *and*
+beautiful
+----
+Simple
+Elegant
+----
+  $|++
+----
+  use IO::Handle;
+  STDOUT->autoflush(1);
+----
+it's core.
+it's fine.
+----
+but why
+think?
+----
+  select((select(FOO),$|++)[0])
+----
+  (select(FOO),$|++)
+  ->
+  ($old_selected_fh,$|)
+----
+  (select(FOO),$|++)[0]
+  ->
+  $old_select_fh
+----
+  select((select(FOO),$|++)[0])
+  ->
+  use IO::Handle;
+  FOO->autoflush(1)
+----
+~~
+----
+  ~~@x
+----
+  ~(~(@x))
+----
+bitwise
+negation
+----
+so ...
+----
+  ~@x
+  ->
+  ~(scalar @x)
+----
+  ~~$number
+  ->
+  $number
+----
+  ~~@x
+  ->
+  scalar @x
+----
+  perl -MMoose -e'print ~~keys %INC'
+  84
+----
+overload::constant
+----
+lets you
+affect
+parsing
+----
+numbers
+strings
+----
+q qq qr
+t s qw
+----
+i18n.pm
+----
+~~"$foo bar"
+loc("_[0] bar", $foo)
+----
+for
+----
+  for ($foo) {
+    /bar/ and ...
+----
+  for ($foo) {
+    /bar/ and return do {
+      <code here>
+    }
+----
+  /foo/gc
+----
+  /\Gbar/gc
+----
+  sub parse {
+    my ($self, $str) = @_;
+    for ($str) {
+      /match1/gc and return
+        $self->_subparse_1($_)
+----
+  sub _subparse_1 {
+    my ($self) = @_;
+    for ($_[1]) {
+      /\Gsubmatch1/gc ...
+----
+prototypes
+----
+  sub foo (&) {
+----
+  foo {
+    ...
+  };
+----
+  prototype \&foo
+----
+typeglobs
+----
+  *{"${package}::${name}"}
+    = sub { ... }
+---- 
+  local
+----
+  local $_
+----
+  local *Carp::croak
+    = \&Carp::confess;
+----
+  do {
+    local (@ARGV, $/) = $file;
+    <>
+  }
+----
+strict
+and
+warnings
+----
+  strict->import
+----
+affects
+compilation
+scope
+----
+  sub strict_and_warnings::import {
+    strict->import;
+    warnings->import;
+  }
+----
+  use strict_and_warnings;
+----
+$^H
+%^H
+----
+  $^H |= 0x120000;
+  $^H{'foo'}
+    = bless($foo, 'My::Foo');
+----
+  sub My::Foo::DESTROY {
+----
+  delete ${$package}{myimport}
+----
+B::Hooks::EndOfScope
+----
+tie
+----
+  tie $var, 'Foo';
+----
+  sub FETCH
+  sub STORE
+----
+Scalar
+Array
+Hash
+Handle
+----
+now ...
+----
+mst: destruction
+testing technology
+since March 1983
+----
+3 days
+old
+----
+2 weeks
+early
+----
+incubator
+----
+glass box
+plastic tray
+heater
+----
+design
+flaw
+----
+BANG
+----
+so ...
+----
+interesting
+fact
+----
+prototypes
+only warn
+when parsed
+----
+error when
+compiled
+----
+so ...
+----
+  dispatch [
+    sub (GET + /) { ... },
+    sub (GET + /user/*) { ... }
+  ];
+----
+  foreach my $sub (@$dispatch) {
+    my $proto = prototype $sub;
+    $parser->parse($proto);
+    ...
+----
+  PARSE: { do {
+    push @match, $self->_parse_spec_section($spec)
+      or $self->_blam("Unable to work out what the next section is");
+    last PARSE if (pos == length);
+    /\G\+/gc or $self->_blam('Spec sections must be separated by +');
+  } until (pos == length) };
+----
+  sub _blam {
+    my ($self, $error) = @_;
+    my $hat = (' ' x pos).'^';
+    die "Error parsing dispatch specification: ${error}\n
+  ${_}
+  ${hat} here\n";
+  }
+----
+  Error parsing ...
+  GET+/foo
+     ^ here
+----
+  sub (GET + /user/*) {
+   my ($self, $user) = @_;
+----
+I hate
+fetching
+$self
+----
+  *{"${app}::self"}
+    = \${"${app}::self"};
+----
+use vars
+----
+  sub _run_with_self {
+    my ($self, $run, @args) = @_;
+    my $class = ref($self);
+    no strict 'refs';
+    local *{"${class}::self"} = \$self;
+    $self->$run(@args);
+  }
+----
+HTML
+output
+----
+templates
+----
+HTML is
+NOT TEXT
+----
+  <div>,
+    $text,
+  </div>;
+----
+<div>
+----
+<$fh>
+----
+  tie *{"${app}::${name}"},
+    'XML::Tags::TIEHANDLE',
+    "<${name}>";
+----
+  sub TIEHANDLE { my $str = $_[1]; bless \$str, $_[0] }
+  sub READLINE { ${$_[0]} }
+----
+  sub DESTROY {
+    my ($into, @names) = @$_[0];
+    no strict 'refs';
+    delete ${$into}{$_}
+      for @names;
+  }
+----
+</div>
+----
+glob('/div');
+----
+  *CORE::GLOBAL::glob
+    = sub { ... };
+----
+  delete
+    ${CORE::GLOBAL::}{glob};
+----
+  sub foo {
+    use XML::Tags qw(div);
+    <div>, "foo!", </div>;
+  }
+----
+what about
+interpolation
+----
+  my $stuff = 'foo"bar';
+  <a href="$stuff">
+----
+hmm ...
+----
+overload::constant!
+----
+  glob('a href="'.$stuff.'"');
+----
+  glob(
+    bless(\'a href="', 'MagicTag')
+    .$stuff
+    .bless(\'"', 'MagicTag')
+  )
+----
+  use overload
+    '.' => 'concat';
+
+  sub concat {
+----
+hooking
+it up
+----
+  sub (.html) {
+    filter_response {
+      $self->render_html($_[1])
+    }
+  }
+----
+  bless(
+    $_[1],
+    'Web::Simple::ResponseFilter'
+  );
+----
+  if ($self->_is_response_filter($result)) {
+    return $self->_run_with_self(
+      $result,
+      $self->_run_dispatch_for($new_env, \@disp)
+    );
+  }
+----
+and the result?
+----
+ goto &demo;
+----
+questions?
+----
+thank
+you
+]]></html:textarea>\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+<deck flex="1" id="deck">\r
+\r
+<vbox flex="1"\r
+       onmousemove="Presentation.onMouseMoveOnCanvas(event);">\r
+       <toolbox id="canvasToolbar">\r
+               <toolbar>\r
+                       <toolbarbutton oncommand="Presentation.home()" label="|&lt;&lt;"\r
+                               observes="canBack"/>\r
+                       <toolbarbutton oncommand="Presentation.back()" label="&lt;"\r
+                               observes="canBack"/>\r
+                       <toolbarbutton oncommand="Presentation.forward()" label="&gt;"\r
+                               observes="canForward"/>\r
+                       <toolbarbutton oncommand="Presentation.end()" label="&gt;&gt;|"\r
+                               observes="canForward"/>\r
+                       <toolbarseparator/>\r
+                       <hbox align="center">\r
+                               <textbox id="current_page" size="4"\r
+                                       oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/>\r
+                               <description value="/"/>\r
+                               <description id="max_page"/>\r
+                       </hbox>\r
+                       <toolbarseparator/>\r
+                       <vbox flex="2">\r
+                               <spacer flex="1"/>\r
+                               <scrollbar id="scroller"\r
+                                       align="center" orient="horizontal"\r
+                                       oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"\r
+                                       onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"\r
+                                       onmousedown="Presentation.onScrollerDragStart();"\r
+                                       onmousemove="Presentation.onScrollerDragMove();"\r
+                                       onmouseup="Presentation.onScrollerDragDrop();"/>\r
+                               <spacer flex="1"/>\r
+                       </vbox>\r
+                       <toolbarseparator/>\r
+                       <spacer flex="1"/>\r
+                       <toolbarseparator/>\r
+                       <toolbarbutton id="toggleEva" label="Eva"\r
+                               type="checkbox"\r
+                               autoCheck="false"\r
+                               oncommand="Presentation.toggleEvaMode();"/>\r
+                       <toolbarseparator/>\r
+                       <toolbarbutton label="Edit"\r
+                               oncommand="Presentation.toggleEditMode();"/>\r
+                       <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>\r
+               </toolbar>\r
+       </toolbox>\r
+       <vbox flex="1" id="canvas"\r
+               onclick="Presentation.onPresentationClick(event);">\r
+               <spacer flex="1"/>\r
+               <hbox flex="1">\r
+                       <spacer flex="1"/>\r
+                       <vbox id="content"/>\r
+                       <spacer flex="1"/>\r
+               </hbox>\r
+               <spacer flex="1"/>\r
+       </vbox>\r
+</vbox>\r
+\r
+\r
+<vbox flex="1" id="edit">\r
+       <toolbox>\r
+               <toolbar>\r
+                       <toolbarbutton label="New Page"\r
+                               oncommand="Presentation.addPage()"/>\r
+                       <spacer flex="1"/>\r
+                       <toolbarseparator/>\r
+                       <toolbarbutton label="View"\r
+                               oncommand="Presentation.toggleEditMode();"/>\r
+                       <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>\r
+               </toolbar>\r
+       </toolbox>\r
+       <textbox id="textField" flex="1" multiline="true"\r
+               oninput="Presentation.onEdit()"/>\r
+       <hbox collapsed="true">\r
+               <iframe id="dataLoader" onload="if (window.Presentation) Presentation.onDataLoad();"/>\r
+       </hbox>\r
+</vbox>\r
+\r
+</deck>\r
+\r
+\r
+<broadcasterset>\r
+       <broadcaster id="canBack"/>\r
+       <broadcaster id="canForward"/>\r
+</broadcasterset>\r
+\r
+<commandset>\r
+       <command id="cmd_forward"\r
+               oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>\r
+       <command id="cmd_back"\r
+               oncommand="if (Presentation.isPresentationMode) Presentation.back();"/>\r
+       <command id="cmd_home"\r
+               oncommand="if (Presentation.isPresentationMode) Presentation.home();"/>\r
+       <command id="cmd_end"\r
+               oncommand="if (Presentation.isPresentationMode) Presentation.end();"/>\r
+</commandset>\r
+<keyset>\r
+       <key keycode="VK_ENTER"      command="cmd_forward"/>\r
+       <key keycode="VK_RETURN"     command="cmd_forward"/>\r
+       <key keycode="VK_PAGE_DOWN"  command="cmd_forward"/>\r
+       <key keycode="VK_RIGHT"      command="cmd_forward"/>\r
+       <key keycode="VK_DOWN"       command="cmd_forward"/>\r
+       <!-- key keycode="VK_BACK_SPACE" command="cmd_back"/-->\r
+       <key keycode="VK_PAGE_UP"    command="cmd_back"/>\r
+        <!-- <key keycode="VK_BACK_UP"    command="cmd_back"/>-->\r
+        <!-- <key keycode="VK_BACK_LEFT"  command="cmd_back"/>-->\r
+       <key keycode="VK_HOME"       command="cmd_home"/>\r
+       <key keycode="VK_END"        command="cmd_end"/>\r
+       <key key="n" modifiers="accel" oncommand="Presentation.addPage();"/>\r
+       <key key="r" modifiers="accel" oncommand="window.location.reload();"/>\r
+       <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>\r
+       <key key="a" modifiers="accel" oncommand="Presentation.toggleEvaMode();"/>\r
+</keyset>\r
+\r
+\r
+<script src="takahashi.js" type="application/x-javascript" />\r
+</page>\r
+<!-- ***** BEGIN LICENSE BLOCK *****\r
+   - Version: MPL 1.1\r
+   -\r
+   - The contents of this file are subject to the Mozilla Public License Version\r
+   - 1.1 (the "License"); you may not use this file except in compliance with\r
+   - the License. You may obtain a copy of the License at\r
+   - http://www.mozilla.org/MPL/\r
+   -\r
+   - Software distributed under the License is distributed on an "AS IS" basis,\r
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
+   - for the specific language governing rights and limitations under the\r
+   - License.\r
+   -\r
+   - The Original Code is the Takahashi-Method-based Presentation Tool in XUL.\r
+   -\r
+   - The Initial Developer of the Original Code is SHIMODA Hiroshi.\r
+   - Portions created by the Initial Developer are Copyright (C) 2005\r
+   - the Initial Developer. All Rights Reserved.\r
+   -\r
+   - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>\r
+   -\r
+   - ***** END LICENSE BLOCK ***** -->\r
+\r
+\r
diff --git a/docs/takahashi.css b/docs/takahashi.css
new file mode 100755 (executable)
index 0000000..762553d
--- /dev/null
@@ -0,0 +1,161 @@
+@charset "UTF-8";\r
+\r
+/* ***** BEGIN LICENSE BLOCK *****\r
+ * Version: MPL 1.1\r
+ *\r
+ * The contents of this file are subject to the Mozilla Public License Version\r
+ * 1.1 (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ * http://www.mozilla.org/MPL/\r
+ *\r
+ * Software distributed under the License is distributed on an "AS IS" basis,\r
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
+ * for the specific language governing rights and limitations under the\r
+ * License.\r
+ *\r
+ * The Original Code is the Takahashi-Method-based Presentation Tool in XUL.\r
+ *\r
+ * The Initial Developer of the Original Code is SHIMODA Hiroshi.\r
+ * Portions created by the Initial Developer are Copyright (C) 2005\r
+ * the Initial Developer. All Rights Reserved.\r
+ *\r
+ * Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>\r
+ *\r
+ * ***** END LICENSE BLOCK ***** */\r
+\r
+#canvas {\r
+       background: black !important;\r
+       color: white !important;\r
+        /* font-weight: bold; */\r
+       font-family:\r
+                "Georgia"\r
+                "DejaVu Serif Condensed"\r
+                "Arial"\r
+               "Bitstream Vera Sans"\r
+               "Verdana"\r
+               "Apple LiGothic"\r
+               "Arial Black"\r
+                "Bitstream Vera Sans"\r
+               sans-serif !important;\r
+}\r
+#canvas * {\r
+       cursor: pointer !important;\r
+}\r
+#canvas image {\r
+       width: auto;\r
+       height: auto;\r
+}\r
+.link-text {\r
+       color: #99CCFF !important;\r
+       text-decoration: none !important;\r
+}\r
+.link-text:hover {\r
+       color: #CCEEFF !important;\r
+/*        border-bottom: dotted 1px; */\r
+}\r
+.link-text:active {\r
+       color: white !important;\r
+}\r
+.s {\r
+        text-decoration: line-through;\r
+}\r
+.iu {\r
+        text-decoration: underline;\r
+        font-style: italic;\r
+}\r
+.ui {\r
+/*      text-decoration: underline; */\r
+        font-style: italic;\r
+}\r
+.u {\r
+        text-decoration: underline;\r
+}\r
+.i {\r
+        font-style: italic;\r
+        font-family: "Times New Roman"\r
+                     "Bitstream Vera Serif"\r
+                     serif;\r
+}\r
+.c {\r
+        font-family: "Anonymous"\r
+                    "Lucida Console"\r
+                    "Andale Mono"\r
+                     "Bitstream Vera Sans Mono"\r
+                     monospace;\r
+}\r
+.t {\r
+        font-style: italic;\r
+}\r
+.tag {\r
+        color: #33ff33;\r
+}\r
+.att {\r
+        color: #9999cc;\r
+}\r
+.key {\r
+        color: #00ffff;\r
+}\r
+.hid {\r
+        color: #999999;\r
+}\r
+.hidt {\r
+        color: #999999;\r
+        font-style: italic;\r
+}\r
+.pre {\r
+        font-family: "Anonymous"\r
+                    "Lucida Console"\r
+                    "Andale Mono"\r
+                     "Bitstream Vera Sans Mono"\r
+                     monospace;\r
+        padding-bottom: 8px;\r
+}\r
+#canvas[rendering="true"] image {\r
+       display: none;\r
+}\r
+#canvas[rendering="true"] *,\r
+#canvas[rendering="true"] .text-link {\r
+       color: white !important;\r
+}\r
+\r
+\r
+tabbox, tabpanels, tabpanel {\r
+       margin: 0;\r
+       padding: 0;\r
+}\r
+\r
+\r
+\r
+\r
+#canvas[eva="true"] {\r
+       background: white !important;\r
+       color: black !important;\r
+       font-family:\r
+                "Georgia"\r
+                "DejaVu Serif Condensed"\r
+               "Apple LiGothic"\r
+               "Arial Black"\r
+               serif !important;\r
+}\r
+#canvas[eva="true"] .link-text {\r
+       color: red !important;\r
+       text-decoration: none !important;\r
+}\r
+#canvas[eva="true"] .link-text:hover {\r
+       color: pink !important;\r
+}\r
+#canvas[eva="true"] .link-text:active {\r
+       color: orange !important;\r
+}\r
+#canvas[rendering="true"] *,\r
+#canvas[rendering="true"] .text-link {\r
+       color: black !important;\r
+}\r
+\r
+\r
+\r
+\r
+#canvasToolbar {\r
+       position: relative;\r
+}\r
+\r
diff --git a/docs/takahashi.js b/docs/takahashi.js
new file mode 100755 (executable)
index 0000000..c5d6933
--- /dev/null
@@ -0,0 +1,503 @@
+var Presentation = {
+    init : function(option){
+        this.size = 9;
+
+        this._offset  = 0;
+        this.canvas   = document.getElementById('canvas');
+        this.content  = document.getElementById('content');
+        this.textbox  = document.getElementById('textField');
+        this.deck     = document.getElementById('deck');
+        this.scroller = document.getElementById('scroller');
+
+        this.toolbar         = document.getElementById('canvasToolbar');
+        this.toolbarHeight   = this.toolbar.boxObject.height;
+        this.isToolbarHidden = true;
+        this.toolbar.setAttribute('style', 'margin-top:'+(0-this.toolbarHeight)+'px;margin-bottom:0px;');
+
+        if(option){
+            for(var i in option){this[i] = option[i]}
+        }
+
+        if (this.readParameter()) {
+            this.takahashi();
+        }
+
+        document.documentElement.focus();
+    },
+
+    takahashi : function(){
+        if (!document.title)
+            document.title = this.data[0].replace(/[\r\n]/g, ' ');
+
+        if(!this.data[this.offset]){
+            this.offset = this.data.length-1;
+        }
+        document.getElementById("current_page").value = this.offset+1;
+        document.getElementById("max_page").value     = this.data.length;
+
+        this.scroller.setAttribute('maxpos', this.data.length-1);
+        this.scroller.setAttribute('curpos', this.offset);
+
+        var broadcaster = document.getElementById('canBack');
+        if (!this.offset)
+            broadcaster.setAttribute('disabled', true);
+        else
+            broadcaster.removeAttribute('disabled');
+
+        var broadcaster = document.getElementById('canForward');
+        if (this.offset == this.data.length-1)
+            broadcaster.setAttribute('disabled', true);
+        else
+            broadcaster.removeAttribute('disabled');
+
+        this.canvas.setAttribute('rendering', true);
+
+        var text = this.data[this.offset].
+                replace(/^[\r\n]+/g,"").replace(/[\r\n]+$/g,"").replace(/(\r\n|[\r\n])/g,"\n")
+                .split('\n');
+        var range = document.createRange();
+        range.selectNodeContents(this.content);
+        range.deleteContents();
+        range.detach();
+
+        var line;
+        var newLine;
+        var uri;
+        var image_width;
+        var image_total_width  = 0;
+        var image_height;
+        var image_total_height = 0;
+        var image_src;
+        var code_listing = 0;
+
+
+        var labelId = 0;
+
+        for (var i = 0; i < text.length; i++)
+        {
+            this.content.appendChild(document.createElement('hbox'));
+            this.content.lastChild.setAttribute('align', 'center');
+            this.content.lastChild.setAttribute('pack', 'center');
+
+            line = text[i];
+            image_width  = 0;
+            image_height = 0;
+
+            if (line.match(/^ /)) {
+              code_listing = 1; 
+              this.content.lastChild.setAttribute('align', 'left');
+              this.content.lastChild.setAttribute('class', 'pre');
+              line = line.substring(1)
+            }
+
+            while (line.match(/^([^\{]+)?(\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}|\{\{(([^\|]+)?\||)([^\}]+)\}\})(.+)?/))
+            {
+                if (RegExp.$1) {
+                    this.content.lastChild.appendChild(document.createElement('description'));
+                    this.content.lastChild.lastChild.setAttribute('value', RegExp.$1);
+                }
+                newLine = line.substring((RegExp.$1+RegExp.$2).length);
+
+                // Images
+                if (/^([^\{]+)?\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}/.test(line)) {
+                    this.content.lastChild.appendChild(document.createElement('image'));
+                    image_src = RegExp.$2;
+                    if (image_src.indexOf('http://') < 0 &&
+                        image_src.indexOf('https://') < 0)
+                        image_src = this.dataFolder+image_src;
+                    this.content.lastChild.lastChild.setAttribute('src', image_src);
+                    this.content.lastChild.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0'));
+                    this.content.lastChild.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0'));
+                    image_width  += parseInt(RegExp.$3 || '0');
+                    image_height = Math.max(image_height, parseInt(RegExp.$4 || '0'));
+                }
+
+                // Styles
+                // else if (/^([^\{]+)?\{\{#([^\|]+)\|([^\}]+)\}\}/.test(line)) {
+                else if (/^([^\{]+)?\{\{(#([^\|]+)?\|)([^\}]+)\}\}/.test(line)) {
+                    uri = RegExp.$4;
+                    this.content.lastChild.appendChild(document.createElement('description'));
+                    this.content.lastChild.lastChild.setAttribute('value', uri);
+                    this.content.lastChild.lastChild.setAttribute('class', RegExp.$3);
+                }
+
+                // Links
+                else if (/^([^\{]+)?\{\{(([^\|]+)?\||)([^\}]+)\}\}/.test(line)) {
+                    uri = RegExp.$4;
+                    if (uri.indexOf('://') < 0)
+                        uri = this.dataFolder+uri;
+                    this.content.lastChild.appendChild(document.createElement('description'));
+                    this.content.lastChild.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4);
+                    this.content.lastChild.lastChild.setAttribute('href', uri);
+                    this.content.lastChild.lastChild.setAttribute('tooltiptext', uri);
+                    this.content.lastChild.lastChild.setAttribute('statustext', uri);
+                    this.content.lastChild.lastChild.setAttribute('class', 'link-text');
+                }
+
+                line = newLine;
+            }
+
+            if (line) {
+                this.content.lastChild.appendChild(document.createElement('description'));
+                this.content.lastChild.lastChild.setAttribute('value', line);
+            }
+
+            image_total_width = Math.max(image_total_width, image_width);
+            image_total_height += image_height;
+        }
+
+        this.content.setAttribute('style', 'font-size:10px;');
+
+        if (this.content.boxObject.width) {
+            var canvas_w  = this.canvas.boxObject.width;
+            var canvas_h  = this.canvas.boxObject.height-image_total_height;
+
+            var content_w = this.content.boxObject.width;
+            var new_fs = Math.round((canvas_w/content_w) * this.size);
+
+            new_fs = new_fs - (new_fs % 32);
+            if (code_listing) { new_fs = 48;}
+
+            this.content.setAttribute('style', 'top: 0');
+            this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+
+            if (this.content.boxObject.width < image_total_width) {
+                content_w = image_total_width;
+                new_fs = Math.round((canvas_w/content_w) * this.size);
+                this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+            }
+
+            var content_h = this.content.boxObject.height;
+            if(content_h >= canvas_h){
+                content_h = this.content.boxObject.height;
+                new_fs = Math.round((canvas_h/content_h) * new_fs);
+                this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+            }
+        }
+
+
+
+        this.canvas.removeAttribute('rendering');
+    },
+
+    reload : function() {
+        if (this.dataPath != location.href) {
+            var path = this.dataPath;
+            if (location.href.match(/^https?:/)) {
+                var request = new XMLHttpRequest();
+                request.open('GET', path);
+                request.onload = function() {
+                    Presentation.textbox.value = request.responseText;
+                    Presentation.data = Presentation.textbox.value.split('----');
+
+                    Presentation.takahashi();
+
+                    path = null;
+                    request = null;
+                };
+                request.send(null);
+            }
+            else {
+                document.getElementById('dataLoader').setAttribute('src', 'about:blank');
+                window.setTimeout(function() {
+                    document.getElementById('dataLoader').setAttribute('src', path);
+                    path = null;
+                }, 10);
+            }
+        }
+        else
+            window.location.reload();
+    },
+
+    forward : function(){
+        this.offset++;
+        this.takahashi();
+    },
+    back : function(){
+        this.offset--;
+        if(this.offset < 0){this.offset = 0}
+        this.takahashi();
+    },
+    home : function(){
+        this.offset = 0;
+        this.takahashi();
+    },
+    end : function(){
+        this.offset = this.data.length-1;
+        this.takahashi();
+    },
+    showPage : function(aPageOffset){
+        this.offset = aPageOffset ? aPageOffset : 0 ;
+        this.takahashi();
+    },
+
+    addPage : function() {
+        if (this.textbox.value &&
+            !this.textbox.value.match(/(\r\n|[\r\n])$/))
+            this.textbox.value += '\n';
+        this.textbox.value += '----\n';
+        this.onEdit();
+    },
+
+    toggleEditMode : function(){
+        this.deck.selectedIndex = (this.deck.selectedIndex == 0) ? 1 : 0 ;
+    },
+    toggleEvaMode : function(){
+        var check = document.getElementById('toggleEva');
+        if (this.canvas.getAttribute('eva') == 'true') {
+            this.canvas.removeAttribute('eva');
+            check.checked = false;
+        }
+        else {
+            this.canvas.setAttribute('eva', true);
+            check.checked = true;
+        }
+    },
+
+    onPresentationClick : function(aEvent){
+        if (!this.isToolbarHidden)
+            this.showHideToolbar();
+
+        switch(aEvent.button)
+        {
+            case 0:
+                var uri = aEvent.target.getAttribute('href');
+                if (uri)
+                    window.open(uri);
+                else {
+                    this.forward();
+                    document.documentElement.focus();
+                }
+                break;
+            case 2:
+                this.back();
+                document.documentElement.focus();
+                break;
+            default:
+                break;
+        }
+    },
+    onScrollerDragStart : function(){
+        this.scroller.dragging = true;
+    },
+    onScrollerDragMove : function(){
+        if (this.scroller.dragging)
+            this.showPage(parseInt(this.scroller.getAttribute('curpos')));
+    },
+    onScrollerDragDrop : function(){
+        if (this.scroller.dragging) {
+            this.showPage(parseInt(this.scroller.getAttribute('curpos')));
+        }
+         this.scroller.dragging = false;
+    },
+    onEdit : function() {
+        this.data = this.textbox.value.split('----');
+        this.takahashi();
+    },
+
+    onKeyPress : function(aEvent) {
+        switch(aEvent.keyCode)
+        {
+            case aEvent.DOM_VK_BACK_SPACE:
+                if (this.isPresentationMode) {
+                    aEvent.preventBubble();
+                    aEvent.preventDefault();
+                    Presentation.back();
+                }
+                break;
+            default:
+                break;
+        }
+    },
+
+
+    onToolbarArea   : false,
+    toolbarHeight   : 0,
+    toolbarDelay    : 300,
+    toolbarTimer    : null,
+    isToolbarHidden : false,
+    onMouseMoveOnCanvas : function(aEvent) {
+        if (this.scroller.dragging) return;
+
+        this.onToolbarArea = (aEvent.clientY < this.toolbarHeight);
+
+        if (this.isToolbarHidden == this.onToolbarArea) {
+            if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer);
+            this.toolbarTimer = window.setTimeout('Presentation.onMouseMoveOnCanvasCallback()', this.toolbarDelay);
+        }
+    },
+    onMouseMoveOnCanvasCallback : function() {
+        if (this.isToolbarHidden == this.onToolbarArea)
+            this.showHideToolbar();
+    },
+
+    toolbarAnimationDelay : 100,
+    toolbarAnimationSteps : 5,
+    toolbarAnimationInfo  : null,
+    toolbarAnimationTimer : null,
+    showHideToolbar : function()
+    {
+        if (this.toolbarAnimationTimer) window.clearTimeout(this.toolbarAnimationTimer);
+
+        this.toolbarAnimationInfo = { count : 0 };
+        if (this.isToolbarHidden) {
+            this.toolbarAnimationInfo.start = 0;
+            this.toolbarAnimationInfo.end   = this.toolbarHeight;
+        }
+        else {
+            this.toolbarAnimationInfo.start = this.toolbarHeight;
+            this.toolbarAnimationInfo.end   = 0;
+        }
+        this.toolbarAnimationInfo.current = 0;
+
+        this.toolbar.setAttribute('style', 'margin-top:'+(0-(this.toolbarHeight-this.toolbarAnimationInfo.start))+'px; margin-bottom:'+(0-this.toolbarAnimationInfo.start)+'px;');
+
+        this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
+    },
+    animateToolbar : function()
+    {
+        this.toolbarAnimationInfo.current += parseInt(this.toolbarHeight/this.toolbarAnimationSteps);
+
+        var top, bottom;
+        if (this.toolbarAnimationInfo.start < this.toolbarAnimationInfo.end) {
+            top    = this.toolbarHeight-this.toolbarAnimationInfo.current;
+            bottom = this.toolbarAnimationInfo.current;
+        }
+        else {
+            top    = this.toolbarAnimationInfo.current;
+            bottom = this.toolbarHeight-this.toolbarAnimationInfo.current;
+        }
+
+        top    = Math.min(Math.max(top, 0), this.toolbarHeight);
+        bottom = Math.min(Math.max(bottom, 0), this.toolbarHeight);
+
+        this.toolbar.setAttribute('style', 'margin-top:'+(0-top)+'px; margin-bottom:'+(0-bottom)+'px');
+
+        if (this.toolbarAnimationInfo.count < this.toolbarAnimationSteps) {
+            this.toolbarAnimationInfo.count++;
+            this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
+        }
+        else
+            this.isToolbarHidden = !this.isToolbarHidden;
+    },
+
+
+
+    get offset(){
+        return this._offset;
+    },
+    set offset(aValue){
+        this._offset = parseInt(aValue || 0);
+        document.documentElement.setAttribute('lastoffset', this.offset);
+        return this.offset;
+    },
+
+    get data(){
+        if (!this._data) {
+             // Make sure you break the text into parts smaller than 4096
+             // characters, and name them as indicated. Tweak as required.
+             // (What a hack. A JS programmer should find a better way.)
+             // Luc St-Louis, and email is lucs@pobox.com.
+
+                 nodes = document.getElementById('builtinCode').childNodes;
+                 content = '';
+                for (i in nodes) {
+                    if (nodes[i].nodeValue) {
+                    content = content + nodes[i].nodeValue;
+                    }
+                }
+    
+               this._data = content.split("----");
+        }
+
+        return this._data;
+    },
+    set data(aValue){
+        this._data = aValue;
+        return aValue;
+    },
+
+
+    get isPresentationMode(){
+        return (this.deck.selectedIndex == 0);
+    },
+
+
+    get dataPath(){
+        if (!this._dataPath)
+            this.dataPath = location.href;
+        return this._dataPath;
+    },
+    set dataPath(aValue){
+        var oldDataPath = this._dataPath;
+        this._dataPath = aValue;
+        if (oldDataPath != aValue) {
+            this._dataFolder = this._dataPath.split('?')[0].replace(/[^\/]+$/, '');
+        }
+        return this._dataPath;
+    },
+
+    get dataFolder(){
+        if (!this._dataFolder)
+            this.dataPath = this.dataPath;
+        return this._dataFolder;
+    },
+    set dataFolder(aValue){
+        this._dataFolder = aValue;
+        return this._dataFolder;
+    },
+
+    readParameter : function() {
+        if (location.search) {
+            var param = location.search.replace(/^\?/, '');
+
+            if (param.match(/page=([0-9]+)/i))
+                this.offset = parseInt(RegExp.$1)-1;
+
+            if (param.match(/edit=(1|true|yes)/i))
+                this.toggleEditMode();
+
+            if (param.match(/eva=(1|true|yes)/i))
+                this.toggleEvaMode();
+
+            if (param.match(/data=([^&;]+)/i)) {
+                var path = unescape(RegExp.$1);
+                this.dataPath = path;
+                if (location.href.match(/^https?:/)) {
+                    var request = new XMLHttpRequest();
+                    request.open('GET', path);
+                    request.onload = function() {
+                        Presentation.textbox.value = request.responseText;
+                        Presentation.data = Presentation.textbox.value.split('----');
+
+                        Presentation.takahashi();
+                    };
+                    request.send(null);
+                }
+                else {
+                    document.getElementById('dataLoader').setAttribute('src', path);
+                }
+                return false;
+            }
+        }
+        return true;
+    },
+    onDataLoad : function() {
+        if (!window.frames[0].document.body.hasChildNodes()) return;
+        var data = window.frames[0].document.body.firstChild.innerHTML;
+        if (!data) return;
+
+        this.textbox.value = data;
+        this.data = this.textbox.value.split('----');
+
+        this.takahashi();
+    }
+};
+
+function init()
+{
+    window.removeEventListener('load', init, false);
+
+    Presentation.init();
+}
+window.addEventListener('load', init, false);