====== Development ======

===== Frequently Asked Questions =====

==== Q. How do you enable login to wiki using Greenstone registration? ====

The code changes to allow for Greenstone registration integration should already be present in the dokuwiki retrieved from Greenstone's SVN. To configure the dokuwiki for login follow these instructions:
  - Copy ''<dokuwiki>/conf/mysql.conf.php.example'' to ''<dokuwiki>/conf/mysql.conf.php''
  - Edit the ''mysql.conf.php'' file to have the correct details:<code>$conf['auth']['mysql']['server']   = 'localhost';
$conf['auth']['mysql']['user']     = 'greenstonewiki';
$conf['auth']['mysql']['password'] = '********';
$conf['auth']['mysql']['database'] = 'gs_services';</code>
  - While still in the conf directory, create a file ''local.protected.php'' with the content:<code><?php
require_once('mysql.conf.php');
?></code>
  - Edit the file ''local.php'' and ammend/add the line:<code>...
$conf['authtype'] = 'mysql';
...</code>
  - Ensure the permissions for all three files you've edited are correct as to be readble by the //nzdl// group
  - Disable Dokuwiki's built-in register and email new password abilities by editing ''<dokuwiki>/conf/local.php'' and adding (or updating):<code>$conf['disableactions'] = 'register,resendpwd';</code>Alternatively, you can set these in the "Configuration Settings" page within the "Admin" page. **Note** a later customization step will add back in links to the global Greenstone registration system.

==== Q. How do I create a page? ====

The easiest way is to use the search box in the left navigation to search for a page that isn't already created. Include in the search any path/namespace as required. For instance, we (originally) created this page by searching for:<code>faq</code>but we could have included a path like so:<code>Manuals:User:Section1</code>which would create a ''Manuals'' folder, with a ''User'' folder within it, and finally the ''Section1'' page within that.

When you search for a page that isn't there, the result page will helpfully suggest //"If you didn't find what you were looking for, you can create or edit the page named after your query with the appropriate button."// However, instead of a button, in this page template you'll need to click the tab at the top of the search results page labelled ''create this page''.  If it all works you should find yourself in a textarea editor entering content for the page. Click ''Preview'' to review your content for formatting etc, and ''Save'' to commit changes to the page.

