/frameworks/solar/1.1.1/source/solar/Solar/Markdown/Apidoc/Table.php

https://github.com/ggunlugu/ornekler · PHP · 243 lines · 124 code · 18 blank · 101 comment · 6 complexity · 3cc70192031306105611bb3aaa2cc7a5 MD5 · raw file

  1. <?php
  2. /**
  3. *
  4. * Block class to form tables from Markdown syntax.
  5. *
  6. * Syntax is ...
  7. *
  8. * | Header 1 | Header 2 | Header N
  9. * | ---------- | ---------- | ----------
  10. * | data cell | data cell | data cell
  11. * | data cell | data cell | data cell
  12. * | data cell | data cell | data cell
  13. * | data cell | data cell | data cell
  14. *
  15. * You can force columns alignment by putting a colon in the header-
  16. * underline row.
  17. *
  18. * | Left-Aligned | No Align | Right-Aligned
  19. * | :----------- | --------- | -------------:
  20. * | data cell | data cell | data cell
  21. * | data cell | data cell | data cell
  22. * | data cell | data cell | data cell
  23. * | data cell | data cell | data cell
  24. *
  25. * @category Solar
  26. *
  27. * @package Solar_Markdown_Extra
  28. *
  29. * @author Michel Fortin <http://www.michelf.com/projects/php-markdown/>
  30. *
  31. * @author Paul M. Jones <pmjones@solarphp.com>
  32. *
  33. * @license http://opensource.org/licenses/bsd-license.php BSD
  34. *
  35. * @version $Id: Table.php 4600 2010-06-16 03:27:55Z pmjones $
  36. *
  37. */
  38. class Solar_Markdown_Apidoc_Table extends Solar_Markdown_Plugin
  39. {
  40. /**
  41. *
  42. * This is a block plugin.
  43. *
  44. * @var bool
  45. *
  46. */
  47. protected $_is_block = true;
  48. /**
  49. *
  50. * Uses these chars for parsing.
  51. *
  52. * @var string
  53. *
  54. */
  55. protected $_chars = '|';
  56. /**
  57. *
  58. * Transforms Markdown syntax to XHTML tables.
  59. *
  60. * @param string $text The source text.
  61. *
  62. * @return string The transformed XHTML.
  63. *
  64. */
  65. public function parse($text)
  66. {
  67. $less_than_tab = $this->_getTabWidth() - 1;
  68. // Find tables with leading pipe.
  69. //
  70. // | Header 1 | Header 2
  71. // | -------- | --------
  72. // | Cell 1 | Cell 2
  73. // | Cell 3 | Cell 4
  74. //
  75. $text = preg_replace_callback('
  76. {
  77. ( # optional caption
  78. ^(.+)[ \t]* # $2: caption text
  79. \n=+[ \t]*\n # separator
  80. )?
  81. ^ # Start of a line
  82. [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
  83. [|] # Optional leading pipe (present)
  84. (.+) \n # $3: Header row (at least one pipe)
  85. [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
  86. [|] ([ ]*[-:]+[-| :]*) \n # $4: Header underline
  87. ( # $5: Cells
  88. (?:
  89. [ ]* # Allowed whitespace.
  90. [|] .* \n # Row content.
  91. )*
  92. )
  93. (?=\n|\Z) # Stop at final double newline.
  94. }xm',
  95. array($this, '_parsePipe'),
  96. $text
  97. );
  98. //
  99. // Find tables without leading pipe.
  100. //
  101. // Header 1 | Header 2
  102. // -------- | --------
  103. // Cell 1 | Cell 2
  104. // Cell 3 | Cell 4
  105. //
  106. $text = preg_replace_callback('
  107. {
  108. ( # optional caption
  109. ^(.+)[ \t]* # $2: caption text
  110. \n=+[ \t]*\n # separator
  111. )?
  112. ^ # Start of a line
  113. [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
  114. (\S.*[|].*) \n # $3: Header row (at least one pipe)
  115. [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
  116. ([-:]+[ ]*[|][-| :]*) \n # $4: Header underline
  117. ( # $5: Cells
  118. (?:
  119. .* [|] .* \n # Row content
  120. )*
  121. )
  122. (?=\n|\Z) # Stop at final double newline.
  123. }xm',
  124. array($this, '_parsePlain'),
  125. $text
  126. );
  127. return $text;
  128. }
  129. /**
  130. *
  131. * Support callback for leading-pipe syntax.
  132. *
  133. * @param array $matches Matches from preg_replace_callback().
  134. *
  135. * @return string The replacement text.
  136. *
  137. */
  138. protected function _parsePipe($matches)
  139. {
  140. // Remove leading pipe for each row.
  141. $matches[3] = preg_replace('/^ *[|]/m', '', $matches[3]);
  142. return $this->_parsePlain($matches);
  143. }
  144. /**
  145. *
  146. * Support callback for table conversion.
  147. *
  148. * @param array $matches Matches from preg_replace_callback().
  149. *
  150. * @return string The replacement text.
  151. *
  152. */
  153. protected function _parsePlain($matches)
  154. {
  155. $caption = $matches[2];
  156. $head = $matches[3];
  157. $underline = $matches[4];
  158. $content = $matches[5];
  159. // Remove any tailing pipes for each line.
  160. $head = preg_replace('/[|] *$/m', '', $head);
  161. $underline = preg_replace('/[|] *$/m', '', $underline);
  162. $content = preg_replace('/[|] *$/m', '', $content);
  163. // Reading alignment from header underline.
  164. $separators = preg_split('/ *[|] */', $underline);
  165. $attr = array();
  166. foreach ($separators as $n => $s) {
  167. if (preg_match('/^ *-+: *$/', $s)) {
  168. $attr[$n] = ' align="right"';
  169. } elseif (preg_match('/^ *:-+: *$/', $s)) {
  170. $attr[$n] = ' align="center"';
  171. } elseif (preg_match('/^ *:-+ *$/', $s)) {
  172. $attr[$n] = ' align="left"';
  173. } else {
  174. $attr[$n] = '';
  175. }
  176. }
  177. // handle all spans at once, not just code spans
  178. $head = $this->_processSpans($head);
  179. $headers = preg_split('/ *[|] */', $head);
  180. $col_count = count($headers);
  181. // begin the table
  182. if ($caption) {
  183. $text = "\n<table>\n"
  184. . " <caption>"
  185. . $this->_processSpans($caption)
  186. . "</caption>\n";
  187. } else {
  188. $text = "\n<informaltable>\n";
  189. }
  190. // Write column headers.
  191. $text .= " <thead>\n";
  192. $text .= " <tr>\n";
  193. foreach ($headers as $n => $header) {
  194. $text .= " <th$attr[$n]>". trim($header) ."</th>\n";
  195. }
  196. $text .= " </tr>\n";
  197. $text .= " </thead>\n";
  198. // Split content by row.
  199. $rows = explode("\n", trim($content, "\n"));
  200. $text .= " <tbody>\n";
  201. foreach ($rows as $row) {
  202. // handle all spans at once, not just code spans
  203. $row = $this->_processSpans($row);
  204. // Split row by cell.
  205. $row_cells = preg_split('/ *[|] */', $row, $col_count);
  206. $row_cells = array_pad($row_cells, $col_count, '');
  207. $text .= " <tr>\n";
  208. foreach ($row_cells as $n => $cell) {
  209. $text .= " <td$attr[$n]>". trim($cell) ."</td>\n";
  210. }
  211. $text .= " </tr>\n";
  212. }
  213. $text .= " </tbody>\n";
  214. if ($caption) {
  215. $text .= "</table>\n";
  216. } else {
  217. $text .= "</informaltable>\n";
  218. }
  219. return $this->_toHtmlToken($text) . "\n";
  220. }
  221. }