/src/ChartDown/Compiler.php

https://github.com/bshaffer/ChartDown · PHP · 220 lines · 145 code · 18 blank · 57 comment · 1 complexity · 2e0e0a7b69d62773af496efc8daffe1c MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of ChartDown.
  4. *
  5. * (c) 2009 Fabien Potencier
  6. * (c) 2009 Armin Ronacher
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. /**
  12. * Compiles a node to PHP code.
  13. *
  14. * @package chartdown
  15. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  16. */
  17. class ChartDown_Compiler implements ChartDown_CompilerInterface
  18. {
  19. protected $lastLine;
  20. protected $source;
  21. protected $indentation;
  22. protected $env;
  23. /**
  24. * Constructor.
  25. *
  26. * @param ChartDown_Environment $env The chartdown environment instance
  27. */
  28. public function __construct(ChartDown_Environment $env)
  29. {
  30. $this->env = $env;
  31. }
  32. /**
  33. * Returns the environment instance related to this compiler.
  34. *
  35. * @return ChartDown_Environment The environment instance
  36. */
  37. public function getEnvironment()
  38. {
  39. return $this->env;
  40. }
  41. /**
  42. * Gets the current PHP code after compilation.
  43. *
  44. * @return string The PHP code
  45. */
  46. public function getSource()
  47. {
  48. return $this->source;
  49. }
  50. /**
  51. * Compiles a node.
  52. *
  53. * @param ChartDown_NodeInterface $node The node to compile
  54. * @param integer $indent The current indentation
  55. *
  56. * @return ChartDown_Compiler The current compiler instance
  57. */
  58. public function compile(ChartDown_NodeInterface $node, $indentation = 0)
  59. {
  60. $this->lastLine = null;
  61. $this->source = '';
  62. $this->indentation = $indentation;
  63. $node->compile($this);
  64. return $this;
  65. }
  66. public function subcompile(ChartDown_NodeInterface $node, $raw = true)
  67. {
  68. if (false === $raw)
  69. {
  70. $this->addIndentation();
  71. }
  72. $node->compile($this);
  73. return $this;
  74. }
  75. /**
  76. * Adds a raw string to the compiled code.
  77. *
  78. * @param string $string The string
  79. *
  80. * @return ChartDown_Compiler The current compiler instance
  81. */
  82. public function raw($string)
  83. {
  84. $this->source .= $string;
  85. return $this;
  86. }
  87. /**
  88. * Writes a string to the compiled code by adding indentation.
  89. *
  90. * @return ChartDown_Compiler The current compiler instance
  91. */
  92. public function write()
  93. {
  94. $strings = func_get_args();
  95. foreach ($strings as $string) {
  96. $this->addIndentation();
  97. $this->source .= $string;
  98. }
  99. return $this;
  100. }
  101. public function addIndentation()
  102. {
  103. $this->source .= str_repeat(' ', $this->indentation * 4);
  104. return $this;
  105. }
  106. /**
  107. * Adds a quoted string to the compiled code.
  108. *
  109. * @param string $string The string
  110. *
  111. * @return ChartDown_Compiler The current compiler instance
  112. */
  113. public function string($value)
  114. {
  115. $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\"));
  116. return $this;
  117. }
  118. /**
  119. * Returns a PHP representation of a given value.
  120. *
  121. * @param mixed $value The value to convert
  122. *
  123. * @return ChartDown_Compiler The current compiler instance
  124. */
  125. public function repr($value)
  126. {
  127. if (is_int($value) || is_float($value)) {
  128. $this->raw($value);
  129. } else if (null === $value) {
  130. $this->raw('null');
  131. } else if (is_bool($value)) {
  132. $this->raw($value ? 'true' : 'false');
  133. } else if (is_array($value)) {
  134. $this->raw('array(');
  135. $i = 0;
  136. foreach ($value as $key => $value) {
  137. if ($i++) {
  138. $this->raw(', ');
  139. }
  140. $this->repr($key);
  141. $this->raw(' => ');
  142. $this->repr($value);
  143. }
  144. $this->raw(')');
  145. } else {
  146. $this->string($value);
  147. }
  148. return $this;
  149. }
  150. /**
  151. * Adds debugging information.
  152. *
  153. * @param ChartDown_NodeInterface $node The related chartdown node
  154. *
  155. * @return ChartDown_Compiler The current compiler instance
  156. */
  157. public function addDebugInfo(ChartDown_NodeInterface $node)
  158. {
  159. if ($node->getLine() != $this->lastLine) {
  160. $this->lastLine = $node->getLine();
  161. $this->write("// line {$node->getLine()}\n");
  162. }
  163. return $this;
  164. }
  165. /**
  166. * Indents the generated code.
  167. *
  168. * @param integer $indent The number of indentation to add
  169. *
  170. * @return ChartDown_Compiler The current compiler instance
  171. */
  172. public function indent($step = 1)
  173. {
  174. $this->indentation += $step;
  175. return $this;
  176. }
  177. /**
  178. * Outdents the generated code.
  179. *
  180. * @param integer $indent The number of indentation to remove
  181. *
  182. * @return ChartDown_Compiler The current compiler instance
  183. */
  184. public function outdent($step = 1)
  185. {
  186. $this->indentation -= $step;
  187. if ($this->indentation < 0) {
  188. throw new ChartDown_Error('Unable to call outdent() as the indentation would become negative');
  189. }
  190. return $this;
  191. }
  192. }