1<?php
2/**
3 * Plugin Chessdiagram: Creates a chessdiagram from FEN or 8x8 characters
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Michael Arlt <michael.arlt@sk-schwanstetten.de>
7 * @version    2016-11-08
8 */
9
10if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
12if(!defined('IMAGE_PATH')) define('IMAGE_PATH',DOKU_BASE.'lib/plugins/chessdiagram/images/');
13require_once(DOKU_PLUGIN.'syntax.php');
14
15/**
16 * All DokuWiki plugins to extend the parser/rendering mechanism
17 * need to inherit from this class
18 */
19class syntax_plugin_chessdiagram extends DokuWiki_Syntax_Plugin {
20
21    /**
22     * function constructor
23     */
24    function syntax_plugin_chessdiagram(){
25      // enable direct access to language strings
26      $this->setupLocale();
27    }
28
29    /**
30     * return some info
31     */
32    function getInfo(){
33        return array(
34            'author' => 'Michael Arlt',
35            'email'  => 'michael.arlt@sk-schwanstetten.de',
36            'date'   => '2016-11-08',
37            'name'   => 'Chessdiagram Plugin',
38            'desc'   => $lang['desc'],
39            'url'    => 'http://wiki.splitbrain.org/plugin:chessdiagram'
40        );
41    }
42
43    /**
44     * What kind of syntax are we?
45     */
46    function getType(){
47        return 'substition';
48    }
49
50    /**
51     * Where to sort in?
52     */
53    function getSort(){
54        return 999;
55    }
56
57
58    /**
59     * Connect pattern to lexer
60     */
61    function connectTo($mode) {
62      $this->Lexer->addSpecialPattern('<'.$this->lang['kwpattern'].'>.+?</'.$this->lang['kwpattern'].'>',$mode,'plugin_chessdiagram');
63    }
64
65    /**
66     * Handle the match
67     */
68    function handle($match, $state, $pos, Doku_Handler $handler)
69    {
70      $match=substr($match,strlen($this->lang['kwpattern'])+2,-(strlen($this->lang['kwpattern'])+3));
71      foreach (preg_split('/\r\n|\r|\n/',$match) as $line)
72      {
73         $line=preg_replace("/#.*/","",trim($line));
74         if(substr($line,0,1) != "") { $lines.=$line; };
75      }
76      $pos = strpos($lines,')');
77      if (preg_match('/[0-9]/',$lines)) {
78        return strip_tags(strtr(substr($lines,0,$pos),$this->lang['kwoptions'],'TBLRdl').substr($lines,$pos));
79      } else
80      {
81        return strip_tags(strtr(substr($lines,0,$pos),$this->lang['kwoptions'],'TBLRdl').strtr(substr($lines,$pos),$this->lang['kwpieces'],'kqrbnpKQRBNP'));
82      }
83    }
84
85    /**
86     * Create output
87     */
88    function render($mode, Doku_Renderer $renderer,$data)
89    {
90      if($mode == 'xhtml')
91      {
92        // for debug: $renderer->doc .= '<pre>'.$data.'</pre>';
93        $renderer->doc .= '<p style="line-height:0">'.chessboard_render($data).'</p>';
94        return true;
95      }
96      return false;
97    }
98}
99
100/*
101Copyright (C) 2006  http://www.vyvy.org/
102
103This library is free software; you can redistribute it and/or
104modify it under the terms of the GNU Lesser General Public
105License as published by the Free Software Foundation; either
106version 2.1 of the License, or (at your option) any later version.
107
108This library is distributed in the hope that it will be useful,
109but WITHOUT ANY WARRANTY; without even the implied warranty of
110MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
111Lesser General Public License for more details.
112
113You should have received a copy of the GNU Lesser General Public
114License along with this library; if not, write to the Free Software
115Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
116
117Changes:
118  15-Jun-06: [v1.0]  Initial Release
119
120
121Usage:
122  To convert a board to XHTML code, simply get the return value from:
123    chessboard_render($board)
124*/
125
126/*================================*/
127/* Routines                       */
128/*================================*/
129
130function chessboard_border_filename($border)
131{
132  // $border: T, B, L, R, TL, TR, BL, BR
133
134  switch ($border) {
135   case 'T':
136   case '':
137    return IMAGE_PATH.'h.png';
138   case 'L':
139   case 'R':
140    return IMAGE_PATH.'v.png';
141   default:
142    return IMAGE_PATH.'c.png';
143  }
144}
145
146
147function chessboard_piece_filename($piece, $square_color)
148{
149  // $piece        : KQBNRPkqbnrp-
150  // $square_color : 0 1
151
152  switch ($piece) {
153   case 'x':
154    $name = 'xx';
155    break;
156   case '-':
157    $name = '';
158    break;
159   default:
160    $name = strtolower($piece).(ctype_lower($piece)?'d':'l');
161    break;
162  }
163
164  return IMAGE_PATH.$name.($square_color?'d':'l').'.png';
165}
166
167
168function chessboard_render($content)
169{
170  static $table_constructed = false;
171  static $table_xhtml;
172
173  if (!$table_constructed) {
174
175    // Construct the translation table
176
177    // Empty and marked squares
178    $table_xhtml = array('-0' => '<img src="'
179                           . chessboard_piece_filename('-', 0)
180                           . '" alt="-" />',
181                         '-1' => '<img src="'
182                           . chessboard_piece_filename('-', 1)
183                           . '" alt="-" />',
184                         'x0' => '<img src="'
185                           . chessboard_piece_filename('x', 0)
186                           . '" alt="x" />',
187                         'x1' => '<img src="'
188                           . chessboard_piece_filename('x', 1)
189                           . '" alt="x" />',
190                        );
191
192    // Pieces
193    $pieces = 'kqbnrp';
194    for ($i=0; $i<6; $i++) {
195      $piece = $pieces[$i];
196      $table_xhtml += array(strtoupper($piece) . '0' => '<img src="'
197                              . chessboard_piece_filename(strtoupper($piece), 0)
198                              . '" alt="' . strtoupper($piece) . '" />',
199                            strtoupper($piece) . '1' => '<img src="'
200                              . chessboard_piece_filename(strtoupper($piece), 1)
201                              . '" alt="' . strtoupper($piece) . '" />',
202                            $piece . '0' => '<img src="'
203                              . chessboard_piece_filename($piece, 0)
204                              . '" alt="' . $piece . '" />',
205                            $piece . '1' => '<img src="'
206                              . chessboard_piece_filename($piece, 1)
207                              . '" alt="' . $piece . '" />',
208                           );
209    }
210
211    // Borders
212    $table_xhtml += array('T' => '<img src="'
213                            . chessboard_border_filename('T')
214                            . '" alt="" />',
215                          '' => '<img src="'
216                            . chessboard_border_filename('B')
217                            . '" alt="" />',
218                          'L' => '<img src="'
219                            . chessboard_border_filename('L')
220                            . '" alt="" />',
221                          'R' => '<img src="'
222                            . chessboard_border_filename('R')
223                            . '" alt="" />',
224                          'TL' => '<img src="'
225                            . chessboard_border_filename('TL')
226                            . '" alt="" />',
227                          'TR' => '<img src="'
228                            . chessboard_border_filename('TR')
229                            . '" alt="" />',
230                          'BL' =>
231                            '<img src="'
232                            . chessboard_border_filename('BL')
233                            . '" alt="" />',
234                          'BR' =>
235                            '<img src="'
236                            . chessboard_border_filename('BR')
237                            . '" alt="" />',
238                         );
239
240    $table_constructed = true;
241  }
242
243  preg_match('@^\s*(?:\((.*?)\))?(.*)$@s', $content, $matches);
244
245  // Parameter Parsing
246  //--------------------------------
247  $params =& $matches[1];
248
249  // Number of files: any integer (default: 8)
250  $file_max = preg_match('@[0-9]+@', $params, $m) ? $m[0] : 8;
251
252  // Color of the upper left square: [l]ight (default), or [d]ark
253  $square_color_first = (strpos($params, 'd') !== false) ? 1 : 0;
254
255  // Borders
256  $border = array('T' => (strpos($params, 'T') !== false),
257                  '' => (strpos($params, '') !== false),
258                  'L' => (strpos($params, 'L') !== false),
259                  'R' => (strpos($params, 'R') !== false));
260
261  // Render the board in XHTML syntax
262  //----------------------------------
263  $board =& $matches[2];
264  $xhtml = '';
265
266  // Top border
267  if ($border['T']) {
268    if ($border['L'])
269      $xhtml .= $table_xhtml['TL'];
270    $xhtml .= str_repeat($table_xhtml['T'], $file_max);
271    if ($border['R'])
272      $xhtml .= $table_xhtml['TR'];
273    $file = $file_max;
274  }
275  else {
276    $file = 0;
277    $square_color = $square_color_first;
278    $square_color_first = 1 - $square_color_first;
279  }
280
281  // Left border, board, right border
282  for ($i=0; isset($board[$i]); $i++) {
283
284    // Ignore unknown characters
285    if (strpos('12345678KQBNRPkqbnrp-x', $board[$i]) === false) {
286      continue;
287    }
288
289    if ($file >= $file_max) {
290      $xhtml .= '<br />';
291      $file = 0;
292      $square_color = $square_color_first;
293      $square_color_first = 1 - $square_color_first;
294      if ($border['L'])
295        $xhtml .= $table_xhtml['L'];
296    }
297
298    $key = $board[$i].$square_color;
299    if (strpos('12345678', $board[$i]) !== false) {
300      // Multiple empty squares
301      for ($j=0; $j<$board[$i]; $j++) {
302        $xhtml .= $table_xhtml['-'.$square_color];
303        $square_color = 1 - $square_color;
304      }
305      $file += (int) $board[$i];
306    }
307    else {
308      // $table_xhtml[$key] is defined as we have filtered unknown characters
309      $xhtml .= $table_xhtml[$key];
310      $square_color = 1 - $square_color;
311      $file++;
312    }
313
314    if ($file >= $file_max) {
315      if ($border['R'])
316        $xhtml .= $table_xhtml['R'];
317    }
318  }
319
320  // Bottom border
321  if ($border['']) {
322    $xhtml .= '<br />';
323    if ($border['L'])
324      $xhtml .= $table_xhtml['BL'];
325    $xhtml .= str_repeat($table_xhtml[''], $file_max);
326    if ($border['R'])
327      $xhtml .= $table_xhtml['BR'];
328  }
329
330  return $xhtml;
331}
332
333//Setup VIM: ex: et ts=4 enc=utf-8 :
334