/Text/Wiki2/Parse/Tiki/Url.php

https://github.com/pear/Text_Wiki2 · PHP · 293 lines · 91 code · 41 blank · 161 comment · 4 complexity · 74951a042bf1c8ba50c6c670d35f3af4 MD5 · raw file

  1. <?php
  2. /**
  3. *
  4. * Parse for URLS in the source text.
  5. *
  6. * @category Text
  7. *
  8. * @package Text_Wiki
  9. *
  10. * @author Justin Patrin <papercrane@reversefold.com>
  11. * @author Paul M. Jones <pmjones@php.net>
  12. *
  13. * @license LGPL
  14. *
  15. * @version $Id$
  16. *
  17. */
  18. /**
  19. *
  20. * Parse for URLS in the source text.
  21. *
  22. * Various URL markings are supported: inline (the URL by itself),
  23. * numbered or footnote reference (where the URL is enclosed in square
  24. * brackets), and named reference (where the URL is enclosed in square
  25. * brackets and has a name included inside the brackets). E.g.:
  26. *
  27. * inline -- http://example.com
  28. * numbered -- [http://example.com]
  29. * described -- [http://example.com Example Description]
  30. *
  31. * When rendering a URL token, this will convert URLs pointing to a .gif,
  32. * .jpg, or .png image into an inline <img /> tag (for the 'xhtml'
  33. * format).
  34. *
  35. * Token options are:
  36. *
  37. * 'type' => ['inline'|'footnote'|'descr'] the type of URL
  38. *
  39. * 'href' => the URL link href portion
  40. *
  41. * 'text' => the displayed text of the URL link
  42. *
  43. * @category Text
  44. *
  45. * @package Text_Wiki
  46. *
  47. * @author Justin Patrin <papercrane@reversefold.com>
  48. * @author Paul M. Jones <pmjones@php.net>
  49. *
  50. */
  51. class Text_Wiki2_Parse_Url extends Text_Wiki2_Parse {
  52. /**
  53. *
  54. * Keeps a running count of numbered-reference URLs.
  55. *
  56. * @access public
  57. *
  58. * @var int
  59. *
  60. */
  61. var $footnoteCount = 0;
  62. /**
  63. *
  64. * URL schemes recognized by this rule.
  65. *
  66. * @access public
  67. *
  68. * @var array
  69. *
  70. */
  71. var $conf = array(
  72. 'schemes' => array(
  73. 'http://',
  74. 'https://',
  75. 'ftp://',
  76. 'gopher://',
  77. 'news://',
  78. 'mailto:'
  79. )
  80. );
  81. /**
  82. *
  83. * Constructor.
  84. *
  85. * We override the constructor so we can comment the regex nicely.
  86. *
  87. * @access public
  88. *
  89. */
  90. function __construct(&$obj)
  91. {
  92. parent::__construct($obj);
  93. // convert the list of recognized schemes to a regex-safe string,
  94. // where the pattern delim is a slash
  95. $tmp = array();
  96. $list = $this->getConf('schemes', array());
  97. foreach ($list as $val) {
  98. $tmp[] = preg_quote($val, '/');
  99. }
  100. $schemes = implode('|', $tmp);
  101. // build the regex
  102. $this->regex =
  103. "(?:$schemes)" . // allowed schemes
  104. "(?:" . // start pattern
  105. "[^ \\/\"\'{$this->wiki->delim}]*\\/" . // no spaces, backslashes, slashes, double-quotes, single quotes, or delimiters;
  106. ")*" . // end pattern
  107. "[^ \\t\\n\\/\"\'{$this->wiki->delim}]*" .
  108. "[A-Za-z0-9\\/?=&~_#]";
  109. }
  110. /**
  111. *
  112. * Find three different kinds of URLs in the source text.
  113. *
  114. * @access public
  115. *
  116. */
  117. function parse()
  118. {
  119. // -------------------------------------------------------------
  120. //
  121. // Described-reference (named) URLs.
  122. //
  123. // the regular expression for this kind of URL
  124. $tmp_regex = '/(\[{1,2})([^\]]*' . /*$this->regex .*/ ')(\|)([^\]]+)(\])/';
  125. // use a custom callback processing method to generate
  126. // the replacement text for matches.
  127. $this->wiki->source = preg_replace_callback(
  128. $tmp_regex,
  129. array(&$this, 'processDescr'),
  130. $this->wiki->source
  131. );
  132. // -------------------------------------------------------------
  133. //
  134. // Numbered-reference (footnote-style) URLs.
  135. //
  136. // the regular expression for this kind of URL
  137. $tmp_regex = '/(\[{1,2})(' . str_replace('[^',
  138. '[^\|',
  139. $this->regex) . ')(\])/U';
  140. // use a custom callback processing method to generate
  141. // the replacement text for matches.
  142. $this->wiki->source = preg_replace_callback(
  143. $tmp_regex,
  144. array(&$this, 'processFootnote'),
  145. $this->wiki->source
  146. );
  147. // -------------------------------------------------------------
  148. //
  149. // Normal inline URLs.
  150. //
  151. // the regular expression for this kind of URL
  152. $tmp_regex = '/(^|[^A-Za-z])('
  153. .$this->regex
  154. .')(.*?)/';
  155. // use the standard callback for inline URLs
  156. $this->wiki->source = preg_replace_callback(
  157. $tmp_regex,
  158. array(&$this, 'process'),
  159. $this->wiki->source
  160. );
  161. }
  162. /**
  163. *
  164. * Process inline URLs.
  165. *
  166. * @param array &$matches
  167. *
  168. * @param array $matches An array of matches from the parse() method
  169. * as generated by preg_replace_callback. $matches[0] is the full
  170. * matched string, $matches[1] is the first matched pattern,
  171. * $matches[2] is the second matched pattern, and so on.
  172. *
  173. * @return string The processed text replacement.
  174. *
  175. */
  176. function process(&$matches)
  177. {
  178. // set options
  179. $options = array(
  180. 'type' => 'inline',
  181. 'href' => $matches[2],
  182. 'text' => $matches[2]
  183. );
  184. // tokenize
  185. return $matches[1] . $this->wiki->addToken($this->rule, $options) . $matches[3];
  186. }
  187. /**
  188. *
  189. * Process numbered (footnote) URLs.
  190. *
  191. * Token options are:
  192. * @param array &$matches
  193. *
  194. * @param array $matches An array of matches from the parse() method
  195. * as generated by preg_replace_callback. $matches[0] is the full
  196. * matched string, $matches[1] is the first matched pattern,
  197. * $matches[2] is the second matched pattern, and so on.
  198. *
  199. * @return string The processed text replacement.
  200. *
  201. */
  202. function processFootnote(&$matches)
  203. {
  204. if ($matches[1] == '[[') {
  205. return '['.$matches[2].$matches[3];
  206. }
  207. // keep a running count for footnotes
  208. $this->footnoteCount++;
  209. // set options
  210. $options = array(
  211. 'type' => 'descr',
  212. 'href' => $matches[2],
  213. 'text' => $matches[2]//$this->footnoteCount
  214. );
  215. // tokenize
  216. return $this->wiki->addToken($this->rule, $options);
  217. }
  218. /**
  219. *
  220. * Process described-reference (named-reference) URLs.
  221. *
  222. * Token options are:
  223. * 'type' => ['inline'|'footnote'|'descr'] the type of URL
  224. * 'href' => the URL link href portion
  225. * 'text' => the displayed text of the URL link
  226. *
  227. * @param array &$matches
  228. *
  229. * @param array $matches An array of matches from the parse() method
  230. * as generated by preg_replace_callback. $matches[0] is the full
  231. * matched string, $matches[1] is the first matched pattern,
  232. * $matches[2] is the second matched pattern, and so on.
  233. *
  234. * @return string The processed text replacement.
  235. *
  236. */
  237. function processDescr(&$matches)
  238. {
  239. if ($matches[1] == '[[') {
  240. return '['.$matches[2].$matches[3].$matches[4].$matches[5];
  241. }
  242. // set options
  243. $options = array(
  244. 'type' => 'descr',
  245. 'href' => $matches[2],
  246. 'text' => $matches[4]
  247. );
  248. // tokenize
  249. return $this->wiki->addToken($this->rule, $options);
  250. }
  251. }
  252. ?>