1<?php
2/**
3 * DokuWiki Plugin criticmarkup (Syntax Component)
4 *
5 * Jednoduchá podpora Critic Markup syntaxe:
6 *
7 *  {++vložený text++}         -> <ins>vložený text</ins>
8 *  {--smazaný text--}         -> <del>smazaný text</del>
9 *  {==zvýrazněný text==}      -> <mark>zvýrazněný text</mark>
10 *  {~~původní~>nový~~}        -> <del>původní</del><ins>nový</ins>
11 *  {>>komentář<<}             -> <span class="critic-comment">komentář</span>
12 */
13
14if (!defined('DOKU_INC')) {
15    die();
16}
17
18class syntax_plugin_criticmarkup extends DokuWiki_Syntax_Plugin {
19
20    public function getType() {
21        return 'formatting';
22    }
23
24    public function getPType() {
25        return 'normal';
26    }
27
28    public function getSort() {
29        return 199;
30    }
31
32    /**
33     * Registrace vzorů pro všechny režimy
34     */
35    public function connectTo($mode) {
36        $this->Lexer->addSpecialPattern('\{\+\+.*?\+\+\}', $mode, 'plugin_criticmarkup'); // insert
37        $this->Lexer->addSpecialPattern('\{\-\-.*?\-\-\}', $mode, 'plugin_criticmarkup'); // delete
38        $this->Lexer->addSpecialPattern('\{==.*?==\}',   $mode, 'plugin_criticmarkup');  // mark
39        $this->Lexer->addSpecialPattern('\{~~.*?~~\}',   $mode, 'plugin_criticmarkup');  // substitution
40        $this->Lexer->addSpecialPattern('\{>>.*?<<\}',   $mode, 'plugin_criticmarkup');  // comment
41    }
42
43    /**
44     * Rozparsování nalezeného zápisu
45     */
46    public function handle($match, $state, $pos, Doku_Handler $handler) {
47        // $match je např.:
48        // "{++text++}", "{--text--}", "{==text==}", "{~~old~>new~~}", "{>>comment<<}"
49
50        // druh podle prvních dvou znaků po '{'
51        $marker = substr($match, 1, 2);
52        $type   = null;
53
54        switch ($marker) {
55            case '++':
56                $type = 'ins';
57                break;
58            case '--':
59                $type = 'del';
60                break;
61            case '==':
62                $type = 'mark';
63                break;
64            case '~~':
65                $type = 'subst';
66                break;
67            case '>>':
68                $type = 'comment';
69                break;
70            default:
71                return null;
72        }
73
74        // odřízneme počáteční "{++"/"{--"/"{=="/"{~~"/"{>>" (3 znaky)
75        // a koncové "++}"/"--}"/"==}"/"~~}"/"<<}" (3 znaky)
76        $inner = substr($match, 3, -3);
77
78        if ($type === 'subst') {
79            // {~~původní~>nový~~}
80            $parts = explode('~>', $inner, 2);
81            $old = isset($parts[0]) ? $parts[0] : '';
82            $new = isset($parts[1]) ? $parts[1] : '';
83
84            return array(
85                'type' => 'subst',
86                'old'  => $old,
87                'new'  => $new,
88            );
89        }
90
91        return array(
92            'type' => $type,
93            'text' => $inner,
94        );
95    }
96
97    /**
98     * Generování výsledného XHTML
99     */
100    public function render($mode, Doku_Renderer $R, $data) {
101        if ($mode !== 'xhtml') {
102            return false;
103        }
104
105        if ($data === null || !is_array($data)) {
106            return false;
107        }
108
109        $type = $data['type'];
110
111        switch ($type) {
112            case 'ins':
113                $R->doc .= '<ins>';
114                $R->cdata($data['text']);
115                $R->doc .= '</ins>';
116                break;
117
118            case 'del':
119                $R->doc .= '<del>';
120                $R->cdata($data['text']);
121                $R->doc .= '</del>';
122                break;
123
124            case 'mark':
125                $R->doc .= '<mark>';
126                $R->cdata($data['text']);
127                $R->doc .= '</mark>';
128                break;
129
130            case 'subst':
131                // {~~old~>new~~} -> <del>old</del><ins>new</ins>
132                $old = isset($data['old']) ? $data['old'] : '';
133                $new = isset($data['new']) ? $data['new'] : '';
134
135                if ($old !== '') {
136                    $R->doc .= '<del>';
137                    $R->cdata($old);
138                    $R->doc .= '</del>';
139                }
140                if ($new !== '') {
141                    $R->doc .= '<ins>';
142                    $R->cdata($new);
143                    $R->doc .= '</ins>';
144                }
145                break;
146
147            case 'comment':
148                // {>>komentář<<} -> <span class="critic-comment">komentář</span>
149                $R->doc .= '<span class="critic-comment">';
150                $R->cdata($data['text']);
151                $R->doc .= '</span>';
152                break;
153
154            default:
155                return false;
156        }
157
158        return true;
159    }
160}
161