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