url.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Paul M. Jones <pmjones@ciaweb.net> |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: url.php,v 1.2 2004/01/31 15:52:08 pmjones Exp $
  20. /**
  21. *
  22. * This class implements a Text_Wiki_Rule to find source text marked as a
  23. * URL. Various URL markings are supported: inline (the URL by itself),
  24. * numbered or footnote reference (where the URL is enclosed in square brackets), and
  25. * named reference (where the URL is enclosed in square brackets and has a
  26. * name included inside the brackets). E.g.:
  27. *
  28. * inline -- http://example.com
  29. * numbered -- [http://example.com]
  30. * described -- [http://example.com Example Description]
  31. *
  32. * When rendering a URL token, this will convert URLs pointing to a .gif,
  33. * .jpg, or .png image into an inline <img /> tag (for the 'xhtml'
  34. * format).
  35. *
  36. * @author Paul M. Jones <pmjones@ciaweb.net>
  37. *
  38. * @package Text_Wiki
  39. *
  40. */
  41. class Text_Wiki_Rule_url extends Text_Wiki_Rule {
  42. /**
  43. *
  44. * When doing numbered references (footnote-style references), we
  45. * need to keep a running count of how many references there are.
  46. *
  47. * @access public
  48. *
  49. * @var int
  50. *
  51. */
  52. var $footnoteCount = 0;
  53. /**
  54. *
  55. * An array of filename extensions that indicate a file is an image.
  56. *
  57. * @access public
  58. *
  59. * @var array
  60. *
  61. */
  62. var $img_ext = array('.jpg', '.png', '.gif');
  63. /**
  64. *
  65. * A somewhat complex parsing method to find three different kinds
  66. * of URLs in the source text.
  67. *
  68. * @access public
  69. *
  70. */
  71. function parse()
  72. {
  73. $this->regex = "(http:|mailto:|https:|ftp:|gopher:|news:)([^ \\/\"\']*\\/)*[^ \\t\\n\\/\"\'{$this->_wiki->delim}]*[A-Za-z0-9\\/?=&~_]";
  74. // -------------------------------------------------------------
  75. //
  76. // Described-reference (named) URLs.
  77. //
  78. // the regular expression for this kind of URL
  79. $tmp_regex = '/\[(' . $this->regex . ') ([^\]]+)\]/';
  80. // use a custom callback processing method to generate
  81. // the replacement text for matches.
  82. $this->_wiki->_source = preg_replace_callback(
  83. $tmp_regex,
  84. array(&$this, 'processDescr'),
  85. $this->_wiki->_source
  86. );
  87. // -------------------------------------------------------------
  88. //
  89. // Numbered-reference (footnote-style) URLs.
  90. //
  91. // the regular expression for this kind of URL
  92. $tmp_regex = '/\[(' . $this->regex . ')\]/U';
  93. // use a custom callback processing method to generate
  94. // the replacement text for matches.
  95. $this->_wiki->_source = preg_replace_callback(
  96. $tmp_regex,
  97. array(&$this, 'processFootnote'),
  98. $this->_wiki->_source
  99. );
  100. // -------------------------------------------------------------
  101. //
  102. // Normal inline URLs.
  103. //
  104. // the regular expression for this kind of URL
  105. $tmp_regex = '/(^|[^A-Za-z])(' . $this->regex .
  106. ')(\$|[^\\/?=&~A-Za-z0-9])/';
  107. // use the standard callback for inline URLs
  108. $this->_wiki->_source = preg_replace_callback(
  109. $tmp_regex,
  110. array(&$this, 'process'),
  111. $this->_wiki->_source
  112. );
  113. }
  114. /**
  115. *
  116. * Process inline URLs and return replacement text with a delimited
  117. * token.
  118. *
  119. * Token options are:
  120. * 'type' => ['inline'|'footnote'|'descr'] the type of URL
  121. * 'href' => the URL link href portion
  122. * 'text' => the displayed text of the URL link
  123. *
  124. * @param array &$matches
  125. *
  126. * @param array $matches An array of matches from the parse() method
  127. * as generated by preg_replace_callback. $matches[0] is the full
  128. * matched string, $matches[1] is the first matched pattern,
  129. * $matches[2] is the second matched pattern, and so on.
  130. *
  131. * @return string The processed text replacement.
  132. *
  133. */
  134. function process(&$matches)
  135. {
  136. // set options
  137. $options = array(
  138. 'type' => 'inline',
  139. 'href' => $matches[2],
  140. 'text' => $matches[2]
  141. );
  142. // tokenize
  143. return $matches[1] . $this->addToken($options) . $matches[5];
  144. }
  145. /**
  146. *
  147. * Process numbered (footnote) URLs and return replacement text with
  148. * a delimited token.
  149. *
  150. * Token options are:
  151. * 'type' => ['inline'|'footnote'|'descr'] the type of URL
  152. * 'href' => the URL link href portion
  153. * 'text' => the displayed text of the URL link
  154. *
  155. * @param array &$matches
  156. *
  157. * @param array $matches An array of matches from the parse() method
  158. * as generated by preg_replace_callback. $matches[0] is the full
  159. * matched string, $matches[1] is the first matched pattern,
  160. * $matches[2] is the second matched pattern, and so on.
  161. *
  162. * @return string The processed text replacement.
  163. *
  164. */
  165. function processFootnote(&$matches)
  166. {
  167. // keep a running count for footnotes
  168. $this->footnoteCount++;
  169. // set options
  170. $options = array(
  171. 'type' => 'footnote',
  172. 'href' => $matches[1],
  173. 'text' => $this->footnoteCount
  174. );
  175. // tokenize
  176. return $this->addToken($options);
  177. }
  178. /**
  179. *
  180. * Process described-reference (named-reference) URLs and return
  181. * replacement text with a delimited token.
  182. *
  183. * Token options are:
  184. * 'type' => ['inline'|'footnote'|'descr'] the type of URL
  185. * 'href' => the URL link href portion
  186. * 'text' => the displayed text of the URL link
  187. *
  188. * @param array &$matches
  189. *
  190. * @param array $matches An array of matches from the parse() method
  191. * as generated by preg_replace_callback. $matches[0] is the full
  192. * matched string, $matches[1] is the first matched pattern,
  193. * $matches[2] is the second matched pattern, and so on.
  194. *
  195. * @return string The processed text replacement.
  196. *
  197. */
  198. function processDescr(&$matches)
  199. {
  200. // set options
  201. $options = array(
  202. 'type' => 'descr',
  203. 'href' => $matches[1],
  204. 'text' => $matches[4]
  205. );
  206. // tokenize
  207. return $this->addToken($options);
  208. }
  209. /**
  210. *
  211. * Renders a token into text matching the requested format.
  212. *
  213. * @access public
  214. *
  215. * @param array $options The "options" portion of the token (second
  216. * element).
  217. *
  218. * @return string The text rendered from the token options.
  219. *
  220. */
  221. function renderXhtml($options)
  222. {
  223. // create local variables from the options array (text,
  224. // href, type)
  225. extract($options);
  226. // find the rightmost dot and determine the filename
  227. // extension.
  228. $pos = strrpos($href, '.');
  229. $ext = strtolower(substr($href, $pos));
  230. // does the filename extension indicate an image file?
  231. if (in_array($ext, $this->img_ext)) {
  232. // create alt text for the image
  233. if (! isset($text) || $text == '') {
  234. $text = basename($href);
  235. }
  236. // generate an image tag
  237. $output = "<img src=\"$href\" alt=\"$text\" />";
  238. } else {
  239. // generate a regular link (not an image)
  240. $output = "<a href=\"$href\">$text</a>";
  241. // make numbered references look like footnotes
  242. if ($type == 'footnote') {
  243. $output = '<sup>' . $output . '</sup>';
  244. }
  245. }
  246. return $output;
  247. }
  248. }
  249. ?>