wproot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +2 -0
  4. data/bin/wproot +7 -0
  5. data/lib/wproot.rb +11 -0
  6. data/lib/wproot/cli.rb +35 -0
  7. data/lib/wproot/compass.rb +15 -0
  8. data/lib/wproot/haml.rb +15 -0
  9. data/lib/wproot/version.rb +3 -0
  10. data/spec/spec_helper.rb +7 -0
  11. data/spec/wproot_spec.rb +59 -0
  12. data/vendor/HamlPHP.php +7 -0
  13. data/vendor/HamlPHP/.gitignore +6 -0
  14. data/vendor/HamlPHP/MIT-LICENSE +22 -0
  15. data/vendor/HamlPHP/README.mkd +39 -0
  16. data/vendor/HamlPHP/src/HamlPHP/CommentNode.php +92 -0
  17. data/vendor/HamlPHP/src/HamlPHP/Compiler.php +109 -0
  18. data/vendor/HamlPHP/src/HamlPHP/ContentEvaluator/ContentEvaluator.php +16 -0
  19. data/vendor/HamlPHP/src/HamlPHP/ContentEvaluator/DefaultContentEvaluator.php +22 -0
  20. data/vendor/HamlPHP/src/HamlPHP/DoctypeNode.php +47 -0
  21. data/vendor/HamlPHP/src/HamlPHP/Element.php +618 -0
  22. data/vendor/HamlPHP/src/HamlPHP/ElementNode.php +222 -0
  23. data/vendor/HamlPHP/src/HamlPHP/Filter/CssFilter.php +31 -0
  24. data/vendor/HamlPHP/src/HamlPHP/Filter/Filter.php +18 -0
  25. data/vendor/HamlPHP/src/HamlPHP/Filter/FilterContainer.php +34 -0
  26. data/vendor/HamlPHP/src/HamlPHP/Filter/JavascriptFilter.php +29 -0
  27. data/vendor/HamlPHP/src/HamlPHP/Filter/PhpFilter.php +24 -0
  28. data/vendor/HamlPHP/src/HamlPHP/Filter/PlainFilter.php +46 -0
  29. data/vendor/HamlPHP/src/HamlPHP/FilterNode.php +29 -0
  30. data/vendor/HamlPHP/src/HamlPHP/HamlNode.php +75 -0
  31. data/vendor/HamlPHP/src/HamlPHP/HamlPHP.php +191 -0
  32. data/vendor/HamlPHP/src/HamlPHP/Helpers.php +136 -0
  33. data/vendor/HamlPHP/src/HamlPHP/Interpolation.php +71 -0
  34. data/vendor/HamlPHP/src/HamlPHP/NodeFactory.php +80 -0
  35. data/vendor/HamlPHP/src/HamlPHP/RootNode.php +133 -0
  36. data/vendor/HamlPHP/src/HamlPHP/Storage/DontEvaluateStorage.php +68 -0
  37. data/vendor/HamlPHP/src/HamlPHP/Storage/FileStorage.php +74 -0
  38. data/vendor/HamlPHP/src/HamlPHP/Storage/Storage.php +24 -0
  39. data/vendor/HamlPHP/src/HamlPHP/TagNode.php +125 -0
  40. data/vendor/HamlPHP/src/HamlPHP/Util/BaseException.php +340 -0
  41. data/vendor/HamlPHP/src/HamlPHP/Util/BaseObject.php +94 -0
  42. data/vendor/HamlPHP/src/HamlPHP/Util/StringScanner.php +989 -0
  43. data/wproot.gemspec +21 -0
  44. metadata +126 -0
