Formatter.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /**
  3. * SCSSPHP
  4. *
  5. * @copyright 2012-2015 Leaf Corcoran
  6. *
  7. * @license http://opensource.org/licenses/MIT MIT
  8. *
  9. * @link http://leafo.github.io/scssphp
  10. */
  11. namespace Leafo\ScssPhp;
  12. use Leafo\ScssPhp\Formatter\OutputBlock;
  13. /**
  14. * Base formatter
  15. *
  16. * @author Leaf Corcoran <leafot@gmail.com>
  17. */
  18. abstract class Formatter
  19. {
  20. /**
  21. * @var integer
  22. */
  23. public $indentLevel;
  24. /**
  25. * @var string
  26. */
  27. public $indentChar;
  28. /**
  29. * @var string
  30. */
  31. public $break;
  32. /**
  33. * @var string
  34. */
  35. public $open;
  36. /**
  37. * @var string
  38. */
  39. public $close;
  40. /**
  41. * @var string
  42. */
  43. public $tagSeparator;
  44. /**
  45. * @var string
  46. */
  47. public $assignSeparator;
  48. /**
  49. * @var boolea
  50. */
  51. public $keepSemicolons;
  52. /**
  53. * Initialize formatter
  54. *
  55. * @api
  56. */
  57. public abstract function __construct();
  58. /**
  59. * Return indentation (whitespace)
  60. *
  61. * @return string
  62. */
  63. protected function indentStr()
  64. {
  65. return '';
  66. }
  67. /**
  68. * Return property assignment
  69. *
  70. * @api
  71. *
  72. * @param string $name
  73. * @param mixed $value
  74. *
  75. * @return string
  76. */
  77. public function property($name, $value)
  78. {
  79. return rtrim($name) . $this->assignSeparator . $value . ';';
  80. }
  81. /**
  82. * Strip semi-colon appended by property(); it's a separator, not a terminator
  83. *
  84. * @api
  85. *
  86. * @param array $lines
  87. */
  88. public function stripSemicolon(&$lines)
  89. {
  90. if ($this->keepSemicolons) {
  91. return;
  92. }
  93. if (($count = count($lines)) && substr($lines[$count - 1], -1) === ';') {
  94. $lines[$count - 1] = substr($lines[$count - 1], 0, -1);
  95. }
  96. }
  97. /**
  98. * Output lines inside a block
  99. *
  100. * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
  101. */
  102. protected function blockLines(OutputBlock $block)
  103. {
  104. $inner = $this->indentStr();
  105. $glue = $this->break . $inner;
  106. echo $inner . implode($glue, $block->lines);
  107. if (!empty($block->children)) {
  108. echo $this->break;
  109. }
  110. }
  111. /**
  112. * Output block selectors
  113. *
  114. * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
  115. */
  116. protected function blockSelectors(OutputBlock $block)
  117. {
  118. $inner = $this->indentStr();
  119. echo $inner . implode($this->tagSeparator, $block->selectors) . $this->open . $this->break;
  120. }
  121. /**
  122. * Output block children
  123. *
  124. * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
  125. */
  126. protected function blockChildren(OutputBlock $block)
  127. {
  128. foreach ($block->children as $child) {
  129. $this->block($child);
  130. }
  131. }
  132. /**
  133. * Output non-empty block
  134. *
  135. * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
  136. */
  137. protected function block(OutputBlock $block)
  138. {
  139. if (empty($block->lines) && empty($block->children)) {
  140. return;
  141. }
  142. $pre = $this->indentStr();
  143. if (!empty($block->selectors)) {
  144. $this->blockSelectors($block);
  145. $this->indentLevel++;
  146. }
  147. if (!empty($block->lines)) {
  148. $this->blockLines($block);
  149. }
  150. if (!empty($block->children)) {
  151. $this->blockChildren($block);
  152. }
  153. if (!empty($block->selectors)) {
  154. $this->indentLevel--;
  155. if (empty($block->children)) {
  156. echo $this->break;
  157. }
  158. echo $pre . $this->close . $this->break;
  159. }
  160. }
  161. /**
  162. * Entry point to formatting a block
  163. *
  164. * @api
  165. *
  166. * @param \Leafo\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree
  167. *
  168. * @return string
  169. */
  170. public function format(OutputBlock $block)
  171. {
  172. ob_start();
  173. $this->block($block);
  174. $out = ob_get_clean();
  175. return $out;
  176. }
  177. }