1<?php
2if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4if(!defined('DOKU_REL')) define('DOKU_REL', '/dokuwiki/');
5require_once(DOKU_PLUGIN.'syntax.php');
6require_once(DOKU_PLUGIN.'autolink4/consts.php');
7
8/********
9 * This is a work in progress. See regex.php for active code.
10 ********/
11
12/**
13 * Autolink 4 DokuWiki plugin
14 *
15 * @license    MIT
16 * @author     Eli Fenton
17 */
18class syntax_plugin_autolink4_allwords extends DokuWiki_Syntax_Plugin {
19	use autotooltip4_consts;
20
21	/** @type helper_plugin_autotooltip $tooltip */
22	private $tooltip;
23	/** @type helper_plugin_autolink4 $tooltip */
24	private $helper;
25
26	public function __construct() {
27		if (!plugin_isdisabled('autotooltip')) {
28			$this->tooltip = plugin_load('helper', 'autotooltip');
29		}
30
31		$this->helper = plugin_load('helper', 'autolink4');
32		$this->helper->loadAndProcessConfigFile();
33	}
34
35
36	/**
37	 * @return string
38	 */
39	function getType() {
40		return 'substition';
41	}
42
43
44	/**
45	 * @return string
46	 */
47	function getPType() {
48		return 'normal';
49	}
50
51
52	/**
53	 * @return int
54	 */
55	function getSort() {
56		// Try not to interfere with any other lexer patterns.
57		return 1000;
58	}
59
60
61	//TODO: Doesn't seem to do anything.
62	function getAllowedTypes() {
63		global $PARSER_MODES;
64		return array_keys($PARSER_MODES);
65	}
66
67
68	/**
69	 * @param $mode
70	 */
71	function connectTo($mode) {
72		global $ID;
73		$ns = getNS($ID);
74
75		/*
76		TODO: Optimization
77		Match any string of words (hoping that the high getSort avoids other plugins).
78		Make my own word-by-word parser, after sorting match strings and caching. (only for non-regexes)
79		Looking for earliest starting, longest match.
80		- See a word. Make array of partial matches with start pos.
81		- Next word - Eliminate in-progress matches, and add new ones.
82		- If a match is found and there are no in-progress matches of its start pos or earlier, do the
83		  replacement.
84		Autolink all titles:
85		- Every time a page is indexed, add the title to the cache. Remove deleted.
86		*/
87		//TODO: Because this always starts at the first word, it wins over the regex version except when the regex version matches the first word.
88		//		If I make it non-greedy, it competes with itself, and always matches exactly one word.
89		//		I could get rid of the regex plugin and only use this one, but it could interfere with other plugins.
90		//$this->Lexer->addSpecialPattern('(?:[\w\'\-]+ *)+?', $mode, 'plugin_autolink4_allwords');
91	}
92
93
94	/**
95	 * Handle the found text, and send it off to render().
96	 *
97	 * @param string $match - The found text, from addSpecialPattern.
98	 * @param int $state - The DokuWiki event state.
99	 * @param int $pos - The position in the full text.
100	 * @param Doku_Handler $handler
101	 * @return array|string
102	 */
103	function handle($match, $state, $pos, Doku_Handler $handler) {
104		msg($match);
105		return $match;
106		/*
107		$this->helper->init();
108
109		// Load from cache
110		if (isset($this->helper->getSimpleSubs()[$match])) {
111			return $this->helper->getSimpleSubs()[$match];
112		}
113
114		// Annoyingly, there's no way (I know of) to determine which match sent us here, so we have to loop through the
115		// whole list.
116		foreach ($this->helper->getRegexSubs() as &$s) {
117			if (preg_match('/^' . $s[self::$MATCH] . '$/', $match)) {
118				// Add all found matches to simpleSubs, so we don't have to loop more than once for the same string.
119				$mod = null;
120				if (!isset($this->helper->getSimpleSubs()[$match])) {
121					$mod = $s;
122					$mod[self::$TEXT] = $match;
123					$this->helper->getSimpleSubs()[$match] = $mod;
124				}
125
126				return $mod;
127			}
128		}
129
130		return $match;
131		*/
132	}
133
134
135	/**
136	 * Render the replaced links.
137	 *
138	 * @param string $mode
139	 * @param Doku_Renderer|Doku_Renderer_metadata $renderer
140	 * @param array|string $data - Data from handle()
141	 * @return bool
142	 */
143	function render($mode, Doku_Renderer $renderer, $data) {
144		$renderer->doc .= $data;
145		return true;
146
147
148		if (is_string($data)) {
149			$renderer->doc .= $data;
150		}
151		else if ($mode == 'xhtml') {
152			if ($this->tooltip && $data[self::$TOOLTIP]) {
153				$renderer->doc .= $this->tooltip->forWikilink($data[self::$TO], $data[self::$TEXT]);
154			}
155			else {
156				$renderer->internallink($data[self::$TO], $data[self::$TEXT]);
157			}
158		}
159		else {
160			if (!$renderer->capture) {
161				return false;
162			}
163			$renderer->doc .= $data[self::$TEXT];
164		}
165		return true;
166	}
167
168
169	/**
170	 * Is one namespace inside another.
171	 *
172	 * @param string $ns - Search inside this namespace.
173	 * @param string $test - Look for this namespace.
174	 * @return bool
175	 */
176	function _inNS($ns, $test) {
177		$len = strlen($test);
178		return !$len || substr($ns, 0, $len) == $test;
179	}
180
181
182	/**
183	 * Are these two the same page>
184	 *
185	 * @param string $p1 - One page.
186	 * @param string $p2 - Another page.
187	 * @return bool
188	 */
189	function _isSamePage($p1, $p2) {
190		return preg_replace('/#.*/', '', $p1) == preg_replace('/#.*/', '', $p2);
191	}
192}
193