===== Installation =====

  - Checkout the ''gsdl-docs'' package out of SVN
  - Go to ''<gsdl-docs>/lib/dokuwiki/'' and untar the [[http://www.dokuwiki.org/dokuwiki|dokuwiki]] tarball (currently the stable version [[http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2011-05-25a.tgz|Ricewind]])
  - Go back up to ''<gsdl-docs>/'' and create a symlink to the folder you just unpacked called just ''dokuwiki'':<code>ln -s ./lib/dokuwiki/dokuwiki-<version> ./dokuwiki</code> 
  - Copy all of the archive files in ''<gsdl-docs>/lib/dokuwiki/plugins/'' into ''<gsdl-docs>/dokuwiki/lib/plugins/'', then unpack
    * **note** you may need to rename the plugin folders---you'll find Dokuwiki will complain about incorrectly named folders at startup
  - Similarly, copy the ''monobook'' template archive from ''<gsdl-docs>/lib/dokuwiki/templates'' to ''<gsdl-docs>/dokuwiki/lib/tpl/'' and unpack
  - Setup your webserver (as needed) so you can access this dokuwiki directory and run the PHP scripts therein
  - Visit the dokuwiki installer page in a web browser. For example, if you're webserver is running on ''localhost'', at port ''8080'', and the path to ''<gsdl-docs>/'' //is// ''/gsdl-docs'', then visit:<code>http://localhost:8080/gsdl-docs/dokuwiki/install.php</code>
  - Follow the setup instructions, and then follow the recommended [[http://www.dokuwiki.org/security|security settings]] for Dokuwiki, including renaming the ''install.php'' file
  - Overwrite the default configuration by copying the file ''<gsdl-docs>/lib/dokuwiki/conf/local.php'' to ''<gsdl-docs>/dokuwiki/conf/'' overwriting the existing file
  - Recursively copy the starting pages file into place, overwriting existing files if prompted<code>cp -r <gsdl-docs>/lib/dokuwiki/pages/ <gsdl-docs>/dokuwiki/data/pages/</code> 
    * **note** there is a copy of these instructions in the starting files, located at [[wiki:development]]
  - Enter ''<gsdl-docs>/lib/php/''
  - Run each of these commands in order to transform the manual's XML files into Dokuwiki pages:<code>php gs-manuals-import.php -m user
php gs-manuals-import.php -m install
php gs-manuals-import.php -m develop
php gs-manuals-import.php -m paper</code>
    * **note** these require a command line version of PHP to be available on the path
  - Enter the wiki again, log in using the administrator account you created when installing, and then visit each manual wiki page, 'edit' it and click approve
===== Required Plugins =====

  * [[http://www.dokuwiki.org/plugin:captcha|Captcha]] - Use a CAPTCHA challenge to protect DokuWiki against automated spam 
  * [[http://wiki.splitbrain.org/plugin:code2|Code2]] - Enhanced code syntax highlighting with line numbering
  * [[http://wiki.splitbrain.org/plugin:htmlcomment|HTMLComment]] - allows HTML comments to be retained in the output
  * [[http://wiki.splitbrain.org/plugin:ifauth|IFAuth]] - so content only for specific groups and/or users
  * [[http://wiki.splitbrain.org/plugin:imagereference|ImageReference]] - create image references like latex is doing with figures
  * [[http://dokuwiki.org/plugin:orphanswanted|OrphansWanted]] - provide macros to list orphan pages and wanted pages
  * [[http://www.dokuwiki.org/plugin:publish|Publish]] - integrate a publishing process into DokuWiki (differentiating between draft and approved copies of pages)
  * [[http://www.dokuwiki.org/plugin:tablewidth|TableWidth]] - allows the width of tables and table cells to be defined
  * [[:wiki:development#custom_plugins|SimpleTabs]] - as explained below.

===== Customizations =====

**Note:** The diffs regarding the main Dokuwiki code are against the stable release 2011-05-25a "Rincewind". 
==== Dokuwiki ====

=== inc/common.php ===

^ File  ^ Changes  ^
^ inc/common.php  | Allow for 'no change' submissions as long as the Approve flag is ticked (see documentation for [[http://www.dokuwiki.org/plugin:publish|plugin:publish]])  |
| <code diff u>
--- dokuwiki-2011-05-25a/inc/common.php	2011-06-15 07:58:53.000000000 +1200
+++ dokuwiki/inc/common.php	2012-01-17 13:53:12.860063701 +1300
@@ -973,7 +973,8 @@
     global $lang;
     global $REV;
     // ignore if no changes were made
-    if($text == rawWiki($id,'')){
+    // - [jmt12] unless the approved checkbox is set
+    if(!$_POST['approved'] && $text == rawWiki($id,'')){
         return;
     }
</code> ||

=== inc/html.php ===

^ File  ^ Changes  ^
^ inc/html.php  | Add id attributes to the table of contents list items so we can hide the ones on currently hidden tabs. Allow for a 'reset' header to be specified by the user in order to 'break out of' the current TOC nesting (for instance, at the end of a tabbed area to prevent following headings being grouped under Tab area headings).  |
| <code diff u>
--- html.original.php	2014-03-13 11:16:37.000000000 +1300
+++ html.php	2014-03-13 11:13:34.000000000 +1300
@@ -758,9 +758,28 @@ function html_li_index($item){
  *
  * @author Andreas Gohr <andi@splitbrain.org>
  */
+// In order to alter the TOC when a user changes a tab, we
+// need some way to uniquely identify what titles lurk in
+// what tabs. Dokuwiki automagically labels headers with
+// <a name=""> tags - so if I use the same information here
+// they should match (and be unique etc)
+// - jmt12
+// At some stage the traditional 'link' attribute was (some-
+// times) replaced with information in 'hid'
+// - jmt12 2014MAR13
 function html_li_default($item)
 {
-    return '<li class="level' . $item['level'] . '">';
+  $link = $item['link'];
+  if (isset($item['hid']) && !empty($item['hid']))
+    {
+      $link = $item['hid'];
+    }
+  $hash_pos = strpos($link, '#');
+  if ($hash_pos !== false)
+    {
+      $link = substr($link, $hash_pos + 1);
+    }
+  return '<li id="toc_' . $link . '" class="level' . $item['level'] . '">';
 }

 /**
@@ -784,7 +803,24 @@ function html_buildlist($data,$class,$fu
     $ret   = '';
 
     foreach ($data as $item){
-	if( $item['level'] > $level ){
+      // A reset closes all TOC items, all the way back to the top
+      if ($item['title'] == '#')
+	{
+	  //close last item
+	  $ret .= "</li>\n";
+	  while( $level > 0 && $open > 0 ){
+	    //close higher lists
+	    $ret .= "</ul>\n</li>\n";
+	    $level--;
+	    $open--;
+	  }
+	  // open a dummy item list, although we don't output a list item
+	  $ret .= "<li class=\"clear\">\n<ul class=\"$class\">\n<li class=\"clear\">";
+	  $level++;
+	  $open++;
+	  // skip to next item
+	  continue;
+	}elseif( $item['level'] > $level ){
             //open new list
             for($i=0; $i<($item['level'] - $level); $i++){
                 if ($i) $ret .= "<li class=\"clear\">\n";
</code>||


=== inc/lang/en/login.txt ===

^ File  ^ Changes  ^
^ inc/lang/en/login.txt  | Add a link to the global Greenstone registration / password reset page (because we have disabled Dokuwiki's built-in user stuff at the top of this page).  |
| <code diff u>
--- dokuwiki-2011-05-25a/inc/lang/en/login.txt	2012-02-09 10:17:32.000000000 +1300
+++ greenstone-wiki/inc/lang/en/login.txt	2013-10-24 12:12:14.000000000 +1300
@@ -2,3 +2,4 @@
 
 You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.
 
+Don't have an account? [[http://www.greenstone.org/users?&returnto=GreenstoneWiki|Create an account or email new password]].
</code>||
=== inc/parserutils.php ===

^ File  ^ Changes  ^
^ inc/parserutils.php  | Add a check to an introspective call to ensure that the function called exists in the class //before// calling it - otherwise the logs fill up with warnings from classes that don't (i.e. ''Doku_Renderer_metadata'') |
| <code diff u>
--- /greenstone/greenstone-documentation/packages/dokuwiki-2011-05-25a/inc/parserutils.php	2012-02-01 16:03:06.000000000 +1300
+++ parserutils.php	2013-09-19 10:46:58.000000000 +1200
@@ -522,7 +522,12 @@ function p_render_metadata($id, $orig){
         // loop through the instructions
         foreach ($instructions as $instruction){
             // execute the callback against the renderer
-            call_user_func_array(array(&$renderer, $instruction[0]), (array) $instruction[1]);
+	    // - check we can, first, otherwise logs fill up with warnings
+	    $handler = array(&$renderer, $instruction[0]);
+	    if (is_callable($handler))
+            {
+              call_user_func_array($handler, (array) $instruction[1]);
+	    }
         }
 
         $evt->result = array('current'=>&$renderer->meta,'persistent'=>&$renderer->persistent);
</code>||
=== inc/parser/handler.php ===

^ File  ^ Changes  ^
^ inc/parser/handler.php  | Hide HTML comments (namely text ids) in headings  |
| <code diff u>
--- dokuwiki-2011-05-25a/inc/parser/handler.php	2011-06-15 07:58:54.000000000 +1200
+++ dokuwiki/inc/parser/handler.php	2011-12-16 11:37:45.036066485 +1300
@@ -97,6 +97,9 @@
         $title = trim($title,'=');
         $title = trim($title);
 
+        // Hide HTML comments [jmt12]
+        $title = preg_replace('/<\!--[^>]*-->/','',$title);
+
         if ($this->status['section']) $this->_addCall('section_close',array(),$pos);
 
         $this->_addCall('header',array($title,$level,$pos), $pos);
</code> ||

=== inc/parser/xhtml.php ===

^ File  ^ Changes  ^
^ inc/parser/xhtml.php  | Hide the reset header (whose content is simply "#"). Heavily altered //_highlight()// in order to allow the id specifying HTML comments to remain hidden. Added macro to external urls to allow for links to pages on the same host.  |
| <code diff u>
--- dokuwiki-2011-05-25a/inc/parser/xhtml.php	2011-06-15 07:58:54.000000000 +1200
+++ dokuwiki/inc/parser/xhtml.php	2012-01-23 13:16:49.317187175 +1300
@@ -170,6 +170,12 @@
         }
         $this->lastlevel = $level;
 
+	// Hide the 'reset' header
+        if ($text == '#')
+	{
+	  return;
+	}
+
         if ($level <= $conf['maxseclevel'] &&
             count($this->sectionedits) > 0 &&
             $this->sectionedits[count($this->sectionedits) - 1][2] === 'section') {
             
@@ -449,19 +449,24 @@
             $text = substr($text, 0, -1);
         }
 
+        // - code HTML is now temporarily stored in a local string so we can
+        //   restore specific HTML comments [jmt12]
+        $code_text = '';
         if ( is_null($language) ) {
-            $this->doc .= '<pre class="'.$type.'">'.$this->_xmlEntities($text).'</pre>'.DOKU_LF;
+          $code_text = '<pre class="'.$type.'">'.$this->_xmlEntities($text).'</pre>'.DOKU_LF; // [jmt12]
         } else {
             $class = 'code'; //we always need the code class to make the syntax highlighting apply
             if($type != 'code') $class .= ' '.$type;
 
-            $this->doc .= "<pre class=\"$class $language\">".p_xhtml_cached_geshi($text, $language, '').'</pre>'.DOKU_LF;
+            $code_text = "<pre class=\"$class $language\">".p_xhtml_cached_geshi($text, $language, '').'</pre>'.DOKU_LF; // [jmt12]
         }
+        // - restore id comments! [jmt12]
+        $code_text = preg_replace('/\&lt\;\!\-\-\s+id\:([^\s]+)\s+\-\-\&gt\;/','<!-- id:\1 -->', $code_text);
+        $this->doc .= $code_text; // [jmt12]
 
         if($filename){
             $this->doc .= '</dd></dl>'.DOKU_LF;
         }

         $this->_codeblock++;
     }
 
@@ -665,6 +670,16 @@
             $class='media';
         }
 
+        // [jmt12] Replace the macro ~~localhost~~ with the hostname (and port
+        //         number if necessary) of the current host
+        if (preg_match('/^http:\/\/~~baseurl~~(\/.*)$/', $url, $matches))
+        {
+          $host = $_SERVER['HTTP_HOST'];
+          $path = substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/'));
+          $url = 'http://' . $host . $path . $matches[1];
+        }
+        // [jmt12]
+
         //prepare for formating
         $link['target'] = $conf['target']['extern'];
         $link['style']  = '';
</code> ||
===== Plugins =====

==== Custom Plugins ====

=== SimpleTabs ===

Support for simple tabbed areas (as compared to the existing complicated tabbed area plugins ala [[https://www.dokuwiki.org/plugin:tabinclude|TabInclude]]) is provided through a custom-built plugin. To reinstall:
  * download {{:wiki:simpletabs-2014dec05.tgz|SimpleTabs}} (5.5K)
  * extract to ''<dokuwiki>/lib/plugins/''
The syntax looks like this:<code><TABAREA tabs="comma,separated,list">
<TAB>content for 'comma' //including// wiki <del>magic</del> formatting</TAB>
<TAB>content for 'separated' and a [[:playground|link]]</TAB>
<TAB>content for 'list'</TAB>
</TABAREA></code>

Older versions: {{:wiki:simpletabs-2013sep18.tgz|2013SEP18}} (5.0K) {{:wiki:simpletabs-2013aug02.tgz|2013AUG02}} (4.3K)
==== Code ====

Diff against [[http://wiki.splitbrain.org/plugin:code2|code2]] plugin dated 2008-07-22.

^ File  ^ Changes  ^
^ syntax.php  | Restore the HTML comments containing text fragment ids to be proper hidden comments.  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/code/syntax.php	2012-01-23 11:16:05.033314469 +1300
+++ dokuwiki/lib/plugins/code/syntax.php	2012-01-23 11:16:19.122156271 +1300
@@ -226,6 +226,8 @@
 	function &_entities(&$aString) {
 		$aString = str_replace(array('&', '<', '>'),
 			array('&#38;', '&#60;', '&#62;'), $aString);
+                // [jmt12] Restore the hidden ids to normal HTML comments
+                $aString = preg_replace('/&#60;!-- id:(.*?) --&#62;/','<!-- id:\1 -->', $aString);
 		return $aString;
 	} // _entities()
</code>  ||
==== HTMLComment ====

Diff against [[http://wiki.splitbrain.org/plugin:htmlcomment|htmlcomment]] plugin dated 2005-10-08.

^ File  ^ Changes  ^
^ syntax.php  | Added code to allow the use of an alternate HTML comment block (prefix %!--, suffix --%) that is automagically rendered using entities to appear verbatim in text (so appears as <!-- ... --> rather than being hidden).  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/htmlcomment/syntax.php	2005-10-09 11:31:47.000000000 +1300
+++ dokuwiki/lib/plugins/htmlcomment/syntax.php	2012-01-20 14:03:27.078084422 +1300
@@ -41,15 +41,24 @@
     }
 
     function connectTo($mode) {
-        $this->Lexer->addSpecialPattern("<\!--.*?-->", $mode,
-          'plugin_htmlcomment');
+        $this->Lexer->addSpecialPattern("<\!--.*?-->", $mode, 'plugin_htmlcomment');
+        $this->Lexer->addSpecialPattern("%\!--.*?--%", $mode, 'plugin_htmlcomment');
+        $this->Lexer->addSpecialPattern("<br/>", $mode, 'plugin_htmlcomment');
     }
 
     function handle($match, $state, $pos, &$handler) {
         if ($state == DOKU_LEXER_SPECIAL) {
-             // strip <!-- from start and --> from end
-            $match = substr($match,4,-3);
-            return array($state, $match);
+          if ($match == '<br/>')
+          {
+            return array('newline',$match);
+          }
+          if (strpos($match, '%!--') !== false)
+          {
+            $state = 'displaycomment';
+          }
+          // strip <!-- from start and --> from end
+          $match = substr($match,4,-3);
+          return array($state, $match);
         }
         return array();
     }
@@ -57,14 +66,31 @@
     function render($mode, &$renderer, $data) {
         if ($mode == 'xhtml') {
             list($state, $match) = $data;
-            if ($state == DOKU_LEXER_SPECIAL) {
-                $renderer->doc .= '<!--';
-                if (HTMLCOMMENT_SAFE) {
-                    $renderer->doc .= $renderer->_xmlEntities($match);
-                } else {
-                    $renderer->doc .= $match;
-                }
-                $renderer->doc .= '-->';
+            if ($state == 'newline')
+            {
+              $renderer->doc .= $match;
+              return true;
+            }
+            if ($state == 'displaycomment')
+            {
+              $renderer->doc .= '&lt;!--';
+            }
+            else
+            {
+              $renderer->doc .= '<!--';
+            }
+            if (HTMLCOMMENT_SAFE) {
+              $renderer->doc .= $renderer->_xmlEntities($match);
+            } else {
+              $renderer->doc .= $match;
+            }
+            if ($state == 'displaycomment')
+            {
+              $renderer->doc .= '--&gt;';
+            }
+            else
+            {
+              $renderer->doc .= '-->';
             }
             return true;
         }
</code> ||
==== ImageReference ====

Diff against [[http://wiki.splitbrain.org/plugin:imagereference|imagereference]] plugin dated 2008-05-30.

^ File  ^ Changes  ^
^ script.js  | More tests to prevent trying to access null objects  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/imagereference/script.js      2009-01-07 21:48:25.000000000 +1300
+++ dokuwiki/lib/plugins/imagereference/script.js       2011-12-16 11:40:42.128166685 +1300
@@ -3,7 +3,8 @@
        var divs=document.getElementsByTagName("DIV");
  
       for (var i=0;i<divs.length;i++) {
-        if (divs[i].className == "imgcaption" || divs[i].className == "imgcaptionleft" || divs[i].className == "imgcaptionright") {
+        // adding in more checks to ensure elements exist [jmt12]
+        if (divs[i] && divs[i].childNodes[0] && divs[i].childNodes[0].childNodes[0] && (divs[i].className == "imgcaption" || divs[i].className == "imgcaptionleft" || divs[i].className == "imgcaptionright")) {
  
             var children = divs[i].getElementsByTagName("IMG");
             // check if there is a link encapsulating the image        
@@ -13,12 +14,16 @@
             else {
                 // we have link and we can build the link image
                 var innerElements = divs[i];
-                var iLink = innerElements.childNodes[1].childNodes[2];
-                var iSpan = iLink.childNodes[0];
-                // set the href of the link to the image link
-                iLink.href= innerElements.childNodes[0].href;
-                // show the link image
-                iSpan.style.display="inline";
+                // adding in more checks to ensure elements exist [jmt12]
+                if (innerElements && innerElements.childNodes[0] && innerElements.childNodes[1])
+                {
+                  var iLink = innerElements.childNodes[1].childNodes[2];
+                  var iSpan = iLink.childNodes[0];
+                  // set the href of the link to the image link
+                  iLink.href= innerElements.childNodes[0].href;
+                  // show the link image
+                  iSpan.style.display="inline";
+                }
             }    
             //var tmpLink = divs[i].childNodes[0];
             divs[i].style.width=(tmpImg.width + 8)+"px";
</code> ||
^ style.css  | Altering colours to make caption bars fit in better with Monobook template  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/imagereference/style.css      2008-09-11 02:56:24.000000000 +1200
+++ dokuwiki/lib/plugins/imagereference/style.css       2012-01-16 10:48:34.558129586 +1300
@@ -7,15 +7,17 @@
 
 
 div.imgcaption {
-    border: 1px solid #ccc;
+    border: 0px solid #000;
     padding: 3px !important;
-    background-color: #f9f9f9;  
-    font-size: 94%;
+    /*background-color: #113355;*/
+    background-color: #777777;
+    /*font-size: 94%;*/
     text-align: center;
     width: auto;
     overflow: hidden;
     margin: 1px auto;
     float: none;
+    font-weight: bold;
 }
 
 div.imgcaptionleft {
@@ -62,7 +64,8 @@
 }
 
 div.dokuwiki .undercaption a:hover {
-    text-decoration:none;
+    color: #002BB8 !important;
+    text-decoration:underline;
 }
 
 div.dokuwiki .undercaption span {
</code> ||
^ syntax.php  | Rewrote large chunks of this code to; a) allow for table captions too, b) preserve formatting (italics) in the captions, c) allow specially formatted 'HTML comments' to be inserted but not display (to allow capture and retention of explicit text ids) and d) fix minor bugs (looks like some things were in a state of change from strings to arrays - some bits of the code were expecting the other)  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/imagereference/syntax.php     2008-09-11 18:29:12.000000000 +1200
+++ dokuwiki/lib/plugins/imagereference/syntax.php      2012-01-19 11:03:52.285067251 +1300
@@ -22,6 +22,7 @@
        
        var $_figure_name_array = array("");
        var $_figure_map = array();
+        var $_captions = array();
        
        
    /**
@@ -80,13 +81,17 @@
     * @see render()
     */
     function connectTo($mode) {
+
       $this->Lexer->addSpecialPattern('<imgref\s[^\r\n]*?>',$mode, 'plugin_imagereference');
-         $this->Lexer->addEntryPattern('<imgcaption\s[^\r\n\|]*?>(?=.*?</imgcaption.*?>)',$mode,'plugin_imagereference');
-         $this->Lexer->addEntryPattern('<imgcaption\s[^\r\n\|]*?\|(?=[^\r\n]*>.*?</imgcaption.*>)',$mode,'plugin_imagereference');
+      $this->Lexer->addSpecialPattern('<tblref\s[^\r\n]*?>',$mode, 'plugin_imagereference');
+
+      $this->Lexer->addEntryPattern('<imgcaption\s[^\|]+\|[^>]+(?=>.*?</imgcaption>)',$mode,'plugin_imagereference');
+      $this->Lexer->addEntryPattern('<tblcaption\s[^\|]+\|[^>]+(?=>.*?</tblcaption>)',$mode,'plugin_imagereference');
     }
- 
+
     function postConnect() {
       $this->Lexer->addExitPattern('</imgcaption>', 'plugin_imagereference');
+      $this->Lexer->addExitPattern('</tblcaption>', 'plugin_imagereference');
     }
        
  
@@ -120,24 +125,39 @@
     * @static
     */
     function handle($match, $state, $pos, &$handler){
-       
         switch ($state) {
         // =========================================================
            case DOKU_LEXER_ENTER : {
-               /* --------------------------------------------------- */
-               $refLabel = trim(substr($match, 11, -1));
+
+             /* --------------------------------------------------- */
+             $refLabel = ''; //trim(substr($match, 11, -1));
+             $caption = '';
+             if (preg_match('/<(?:img|tbl)caption\s+([^\|]+)\|([^>]+)/', $match, $matches))
+             {
+               $refLabel = $matches[1];
+               $caption = $matches[2];
+             }
                // -----------------------------------------------------
                $parsedInput = $this->_parseParam($refLabel);
-               
+
                // ------------------------------------------------------
                //$data = $this->_imgstart($parsedInput);
                // store the figure name from imgcaption
                array_push($this->_figure_name_array, $parsedInput[0]);
-               
-               $this->_figure_map[$parsedInput[0]] = "";
-               
+
+               $this->_figure_map[$parsedInput[0]] = '';
+
+                $this->_captions[$parsedInput[0]] = $caption;
+
+                ///cho '<p>refLabel:' . $refLabel . '</p>';
+                ///cho '<p>parsedInput:' . print_r($parsedInput, true) . '</p>';
+                ///cho '<p>figure_name_array: ' . print_r($this->_figure_name_array, true) . '</p>';
+                ///cho '<p>figure_map: ' . print_r($this->_figure_map, true) . '</p>';
+                ///cho '<p>captions: ' . print_r($this->_captions, true). '</p>';
+
                return array('caption_open', $parsedInput);  // image anchor label
                /* --------------------------------------------------- */
+                //}
            }
         // =========================================================
           case DOKU_LEXER_UNMATCHED : {
@@ -191,7 +211,6 @@
     * @see handle()
     */
     function render($mode, &$renderer, $indata) {
-       
         list($case, $data) = $indata;
         if($mode == 'xhtml'){
                // ---------------------------------------------
@@ -200,8 +219,14 @@
                        /* --------------------------------------- */
                        $refNumber = array_search($data, $this->_figure_name_array);
                        if ($refNumber == null || $refNumber == "")
-                               $refNumber = "##";
-                       $str = "<a href=\"#".$data."\">".$this->getLang('figure').$refNumber." </a>";
+                        {
+                          $refNumber = "##";
+                        }
+                        if (strpos($data,'#') === false)
+                        {
+                          $data = "#" . $data;
+                        }
+                       $str = "<a class=\"wikilink1\" href=\"".$data."\">".$this->getLang('figure').$refNumber."</a>";
                        $renderer->doc .= $str; break;
 //                      $renderer->_xmlEntities($str);break;
                        /* --------------------------------------- */
@@ -210,10 +235,26 @@
                case 'caption_close' :  {
                        // -------------------------------------------------------
                                list($name, $number, $caption) = $data;
-                               $layout = "<div class=\"undercaption\">".$this->getLang('fig').$number.": 
-                                       <a name=\"".$name."\">".$caption."</a><a href=\" \"><span></span></a>
-                                       </div></div>";
-                                       $renderer->doc .= $layout; break;
+                        // - retrieve the caption separately
+                        $caption = $this->_captions[$name];
+                        // - special case for 'hidden' tables
+                        $layout = '';
+                        if ($caption != '##HIDDEN##')
+                        {
+                          // - manual do any formatting (as leaving it to the
+                          //   parser (to foobar) is why we had to do this in
+                          //   the first place
+                          $caption = preg_replace('/\/\/%%(.+?)%%\/\//','<i>\1</i>',$caption);
+                          $caption = preg_replace('/\/\/(.+?)\/\//','<i>\1</i>',$caption);
+                          $caption = preg_replace('/\*\*(.+?)\*\*/','<b>\1</b>',$caption);
+                          $caption = str_replace('%!--', '<!--', $caption);
+                          $caption = str_replace('--%', '-->', $caption);
+                          // - special case: nested image ref (we can't really resolve these)
+                          $caption = preg_replace('/<imgref\s+([^>]+)><\/imgref>/','\1',$caption);
+                          $layout = "<div class=\"undercaption\">".$this->getLang('fig').$number.": <a name=\"".$name."\"></a>".$caption."</div>";
+                          }
+                        $layout .= "</div>";
+                        $renderer->doc .= $layout; break;
                }
                                // -------------------------------------------------------      
                                // data is mostly empty!!!
@@ -284,7 +325,7 @@
     
     function _imgstart($str) {
        // ============================================ //
-       if (!strlen($str)) return array();
+      if (empty($str)) return '';
        
                $layout = "<div class=\"imgcaption";
                //$layout = "<div><div class=\"imgcaption";
@@ -304,6 +345,8 @@
      * @return array(imagename, image number, image caption)
      */
     function _imgend($str) {
+      // [jmt12] I think this function is unused!
+
        // ===================================================== //
        $figureName = end($this->_figure_name_array);
        // get the position of the figure in the array
@@ -311,8 +354,9 @@
                
                return array($figureName, $refNumber, $str);
                
+
                $layout = "<div class=\"undercaption\">".$this->getLang('fig').$refNumber.": 
-               <a name=\"".end($this->_figure_name_array)."\">".$str."</a></div>";
+               <a name=\"".end($this->_figure_name_array)."\"></a>".$str."</div>";
                
                //$layout = "<div id=\"undercaption\">Fig. ".$refNumber.": 
                //<a name=\"".end($this->_figure_name_array)."\">".$str."</a></div></div></div>";
</code> ||
^ lang/en/lang.php  | Changed the strings  |
| <code diff u>
--- /dokuwiki-2011-05-25a/lib/plugins/imagereference/lang/en/lang.php       2008-09-11 02:56:24.000000000 +1200
+++ dokuwiki/lib/plugins/imagereference/lang/en/lang.php        2011-12-12 11:24:57.668503137 +1300
@@ -3,5 +3,5 @@
  * english language file
  */
 
-$lang['fig']           = 'Fig. ';
-$lang['figure']        = 'figure';
\ No newline at end of file
+$lang['fig']           = 'Figure ';
+$lang['figure']        = 'figure';
</code> ||
==== Publish ====

Diff against [[http://www.dokuwiki.org/plugin:publish|publish]] plugin dated 2011-10-02.

^ File  ^ Changes  ^
^ action.php  | Never display "previous version" span - you can always look under old revisions anyway. In fact, try to hide the 'publish state' message unless the user is looking at a draft or if they are an editor (whereupon they may be interested in when a page was last approved etc)  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/publish/action.php    2011-10-16 03:55:40.000000000 +1300
+++ dokuwiki/lib/plugins/publish/action.php     2012-01-24 10:34:18.115128733 +1300
@@ -147,10 +147,14 @@
         if($approver && !$most_recent_approved) { $strings[] = 'yes'; } else { $strings[] = 'no'; }
         $strings[] = '">';
 
+        # [jmt12] We may not display the message at all
+        $display_message = false;
+
         if($most_recent_draft) {
             $strings[] = '<span class="approval_latest_draft">';
             $strings[] = sprintf($this->getLang('apr_recent_draft'), wl($ID, 'force_rev=1'));
             $strings[] = $this->difflink($ID, null, $REV) . '</span>';
+            $display_message = true;
         }
 
         if($most_recent_approved) {
@@ -160,6 +164,7 @@
             $strings[] = '<span class="approval_outdated">';
             $strings[] = sprintf($this->getLang('apr_outdated'), wl($ID, 'rev=' . $userrev));
             $strings[] = $this->difflink($ID, $userrev, $REV) . '</span>';
+            $display_message = true;
         }
 
         if(!$approver) {
@@ -168,28 +173,27 @@
             $strings[] = sprintf($this->getLang('apr_draft'),
                             '<span class="approval_date">' . $longdate . '</span>');
             $strings[] = '</span>';
+            $display_message = true;
         }
 
-        if($approver) {
+        // [jmt12] Only display this notice to editors
+        if($approver &&  $INFO['perm'] >= AUTH_EDIT) {
             # Approved
             $strings[] = '<span class="approval_approved">';
             $strings[] = sprintf($this->getLang('apr_approved'),
                             '<span class="approval_date">' . $longdate . '</span>',
                             editorinfo($approver));
             $strings[] = '</span>';
-        }
-
-        if($previous_approved) {
-            $strings[] = '<span class="approval_previous">';
-            $strings[] = sprintf($this->getLang('apr_previous'),
-                            wl($ID, 'rev=' . $previous_approved),
-                            dformat($previous_approved));
-            $strings[] = $this->difflink($ID, $previous_approved, $REV) . '</span>';
+            $display_message = true;
         }
 
         $strings[] = '</div>';
 
-        ptln(implode($strings));
+        // [jmt12] if there is no message content, hide empty div
+        if ($display_message)
+        {
+          ptln(implode($strings));
+        }
         return true;
     }
 
</code> ||
^ style.css  | Making the message bubbles at the top of pages a little smaller (it was taking up about 2 inches of vertical real-estate, which was expensive even on my wide screen---small screen users would have suffered greatly)  |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/plugins/publish/style.css     2011-10-16 03:55:40.000000000 +1300
+++ dokuwiki/lib/plugins/publish/style.css      2012-01-17 13:47:35.324065886 +1300
@@ -3,7 +3,7 @@
   margin-left: auto;
   margin-right: auto;
   width: 70% !important;
-  min-height: 40px;
+  min-height: 20px;
   clear: both;
   text-align: justify;
   vertical-align: middle;
</code> ||  
===== Templates =====

==== Monobook ====

Diff against [[https://www.dokuwiki.org/template:monobook|monobook]] template dated 2011-12-10.

^ File  ^ Changes  ^
^ main.php  | Removed positioning test so that the hierarchy navigation appears at both the top and bottom of pages (rather than one or the other)  |
|  <code diff u>
--- dokuwiki-2011-05-25a/lib/tpl/monobook/main.php	2012-01-23 13:37:25.353131918 +1300
+++ dokuwiki/lib/tpl/monobook/main.php	2013-10-24 12:22:48.000000000 +1300
@@ -613,8 +613,8 @@
               $ACT !== "media" && //var comes from DokuWiki
               (empty($conf["useacl"]) || //are there any users?
                $loginname !== "" || //user is logged in?
-               !tpl_getConf("monobook_closedwiki")) &&
-              tpl_getConf("monobook_youarehere_position") === "top"){
+               !tpl_getConf("monobook_closedwiki"))){// &&
+                //              tpl_getConf("monobook_youarehere_position") === "top"){
               echo "\n          <div class=\"catlinks noprint\"><p>\n            ";
               tpl_youarehere();
               echo "\n          </p></div>\n";
@@ -665,8 +665,8 @@
               $ACT !== "media" && //var comes from DokuWiki
               (empty($conf["useacl"]) || //are there any users?
                $loginname !== "" || //user is logged in?
-               !tpl_getConf("monobook_closedwiki")) &&
-              tpl_getConf("monobook_youarehere_position") === "bottom"){
+               !tpl_getConf("monobook_closedwiki"))){ // &&
+                //              tpl_getConf("monobook_youarehere_position") === "bottom"){
               echo "\n          <div class=\"catlinks noprint\"><p>\n            ";
               tpl_youarehere();
               echo "\n          </p></div>\n";               
@@ -698,7 +698,7 @@
           //default
           echo "style=\"background-image:url(".DOKU_TPL."static/3rd/dokuwiki/logo.png);\"";
       }
-      echo " accesskey=\"h\" title=\"[ALT+H]\"></a>\n";
+      echo " accesskey=\"h\" title=\"Back to start [ALT+H]\"></a>\n";
       ?>
     </div>
     <?php
@@ -733,7 +733,7 @@
                 echo "          <li id=\"pt-mytalk\">".html_wikilink(tpl_getConf("monobook_discuss_ns").ltrim(tpl_getConf("monobook_userpage_ns"), ":").$loginname, hsc($lang["monobook_tab_mytalk"]))."</li>";
             }
             //profile
-            echo  "          <li id=\"pt-preferences\"><a href=\"".wl(cleanID(getId()), array("do" => "profile"))."\" rel=\"nofollow\">".hsc($lang["btn_profile"])."</a></li>\n"; //language comes from DokuWiki core
+            echo  "          <li id=\"pt-preferences\"><a href=\"http://www.greenstone.org/users/change.php\" rel=\"nofollow\">".hsc($lang["btn_profile"])."</a></li>\n"; //language comes from DokuWiki core
             //logout
             echo  "          <li id=\"pt-logout\"><a href=\"".wl(cleanID(getId()), array("do" => "logout"))."\" rel=\"nofollow\">".hsc($lang["btn_logout"])."</a></li>\n"; //language comes from DokuWiki core
         }  
</code>  ||
^ static/css/screen.css  | Restrict the width of code blocks - otherwise they'll push out past the 1000px limit anyway - and set them to use scrollbars for any overflow.  Making h5 different (I can't remember why). Two little fixes for the new simple tabbed area where there are extra pixels sneaking in between the tabs and the tab content areas. |
| <code diff u>
--- screen.css.original	2012-12-13 12:54:13.000000000 +1300
+++ screen.css	2013-08-02 12:00:08.000000000 +1200
@@ -535,10 +535,12 @@ div#content .dokuwiki h1 a,
 div#content .dokuwiki h2 a,
 div#content .dokuwiki h3 a,
 div#content .dokuwiki h4 a,
-div#content .dokuwiki h5 a,
 div#content .dokuwiki h6 a {
   color: __text__;
 }
+div#content .dokuwiki h5 a {
+  color: __background__;
+}
 div#content .dokuwiki h1 a:hover,
 div#content .dokuwiki h2 a:hover,
 div#content .dokuwiki h3 a:hover,
@@ -571,6 +573,7 @@ div#content .dokuwiki h4 {
 }
 div#content .dokuwiki h5 {
   font-size: 100%;
+  color: __background__;
 }
 div#content .dokuwiki h6 {
   font-size: 80%;
@@ -629,7 +632,7 @@ div.dokuwiki li.closed {
 
 div#content div.dokuwiki li {
   margin-left: 0;
-  margin-bottom: 1px;
+  margin-bottom: 0;
 }
 
 /* quotes */
@@ -678,6 +678,8 @@
   line-height: 1.2em;
   padding: 0.5em;
   border-style: dashed;
+  overflow: scroll;
+  width: 800px;
 }
 div#content .dokuwiki dl.file,
 div#content .dokuwiki dl.file dd {
@@ -1338,3 +1343,7 @@ textarea,
   #font-weight: bold;
   #border-left: 1px dashed __background__; /* invisible border triggers IE to render the stuff */
 }
+
+div.tab {
+ margin-top:-1px;
+}
</code> ||
^ static/3rd/dokuwiki/_tabs.css  | Remove the override of foreground and background colours. |
| <code diff u>
--- _tabs.css.original	2013-08-02 12:07:12.000000000 +1200
+++ _tabs.css	2013-08-02 12:07:36.000000000 +1200
@@ -19,8 +19,6 @@
     float: left;
     padding: .3em .8em;
     margin: 0 .3em 0 0;
-    background-color: __background_neu__;
-    color: __text__;
     border-radius: .5em .5em 0 0;
 }
 .dokuwiki ul.tabs li strong {
</code> ||
^ static/3rd/monobook/main.css  | Reduce the text area to around 1000px by centring main div and other absolute divs (logo and top navigation).  Rename the style "preferences" to "preftitle" to prevent CSS being randomly injected where-ever you end up with an anchor tag that just happens to have the word preferences in it (happens surprisingly often in instruction manuals). I can't actually find where this style is used anyway. |
| <code diff u>
--- dokuwiki-2011-05-25a/lib/tpl/monobook/static/3rd/monobook/main.css	2012-01-23 13:41:54.253064506 +1300
+++ dokuwiki/lib/tpl/monobook/static/3rd/monobook/main.css	2012-01-23 11:45:42.674067707 +1300
@@ -27,7 +27,7 @@
 	background: white;
 	color: black;
 	border: 1px solid #aaa;
-	border-right: none;
+	/*border-right: none;*/
 	line-height: 1.5em;
 	position: relative;
 	z-index: 2;
@@ -54,6 +54,8 @@
 /* scale back up to a sane default */
 #globalWrapper {
 	font-size: 127%;
+	width: 1024px;
+	margin: 0 auto;
 	padding: 0;
 }
 .visualClear {
@@ -702,7 +704,7 @@
 	z-index: 3;
 	position: absolute; /*needed to use z-index */
 	top: 0;
-	left: 0;
+	/*left: 0;*/
 	height: 155px;
 	width: 12em;
 	overflow: visible;
@@ -858,9 +860,10 @@
 #p-cactions {
 	position: absolute;
 	top: 1.3em;
-	left: 11.5em;
+	/*left: 11.5em;*/
 	margin: 0;
 	white-space: nowrap;
+	width: 1024px;
 	line-height: 1.1em;
 	overflow: visible;
 	background: none;
@@ -1034,7 +1037,7 @@
 	padding-top: 2em;
 	clear: both;
 }
-#preferences {
+#preftitle {
 	margin: 0;
 	border: 1px solid #aaa;
 	clear: both;
</code> ||