Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/default.php
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/default.php	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/default.php	(revision 30098)
@@ -0,0 +1,3 @@
+<?php
+$conf['defaulttab'] = 'Greenstone 3';
+?>
Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/metadata.php
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/metadata.php	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/conf/metadata.php	(revision 30098)
@@ -0,0 +1,3 @@
+<?php
+$meta['defaulttab'] = array('multichoice', '_choices' => array('Greenstone 3', 'Greenstone 2'));
+?>
Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/plugin.info.txt
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/plugin.info.txt	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/plugin.info.txt	(revision 30098)
@@ -0,0 +1,8 @@
+base    simpletabs
+author  John Thompson
+email   jmt12@students.waikato.ac.nz
+date    2013-07-30
+name    SimpleTab Plugin
+url     http://cms.waikato.ac.nz/
+desc    A simple tabbed area for displaying several flavours of text. Syntax:<TABAREA tabs="comma,separated,list"><TAB>Content of 'comma' including [[:syntax|wiki syntax]]</TAB><TAB>Content of 'separated' and here **is** //some// ''formatting''</TAB><TAB>Content of 'list'</TAB></TABAREA>
+
Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/script.js
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/script.js	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/script.js	(revision 30098)
@@ -0,0 +1,149 @@
+function tabSwitch(tabarea, tab_count, active_tab_number)
+{
+  // Active tab is null if this is the first ever time the page is loaded
+  // by this user. Default to tab 1---which should be Greenstone 3.
+  if (active_tab_number == null)
+  {
+    active_tab_number = 1;
+  }      
+	//alert("tabSwitch(" + tabarea + "," + tab_count + "," + active_tab_number + ")");
+
+    for (var i = 1; i < tab_count + 1; i++)
+    {
+	if (i != active_tab_number)
+	{
+            document.getElementById('t' + tabarea + '_' + i).className = '';
+            document.getElementById('tc' + tabarea + '_' + i).style.display = 'none';
+	    _tabTOCEntries('tc' + tabarea + '_' + i, false);
+        }
+    }
+    document.getElementById('t' + tabarea + '_' + active_tab_number).className = 'active';
+    document.getElementById('tc' + tabarea + '_' + active_tab_number).style.display = 'block';
+    _tabTOCEntries('tc' + tabarea + '_' + active_tab_number, true);
+    // Store the default tab for later page loads
+    _setCookie('dokuwiki_gs_default_tab', active_tab_number, 365);
+}
+
+function initTabArea()
+{
+    // Get the default tab cookie
+    var active_tab_number = _getCookie("dokuwiki_gs_default_tab");
+
+    // Switch tabs appropriately
+    var tab_area_counter = 1;
+    var possible_tab_area_id = 't' + tab_area_counter;
+    // Sometimes - for unknown reasons - t1 is not defined, so lets just try
+    // and update for the first tab tabs
+    for (tab_area_counter = 1; tab_area_counter < 5; tab_area_counter++)
+    {
+      if (document.getElementById('t' + tab_area_counter) != null)
+      {
+        var tab_count = 0;
+        var possible_tab_id = 't' + tab_area_counter + '_' + (tab_count + 1);
+        while (document.getElementById(possible_tab_id) != null)
+        {
+            tab_count++;
+            possible_tab_id = possible_tab_area_id + '_' + (tab_count + 1);
+        }
+        tabSwitch(tab_area_counter, tab_count, active_tab_number);
+      }
+    }
+    // Carry on while we can still find more tabs
+    while (document.getElementById('t' + tab_area_counter) != null)
+    {
+        var tab_count = 0;
+        var possible_tab_id = 't' + tab_area_counter + '_' + (tab_count + 1);
+        while (document.getElementById(possible_tab_id) != null)
+        {
+            tab_count++;
+            possible_tab_id = possible_tab_area_id + '_' + (tab_count + 1);
+        }
+        tabSwitch(tab_area_counter, tab_count, active_tab_number);
+        tab_area_counter++;
+    }
+}
+
+
+/**
+ *  source: http://www.w3schools.com/js/js_cookies.asp
+ */
+function _getCookie(c_name)
+{
+    var c_value = document.cookie;
+    var c_start = c_value.indexOf(" " + c_name + "=");
+    if (c_start == -1)
+    {
+        c_start = c_value.indexOf(c_name + "=");
+    }
+    if (c_start == -1)
+    {
+        c_value = null;
+    }
+    else
+    {
+        c_start = c_value.indexOf("=", c_start) + 1;
+        var c_end = c_value.indexOf(";", c_start);
+        if (c_end == -1)
+        {
+            c_end = c_value.length;
+        }
+        c_value = unescape(c_value.substring(c_start, c_end));
+    }
+    return c_value;
+}
+/** _getCookie() **/
+
+
+/**
+ *  source: http://www.w3schools.com/js/js_cookies.asp
+ */
+function _setCookie(c_name, value, exdays)
+{
+    var exdate=new Date();
+    exdate.setDate(exdate.getDate() + exdays);
+    var c_value = escape(value) + ((exdays==null) ? "" : "; expires=" + exdate.toUTCString());
+    document.cookie=c_name + "=" + c_value;
+}
+/** _setCookie() **/
+
+/**
+ *  Toggle the visibility of TOC entries based upon what tab is selected.
+*/
+function _tabTOCEntries(tab_id, make_visible)
+{
+    // Find all the heading in the indicated tab
+    var the_tab = document.getElementById(tab_id);
+    var headers = the_tab.getElementsByTagName('a');
+    for (var i = 0; i < headers.length; i++)
+    {
+        var id = headers[i].getAttribute('id');
+        var toc_id = 'toc_' + id;
+        var toc_li = document.getElementById(toc_id);
+        if (toc_li)
+        {
+            if (make_visible)
+            {
+                toc_li.style.display = 'block';
+            }
+            else
+            {
+                toc_li.style.display = 'none';
+            }
+        }
+    }
+}
+/** _tabTOCEntries(tab_id, make_visible) **/
+
+/** Register new init function - my first ever use of jQuery!
+ *  - sigh. Doesn't work in Rincewind
+ */
+/*
+jQuery(function() {
+    initTabArea();
+});
+*/
+
+/** Old code */
+addInitEvent(function(){
+    initTabArea();
+});
Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/style.css
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/style.css	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/style.css	(revision 30098)
@@ -0,0 +1,40 @@
+ul.tabs {
+  margin:0px;
+  margin-bottom:6px;
+  margin-top:5px;
+  padding:0px;
+}
+
+ul.tabs li {
+  list-style:none;
+  display:inline;
+}
+
+ul.tabs li a {
+  background-color:#EAEAEA;
+  padding:8px 14px 8px 14px;
+  text-decoration:none;
+  font-family:Verdana, Arial, Helvetica, sans-serif;
+  font-weight:bold;
+  text-transform:uppercase;
+  border:1px solid #464c54;
+}
+
+ul.tabs li a:hover {
+  background-color:#2f343a;
+  border-color:#2f343a;
+  color:#FFFFFF;
+}
+
+ul.tabs li a.active {
+  background-color:#ffffff;
+  color:#282e32;
+  border:1px solid #464c54;
+  border-bottom: 1px solid #ffffff;
+}
+
+.tab {
+  background-color:#ffffff;
+  padding:10px;
+  border:1px solid #464c54;
+}
Index: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/syntax.php
===================================================================
--- documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/syntax.php	(revision 30098)
+++ documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/simpletabs/syntax.php	(revision 30098)
@@ -0,0 +1,332 @@
+<?php
+/**
+ *  A simple tabbed area component, developed from the tutorial given here:
+ *  http://net.tutsplus.com/tutorials/html-css-techniques/how-to-create-a-slick-tabbed-content-area/
+ *
+ *  Syntax:
+ *    <TABAREA tabs="comma,separated,list">
+ *      <TAB>Content of 'comma' including [[:syntax|wiki syntax]]</TAB>
+ *      <TAB>Content of 'separated' and here **is** //some// ''formatting''</TAB>
+ *      <TAB>Content of 'list'</TAB>
+ *    </TABAREA>
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_simpletabs
+extends DokuWiki_Syntax_Plugin
+{
+
+  var $current_tab;
+  var $tab_area_counter;
+  var $tab_counter;
+  var $tabs;
+
+
+  function __construct()
+  {
+    global $PARSER_MODES;
+    $this->allowedModes = array_merge($PARSER_MODES['container'],
+                                      $PARSER_MODES['formatting'],
+                                      $PARSER_MODES['substition'],
+                                      $PARSER_MODES['protected'],
+                                      $PARSER_MODES['disabled'],
+                                      $PARSER_MODES['paragraphs']);
+    $this->tab_area_counter = 0;
+    $this->tab_counter = 0;
+    $this->tabs = array();
+  }
+
+  /**
+   * Get the type of syntax this plugin defines.
+   */
+  function getType()
+  {
+    return 'container';
+  }
+
+
+  /**
+   * What kind of syntax do we allow (optional)
+   */
+  function getAllowedTypes()
+  {
+    return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
+  }
+  /** getAllowedTypes() **/
+
+  /**
+   * Define how this plugin is handled regarding paragraphs.
+   *
+   * <p>
+   * This method is important for correct XHTML nesting. It returns
+   * one of the following values:
+   * </p>
+   * <dl>
+   * <dt>normal</dt><dd>The plugin can be used inside paragraphs.</dd>
+   * <dt>block</dt><dd>Open paragraphs need to be closed before
+   * plugin output.</dd>
+   * <dt>stack</dt><dd>Special case: Plugin wraps other paragraphs.</dd>
+   * </dl>
+   */
+  //  function getPType()
+  //  {
+  //    return 'normal';
+  //  }
+
+
+  /**
+   * Where to sort in?
+   */
+  function getSort()
+  {
+    return 45;
+  }
+
+
+   /**
+    * Connect lookup pattern to lexer.
+    */
+  function connectTo($mode)
+  {
+    $this->Lexer->addEntryPattern('<TABAREA tabs=".*?">(?=.*?</TABAREA>)$',$mode,'plugin_simpletabs');
+    $this->Lexer->addPattern('<TAB>', 'plugin_simpletabs');
+    $this->Lexer->addPattern('</TAB>', 'plugin_simpletabs');
+  }
+
+
+  function postConnect()
+  {
+    $this->Lexer->addExitPattern('</TABAREA>','plugin_simpletabs');
+  }
+
+
+  /**
+   * Handler to prepare matched data for the rendering process.
+   *
+   * <p>
+   * The <tt>$aState</tt> parameter gives the type of pattern
+   * which triggered the call to this method:
+   * </p>
+   * <dl>
+   * <dt>DOKU_LEXER_ENTER</dt>
+   * <dd>a pattern set by <tt>addEntryPattern()</tt></dd>
+   * <dt>DOKU_LEXER_MATCHED</dt>
+   * <dd>a pattern set by <tt>addPattern()</tt></dd>
+   * <dt>DOKU_LEXER_EXIT</dt>
+   * <dd> a pattern set by <tt>addExitPattern()</tt></dd>
+   * <dt>DOKU_LEXER_SPECIAL</dt>
+   * <dd>a pattern set by <tt>addSpecialPattern()</tt></dd>
+   * <dt>DOKU_LEXER_UNMATCHED</dt>
+   * <dd>ordinary text encountered within the plugin's syntax mode
+   * which doesn't match any pattern.</dd>
+   * </dl>
+   * @param $aMatch String The text matched by the patterns.
+   * @param $aState Integer The lexer state for the match.
+   * @param $aPos Integer The character position of the matched text.
+   * @param $aHandler Object Reference to the Doku_Handler object.
+   * @return Integer The current lexer state for the match.
+   * @public
+   * @see render()
+   * @static
+   */
+  function handle($match, $state, $pos, &$handler)
+  {
+    switch ($state)
+    {
+    case DOKU_LEXER_ENTER:
+      $this->tab_area_counter++;
+      //cho "<b>[DEBUG]</b> Encountered tabbed area: " . $this->tab_area_counter . "<br />";
+      $this->current_tab = '';
+      $this->tab_count = 0;
+      $this->tab_names = array();
+      if (preg_match('/tabs="(.+)"/', $match, $matches))
+      {
+        $this->tab_names = explode(',', $matches[1]);
+      }
+      return array($state, array($this->tab_area_counter, $this->tab_names, $this->getConf('defaulttab')));
+      break;
+
+    case DOKU_LEXER_MATCHED:
+      $params = $match;
+      if ($match == '</TAB>')
+      {
+        $this->current_tab = '';
+	// close any section edit block
+	$handler->_addCall('finishSectionEdit', array($pos - 1), $pos);
+	// render end of tabbed area
+        $params = array(true, $this->tab_area_counter, '', 0, false);
+      }
+      else
+      {
+        // Do we have a tab open?
+        $close_first = false;
+        if (!empty($this->current_tab))
+        {
+          // close any section edit block
+          $handler->_addCall('finishSectionEdit', array($pos - 1), $pos);
+          $close_first = true;
+        }
+        $this->current_tab = $this->tab_names[$this->tab_count];
+        $this->tab_count++;
+        $active = false;
+        if ($this->current_tab == $this->getConf('defaulttab'))
+        {
+          $active = true;
+        }
+	// start section edit
+        // - note the +5 is to account for the section starting "<TAB>"
+        $handler->_addCall('startSectionEdit', array(($pos + 5), 'section', $this->current_tab), $pos);
+        $params = array($close_first, $this->tab_area_counter, $this->current_tab, $this->tab_count, $active);
+      }
+      return array($state, $params);
+      break;
+
+    case DOKU_LEXER_UNMATCHED:
+      if (!empty($this->current_tab))
+      {
+        // SPECIAL CASE: We have to handle headers ourselves (apparently -
+        // having looked in several other plugins similar to this)
+        $headerMatch = preg_grep('/([ \t]*={2,}[^\n]+={2,}[ \t]*(?=))/msSi', array($match));
+        // - not a header, just pass it through
+        if (empty($headerMatch))
+        {
+          //$handler->_addCall('cdata', array($match), $pos);
+          return array($state, $match);
+        }
+        else
+        {
+          // if it's a == header ==, use the core header() renderer
+          // (copied from core header() in inc/parser/handler.php)
+          $title = trim($match);
+          $level = 7 - strspn($title,'=');
+          if ($level < 1)
+          {
+            $level = 1;
+          }
+          $title = trim($title,'=');
+          $title = trim($title);
+
+          $handler->_addCall('header',array($title,$level,$pos), $pos);
+          // close the section edit the header could open
+          /*
+          if ($title && $level <= $conf['maxseclevel'])
+          {
+            $handler->addPluginCall('wrap_closesection', array(), DOKU_LEXER_SPECIAL, $pos, '');
+          }
+          */
+        }
+        return false;
+      }
+      break;
+
+    case DOKU_LEXER_EXIT:
+      $close_first = false;
+      if (!empty($this->current_tab))
+      {
+	// close any pending section edit block
+	$handler->_addCall('finishSectionEdit', array($pos - 1), $pos);
+
+        $close_first = true;
+      }
+      // generate dummy heading at top level to ensure that no following headers are nested under titles in the tabbed area
+      $handler->_addCall('header', array('#',1,$pos), $pos);
+      return array($state, $close_first);
+      break;
+
+    case DOKU_LEXER_SPECIAL:
+      break;
+    }
+    return array();
+  }
+
+  /**
+   * Handle the actual output creation.
+   *
+   * <p>
+   * The method checks for the given <tt>$aFormat</tt> and returns
+   * <tt>FALSE</tt> when a format isn't supported. <tt>$aRenderer</tt>
+   * contains a reference to the renderer object which is currently
+   * handling the rendering. The contents of <tt>$aData</tt> is the
+   * return value of the <tt>handle()</tt> method.
+   * </p>
+   * @see handle()
+   */
+  function render($mode, &$renderer, $data)
+  {
+    if($mode == 'xhtml')
+    {
+      list($state, $params) = $data;
+
+      switch ($state)
+      {
+      case DOKU_LEXER_ENTER:
+        list($tab_area_id, $tab_names, $active_tab) = $params;
+	//cho "<b>[DEBUG]</b> Generating tabbed area: " . $tab_area_id . "<br />";
+        $renderer->doc .= '
+<!-- Tabbed Area - Begin -->
+<a href="top' . $tab_area_id . '"></a>
+<div class="tabbed_area" id="t' . $tab_area_id . '">
+  <ul class="tabs">
+';
+        $total_tab_count = count($tab_names);
+        $tab_count = 0;
+        foreach ($tab_names as $tab_name)
+        {
+          $tab_count++;
+          $renderer->doc .= '    <li><a href="javascript:tabSwitch(' . $tab_area_id . ',' . $total_tab_count . ',' . $tab_count . ');" id="t' . $tab_area_id . '_' . $tab_count . '"';
+          if ($tab_name == $active_tab)
+          {
+            $renderer->doc .= ' class="active"';
+          }
+          $renderer->doc .= '>' . $tab_name . '</a></li>
+';
+        }
+        $renderer->doc .= '  </ul>
+';
+        break;
+
+      case DOKU_LEXER_MATCHED:
+        list($close_tab, $tab_area_counter, $tab_name, $tab_content_count, $active) = $params;
+        if ($close_tab)
+        {
+          $renderer->doc .= '<div style="clear:both;height:0px;"></div></div>
+';
+        }
+        if (!empty($tab_name))
+        {
+          $this->tab_content_counter++;
+          $renderer->doc .= '  <div id="tc' . $tab_area_counter . '_' . $tab_content_count . '" class="tab" ';
+          if (!$active)
+          {
+            $renderer->doc .= ' style="display:none;"';
+          }
+          $renderer->doc .= '>';
+        }
+        break;
+
+      case DOKU_LEXER_UNMATCHED:
+        $renderer->doc .= $params;
+        break;
+
+      case DOKU_LEXER_EXIT:
+        $renderer->doc .= '</div>
+<!-- Tabbed Area - End -->';
+        break;
+      }
+      return true;
+    }
+    return false;
+  }
+}
+
+//Setup VIM: ex: et ts=4 enc=utf-8 :
+?>
