blockquote.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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: blockquote.php,v 1.1 2004/01/04 01:35:22 pmjones Exp $
  20. /**
  21. *
  22. * This class implements a Text_Wiki_Rule to find source text marked as a
  23. * blockquote, identified by any number of greater-than signs '>' at the
  24. * start of the line, followed by a space, and then the quote text; each
  25. * '>' indicates an additional level of quoting.
  26. *
  27. * @author Paul M. Jones <pmjones@ciaweb.net>
  28. *
  29. * @package Text_Wiki
  30. *
  31. */
  32. class Text_Wiki_Rule_blockquote extends Text_Wiki_Rule {
  33. /**
  34. *
  35. * The regular expression used to parse the source text and find
  36. * matches conforming to this rule. Used by the parse() method.
  37. *
  38. * @access public
  39. *
  40. * @var string
  41. *
  42. * @see parse()
  43. *
  44. */
  45. var $regex = '/\n((\>).*\n)(?!(\>))/Us';
  46. /**
  47. *
  48. * Generates a replacement for the matched text. Token options are:
  49. *
  50. * 'type' =>
  51. * 'start' : the start of a blockquote
  52. * 'end' : the end of a blockquote
  53. *
  54. * 'level' => the indent level (0 for the first level, 1 for the
  55. * second, etc)
  56. *
  57. * @access public
  58. *
  59. * @param array &$matches The array of matches from parse().
  60. *
  61. * @return A series of text and delimited tokens marking the different
  62. * list text and list elements.
  63. *
  64. */
  65. function process(&$matches)
  66. {
  67. // the replacement text we will return to parse()
  68. $return = '';
  69. // the list of post-processing matches
  70. $list = array();
  71. // $matches[1] is the text matched as a list set by parse();
  72. // create an array called $list that contains a new set of
  73. // matches for the various list-item elements.
  74. preg_match_all(
  75. '=^(\>+) (.*\n)=Ums',
  76. $matches[1],
  77. $list,
  78. PREG_SET_ORDER
  79. );
  80. // a stack of starts and ends; we keep this so that we know what
  81. // indent level we're at.
  82. $stack = array();
  83. // loop through each list-item element.
  84. foreach ($list as $key => $val) {
  85. // $val[0] is the full matched list-item line
  86. // $val[1] is the number of initial '>' chars (indent level)
  87. // $val[2] is the quote text
  88. // we number levels starting at 1, not zero
  89. $level = strlen($val[1]);
  90. // get the text of the line
  91. $text = $val[2];
  92. // add a level to the list?
  93. if ($level > count($stack)) {
  94. // the current indent level is greater than the number
  95. // of stack elements, so we must be starting a new
  96. // level. push the new level onto the stack with a
  97. // dummy value (boolean true)...
  98. array_push($stack, true);
  99. // ...and add a start token to the return.
  100. $return .= $this->addToken(
  101. array(
  102. 'type' => 'start',
  103. 'level' => $level - 1
  104. )
  105. );
  106. $return .= "\n";
  107. }
  108. // remove a level?
  109. while (count($stack) > $level) {
  110. // as long as the stack count is greater than the
  111. // current indent level, we need to end list types.
  112. // continue adding end-list tokens until the stack count
  113. // and the indent level are the same.
  114. array_pop($stack);
  115. $return .= $this->addToken(
  116. array (
  117. 'type' => 'end',
  118. 'level' => count($stack)
  119. )
  120. );
  121. $return .= "\n";
  122. }
  123. // add the line text.
  124. $return .= $text . "\n";
  125. }
  126. // the last line may have been indented. go through the stack
  127. // and create end-tokens until the stack is empty.
  128. while (count($stack) > 0) {
  129. array_pop($stack);
  130. $return .= $this->addToken(
  131. array (
  132. 'type' => 'end',
  133. 'level' => count($stack)
  134. )
  135. );
  136. }
  137. // we're done! send back the replacement text.
  138. return "\n$return";
  139. }
  140. /**
  141. *
  142. * Renders a token into text matching the requested format.
  143. *
  144. * @access public
  145. *
  146. * @param array $options The "options" portion of the token (second
  147. * element).
  148. *
  149. * @return string The text rendered from the token options.
  150. *
  151. */
  152. function renderXhtml($options)
  153. {
  154. $type = $options['type'];
  155. $level = $options['level'];
  156. // set up indenting so that the results look nice; we do this
  157. // in two steps to avoid str_pad mathematics. ;-)
  158. $pad = str_pad('', $level, "\t");
  159. $pad = str_replace("\t", ' ', $pad);
  160. // starting
  161. if ($type == 'start') {
  162. return "$pad<blockquote>";
  163. }
  164. // ending
  165. if ($type == 'end') {
  166. return $pad . "</blockquote>\n";
  167. }
  168. }
  169. }
  170. ?>