1<?php
2
3
4/**
5 * Subject Index plugin : entry syntax
6 * indexes any subject index entries on the page (to data/index/subject.idx by default)
7 *
8 * Using the {{entry>[heading/sub-heading/]entry[|display text]}} syntax
9 * a new subject index entry can be added
10 *
11 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
12 * @author   Symon Bent <hendrybadao@gmail.com>
13 *
14 */
15
16// must be run within Dokuwiki
17if (!defined('DOKU_INC')) die();
18
19if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
20if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
21if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
22require_once(DOKU_PLUGIN.'syntax.php');
23
24
25require_once(DOKU_PLUGIN . 'subjectindex/inc/common.php');
26require_once(DOKU_PLUGIN . 'subjectindex/inc/matcher.php');
27
28
29
30class syntax_plugin_subjectindex_entry extends DokuWiki_Syntax_Plugin {
31
32    function __construct() {
33        $this->matcher = new SI_MatchEntry();
34    }
35
36    function getType() {
37		return 'substition';
38	}
39
40	function getSort() {
41		return 305;
42	}
43
44	function getPType(){
45		return 'normal';
46	}
47
48
49	function connectTo($mode) {
50        // avoid problems with code; {} show up a lot in php and js code!
51        if ( ! in_array($mode, array('unformatted', 'preformatted', 'code', 'file', 'php', 'html'))) {
52            foreach ($this->matcher as $matcher) {
53                $this->Lexer->addSpecialPattern($matcher->regex, $mode, 'plugin_subjectindex_entry');
54            }
55        }
56	}
57
58
59	function handle($match, $state, $pos, Doku_Handler $handler) {
60
61        if ($this->matcher->match($match) === true) {
62            $item          = $this->matcher->first;
63            $item['entry'] = $this->_remove_ord($item['entry']); // remove any ordered list numbers (used for manual sorting)
64            $link_id       = SI_Utils::valid_id($item['entry']);
65            $target_page   = SI_Utils::get_target_page($item['section']);
66            $sep           = $this->getConf('subjectindex_display_sep');
67            $path          = str_replace('/', $sep, $item['entry']);
68            return array($item, $path, $link_id, $target_page);
69        } else {
70            // It wasn't a recognised item so just return the original match for display
71            return $match;
72        }
73	}
74
75
76    private function _remove_ord($text) {
77        $text = preg_replace('`^\d+\.`', '', $text);
78        $text = preg_replace('`\/\d+\.`', '/', $text);
79        return $text;
80    }
81
82
83    // *************************************
84
85	function render($mode, Doku_Renderer $renderer, $data) {
86
87        if ($mode == 'xhtml') {
88            // just re-display a failed match
89            if ( ! is_array($data)) {
90                $renderer->doc .= $data;
91            } else {
92                list($item, $path, $link_id, $target_page) = $data;
93                $star     = $item['star'];
94                $star_css = ($star) ? '' : ' no-star';
95                $display  = $item['display'];
96                if ($display == '-') {
97                    // hidden text
98                    $display    = '';
99                    $hidden_css = ($star === false) ? ' hidden' : ' no text';
100                } else {
101                    // visible text
102                    if (empty($display)) $display = $path;
103                    $display    = $this->_html_encode($display);
104                    $hidden_css = '';
105                }
106                $type = "\n(" . $item['section'] . '-' . $this->getLang($item['type'] . '_type') . ')';
107                if (empty($target_page)) {
108                    $target_page = '';
109                    $title       = $this->getLang('no_default_target') . $type;
110                    $class       = 'bad-entry';
111                } else {
112                    $target_page = wl($target_page) . '#' . $link_id;
113                    if (isset($item['title'])) {
114                        $title = $this->_html_encode($item['title']);
115                    } else {
116                        $title = $this->_html_encode($path . $type);
117                    }
118                    $class = 'entry';
119                }
120
121                $renderer->doc .= '<a id="' . $link_id .
122                                  '" class="' . $class . $hidden_css . $star_css .
123                                  '" title="' . $title .
124                                  '" href="' . $target_page . '">' .
125                                  $display .
126                                  '</a>';
127            }
128			return true;
129		}
130		return false;
131	}
132
133
134    private function _html_encode($text) {
135        $text = htmlentities($text, ENT_QUOTES, 'UTF-8');
136        return $text;
137    }
138}
139