wproot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }