ASCII Tables PHP Class

The following mess that I’ll call code is a rough translation from a Python implementation, found on Reddit. Somebody beat me to a Ruby version, so I decided to flex those rusty PHP braincells.

Please forgive running lines, lack of refactoring and some stupid practices. Don’t blame PHP, because this can be refactored to a more concise version. But like I said, this is a translation, not a reimplementation.

Here’s how to use it:

<?php
$table <<<EOP
---------------------------
|         |       |       |
|         |       |       |
|         |       |       |
|         |-------|       |
|         |       |       |
|         |       |-------|
|         |       |       |
|         |       |       |
|---------|       |-------|
|    |    |       |       |
|    |    |-------|       |
|    |    |       |       |
|    |    |       |       |
|    |    |       |       |
---------------------------
EOP;

$asciiTable = new AsciiTable($table);
echo $asciiTable->toHTML();
?>

And here’s the code:

  1. #!/usr/bin/php
  2. <?php
  3.  
  4. class AsciiTable
  5. {
  6.  
  7. function AsciiTable($table)
  8. {
  9. // $this->grid is an array. $this->grid[$y] is a string,
  10. // this explains count vs. strlen below.
  11. $this->grid = preg_split('/[\n\r]+/', $table);
  12.  
  13. $this->y_delimiters = array();
  14. $this->x_delimiters = array();
  15. }
  16.  
  17. function toHTML()
  18. {
  19. $this->parseAsciiTable();
  20. return $this->renderHtml();
  21. }
  22.  
  23. function parseAsciiTable()
  24. {
  25. $grid = $this->grid;
  26.  
  27. $boxes = array();
  28. for ( $y = 0; $y < count($grid); $y++ )
  29. {
  30. for ( $x = 0; $x < strlen($grid[$y]); $x++ )
  31. {
  32. if ( in_array($grid[$y][$x], array('-', '|'))
  33. && $grid[$y+1][$x] == '|' && $grid[$y][$x+1] == '-' )
  34. {
  35. $right = strpos($grid[$y+1], '|', $x + 1) - 1;
  36.  
  37. // We can't do an array_pos with a callback. Darn.
  38. foreach ( range($y, count($grid)) as $bottom )
  39. {
  40. if ( $grid[$bottom+1][$x+1] == '-' )
  41. break;
  42. }
  43. $this->y_delimiters[] = $bottom;
  44. $this->x_delimiters[] = $right;
  45. array_push($boxes, array('x' => $x, 'y' => $y,
  46. 'r' => $right, 'b' => $bottom));
  47. }
  48. }
  49. }
  50.  
  51. $this->boxes = $boxes;
  52.  
  53. sort($this->y_delimiters);
  54. $this->y_delimiters = array_unique($this->y_delimiters);
  55.  
  56. sort($this->x_delimiters);
  57. $this->x_delimiters = array_unique($this->x_delimiters);
  58.  
  59. return $boxes;
  60. }
  61.  
  62. function rowSpans()
  63. {
  64. foreach ( $this->y_delimiters as $delim )
  65. {
  66. foreach ( $this->boxes as $index => $box )
  67. {
  68. if ( $box['y'] < $delim && $box['b'] >= $delim )
  69. {
  70. $this->boxes[$index]['rs']++;
  71. }
  72. }
  73. }
  74. }
  75.  
  76. function colSpans()
  77. {
  78. foreach ( $this->x_delimiters as $delim )
  79. {
  80. foreach ( $this->boxes as $index => $box )
  81. {
  82. if ( $box['x'] < $delim && $box['r'] >= $delim )
  83. {
  84. $this->boxes[$index]['cs']++;
  85. }
  86. }
  87. }
  88. }
  89.  
  90. function renderHtml()
  91. {
  92. $this->rowSpans();
  93. $this->colSpans();
  94.  
  95. $boxes_left = $this->boxes;
  96. $row = array();
  97.  
  98. foreach ( $this->y_delimiters as $delim )
  99. {
  100. $boxes_in_row = array();
  101. foreach ( $boxes_left as $index => $box )
  102. {
  103. if ( $box['y'] < $delim )
  104. {
  105. $boxes_in_row[] = $box;
  106. unset($boxes_left[$index]);
  107. }
  108. }
  109.  
  110. // sory by $box['x']
  111. usort($boxes_in_row,
  112. create_function('$a, $b', 'return ($a["x"]
  113. == $b["x"]) ? 0 : ($a["x"] < $b["x"]) ? -1 : 1;'));
  114. $rows[] = $boxes_in_row;
  115. }
  116.  
  117. $table = "<table border=\"border\">\n";
  118. foreach ( $rows as $row )
  119. {
  120. $table .= " <tr>\n";
  121. foreach ( $row as $box )
  122. {
  123. $table .= sprintf("
  124. <td rowspan=\"%d\" colspan=\"%d\">%s</td>\n",
  125. $box['rs'], $box['cs'],
  126. str_repeat('blank<br/>', $box['b'] - $box['y'])
  127. );
  128. }
  129. $table .= " </tr>\n";
  130. }
  131. $table .= "</table>\n";
  132. return $table;
  133. }
  134. }
  135. ?>
  136.  


Leave a Reply

Formatting: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Other Entries

Tweets from