@@ -0,0 +1,191 @@
1
+ <?php
2
+
3
+ require_once 'Storage/Storage.php';
4
+ require_once 'Compiler.php';
5
+ require_once 'ContentEvaluator/DefaultContentEvaluator.php';
6
+
7
+ class HamlPHP
8
+ {
9
+ private $_compiler = null;
10
+ private $_storage = null;
11
+ private $_contentEvaluator = null;
12
+ private $_nodeFactory = null;
13
+ private $_filterContainer = null;
14
+ private $_cacheEnabled = true;
15
+
16
+ // Placeholder until config gets properly implemented
17
+ public static $Config = array(
18
+ 'escape_html' => false
19
+ );
20
+
21
+ public function __construct(Storage $storage)
22
+ {
23
+ $this->_compiler = $this->getCompiler();
24
+ $this->_storage = $storage;
25
+
26
+ if ($this->_storage instanceof ContentEvaluator) {
27
+ $this->setContentEvaluator($this->_storage);
28
+ } else {
29
+ $this->setContentEvaluator(new DefaultContentEvaluator());
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Sets a content evaluator.
35
+ *
36
+ * @param ContentEvaluator $contentEvaluator
37
+ */
38
+ public function setContentEvaluator(ContentEvaluator $contentEvaluator)
39
+ {
40
+ $this->_contentEvaluator = $contentEvaluator;
41
+ }
42
+
43
+ /**
44
+ * Sets a filter container and updates the node factory to use it.
45
+ *
46
+ * @param FilterContainer $container
47
+ */
48
+ public function setFilterContainer(FilterContainer $container)
49
+ {
50
+ $this->_filterContainer = $container;
51
+ $this->getNodeFactory()->setFilterContainer($this->getFilterContainer());
52
+ }
53
+
54
+ /**
55
+ * Returns a filter container object. Initializes the filter container with
56
+ * default filters if it's null.
57
+ *
58
+ * @return FilterContainer
59
+ */
60
+ public function getFilterContainer()
61
+ {
62
+ if ($this->_filterContainer === null) {
63
+ $filterContainer = new FilterContainer();
64
+ $filterContainer->addFilter(new CssFilter());
65
+ $filterContainer->addFilter(new PlainFilter());
66
+ $filterContainer->addFilter(new JavascriptFilter());
67
+ $filterContainer->addFilter(new PhpFilter());
68
+
69
+ $this->_filterContainer = $filterContainer;
70
+ }
71
+
72
+ return $this->_filterContainer;
73
+ }
74
+
75
+ /**
76
+ * Sets a node factory.
77
+ *
78
+ * @param NodeFactory $factory
79
+ */
80
+ public function setNodeFactory(NodeFactory $factory)
81
+ {
82
+ $this->_nodeFactory = $factory;
83
+ $this->getNodeFactory()->setFilterContainer($this->getFilterContainer());
84
+ }
85
+
86
+ /**
87
+ * Returns a node factory object.
88
+ *
89
+ * @return NodeFactory
90
+ */
91
+ public function getNodeFactory()
92
+ {
93
+ if ($this->_nodeFactory === null) {
94
+ $this->setNodeFactory(new NodeFactory());
95
+ }
96
+
97
+ return $this->_nodeFactory;
98
+ }
99
+
100
+ /**
101
+ * Sets a compiler.
102
+ *
103
+ * @param Compiler $compiler
104
+ */
105
+ public function setCompiler(Compiler $compiler)
106
+ {
107
+ $this->_compiler = $compiler;
108
+ }
109
+
110
+ /**
111
+ * Returns a compiler object.
112
+ *
113
+ * @return Compiler
114
+ */
115
+ public function getCompiler()
116
+ {
117
+ if ($this->_compiler === null) {
118
+ $this->_compiler = new Compiler($this);
119
+ }
120
+
121
+ return $this->_compiler;
122
+ }
123
+
124
+ /**
125
+ * Enables caching.
126
+ */
127
+ public function enableCache()
128
+ {
129
+ $this->_cacheEnabled = true;
130
+ }
131
+
132
+ /**
133
+ * Disables caching.
134
+ */
135
+ public function disableCache()
136
+ {
137
+ $this->_cacheEnabled = false;
138
+ }
139
+
140
+ /**
141
+ * Returns true if caching is enabled.
142
+ *
143
+ * @return bool
144
+ */
145
+ public function isCacheEnabled()
146
+ {
147
+ return $this->_cacheEnabled;
148
+ }
149
+
150
+ /**
151
+ * Parses a haml file and returns a cached path to the file.
152
+ *
153
+ * @param string $fileName
154
+ */
155
+ public function parseFile($fileName, array $templateVars = array())
156
+ {
157
+ $content = $this->getContentFromStorage($fileName);
158
+
159
+ return $this->_contentEvaluator->evaluate(
160
+ $content, $templateVars, $this->generateFileId($fileName));
161
+ }
162
+
163
+ /**
164
+ * Returns content from a storage
165
+ *
166
+ * @param string $fileName
167
+ * @return string
168
+ */
169
+ public function getContentFromStorage($fileName)
170
+ {
171
+ $fileId = $this->generateFileId($fileName);
172
+
173
+ if ($this->_storage === null) {
174
+ throw new Exception('Storage not set');
175
+ }
176
+
177
+ if ($this->isCacheEnabled()
178
+ && $this->_storage->isFresh($fileId)) {
179
+ return $this->_storage->fetch($fileId);
180
+ }
181
+
182
+ // file is not fresh, so compile and cache it
183
+ $this->_storage->cache($fileId, $this->_compiler->parseFile($fileName));
184
+ return $this->_storage->fetch($fileId);
185
+ }
186
+
187
+ private function generateFileId($filename)
188
+ {
189
+ return str_replace(array(':','/','\\'), '_', ltrim($filename, '/\\'));
190
+ }
191
+ }
@@ -0,0 +1,136 @@
1
+ <?php
2
+
3
+ /**
4
+ * Returns a double or single quoted string. whatever works without changing the content of the string.
5
+ * Example:
6
+ * @code
7
+ * quote("McDonald's") # -> "\"McDonad's\""
8
+ * quote("You \"win\", looser") # -> "'You \"win\", looser'"
9
+ * @endcode
10
+ *
11
+ * If it can't be done. It will return false.
12
+ *
13
+ * @param $str
14
+ * @return mixed The quoted string or false
15
+ */
16
+ function quote($str)
17
+ {
18
+ if(strpos($str, '"') === false)
19
+ return "\"$str\"";
20
+
21
+ if(strpos($str, "'") === false)
22
+ return "'$str'";
23
+
24
+ return false;
25
+ }
26
+
27
+ /**
28
+ * Prints a list of attributes specified by an array of (att_name => att_value)
29
+ *
30
+ * @param array $atts
31
+ * @param bool $echo [optional] Wheter to echo the result or not (default: true)
32
+ *
33
+ * @return string The list of attributes
34
+ */
35
+ function atts($atts, $echo=true)
36
+ {
37
+ $str = '';
38
+ $flatten = array();
39
+
40
+ foreach ($atts as $name => $value)
41
+ {
42
+ if((string)$name != 'id' && (string)$name != 'class' && is_array($value))
43
+ {
44
+ foreach($value as $k => $v)
45
+ {
46
+ // TODO: if we found an Id or a Class attribute here. What should we do? For now, it will replace the original ones instead of append
47
+ $flatten[$k] = $v;
48
+ }
49
+ unset($atts[$name]);
50
+ }
51
+ }
52
+
53
+ $atts = array_merge($atts, $flatten);
54
+
55
+ foreach ($atts as $name => $value)
56
+ {
57
+ if($value === false)
58
+ continue;
59
+
60
+ if($value === true)
61
+ {
62
+ $str .= " $name=\"$name\"";
63
+ }
64
+ else
65
+ {
66
+ if('id' == (string)$name && is_array($value))
67
+ {
68
+ $str .= ' id="'.join('_', $value);
69
+ }
70
+ elseif ('class' == (string)$name && is_array($value))
71
+ $str .= ' class="'.join(' ', $value);
72
+ else
73
+ $str .= " $name=".quote($value);
74
+ }
75
+ }
76
+
77
+ if($echo)
78
+ echo $str;
79
+
80
+ return $str;
81
+ }
82
+
83
+ /**
84
+ * Returns an id generated by joining the class of $obj and the id of $obj, joined by a underscore (_), and prefixing it with $prefix.
85
+ * To get the class, this method will call the class_for() helper.
86
+ * To get the id, this method first check if the \c $id variable is set, if not, it checks for a \c getId()
87
+ * method. If none of them is found, it will use an internal, class specific, object counter.
88
+ *
89
+ * @param object $obj
90
+ * @param string $prefix [Optional]
91
+ */
92
+ function id_for($obj, $prefix = '')
93
+ {
94
+ static $counter = array();
95
+
96
+ if(!empty($prefix))
97
+ $prefix .= '_';
98
+
99
+ $klass = class_for($obj).'_';
100
+
101
+ if(isset($obj->id))
102
+ return $prefix.$klass.$obj->id;
103
+
104
+ if(method_exists($obj, 'getId'))
105
+ return $prefix.$klass.$obj->getId();
106
+
107
+ if(!isset($counter[$klass]))
108
+ $counter[$klass] = 0;
109
+
110
+ $counter[$klass]++;
111
+
112
+ return $prefix.$klass.$counter[$klass];
113
+ }
114
+
115
+ /**
116
+ * Returns the class name of an object to be used in the class attribute.
117
+ * This behaviour can be overloaded by implement a haml_obj_ref (or hamlObjRef) method.
118
+ * Which MUST return a string. If such method isn't present, it will use php's get_class() function.
119
+ * If prefix is not empty, both, the object's class and the prefix, will be returned separated by one space.
120
+ *
121
+ * @param object $obj
122
+ * @param string $prefix [Optional]
123
+ */
124
+ function class_for($obj, $prefix = '')
125
+ {
126
+ if(!empty($prefix))
127
+ $prefix .= ' ';
128
+
129
+ if(method_exists($obj, 'haml_obj_ref'))
130
+ return $prefix.$obj->haml_obj_ref();
131
+
132
+ if(method_exists($obj, 'hamlObjRef'))
133
+ return $prefix.$obj->hamlObjRef();
134
+
135
+ return $prefix.get_class($obj);
136
+ }
@@ -0,0 +1,71 @@
1
+ <?php
2
+
3
+ class Interpolation
4
+ {
5
+ const REGEXP = '/(?:\#\{([^\}]+)\})+/';
6
+ const REPLACEMENT = '<?php echo $1; ?>';
7
+
8
+ private $_text = null;
9
+
10
+ public function __construct($text)
11
+ {
12
+ $this->_text = $text;
13
+ }
14
+
15
+ /**
16
+ * @todo Refactor!
17
+ * @throws LogicException
18
+ */
19
+ public function render()
20
+ {
21
+ $interpolationStarted = false;
22
+ $content = "";
23
+ $interpolationContent = "";
24
+ $len = strlen($this->_text);
25
+ $i = 0;
26
+
27
+ while ($i < $len) {
28
+ $currentChar = $this->_text[$i];
29
+ $nextChar = ($i + 1 <= $len - 1) ? $this->_text[$i + 1] : null;
30
+
31
+ if ($interpolationStarted) {
32
+ if ($currentChar === '}') {
33
+ $interpolationStarted = false;
34
+
35
+ if (empty($interpolationContent)) {
36
+ throw new LogicException("Empty interpolation: " . $this->_text);
37
+ }
38
+
39
+ $content .= "<?php echo " . $interpolationContent . "; ?>";
40
+ $interpolationContent = '';
41
+ $i++;
42
+ continue;
43
+ }
44
+
45
+ if (null !== $nextChar && '#{' === $currentChar . $nextChar) {
46
+ throw new LogicException(
47
+ "Nested interpolation not allowed: " . $this->_text);
48
+ }
49
+
50
+ $interpolationContent .= $currentChar;
51
+ $i++;
52
+ continue;
53
+ }
54
+
55
+ if (null !== $nextChar && '#{' === $currentChar . $nextChar) {
56
+ $interpolationStarted = true;
57
+ $i += 2;
58
+ continue;
59
+ }
60
+
61
+ $content .= $currentChar;
62
+ $i++;
63
+ }
64
+
65
+ if ($interpolationStarted) {
66
+ throw new LogicException("Unclosed interpolation: " . $this->_text);
67
+ }
68
+
69
+ return $content;
70
+ }
71
+ }
@@ -0,0 +1,80 @@
1
+ <?php
2
+
3
+ require_once 'ElementNode.php';
4
+ require_once 'HamlNode.php';
5
+ require_once 'DoctypeNode.php';
6
+ require_once 'TagNode.php';
7
+ require_once 'CommentNode.php';
8
+ require_once 'FilterNode.php';
9
+
10
+ class NodeFactory
11
+ {
12
+ const ELEMENT = '%';
13
+ const ID = '#';
14
+ const KLASS = '.';
15
+
16
+ const HTML_COMMENT = '/';
17
+ const HAML_COMMENT = '-#';
18
+ const DOCTYPE = '!!!';
19
+
20
+ const VARIABLE = '=';
21
+ const TAG = '-';
22
+ const FILTER = ':';
23
+ const LOUD_SCRIPT = '=';
24
+
25
+ private $_filterContainer = null;
26
+
27
+ public function setFilterContainer(FilterContainer $container)
28
+ {
29
+ $this->_filterContainer = $container;
30
+ }
31
+
32
+ protected function getNodeObject($line, Compiler $compiler) {
33
+ $strippedLine = trim($line);
34
+
35
+ if($strippedLine == '')
36
+ return null;
37
+
38
+ if (strpos($strippedLine, self::FILTER, 0) === 0) {
39
+ return new FilterNode($line, $this->_filterContainer);
40
+ }
41
+
42
+ if (strpos($strippedLine, NodeFactory::DOCTYPE, 0) !== false) {
43
+ return new DoctypeNode($line);
44
+ }
45
+
46
+ if (substr($strippedLine, 0, 1) === NodeFactory::HTML_COMMENT
47
+ || substr($strippedLine, 0, 2) === NodeFactory::HAML_COMMENT) {
48
+ return new CommentNode($line);
49
+ }
50
+
51
+ $elements = array(
52
+ NodeFactory::ELEMENT,
53
+ NodeFactory::ID,
54
+ NodeFactory::KLASS,
55
+ );
56
+
57
+ if (in_array($strippedLine[0], $elements)) {
58
+ return new ElementNode($line, $compiler);
59
+ }
60
+
61
+ if ($strippedLine[0] === NodeFactory::TAG
62
+ ||$strippedLine[0] === NodeFactory::LOUD_SCRIPT) {
63
+ return new TagNode($line);
64
+ }
65
+
66
+ return new HamlNode($line);
67
+ }
68
+
69
+ public function createNode($line, $lineNumber, Compiler $compiler)
70
+ {
71
+ $node = $this->getNodeObject($line, $compiler);
72
+
73
+ if ($node !== null) {
74
+ $node->setLineNumber($lineNumber);
75
+ $node->setCompiler($compiler);
76
+ }
77
+
78
+ return $node;
79
+ }
80
+ }