1<?php
2  if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
3  if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4  require_once(DOKU_PLUGIN.'syntax.php');
5
6  if(!defined('DOKU_LF')) define('DOKU_LF',"\n");
7
8/** Column List
9
10    Display a list of items in columns.
11
12    Syntax:
13      , First column.
14      , Second column.
15      , New row.
16        (If using two columns.)
17
18    License: GPL
19    */
20class syntax_plugin_columnlist extends DokuWiki_Syntax_Plugin {
21
22  var $columns = 4;
23  var $cur_col = 0;
24
25  function getInfo() {
26    return array('author' => 'Tom N Harris',
27                 'email'  => 'tnharris@whoopdedo.org',
28                 'date'   => 'Sat, Feb 03, 2007',
29                 'name'   => 'Column List Plugin',
30                 'desc'   => 'Display a list of items formatted as columns. Syntax: <tab>, ...
31                              Default formatting is 4 columns. Add ~~COL:<num>~~ before the first item to change this.',
32                 'url'    => 'http://whoopdedo.org/doku/wiki');
33  }
34
35  function getType() {
36    return 'container';
37  }
38
39  function getPType() {
40    return 'block';
41  }
42
43  function getSort() {
44    return 19;
45  }
46
47  function accepts($mode) {
48    if (!count($this->allowedModes)) {
49      global $PARSER_MODES;
50      $this->allowedModes = array_merge($PARSER_MODES['formatting'],
51                                        $PARSER_MODES['substition'],
52                                        $PARSER_MODES['protected'],
53                                        $PARSER_MODES['disabled']);
54    }
55    return parent::accepts($mode);
56  }
57
58  function connectTo($mode) {
59    $this->Lexer->addEntryPattern('\n {2,},', $mode, 'plugin_columnlist');
60    $this->Lexer->addEntryPattern('\n\t{1,},', $mode, 'plugin_columnlist');
61    $this->Lexer->addEntryPattern('~~COL:\d+~~', $mode, 'plugin_columnlist');
62    $this->Lexer->addPattern('\n {2,},', 'plugin_columnlist');
63    $this->Lexer->addPattern('\n\t{1,},', 'plugin_columnlist');
64  }
65
66  function postConnect() {
67    $this->Lexer->addExitPattern('\n', 'plugin_columnlist');
68  }
69
70  function handle($match, $state, $pos, &$handler){
71    if (substr($match,0,6) == '~~COL:') {
72      $n = (int)substr($match, 6, -2);
73      if ($n != 0) {
74        $this->columns = $n;
75      }
76    }
77    $tags = array();
78    switch ($state) {
79      case DOKU_LEXER_EXIT:
80        $tags[] = 'end_col';
81        $this->cur_col = 0;
82        $this->columns = 4;
83        break;
84      case DOKU_LEXER_ENTER:
85        $tags[] = 'open_col';
86        $tags[] = $this->columns;
87        $this->cur_col = 0;
88        if (substr($match,0,6) == '~~COL:') break;
89      case DOKU_LEXER_MATCHED:
90        $this->cur_col++;
91        if ($this->cur_col > $this->columns) {
92          $tags[] = 'break';
93          $this->cur_col = 1;
94        } else {
95          $tags[] = 'col';
96        }
97        break;
98      case DOKU_LEXER_UNMATCHED:
99        return array(false, $match);
100    }
101    return $tags;
102  }
103
104  function render($format, &$renderer, $data) {
105    static $column = 4;
106    static $cur_col = 0;
107    if (substr($format,0,5) == 'xhtml'){
108      if ($data[0] !== false) {
109        while ($tag = array_shift($data)) {
110          switch ($tag) {
111          case 'open_col':
112            $columns = array_shift($data);
113            if (!$columns) $columns = 4;
114            $renderer->doc .= "<table class=\"columnlist\">";
115            $p = (int)(100 / $columns);
116            for ($n=0;$n<$columns;$n++)
117              $renderer->doc .= "<col width=\"$p%\"/>";
118            $renderer->doc .= "<tr>";
119            $cur_col = 0;
120            break;
121          case 'col':
122            if ($cur_col > 0)
123              $renderer->doc .= "</td>";
124            $renderer->doc .= "<td>";
125            $cur_col++;
126            break;
127          case 'break':
128            if ($cur_col > 0)
129              $renderer->doc .= "</td>";
130            $renderer->doc .= "</tr><tr><td>";
131            $cur_col=1;
132            break;
133          case 'end_col':
134            if ($cur_col > 0) {
135              $renderer->doc .= "</td>";
136              for (;$cur_col < $columns;$cur_col++)
137                $renderer->doc .= "<td></td>";
138            }
139            $renderer->doc .= "</tr></table>";
140            $cur_col = 0;
141            $clumns = 4;
142            break;
143          }
144        }
145      } else {
146        $renderer->doc .= $renderer->_xmlEntities($data[1]);
147      }
148    } elseif ($format == 'metadata') {
149      if ($renderer->capture) {
150        if ($data[0] !== false) {
151          if (in_array('open_col',$data) || in_array('col',$data) || in_array('break',$data)) {
152            $renderer->doc .= DOKU_LF;
153          } elseif (in_array('end_col',$data)) {
154            if (strlen($renderer->doc) > 250) $renderer->capture = false;
155          } else return false;
156        } else {
157          $renderer->doc .= $data[1];
158        }
159      }
160      return true;
161    }
162    return false;
163  }
164}
165