/Text/Wiki2/Parse/Default/Url.php

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