From 3f8c9f0ae60aaa3ddf29c9300f5f5a67cd91bd6c Mon Sep 17 00:00:00 2001 From: Alinson Santos Date: Sun, 2 Mar 2008 19:19:02 -0300 Subject: [PATCH] Gem: haml --- vendor/gems/haml-1.7.2/MIT-LICENSE | 20 + vendor/gems/haml-1.7.2/README | 248 +++++ vendor/gems/haml-1.7.2/Rakefile | 174 ++++ vendor/gems/haml-1.7.2/VERSION | 1 + vendor/gems/haml-1.7.2/bin/css2sass | 7 + vendor/gems/haml-1.7.2/bin/haml | 8 + vendor/gems/haml-1.7.2/bin/html2haml | 7 + vendor/gems/haml-1.7.2/bin/sass | 8 + vendor/gems/haml-1.7.2/init.rb | 7 + vendor/gems/haml-1.7.2/lib/haml.rb | 708 ++++++++++++++ vendor/gems/haml-1.7.2/lib/haml/buffer.rb | 213 +++++ vendor/gems/haml-1.7.2/lib/haml/engine.rb | 876 ++++++++++++++++++ vendor/gems/haml-1.7.2/lib/haml/error.rb | 43 + vendor/gems/haml-1.7.2/lib/haml/exec.rb | 296 ++++++ vendor/gems/haml-1.7.2/lib/haml/filters.rb | 89 ++ vendor/gems/haml-1.7.2/lib/haml/helpers.rb | 328 +++++++ .../haml/helpers/action_view_extensions.rb | 45 + .../lib/haml/helpers/action_view_mods.rb | 86 ++ .../lib/haml/helpers/action_view_mods.rb.rej | 30 + vendor/gems/haml-1.7.2/lib/haml/html.rb | 173 ++++ vendor/gems/haml-1.7.2/lib/haml/template.rb | 99 ++ vendor/gems/haml-1.7.2/lib/haml/util.rb | 18 + vendor/gems/haml-1.7.2/lib/sass.rb | 613 ++++++++++++ vendor/gems/haml-1.7.2/lib/sass/constant.rb | 219 +++++ .../haml-1.7.2/lib/sass/constant/color.rb | 101 ++ .../haml-1.7.2/lib/sass/constant/literal.rb | 53 ++ .../haml-1.7.2/lib/sass/constant/number.rb | 87 ++ .../haml-1.7.2/lib/sass/constant/operation.rb | 30 + .../haml-1.7.2/lib/sass/constant/string.rb | 18 + vendor/gems/haml-1.7.2/lib/sass/css.rb | 197 ++++ vendor/gems/haml-1.7.2/lib/sass/engine.rb | 354 +++++++ vendor/gems/haml-1.7.2/lib/sass/error.rb | 35 + vendor/gems/haml-1.7.2/lib/sass/plugin.rb | 111 +++ .../gems/haml-1.7.2/lib/sass/plugin/merb.rb | 20 + .../gems/haml-1.7.2/lib/sass/plugin/rails.rb | 18 + .../haml-1.7.2/lib/sass/tree/attr_node.rb | 52 ++ .../haml-1.7.2/lib/sass/tree/comment_node.rb | 14 + vendor/gems/haml-1.7.2/lib/sass/tree/node.rb | 46 + .../haml-1.7.2/lib/sass/tree/rule_node.rb | 59 ++ .../haml-1.7.2/lib/sass/tree/value_node.rb | 16 + vendor/gems/haml-1.7.2/test/benchmark.rb | 62 ++ .../gems/haml-1.7.2/test/haml/engine_test.rb | 261 ++++++ .../gems/haml-1.7.2/test/haml/helper_test.rb | 123 +++ .../haml-1.7.2/test/haml/mocks/article.rb | 6 + .../haml/results/content_for_layout.xhtml | 16 + .../test/haml/results/eval_suppressed.xhtml | 8 + .../test/haml/results/filters.xhtml | 57 ++ .../test/haml/results/helpers.xhtml | 84 ++ .../test/haml/results/helpful.xhtml | 10 + .../test/haml/results/just_stuff.xhtml | 59 ++ .../haml-1.7.2/test/haml/results/list.xhtml | 12 + .../test/haml/results/original_engine.xhtml | 24 + .../test/haml/results/partials.xhtml | 20 + .../test/haml/results/silent_script.xhtml | 74 ++ .../test/haml/results/standard.xhtml | 43 + .../test/haml/results/tag_parsing.xhtml | 28 + .../test/haml/results/very_basic.xhtml | 7 + .../haml/results/whitespace_handling.xhtml | 94 ++ .../haml-1.7.2/test/haml/rhtml/standard.rhtml | 55 ++ vendor/gems/haml-1.7.2/test/haml/runner.rb | 16 + .../haml-1.7.2/test/haml/template_test.rb | 155 ++++ .../test/haml/templates/_partial.haml | 7 + .../test/haml/templates/_text_area.haml | 3 + .../test/haml/templates/breakage.haml | 8 + .../haml/templates/content_for_layout.haml | 10 + .../test/haml/templates/eval_suppressed.haml | 10 + .../test/haml/templates/filters.haml | 53 ++ .../test/haml/templates/helpers.haml | 63 ++ .../test/haml/templates/helpful.haml | 11 + .../test/haml/templates/just_stuff.haml | 69 ++ .../haml-1.7.2/test/haml/templates/list.haml | 12 + .../test/haml/templates/original_engine.haml | 17 + .../test/haml/templates/partialize.haml | 1 + .../test/haml/templates/partials.haml | 12 + .../test/haml/templates/silent_script.haml | 40 + .../test/haml/templates/standard.haml | 43 + .../test/haml/templates/tag_parsing.haml | 24 + .../test/haml/templates/very_basic.haml | 4 + .../haml/templates/whitespace_handling.haml | 87 ++ vendor/gems/haml-1.7.2/test/profile.rb | 65 ++ .../gems/haml-1.7.2/test/sass/engine_test.rb | 116 +++ .../gems/haml-1.7.2/test/sass/plugin_test.rb | 136 +++ .../gems/haml-1.7.2/test/sass/results/alt.css | 4 + .../haml-1.7.2/test/sass/results/basic.css | 9 + .../haml-1.7.2/test/sass/results/compact.css | 5 + .../haml-1.7.2/test/sass/results/complex.css | 87 ++ .../test/sass/results/constants.css | 12 + .../haml-1.7.2/test/sass/results/expanded.css | 18 + .../haml-1.7.2/test/sass/results/import.css | 27 + .../haml-1.7.2/test/sass/results/nested.css | 21 + .../test/sass/results/parent_ref.css | 13 + .../subdir/nested_subdir/nested_subdir.css | 1 + .../test/sass/results/subdir/subdir.css | 1 + .../haml-1.7.2/test/sass/templates/alt.sass | 16 + .../haml-1.7.2/test/sass/templates/basic.sass | 23 + .../haml-1.7.2/test/sass/templates/bork.sass | 2 + .../haml-1.7.2/test/sass/templates/bork2.sass | 2 + .../test/sass/templates/compact.sass | 15 + .../test/sass/templates/complex.sass | 309 ++++++ .../test/sass/templates/constants.sass | 88 ++ .../test/sass/templates/expanded.sass | 15 + .../test/sass/templates/import.sass | 8 + .../test/sass/templates/importee.sass | 10 + .../test/sass/templates/nested.sass | 23 + .../test/sass/templates/parent_ref.sass | 25 + .../subdir/nested_subdir/nested_subdir.sass | 3 + .../test/sass/templates/subdir/subdir.sass | 6 + 107 files changed, 8275 insertions(+) create mode 100644 vendor/gems/haml-1.7.2/MIT-LICENSE create mode 100644 vendor/gems/haml-1.7.2/README create mode 100644 vendor/gems/haml-1.7.2/Rakefile create mode 100644 vendor/gems/haml-1.7.2/VERSION create mode 100644 vendor/gems/haml-1.7.2/bin/css2sass create mode 100644 vendor/gems/haml-1.7.2/bin/haml create mode 100644 vendor/gems/haml-1.7.2/bin/html2haml create mode 100644 vendor/gems/haml-1.7.2/bin/sass create mode 100644 vendor/gems/haml-1.7.2/init.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/buffer.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/engine.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/error.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/exec.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/filters.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/helpers.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_extensions.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb.rej create mode 100644 vendor/gems/haml-1.7.2/lib/haml/html.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/template.rb create mode 100644 vendor/gems/haml-1.7.2/lib/haml/util.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant/color.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant/literal.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant/number.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant/operation.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/constant/string.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/css.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/engine.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/error.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/plugin.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/plugin/merb.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/plugin/rails.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/tree/attr_node.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/tree/comment_node.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/tree/node.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/tree/rule_node.rb create mode 100644 vendor/gems/haml-1.7.2/lib/sass/tree/value_node.rb create mode 100644 vendor/gems/haml-1.7.2/test/benchmark.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/engine_test.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/helper_test.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/mocks/article.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/content_for_layout.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/eval_suppressed.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/filters.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/helpers.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/helpful.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/just_stuff.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/list.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/original_engine.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/partials.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/silent_script.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/standard.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/tag_parsing.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/very_basic.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/results/whitespace_handling.xhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/rhtml/standard.rhtml create mode 100644 vendor/gems/haml-1.7.2/test/haml/runner.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/template_test.rb create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/_partial.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/_text_area.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/breakage.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/content_for_layout.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/eval_suppressed.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/filters.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/helpers.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/helpful.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/just_stuff.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/list.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/original_engine.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/partialize.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/partials.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/silent_script.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/standard.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/tag_parsing.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/very_basic.haml create mode 100644 vendor/gems/haml-1.7.2/test/haml/templates/whitespace_handling.haml create mode 100644 vendor/gems/haml-1.7.2/test/profile.rb create mode 100644 vendor/gems/haml-1.7.2/test/sass/engine_test.rb create mode 100644 vendor/gems/haml-1.7.2/test/sass/plugin_test.rb create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/alt.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/basic.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/compact.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/complex.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/constants.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/expanded.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/import.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/nested.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/parent_ref.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/subdir/nested_subdir/nested_subdir.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/results/subdir/subdir.css create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/alt.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/basic.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/bork.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/bork2.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/compact.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/complex.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/constants.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/expanded.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/import.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/importee.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/nested.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/parent_ref.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/subdir/nested_subdir/nested_subdir.sass create mode 100644 vendor/gems/haml-1.7.2/test/sass/templates/subdir/subdir.sass diff --git a/vendor/gems/haml-1.7.2/MIT-LICENSE b/vendor/gems/haml-1.7.2/MIT-LICENSE new file mode 100644 index 0000000..3b9f453 --- /dev/null +++ b/vendor/gems/haml-1.7.2/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2006-2007 Hampton Catlin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/README b/vendor/gems/haml-1.7.2/README new file mode 100644 index 0000000..2022575 --- /dev/null +++ b/vendor/gems/haml-1.7.2/README @@ -0,0 +1,248 @@ += Haml and Sass + +Haml and Sass are templating engines +for the two most common types of documents on the web: +HTML and CSS, respectively. +They are designed to make it both easier and more pleasant +to code HTML and CSS documents, +by eliminating redundancy, +reflecting the underlying structure that the document represents, +and providing elegant, easily understandable, and powerful syntax. + +== Using + +There are several ways to use Haml and Sass. +They can be used as a plugins for Rails or Merb, +or embedded on their own in other applications. +The first step of all of these is to install the Haml gem: + + gem install haml + +To install Haml and Sass as a Rails plugin, +just run haml --rails path/to/rails/app +and both Haml and Sass will be installed. +Views with the .haml (or .html.haml for edge) +extension will automatically use Haml. +Sass is a little more complicated; +.sass files should be placed in public/stylesheets/sass, +where they'll be automatically compiled +to corresponding CSS files in public/stylesheets when needed +(the Sass template directory is customizable... +see the Sass module docs for details). + +For Merb, .html.haml views will work without any further modification. +To enable Sass, you also need to add it add a dependency. +To do so, just add + + dependency "haml" + +to config/dependencies.rb. +Then it'll work just like it does in Rails. + +To use Haml and Sass programatically, +check out the RDocs for the Haml and Sass modules. + +== Formatting + +=== Haml + +The most basic element of Haml +is a shorthand for creating HTML tags: + + %tagname{ :attr1 => 'value1', :attr2 => 'value2' } Contents + +No end-tag is needed; Haml handles that automatically. +Adding class and id attributes is even easier. +Haml uses the same syntax as the CSS that styles the document: + + %tagname#id.class + +In fact, when you're using the
tag, +it becomes even easier. +Because
is such a common element, +a tag without a name defaults to a div. So + + #foo Hello! + +becomes + +
Hello!
+ +Haml uses indentation +to bring the individual elements to represent the HTML structure. +A tag's children are indented two spaces more than the parent tag. +Again, a closing tag is automatically added. +For example: + + %ul + %li Salt + %li Pepper + +becomes: + +
    +
  • Salt
  • +
  • Pepper
  • +
+ +You can also put plain text as a child of an element: + + %p + Hello, + World! + +It's even possible to embed Ruby code into Haml documents. +An equals sign, =, will output the result of the code. +A hyphen, -, will run the code but not output the result. +You can even use control statements +like if and while: + + %p + Date/Time: + - now = DateTime.now + %strong= now + - if now > DateTime.parse("December 31, 2006") + = "Happy new " + "year!" + +Haml provides far more tools than those presented here. +Check out the reference documentation in the Haml module. + +=== Sass + +At its most basic, +Sass is just another way of writing CSS. +Although it's very much like normal CSS, +the basic syntax offers a few helpful features: +tabulation (using *two spaces*) +indicates the attributes in a rule, +rather than non-DRY brackets; +and newlines indicate the end of an attribute, +rather than a semicolon. +For example: + + #main + :background-color #f00 + :width 98% + +becomes: + + #main { + background-color: #f00; + width: 98% } + +However, Sass provides much more than a way to make CSS look nice. +In CSS, it's important to have accurate selectors, +so your styles don't just apply to everything. +However, in order to do this, +you need to use nested element selectors. +These get very ugly very quickly. +I'm sure everyone's had to write something like +"#main .sidebar .top p h1 a", +followed by +"#main .sidebar .top p h1 a:visited" and +"#main .sidebar .top p h1 a:hover". +Well, Sass gets rid of that. +Like Haml, it uses indentation to indicate the structure of the document. +So, what was: + + #main { + width: 90%; + } + #main p { + border-style: solid; + border-width: 1px; + border-color: #00f; + } + #main p a { + text-decoration: none; + font-weight: bold; + } + #main p a:hover { + text-decoration: underline; + } + +becomes: + + #main + :width 90% + p + :border-style solid + :border-width 1px + :border-color #00f + a + :text-decoration none + :font-weight bold + a:hover + :text-decoration underline + +Pretty nice, no? Well, it gets better. +One of the main complaints against CSS is that it doesn't allow constants. +What if have a color or a width you re-use all the time? +In CSS, you just have to re-type it each time, +which is a nightmare when you decide to change it later. +Not so for Sass! +You can use the "!" character to set constants. +Then, if you put "=" after your attribute name, +you can set it to a constant. +For example: + + !note_bg= #55aaff + + #main + :width 70% + .note + :background-color= !note_bg + p + :width 5em + :background-color= !note_bg + +becomes: + + #main { + width: 70%; } + #main .note { + background-color: #55aaff; } + #main p { + width: 5em; + background-color: #55aaff; } + +You can even do simple arithmetic operations with constants, +adding numbers and even colors together: + + !main_bg= #46ar12 + !main_width= 40em + + #main + :background-color= !main_bg + :width= !main_width + .sidebar + :background-color= !main_bg + #333333 + :width= !main_width - 25em + +becomes: + + #main { + background-color: #46a312; + width: 40em; } + #main .sidebar { + background-color: #79d645; + width: 15em; } + +A comprehensive list of features is in +the documentation for the Sass module. + +== Authors + +Haml and Sass are designed by Hampton Catlin (hcatlin). +Help with the Ruby On Rails implementation and much of the documentation +by Jeff Hardy (packagethief). + +Nathan Weizenbaum (Nex3) contributed the buffered-engine code to Haml, +along with many other enhancements +(including the silent-line syntax: "-"). +He continues to actively work on both Haml and Sass. + +If you use this software, you must pay Hampton a compliment. +Say something nice about it. +Beyond that, the implementation is licensed under the MIT License. +Ok, fine, I guess that means compliments aren't *required*. diff --git a/vendor/gems/haml-1.7.2/Rakefile b/vendor/gems/haml-1.7.2/Rakefile new file mode 100644 index 0000000..1942f61 --- /dev/null +++ b/vendor/gems/haml-1.7.2/Rakefile @@ -0,0 +1,174 @@ +require 'rubygems' +require 'rake' + +volatile_requires = ['rcov/rcovtask'] +not_loaded = [] +volatile_requires.each do |file| + begin + require file + rescue LoadError + not_loaded.push file + end +end + +# ----- Benchmarking ----- + +temp_desc = < :test + + require 'rake/testtask' + + desc 'Test the Haml plugin' + Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true + end + + # ----- Packaging ----- + + require 'rake/gempackagetask' + + spec = Gem::Specification.new do |spec| + spec.name = 'haml' + spec.summary = "An elegant, structured XHTML/XML templating engine.\nComes with Sass, a similar CSS templating engine." + spec.version = File.read('VERSION').strip + spec.author = 'Hampton Catlin' + spec.email = 'haml@googlegroups.com' + spec.description = <<-END + Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML + that's designed to express the structure of XHTML or XML documents + in a non-repetitive, elegant, easy way, + using indentation rather than closing tags + and allowing Ruby to be embedded with ease. + It was originally envisioned as a plugin for Ruby on Rails, + but it can function as a stand-alone templating engine. + END + #' + + readmes = FileList.new('*') do |list| + list.exclude(/[a-z]/) + list.exclude('TODO') + end.to_a + spec.executables = ['haml', 'html2haml', 'sass'] + spec.files = FileList['lib/**/*', 'bin/*', 'test/**/*', 'Rakefile', 'init.rb'].to_a + readmes + spec.autorequire = ['haml', 'sass'] + spec.homepage = 'http://haml.hamptoncatlin.com/' + spec.has_rdoc = true + spec.extra_rdoc_files = readmes + spec.rdoc_options += [ + '--title', 'Haml', + '--main', 'README', + '--exclude', 'lib/haml/buffer.rb', + '--line-numbers', + '--inline-source' + ] + spec.test_files = FileList['test/**/*_test.rb'].to_a + end + + Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_zip = true + pkg.need_tar_gz = true + pkg.need_tar_bz2 = true + end + + task :install => [:package] do + sh %{gem install --no-ri pkg/haml-#{File.read('VERSION').strip}} + end + + # ----- Documentation ----- + + require 'rake/rdoctask' + + rdoc_task = Proc.new do |rdoc| + rdoc.title = 'Haml/Sass' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') + rdoc.rdoc_files.exclude('lib/haml/buffer.rb') + rdoc.rdoc_files.exclude('lib/haml/util.rb') + rdoc.rdoc_files.exclude('lib/sass/tree/*') + end + + Rake::RDocTask.new do |rdoc| + rdoc_task.call(rdoc) + rdoc.rdoc_dir = 'rdoc' + end + + Rake::RDocTask.new(:rdoc_devel) do |rdoc| + rdoc_task.call(rdoc) + rdoc.rdoc_dir = 'rdoc_devel' + rdoc.options << '--all' + rdoc.rdoc_files.include('test/*.rb') + + # Get rid of exclusion rules + rdoc.rdoc_files = Rake::FileList.new(*rdoc.rdoc_files.to_a) + rdoc.rdoc_files.include('lib/haml/buffer.rb') + rdoc.rdoc_files.include('lib/sass/tree/*') + end + + # ----- Coverage ----- + + unless not_loaded.include? 'rcov/rcovtask' + Rcov::RcovTask.new do |t| + t.libs << "test" + t.test_files = FileList['test/**/*_test.rb'] + t.rcov_opts << '-x' << '"^\/"' + if ENV['NON_NATIVE'] + t.rcov_opts << "--no-rcovrt" + end + t.verbose = true + end + end + + # ----- Profiling ----- + + temp_desc = <<-END + Run a profile of haml. + ENGINE=str sets the engine to be profiled (Haml or Sass). + TIMES=n sets the number of runs. Defaults to 100. + FILE=n sets the file to profile. Defaults to 'standard'. + END + desc temp_desc.chomp + task :profile do + require 'test/profile' + + engine = ENV['ENGINE'] && ENV['ENGINE'].downcase == 'sass' ? Sass : Haml + + puts '-'*51, "Profiling #{engine}", '-'*51 + + args = [] + args.push ENV['TIMES'].to_i if ENV['TIMES'] + args.push ENV['FILE'] if ENV['FILE'] + + profiler = engine::Profiler.new + res = profiler.profile(*args) + puts res + + puts '-'*51 + end + +end diff --git a/vendor/gems/haml-1.7.2/VERSION b/vendor/gems/haml-1.7.2/VERSION new file mode 100644 index 0000000..f8a696c --- /dev/null +++ b/vendor/gems/haml-1.7.2/VERSION @@ -0,0 +1 @@ +1.7.2 diff --git a/vendor/gems/haml-1.7.2/bin/css2sass b/vendor/gems/haml-1.7.2/bin/css2sass new file mode 100644 index 0000000..8245f18 --- /dev/null +++ b/vendor/gems/haml-1.7.2/bin/css2sass @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/exec' + +opts = Haml::Exec::CSS2Sass.new(ARGV) +opts.parse! diff --git a/vendor/gems/haml-1.7.2/bin/haml b/vendor/gems/haml-1.7.2/bin/haml new file mode 100644 index 0000000..3480fb9 --- /dev/null +++ b/vendor/gems/haml-1.7.2/bin/haml @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +# The command line Haml parser. + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/exec' + +opts = Haml::Exec::Haml.new(ARGV) +opts.parse! diff --git a/vendor/gems/haml-1.7.2/bin/html2haml b/vendor/gems/haml-1.7.2/bin/html2haml new file mode 100644 index 0000000..a85e95a --- /dev/null +++ b/vendor/gems/haml-1.7.2/bin/html2haml @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/exec' + +opts = Haml::Exec::HTML2Haml.new(ARGV) +opts.parse! diff --git a/vendor/gems/haml-1.7.2/bin/sass b/vendor/gems/haml-1.7.2/bin/sass new file mode 100644 index 0000000..1cc522a --- /dev/null +++ b/vendor/gems/haml-1.7.2/bin/sass @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +# The command line Sass parser. + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/exec' + +opts = Haml::Exec::Sass.new(ARGV) +opts.parse! diff --git a/vendor/gems/haml-1.7.2/init.rb b/vendor/gems/haml-1.7.2/init.rb new file mode 100644 index 0000000..3d4283a --- /dev/null +++ b/vendor/gems/haml-1.7.2/init.rb @@ -0,0 +1,7 @@ +require 'haml' +require 'haml/template' +require 'sass' +require 'sass/plugin' + +ActionView::Base.register_template_handler('haml', Haml::Template) +Sass::Plugin.update_stylesheets diff --git a/vendor/gems/haml-1.7.2/lib/haml.rb b/vendor/gems/haml-1.7.2/lib/haml.rb new file mode 100644 index 0000000..85f0fea --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml.rb @@ -0,0 +1,708 @@ +dir = File.dirname(__FILE__) +$LOAD_PATH << dir unless $LOAD_PATH.include?(dir) + +# = Haml (XHTML Abstraction Markup Language) +# +# Haml is a markup language +# that's used to cleanly and simply describe the XHTML of any web document, +# without the use of inline code. +# Haml functions as a replacement +# for inline page templating systems such as PHP, ERB, and ASP. +# However, Haml avoids the need for explicitly coding XHTML into the template, +# because it is actually an abstract description of the XHTML, +# with some code to generate dynamic content. +# +# == Features +# +# * Whitespace active +# * Well-formatted markup +# * DRY +# * Follows CSS conventions +# * Integrates Ruby code +# * Implements Rails templates with the .haml extension +# +# == Using Haml +# +# Haml can be used in two ways: +# as a plugin for Ruby on Rails, +# and as a standalone Ruby module. +# +# Sass can be used in several ways: +# As a template engine for Ruby on Rails or Merb, +# or as a standalone engine. +# The first step for all of these is to install the Haml gem: +# +# gem install haml +# +# To enable it as a Rails plugin, +# then run +# +# haml --rails path/to/rails/app +# +# Haml is enabled in Merb by default, +# so Merb users don't have to do anything more. +# +# Once it's installed, all view files with the ".haml" extension +# (or ".html.haml" for Merb or edge Rails) +# will be compiled using Haml. +# +# You can access instance variables in Haml templates +# the same way you do in ERb templates. +# Helper methods are also available in Haml templates. +# For example (this example uses Rails, but the principle for Merb is the same): +# +# # file: app/controllers/movies_controller.rb +# +# class MoviesController < ApplicationController +# def index +# @title = "Teen Wolf" +# end +# end +# +# -# file: app/views/movies/index.haml +# +# #content +# .title +# %h1= @title +# = link_to 'Home', home_url +# +# may be compiled to: +# +#
+#
+#

Teen Wolf

+# Home +#
+#
+# +# === Ruby Module +# +# Haml can also be used completely separately from Rails and ActionView. +# To do this, install the gem with RubyGems: +# +# gem install haml +# +# You can then use it by including the "haml" gem in Ruby code, +# and using Haml::Engine like so: +# +# engine = Haml::Engine.new("%p Haml code!") +# engine.render #=> "

Haml code!

\n" +# +# == Characters with meaning to Haml +# +# Various characters, when placed at a certain point in a line, +# instruct Haml to render different types of things. +# +# === XHTML Tags +# +# These characters render XHTML tags. +# +# ==== % +# +# +# The percent character is placed at the beginning of a line. +# It's followed immediately by the name of an element, +# then optionally by modifiers (see below), a space, +# and text to be rendered inside the element. +# It creates an element in the form of . +# For example: +# +# %one +# %two +# %three Hey there +# +# is compiled to: +# +# +# +# Hey there +# +# +# +# Any string is a valid element name; +# Haml will automatically generate opening and closing tags for any element. +# +# ==== {} +# +# Brackets represent a Ruby hash +# that is used for specifying the attributes of an element. +# It is literally evaluated as a Ruby hash, +# so logic will work in it and local variables may be used. +# Quote characters within the attribute +# will be replaced by appropriate escape sequences. +# The hash is placed after the tag is defined. +# For example: +# +# %head{ :name => "doc_head" } +# %script{ 'type' => "text/" + "javascript", +# :src => "javascripts/script_#{2 + 7}" } +# +# is compiled to: +# +# +# +# +# +# ==== [] +# +# Square brackets follow a tag definition and contain a Ruby object +# that is used to set the class and id of that tag. +# The class is set to the object's class +# (transformed to use underlines rather than camel case) +# and the id is set to the object's class, followed by its id. +# Because the id of an object is normally an obscure implementation detail, +# this is most useful for elements that represent instances of Models. +# For example: +# +# # file: app/controllers/users_controller.rb +# +# def show +# @user = CrazyUser.find(15) +# end +# +# -# file: app/views/users/show.haml +# +# %div[@user] +# %bar[290]/ +# Hello! +# +# is compiled to: +# +#
+# +# Hello! +#
+# +# This is based off of DHH's SimplyHelpful syntax, +# as presented at RailsConf Europe 2006. +# +# ==== / +# +# The forward slash character, when placed at the end of a tag definition, +# causes the tag to be self-closed. +# For example: +# +# %br/ +# %meta{'http-equiv' => 'Content-Type', :content => 'text/html'}/ +# +# is compiled to: +# +#
+# +# +# Some tags are automatically closed, as long as they have no content. +# +meta+, +img+, +link+, +script+, +br+, and +hr+ tags are closed by default. +# This list can be customized by setting the :autoclose option (see below). +# For example: +# +# %br +# %meta{'http-equiv' => 'Content-Type', :content => 'text/html'} +# +# is also compiled to: +# +#
+# +# +# ==== . and # +# +# The period and pound sign are borrowed from CSS. +# They are used as shortcuts to specify the class +# and id attributes of an element, respectively. +# Multiple class names can be specified in a similar way to CSS, +# by chaining the class names together with periods. +# They are placed immediately after the tag and before an attributes hash. +# For example: +# +# %div#things +# %span#rice Chicken Fried +# %p.beans{ :food => 'true' } The magical fruit +# %h1.class.otherclass#id La La La +# +# is compiled to: +# +#
+# Chicken Fried +#

The magical fruit

+#

La La La

+#
+# +# And, +# +# #content +# .articles +# .article.title +# Doogie Howser Comes Out +# .article.date +# 2006-11-05 +# .article.entry +# Neil Patrick Harris would like to dispel any rumors that he is straight +# +# is compiled to: +# +#
+#
+#
Doogie Howser Comes Out
+#
2006-11-05
+#
+# Neil Patrick Harris would like to dispel any rumors that he is straight +#
+#
+#
+# +# ==== Implicit Div Elements +# +# Because the div element is used so often, it is the default element. +# If you only define a class and/or id using the . or # syntax, +# a div element is automatically used. +# For example: +# +# #collection +# .item +# .description What a cool item! +# +# is the same as: +# +# %div{:id => collection} +# %div{:class => 'item'} +# %div{:class => 'description'} What a cool item! +# +# and is compiled to: +# +#
+#
+#
What a cool item!
+#
+#
+# +# ==== = +# +# = is placed at the end of a tag definition, +# after class, id, and attribute declarations. +# It's just a shortcut for inserting Ruby code into an element. +# It works the same as = without a tag: +# it inserts the result of the Ruby code into the template. +# However, if the result is short enough, +# it is displayed entirely on one line. +# For example: +# +# %p= "hello" +# +# is not quite the same as: +# +# %p +# = "hello" +# +# It's compiled to: +# +#

hello

+# +# === XHTML Helpers +# +# ==== No Special Character +# +# If no special character appears at the beginning of a line, +# the line is rendered as plain text. +# For example: +# +# %gee +# %whiz +# Wow this is cool! +# +# is compiled to: +# +# +# +# Wow this is cool! +# +# +# +# ==== !!! +# +# When describing XHTML documents with Haml, +# you can have a document type or XML prolog generated automatically +# by including the characters !!!. +# For example: +# +# !!! XML +# !!! +# %html +# %head +# %title Myspace +# %body +# %h1 I am the international space station +# %p Sign my guestbook +# +# is compiled to: +# +# +# +# +# +# Myspace +# +# +#

I am the international space station

+#

Sign my guestbook

+# +# +# +# You can also specify the version and type of XHTML after the !!!. +# XHTML 1.0 Strict, Transitional, and Frameset and XHTML 1.1 are supported. +# The default version is 1.0 and the default type is Transitional. +# For example: +# +# !!! 1.1 +# +# is compiled to: +# +# +# +# and +# +# !!! Strict +# +# is compiled to: +# +# +# +# If you're not using the UTF-8 character set for your document, +# you can specify which encoding should appear +# in the XML prolog in a similar way. +# For example: +# +# !!! XML iso-8859-1 +# +# is compiled to: +# +# +# +# ==== / +# +# The forward slash character, when placed at the beginning of a line, +# wraps all text after it in an HTML comment. +# For example: +# +# %peanutbutterjelly +# / This is the peanutbutterjelly element +# I like sandwiches! +# +# is compiled to: +# +# +# +# I like sandwiches! +# +# +# The forward slash can also wrap indented sections of code. For example: +# +# / +# %p This doesn't render... +# %div +# %h1 Because it's commented out! +# +# is compiled to: +# +# +# +# You can also use Internet Explorer conditional comments +# (about)[http://www.quirksmode.org/css/condcom.html] +# by enclosing the condition in square brackets after the /. +# For example: +# +# /[if IE] +# %a{ :href => 'http://www.mozilla.com/en-US/firefox/' } +# %h1 Get Firefox +# +# is compiled to: +# +# +# +# ==== \ +# +# The backslash character escapes the first character of a line, +# allowing use of otherwise interpreted characters as plain text. +# For example: +# +# %title +# = @title +# \- MySite +# +# is compiled to: +# +# +# MyPage +# - MySite +# +# +# ==== | +# +# The pipe character designates a multiline string. +# It's placed at the end of a line +# and means that all following lines that end with | +# will be evaluated as though they were on the same line. +# For example: +# +# %whoo +# %hoo I think this might get | +# pretty long so I should | +# probably make it | +# multiline so it doesn't | +# look awful. | +# %p This is short. +# +# is compiled to: +# +# +# +# I think this might get pretty long so I should probably make it multiline so it doesn't look awful. +# +# +# +# ==== : +# +# The colon character designates a filter. +# This allows you to pass an indented block of text as input +# to another filtering program and add the result to the output of Haml. +# The syntax is simply a colon followed by the name of the filter. +# For example, +# +# %p +# :markdown +# Textile +# ======= +# +# Hello, *World* +# +# is compiled to +# +#

+#

Textile

+# +#

Hello, World

+#

+# +# Haml has the following filters defined: +# +# [plain] Does not parse the filtered text. +# This is useful for large blocks of text without HTML tags, +# when you don't want lines starting with . or - +# to be parsed. +# +# [ruby] Parses the filtered text with the normal Ruby interpreter. +# All output sent to $stdout, like with +puts+, +# is output into the Haml document. +# Not available if the suppress_eval option is set to true. +# +# [preserve] Inserts the filtered text into the template with whitespace preserved. +# preserved blocks of text aren't indented, +# and newlines are replaced with the HTML escape code for newlines, +# to preserve nice-looking output. +# +# [erb] Parses the filtered text with ERB, like an RHTML template. +# Not available if the suppress_eval option is set to true. +# At the moment, this doesn't support access to variables +# defined by Ruby on Rails or Haml code. +# +# [sass] Parses the filtered text with Sass to produce CSS output. +# +# [redcloth] Parses the filtered text with RedCloth (http://whytheluckystiff.net/ruby/redcloth), +# which uses both Textile and Markdown syntax. +# Only works if RedCloth is installed. +# +# [textile] Parses the filtered text with Textile (http://www.textism.com/tools/textile). +# Only works if RedCloth is installed. +# +# [markdown] Parses the filtered text with Markdown (http://daringfireball.net/projects/markdown). +# Only works if RedCloth or BlueCloth (http://www.deveiate.org/projects/BlueCloth) +# is installed +# (BlueCloth takes precedence if both are installed). +# +# You can also define your own filters (see Setting Options, below). +# +# === Ruby evaluators +# +# ==== = +# +# The equals character is followed by Ruby code, +# which is evaluated and the output inserted into the document as plain text. +# For example: +# +# %p +# = ['hi', 'there', 'reader!'].join " " +# = "yo" +# +# is compiled to: +# +#

+# hi there reader! +# yo +#

+# +# You can also use two equal signs, ==, +# along with conventional Ruby string-embedding syntax +# to easily embed Ruby code in otherwise static text. +# For example: +# +# %p +# == 1 + 1 = #{1 + 1} +# +# is compiled to: +# +#

+# 1 + 1 = 2 +#

+# +# ==== - +# +# The hyphen character makes the text following it into "silent script": +# Ruby script that is evaluated, but not output. +# +# It is not recommended that you use this widely; +# almost all processing code and logic should be restricted +# to the Controller, the Helper, or partials. +# +# For example: +# +# - foo = "hello" +# - foo << " there" +# - foo << " you!" +# %p= foo +# +# is compiled to: +# +#

+# hello there you! +#

+# +# ===== Blocks +# +# Ruby blocks, like XHTML tags, don't need to be explicitly closed in Haml. +# Rather, they're automatically closed, based on indentation. +# A block begins whenever the indentation is increased +# after a silent script command. +# It ends when the indentation decreases +# (as long as it's not an +else+ clause or something similar). +# For example: +# +# - (42...47).each do |i| +# %p= i +# %p See, I can count! +# +# is compiled to: +# +#

+# 42 +#

+#

+# 43 +#

+#

+# 44 +#

+#

+# 45 +#

+#

+# 46 +#

+# +# Another example: +# +# %p +# - case 2 +# - when 1 +# = "1!" +# - when 2 +# = "2?" +# - when 3 +# = "3." +# +# is compiled to: +# +#

+# 2? +#

+# +# ==== -# +# +# The hyphen followed immediately by the pound sign +# signifies a silent comment. +# Any text following this isn't rendered in the resulting document +# at all. +# +# For example: +# +# %p foo +# -# This is a comment +# %p bar +# +# is compiled to: +# +#

foo

+#

bar

+# +# == Other Useful Things +# +# === Helpers +# +# Haml offers a bunch of helpers that are useful +# for doing stuff like preserving whitespace, +# creating nicely indented output for user-defined helpers, +# and other useful things. +# The helpers are all documented in the Haml::Helpers and Haml::Helpers::ActionViewExtensions modules. +# +# === Haml Options +# +# Options can be set by setting the hash Haml::Template.options +# from environment.rb in Rails, +# or by passing an options hash to Haml::Engine. +# Available options are: +# +# [:suppress_eval] Whether or not attribute hashes and Ruby scripts +# designated by = or ~ should be +# evaluated. If this is true, said scripts are +# rendered as empty strings. Defaults to false. +# +# [:attr_wrapper] The character that should wrap element attributes. +# This defaults to ' (an apostrophe). Characters +# of this type within the attributes will be escaped +# (e.g. by replacing them with ') if +# the character is an apostrophe or a quotation mark. +# +# [:filename] The name of the Haml file being parsed. +# This is only used as information when exceptions are raised. +# This is automatically assigned when working through ActionView, +# so it's really only useful for the user to assign +# when dealing with Haml programatically. +# +# [:filters] A hash of filters that can be applied to Haml code. +# The keys are the string names of the filters; +# the values are references to the classes of the filters. +# User-defined filters should always have lowercase keys, +# and should have: +# * An +initialize+ method that accepts one parameter, +# the text to be filtered. +# * A +render+ method that returns the result of the filtering. +# +# [:locals] The local variables that will be available within the +# template. For instance, if :locals is +# { :foo => "bar" }, then within the template, +# = foo will produce bar. +# +# [:autoclose] A list of tag names that should be automatically self-closed +# if they have no content. +# Defaults to ['meta', 'img', 'link', 'script', 'br', 'hr']. +# +module Haml; end + +require 'haml/engine' diff --git a/vendor/gems/haml-1.7.2/lib/haml/buffer.rb b/vendor/gems/haml-1.7.2/lib/haml/buffer.rb new file mode 100644 index 0000000..ca7674f --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/buffer.rb @@ -0,0 +1,213 @@ +module Haml + # This class is used only internally. It holds the buffer of XHTML that + # is eventually output by Haml::Engine's to_html method. It's called + # from within the precompiled code, and helps reduce the amount of + # processing done within instance_eval'd code. + class Buffer + include Haml::Helpers + + # Set the maximum length for a line to be considered a one-liner. + # Lines <= the maximum will be rendered on one line, + # i.e.

Hello world

+ ONE_LINER_LENGTH = 50 + + # The string that holds the compiled XHTML. This is aliased as + # _erbout for compatibility with ERB-specific code. + attr_accessor :buffer + + # Gets the current tabulation of the document. + def tabulation + @real_tabs + @tabulation + end + + # Sets the current tabulation of the document. + def tabulation=(val) + val = val - @real_tabs + @tabulation = val > -1 ? val : 0 + end + + # Creates a new buffer. + def initialize(options = {}) + @options = options + @quote_escape = options[:attr_wrapper] == '"' ? """ : "'" + @other_quote_char = options[:attr_wrapper] == '"' ? "'" : '"' + @buffer = "" + @one_liner_pending = false + @tabulation = 0 + + # The number of tabs that Engine thinks we should have + # @real_tabs + @tabulation is the number of tabs actually output + @real_tabs = 0 + end + + # Renders +text+ with the proper tabulation. This also deals with + # making a possible one-line tag one line or not. + def push_text(text, tabulation) + if @one_liner_pending && Buffer.one_liner?(text) + @buffer << text + else + if @one_liner_pending + @buffer << "\n" + @one_liner_pending = false + end + @buffer << "#{tabs(tabulation)}#{text}\n" + end + end + + # Properly formats the output of a script that was run in the + # instance_eval. + def push_script(result, tabulation, flattened) + if flattened + result = Haml::Helpers.find_and_preserve(result) + end + + result = result.to_s + while result[-1] == 10 # \n + # String#chomp is slow + result = result[0...-1] + end + + result = result.gsub("\n", "\n#{tabs(tabulation)}") + push_text result, tabulation + nil + end + + + def open_prerendered_tag(tag, tabulation) + @buffer << "#{tabs(tabulation)}#{tag}" + @real_tabs += 1 + end + + # Takes the various information about the opening tag for an + # element, formats it, and adds it to the buffer. + def open_tag(name, tabulation, atomic, try_one_line, class_id, obj_ref, attributes_hash) + attributes = class_id + if attributes_hash + attributes_hash.keys.each { |key| attributes_hash[key.to_s] = attributes_hash.delete(key) } + self.class.merge_attrs(attributes, attributes_hash) + end + self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref + + @one_liner_pending = false + if atomic + str = " />\n" + elsif try_one_line + @one_liner_pending = true + str = ">" + else + str = ">\n" + end + @buffer << "#{tabs(tabulation)}<#{name}#{build_attributes(attributes)}#{str}" + @real_tabs += 1 + end + + def self.merge_attrs(to, from) + if to['id'] && from['id'] + to['id'] << '_' << from.delete('id') + end + + if to['class'] && from['class'] + # Make sure we don't duplicate class names + from['class'] = (from['class'].split(' ') | to['class'].split(' ')).join(' ') + end + + to.merge!(from) + end + + # Creates a closing tag with the given name. + def close_tag(name, tabulation) + if @one_liner_pending + @buffer << "\n" + @one_liner_pending = false + else + push_text("", tabulation) + end + end + + # Opens an XHTML comment. + def open_comment(try_one_line, conditional, tabulation) + conditional << ">" if conditional + @buffer << "#{tabs(tabulation)}" : "-->" + if @one_liner_pending + @buffer << " #{close_tag}\n" + @one_liner_pending = false + else + push_text(close_tag, tabulation) + end + end + + # Some of these methods are exposed as public class methods + # so they can be re-used in helpers. + + # Takes a hash and builds a list of XHTML attributes from it, returning + # the result. + def build_attributes(attributes = {}) + result = attributes.collect do |a,v| + v = v.to_s + unless v.nil? || v.empty? + attr_wrapper = @options[:attr_wrapper] + if v.include? attr_wrapper + if v.include? @other_quote_char + v = v.gsub(attr_wrapper, @quote_escape) + else + attr_wrapper = @other_quote_char + end + end + " #{a}=#{attr_wrapper}#{v}#{attr_wrapper}" + end + end + result.compact.sort.join + end + + # Returns whether or not the given value is short enough to be rendered + # on one line. + def self.one_liner?(value) + value.length <= ONE_LINER_LENGTH && value.scan(/\n/).empty? + end + + private + + @@tab_cache = {} + # Gets count tabs. Mostly for internal use. + def tabs(count) + @real_tabs = count + tabs = count + @tabulation + ' ' * tabs + @@tab_cache[tabs] ||= ' ' * tabs + end + + # Takes an array of objects and uses the class and id of the first + # one to create an attributes hash. + def parse_object_ref(ref) + ref = ref[0] + # Let's make sure the value isn't nil. If it is, return the default Hash. + return {} if ref.nil? + class_name = underscore(ref.class) + id = "#{class_name}_#{ref.id || 'new'}" + + {'id' => id, 'class' => class_name} + end + + # Changes a word from camel case to underscores. + # Based on the method of the same name in Rails' Inflector, + # but copied here so it'll run properly without Rails. + def underscore(camel_cased_word) + camel_cased_word.to_s.gsub(/::/, '_'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/engine.rb b/vendor/gems/haml-1.7.2/lib/haml/engine.rb new file mode 100644 index 0000000..32d2e42 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/engine.rb @@ -0,0 +1,876 @@ +require 'haml/helpers' +require 'haml/buffer' +require 'haml/filters' +require 'haml/error' +require 'haml/util' + +module Haml + # This is the class where all the parsing and processing of the Haml + # template is done. It can be directly used by the user by creating a + # new instance and calling to_html to render the template. For example: + # + # template = File.read('templates/really_cool_template.haml') + # haml_engine = Haml::Engine.new(template) + # output = haml_engine.to_html + # puts output + class Engine + # Allow reading and writing of the options hash + attr :options, true + + # Designates an XHTML/XML element. + ELEMENT = ?% + + # Designates a
element with the given class. + DIV_CLASS = ?. + + # Designates a
element with the given id. + DIV_ID = ?# + + # Designates an XHTML/XML comment. + COMMENT = ?/ + + # Designates an XHTML doctype. + DOCTYPE = ?! + + # Designates script, the result of which is output. + SCRIPT = ?= + + # Designates script, the result of which is flattened and output. + FLAT_SCRIPT = ?~ + + # Designates script which is run but not output. + SILENT_SCRIPT = ?- + + # When following SILENT_SCRIPT, designates a comment that is not output. + SILENT_COMMENT = ?# + + # Designates a non-parsed line. + ESCAPE = ?\\ + + # Designates a block of filtered text. + FILTER = ?: + + # Designates a non-parsed line. Not actually a character. + PLAIN_TEXT = -1 + + # Keeps track of the ASCII values of the characters that begin a + # specially-interpreted line. + SPECIAL_CHARACTERS = [ + ELEMENT, + DIV_CLASS, + DIV_ID, + COMMENT, + DOCTYPE, + SCRIPT, + FLAT_SCRIPT, + SILENT_SCRIPT, + ESCAPE, + FILTER + ] + + # The value of the character that designates that a line is part + # of a multiline string. + MULTILINE_CHAR_VALUE = ?| + + # Characters that designate that a multiline string may be about + # to begin. + MULTILINE_STARTERS = SPECIAL_CHARACTERS - [?/] + + # Keywords that appear in the middle of a Ruby block with lowered + # indentation. If a block has been started using indentation, + # lowering the indentation with one of these won't end the block. + # For example: + # + # - if foo + # %p yes! + # - else + # %p no! + # + # The block is ended after %p no!, because else + # is a member of this array. + MID_BLOCK_KEYWORDS = ['else', 'elsif', 'rescue', 'ensure', 'when'] + + # The Regex that matches an HTML comment command. + COMMENT_REGEX = /\/(\[[\w\s\.]*\])?(.*)/ + + # The Regex that matches a Doctype command. + DOCTYPE_REGEX = /(\d\.\d)?[\s]*([a-z]*)/i + + # The Regex that matches an HTML tag command. + TAG_REGEX = /[%]([-:\w]+)([-\w\.\#]*)(\{.*\})?(\[.*\])?([=\/\~]?)?(.*)?/ + + # The Regex that matches a literal string or symbol value + LITERAL_VALUE_REGEX = /^\s*(:(\w*)|(('|")([^\\\#'"]*?)\4))\s*$/ + + FLAT_WARNING = <render is called. + # See README for available options. + # + #-- + # When adding options, remember to add information about them + # to README! + #++ + # + def initialize(template, l_options = {}) + @options = { + :suppress_eval => false, + :attr_wrapper => "'", + :locals => {}, + :autoclose => ['meta', 'img', 'link', 'br', 'hr', 'input', 'area'], + :filters => { + 'sass' => Sass::Engine, + 'plain' => Haml::Filters::Plain, + 'preserve' => Haml::Filters::Preserve } + } + + if !NOT_LOADED.include? 'redcloth' + @options[:filters].merge!({ + 'redcloth' => RedCloth, + 'textile' => Haml::Filters::Textile, + 'markdown' => Haml::Filters::Markdown + }) + end + if !NOT_LOADED.include? 'bluecloth' + @options[:filters]['markdown'] = Haml::Filters::Markdown + end + + @options.rec_merge! l_options + + unless @options[:suppress_eval] + @options[:filters].merge!({ + 'erb' => ERB, + 'ruby' => Haml::Filters::Ruby + }) + end + @options[:filters].rec_merge! l_options[:filters] if l_options[:filters] + + @template = template.strip #String + @to_close_stack = [] + @output_tabs = 0 + @template_tabs = 0 + @index = 0 + + # This is the base tabulation of the currently active + # flattened block. -1 signifies that there is no such block. + @flat_spaces = -1 + + begin + # Only do the first round of pre-compiling if we really need to. + # They might be passing in the precompiled string. + requires_precompile = true + if @@method_names[@template] + # Check that the compiled method supports a superset of the local assigns we want to do + supported_assigns = @@supported_local_assigns[@template] + requires_precompile = !@options[:locals].keys.all? {|var| supported_assigns.include? var} + end + do_precompile if requires_precompile + rescue Haml::Error => e + e.add_backtrace_entry(@index, @options[:filename]) + raise e + end + end + + # Processes the template and returns the result as a string. + def render(scope = Object.new, &block) + @scope_object = scope + @buffer = Haml::Buffer.new(@options) + + # Run the compiled evaluator function + compile &block + + # Return the result string + @buffer.buffer + end + + alias_method :to_html, :render + + # This method is deprecated and shouldn't be used. + def precompiled + $stderr.puts < old_tabs && !line.empty? + + suppress_render = handle_multiline(old_tabs, old_line, old_index) unless @flat_spaces != -1 + + if !suppress_render + line_empty = old_line.empty? + + process_indent(old_tabs, old_line) unless line_empty + flat = @flat_spaces != -1 + + + if !flat && old_spaces != old_tabs * 2 + raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.") + end + + if flat + push_flat(old_uline, old_spaces) + elsif !line_empty && !@haml_comment + process_line(old_line, old_index, block_opened) + end + + if @flat_spaces == -1 && tabs - old_tabs > 1 + raise SyntaxError.new("Illegal Indentation: Indenting more than once per line is illegal.") + end + end + end + + old_line = line + old_index = index + old_spaces = spaces + old_tabs = tabs + old_uline = uline + elsif @flat_spaces != -1 + process_indent(old_tabs, old_line) unless old_line.empty? + + if @flat_spaces != -1 + push_flat(old_line, old_spaces) + old_line = '' + old_uline = '' + old_spaces = 0 + end + end + end + + # Close all the open tags + @template_tabs.times { close } + + push_silent "@haml_is_haml = false\nend\n" + end + + # Processes and deals with lowering indentation. + def process_indent(count, line) + if count <= @template_tabs && @template_tabs > 0 + to_close = @template_tabs - count + + to_close.times do |i| + offset = to_close - 1 - i + unless offset == 0 && mid_block_keyword?(line) + close + end + end + end + end + + # Processes a single line of Haml. + # + # This method doesn't return anything; it simply processes the line and + # adds the appropriate code to @precompiled. + def process_line(line, index, block_opened) + @index = index + 1 + @block_opened = block_opened + + case line[0] + when DIV_CLASS, DIV_ID + render_div(line) + when ELEMENT + render_tag(line) + when COMMENT + render_comment(line) + when SCRIPT + sub_line = line[1..-1] + if sub_line[0] == SCRIPT + push_script(unescape_interpolation(sub_line[1..-1].strip), false) + else + push_script(sub_line, false) + end + when FLAT_SCRIPT + push_flat_script(line[1..-1]) + when SILENT_SCRIPT + sub_line = line[1..-1] + unless sub_line[0] == SILENT_COMMENT + mbk = mid_block_keyword?(line) + push_silent(sub_line, !mbk, true) + if (@block_opened && !mbk) || line[1..-1].split(' ', 2)[0] == "case" + push_and_tabulate([:script]) + end + else + start_haml_comment + end + when FILTER + name = line[1..-1].downcase + start_filtered(options[:filters][name.to_s] || name) + when DOCTYPE + if line[0...3] == '!!!' + render_doctype(line) + else + push_plain line + end + when ESCAPE + push_plain line[1..-1] + else + push_plain line + end + end + + # Returns whether or not the line is a silent script line with one + # of Ruby's mid-block keywords. + def mid_block_keyword?(line) + line.length > 2 && line[0] == SILENT_SCRIPT && MID_BLOCK_KEYWORDS.include?(line[1..-1].split[0]) + end + + # Deals with all the logic of figuring out whether a given line is + # the beginning, continuation, or end of a multiline sequence. + # + # This returns whether or not the line should be + # rendered normally. + def handle_multiline(count, line, index) + suppress_render = false + # Multilines are denoting by ending with a `|` (124) + if is_multiline?(line) && @multiline_buffer + # A multiline string is active, and is being continued + @multiline_buffer += line[0...-1] + suppress_render = true + elsif is_multiline?(line) && (MULTILINE_STARTERS.include? line[0]) + # A multiline string has just been activated, start adding the lines + @multiline_buffer = line[0...-1] + @multiline_count = count + @multiline_index = index + process_indent(count, line) + suppress_render = true + elsif @multiline_buffer + # A multiline string has just ended, make line into the result + unless line.empty? + process_line(@multiline_buffer, @multiline_index, count > @multiline_count) + @multiline_buffer = nil + end + end + + return suppress_render + end + + # Checks whether or not +line+ is in a multiline sequence. + def is_multiline?(line) # ' '[0] == 32 + line && line.length > 1 && line[-1] == MULTILINE_CHAR_VALUE && line[-2] == 32 + end + + # Method for generating compiled method names basically ripped out of ActiveView::Base + # If Haml is to be used as a standalone module without rails and still use the precompiled + # methods technique, it will end up duplicating this stuff. I can't decide whether + # checking compile times to decide whether to recompile a template belongs in here or + # out in template.rb + @@method_names = {} + @@supported_local_assigns = {} + @@render_method_count = 0 + def assign_method_name(template, file_name) + @@render_method_count += 1 + @@method_names[template] = "_render_haml_#{@@render_method_count}".intern + end + + module CompiledTemplates + # holds compiled template code + end + + # Takes @precompiled, a string buffer of Ruby code, and + # evaluates it in the context of @scope_object, after preparing + # @scope_object. The code in @precompiled populates + # @buffer with the compiled XHTML code. + def compile(&block) + # Set the local variables pointing to the buffer + buffer = @buffer + @scope_object.extend Haml::Helpers + @scope_object.instance_eval do + @haml_stack ||= Array.new + @haml_stack.push(buffer) + + class << self + attr :haml_lineno # :nodoc: + end + end + @scope_object.class.instance_eval do + include CompiledTemplates + end + + begin + method_name = @@method_names[@template] + + unless @scope_object.respond_to?(method_name) + CompiledTemplates.module_eval @precompiled + end + @scope_object.send(method_name, options[:locals], &block) + rescue Exception => e + class << e + include Haml::Error + end + + lineno = @scope_object.haml_lineno + + # Get information from the exception and format it so that + # Rails can understand it. + compile_error = e.message.scan(/\(eval\):([0-9]*):in `[-_a-zA-Z]*': compile error/)[0] + + if compile_error + if @precompiled + eval_line = compile_error[0].to_i + line_marker = @precompiled.split("\n")[0...eval_line].grep(/@haml_lineno = [0-9]*/)[-1] + lineno = line_marker.scan(/[0-9]+/)[0].to_i if line_marker + else + lineno = -1 + end + end + + e.add_backtrace_entry(lineno, @options[:filename]) + raise e + end + + # Get rid of the current buffer + @scope_object.instance_eval do + @haml_stack.pop + end + end + + # Evaluates text in the context of @scope_object, but + # does not output the result. + def push_silent(text, add_index = false, can_suppress = false) + unless (can_suppress && options[:suppress_eval]) + if add_index + @precompiled << "@haml_lineno = #{@index}\n#{text}\n" + else + # Not really DRY, but probably faster + @precompiled << "#{text}\n" + end + end + end + + # Adds text to @buffer with appropriate tabulation + # without parsing it. + def push_text(text) + @precompiled << "_hamlout.push_text(#{text.dump}, #{@output_tabs})\n" + end + + # Renders a block of text as plain text. + # Also checks for an illegally opened block. + def push_plain(text) + if @block_opened + raise SyntaxError.new("Illegal Nesting: Nesting within plain text is illegal.") + end + push_text text + end + + # Adds +text+ to @buffer while flattening text. + def push_flat(text, spaces) + tabulation = spaces - @flat_spaces + tabulation = tabulation > -1 ? tabulation : 0 + @filter_buffer << "#{' ' * tabulation}#{text}\n" + end + + # Causes text to be evaluated in the context of + # @scope_object and the result to be added to @buffer. + # + # If flattened is true, Haml::Helpers#find_and_flatten is run on + # the result before it is added to @buffer + def push_script(text, flattened) + unless options[:suppress_eval] + push_silent("haml_temp = #{text}", true) + out = "haml_temp = _hamlout.push_script(haml_temp, #{@output_tabs}, #{flattened})\n" + if @block_opened + push_and_tabulate([:loud, out]) + else + @precompiled << out + end + end + end + + # Causes text to be evaluated, and Haml::Helpers#find_and_flatten + # to be run on it afterwards. + def push_flat_script(text) + if text.empty? + raise SyntaxError.new("Tag has no content.") + else + push_script(text, true) + end + end + + def start_haml_comment + if @block_opened + @haml_comment = true + push_and_tabulate([:haml_comment]) + end + end + + # Closes the most recent item in @to_close_stack. + def close + tag, value = @to_close_stack.pop + case tag + when :script + close_block + when :comment + close_comment value + when :element + close_tag value + when :loud + close_loud value + when :filtered + close_filtered value + when :haml_comment + close_haml_comment + end + end + + # Puts a line in @precompiled that will add the closing tag of + # the most recently opened tag. + def close_tag(tag) + @output_tabs -= 1 + @template_tabs -= 1 + @precompiled << "_hamlout.close_tag(#{tag.dump}, #{@output_tabs})\n" + end + + # Closes a Ruby block. + def close_block + push_silent "end", false, true + @template_tabs -= 1 + end + + # Closes a comment. + def close_comment(has_conditional) + @output_tabs -= 1 + @template_tabs -= 1 + push_silent "_hamlout.close_comment(#{has_conditional}, #{@output_tabs})" + end + + # Closes a loud Ruby block. + def close_loud(command) + push_silent 'end', false, true + @precompiled << command + @template_tabs -= 1 + end + + # Closes a filtered block. + def close_filtered(filter) + @flat_spaces = -1 + if filter.is_a? String + if filter == 'redcloth' || filter == 'markdown' || filter == 'textile' + raise HamlError.new("You must have the RedCloth gem installed to use #{filter}") + else + raise HamlError.new("Filter \"#{filter}\" is not defined!") + end + else + filtered = filter.new(@filter_buffer).render + + unless filter == Haml::Filters::Preserve + push_text(filtered.rstrip.gsub("\n", "\n#{' ' * @output_tabs}")) + else + push_silent("_hamlout.buffer << #{filtered.dump} << \"\\n\"\n") + end + end + + @filter_buffer = nil + @template_tabs -= 1 + end + + def close_haml_comment + @haml_comment = false + @template_tabs -= 1 + end + + # Iterates through the classes and ids supplied through . + # and # syntax, and returns a hash with them as attributes, + # that can then be merged with another attributes hash. + def parse_class_and_id(list) + attributes = {} + list.scan(/([#.])([-_a-zA-Z0-9]+)/) do |type, property| + case type + when '.' + if attributes['class'] + attributes['class'] += " " + else + attributes['class'] = "" + end + attributes['class'] += property + when '#' + attributes['id'] = property + end + end + attributes + end + + def parse_literal_value(text) + text.match(LITERAL_VALUE_REGEX) + + # $2 holds the value matched by a symbol, but is nil for a string match + # $5 holds the value matched by a string + $2 || $5 + end + + def parse_literal_hash(text) + unless text + return {} + end + + attributes = {} + if inner = text.scan(/^\{(.*)\}$/)[0] + inner[0].split(',').each do |attrib| + key, value, more = attrib.split('=>') + + # Make sure the key and value and only the key and value exist + # Otherwise, it's too complicated and we'll defer it to the actual Ruby parser + if more || (key = parse_literal_value(key)).nil? || + (value = parse_literal_value(value)).nil? + return nil + end + + attributes[key] = value + end + end + attributes + end + + def build_attributes(attributes = {}) + @quote_escape = @options[:attr_wrapper] == '"' ? """ : "'" + @other_quote_char = @options[:attr_wrapper] == '"' ? "'" : '"' + + result = attributes.collect do |a,v| + v = v.to_s + unless v.nil? || v.empty? + attr_wrapper = @options[:attr_wrapper] + if v.include? attr_wrapper + if v.include? @other_quote_char + # An imperfection in LITERAL_VALUE_REGEX prevents this + # from ever actually being reached, + # but in case it becomes possible, + # I'm leaving it in. + v = v.gsub(attr_wrapper, @quote_escape) + else + attr_wrapper = @other_quote_char + end + end + " #{a}=#{attr_wrapper}#{v}#{attr_wrapper}" + end + end + result.sort.join + end + + def prerender_tag(name, atomic, attributes) + if atomic + str = " />" + else + str = ">" + end + + "<#{name}#{build_attributes(attributes)}#{str}" + end + + # Parses a line that will render as an XHTML tag, and adds the code that will + # render that tag to @precompiled. + def render_tag(line) + matched = false + line.scan(TAG_REGEX) do |tag_name, attributes, attributes_hash, object_ref, action, value| + matched = true + value = value.to_s.strip + + case action + when '/' + atomic = true + when '=', '~' + parse = true + + if value[0] == ?= + value = value[1..-1].strip.dump.gsub('\\#', '#') + end + end + + flattened = (action == '~') + + value_exists = !value.empty? + literal_attributes = parse_literal_hash(attributes_hash) + attributes_hash = "{nil}" if attributes_hash.nil? || literal_attributes || @options[:suppress_eval] + object_ref = "nil" if object_ref.nil? || @options[:suppress_eval] + + if attributes =~ /[\.#](\.|#|\z)/ + raise SyntaxError.new("Illegal element: classes and ids must have values. Use %div instead.") + end + + # Preparse the attributes hash + attributes = parse_class_and_id(attributes) + Buffer.merge_attrs(attributes, literal_attributes) if literal_attributes + + if @block_opened + if atomic + raise SyntaxError.new("Illegal Nesting: Nesting within an atomic tag is illegal.") + elsif action == '=' || value_exists + raise SyntaxError.new("Illegal Nesting: Nesting within a tag that already has content is illegal.") + end + elsif atomic && value_exists + raise SyntaxError.new("Atomic tags can't have content.") + elsif parse && !value_exists + raise SyntaxError.new("Tag has no content.") + end + + if !@block_opened && !value_exists && @options[:autoclose].include?(tag_name) + atomic = true + end + + do_one_liner = value_exists && !parse && Buffer.one_liner?(value) + + if object_ref == "nil" && attributes_hash == "{nil}" && !flattened && (do_one_liner || !value_exists) + # This means that we can render the tag directly to text and not process it in the buffer + open_tag = prerender_tag(tag_name, atomic, attributes) + + if do_one_liner + open_tag += value + open_tag += "" + end + + open_tag += "\n" + + push_silent "_hamlout.open_prerendered_tag(#{open_tag.dump}, #{@output_tabs})" + return if do_one_liner + else + push_silent "_hamlout.open_tag(#{tag_name.inspect}, #{@output_tabs}, #{atomic.inspect}, #{value_exists.inspect}, #{attributes.inspect}, #{object_ref}, #{attributes_hash[1...-1]})", true + end + + unless atomic + push_and_tabulate([:element, tag_name]) + @output_tabs += 1 + + if value_exists + if parse + push_script(value, flattened) + else + push_text(value) + end + close + elsif flattened + raise SyntaxError.new("Tag has no content.") + end + end + end + + unless matched + raise SyntaxError.new("Invalid tag: \"#{line}\"") + end + end + + # Renders a line that creates an XHTML tag and has an implicit div because of + # . or #. + def render_div(line) + render_tag('%div' + line) + end + + # Renders an XHTML comment. + def render_comment(line) + conditional, content = line.scan(COMMENT_REGEX)[0] + content.strip! + + if @block_opened && !content.empty? + raise SyntaxError.new('Illegal Nesting: Nesting within a tag that already has content is illegal.') + end + + try_one_line = !content.empty? + push_silent "_hamlout.open_comment(#{try_one_line}, #{conditional.inspect}, #{@output_tabs})" + @output_tabs += 1 + push_and_tabulate([:comment, !conditional.nil?]) + if try_one_line + push_text content + close + end + end + + # Renders an XHTML doctype or XML shebang. + def render_doctype(line) + if @block_opened + raise SyntaxError.new("Illegal Nesting: Nesting within a header command is illegal.") + end + line = line[3..-1].lstrip.downcase + if line[0...3] == "xml" + encoding = line.split[1] || "utf-8" + wrapper = @options[:attr_wrapper] + doctype = "" + else + version, type = line.scan(DOCTYPE_REGEX)[0] + if version == "1.1" + doctype = '' + else + case type + when "strict" + doctype = '' + when "frameset" + doctype = '' + else + doctype = '' + end + end + end + push_text doctype + end + + # Starts a filtered block. + def start_filtered(filter) + unless @block_opened + raise SyntaxError.new('Filters must have nested text.') + end + push_and_tabulate([:filtered, filter]) + @flat_spaces = @template_tabs * 2 + @filter_buffer = String.new + end + + def unescape_interpolation(str) + str.dump.gsub('\\#', '#').gsub(/\#\{[^\}]+\}/) do |substr| + substr.gsub('\\"', '"') + end + end + + # Counts the tabulation of a line. + def count_soft_tabs(line) + spaces = line.index(/[^ ]/) + if line[spaces] == ?\t + return nil if line.strip.empty? + + raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.") + end + [spaces, spaces/2] + end + + # Pushes value onto @to_close_stack and increases + # @template_tabs. + def push_and_tabulate(value) + @to_close_stack.push(value) + @template_tabs += 1 + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/error.rb b/vendor/gems/haml-1.7.2/lib/haml/error.rb new file mode 100644 index 0000000..078eb24 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/error.rb @@ -0,0 +1,43 @@ +module Haml + # The abstract type of exception raised by Haml code. + # Haml::SyntaxError includes this module, + # as do all exceptions raised by Ruby code within Haml. + # + # Haml::Error encapsulates information about the exception, + # such as the line of the Haml template it was raised on + # and the Haml file that was being parsed (if applicable). + # It also provides a handy way to rescue only exceptions raised + # because of a faulty template. + module Error + # The line of the Haml template on which the exception was thrown. + attr_reader :haml_line + + # The name of the file that was being parsed when the exception was raised. + # This will be nil unless Haml is being used as an ActionView plugin. + attr_reader :haml_filename + + # Adds a properly formatted entry to the exception's backtrace. + # +lineno+ should be the line on which the error occurred. + # +filename+ should be the file in which the error occurred, + # if applicable (defaults to "(haml)"). + def add_backtrace_entry(lineno, filename = nil) # :nodoc: + @haml_line = lineno + @haml_filename = filename + self.backtrace ||= [] + self.backtrace.unshift "#{filename || '(haml)'}:#{lineno}" + end + end + + # SyntaxError is the type of exception raised when Haml encounters an + # ill-formatted document. + # It's not particularly interesting, except in that it includes Haml::Error. + class SyntaxError < StandardError + include Haml::Error + end + + # HamlError is the type of exception raised when Haml encounters an error + # not of a syntactical nature, such as an undefined Filter. + class HamlError < StandardError + include Haml::Error + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/exec.rb b/vendor/gems/haml-1.7.2/lib/haml/exec.rb new file mode 100644 index 0000000..fd6cd1f --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/exec.rb @@ -0,0 +1,296 @@ +require File.dirname(__FILE__) + '/../haml' +require 'optparse' + +module Haml + # This module contains code for working with the + # haml, sass, and haml2html executables, + # such as command-line parsing stuff. + # It shouldn't need to be invoked by client code. + module Exec # :nodoc: + # A class that encapsulates the executable code + # for all three executables. + class Generic # :nodoc: + def initialize(args) + @args = args + @options = {} + end + + def parse! + begin + @opts = OptionParser.new(&(method(:set_opts).to_proc)) + @opts.parse!(@args) + + process_result + + @options + rescue Exception => e + raise e if e.is_a? SystemExit + + line = e.backtrace[0].scan(/:(.*)/)[0] + puts "#{e.class} on line #{line}: #{e.message}" + + if @options[:trace] + e.backtrace[1..-1].each { |t| puts " #{t}" } + else + puts " Use --trace to see traceback" + end + + exit 1 + end + exit 0 + end + + def to_s + @opts.to_s + end + + private + + def set_opts(opts) + opts.on('--stdin', :NONE, 'Read input from standard input instead of an input file') do + @options[:input] = $stdin + end + + opts.on('--stdout', :NONE, 'Print output to standard output instead of an output file') do + @options[:output] = $stdout + end + + opts.on('-s', '--stdio', 'Read input from standard input and print output to standard output') do + @options[:input] = $stdin + @options[:output] = $stdout + end + + opts.on('--trace', :NONE, 'Show a full traceback on error') do + @options[:trace] = true + end + + opts.on_tail("-?", "-h", "--help", "Show this message") do + puts opts + exit + end + + opts.on_tail("-v", "--version", "Print version") do + puts("Haml " + File.read(File.dirname(__FILE__) + '/../../VERSION')) + exit + end + end + + def process_result + input = @options[:input] + output = @options[:output] + + if input + output ||= ARGV[0] + else + input ||= ARGV[0] + output ||= ARGV[1] + end + + unless input && output + puts @opts + exit 1 + end + + if input.is_a?(String) && !File.exists?(input) + puts "File #{input} doesn't exist!" + exit 1 + end + + unless input.is_a? IO + input = File.open(input) + input_file = true + end + + unless output.is_a? IO + output = File.open(output, "w") + output_file = true + end + + @options[:input] = input + @options[:output] = output + end + end + + # A class encapsulating the executable functionality + # specific to Haml and Sass. + class HamlSass < Generic # :nodoc: + private + + def set_opts(opts) + opts.banner = < err + dep = err.message.scan(/^no such file to load -- (.*)/)[0] + puts "Required dependency #{dep} not found!" + exit 1 + end + end + + def set_opts(opts) + opts.banner = <]*>(.*?)<\/\1>/im) do |tag, contents| + input = input.gsub(contents, preserve(contents)) + end + input + end + + # Takes any string, finds all the endlines and converts them to + # HTML entities for endlines so they'll render correctly in + # whitespace-sensitive tags without screwing up the indentation. + def preserve(input) + input.gsub(/\n/, ' ').gsub(/\r/, '') + end + + alias_method :flatten, :preserve + + # Takes an Enumerable object and a block + # and iterates over the object, + # yielding each element to a Haml block + # and putting the result into
  • elements. + # This creates a list of the results of the block. + # For example: + # + # = list_of([['hello'], ['yall']]) do |i| + # = i[0] + # + # Produces: + # + #
  • hello
  • + #
  • yall
  • + # + # And + # + # = list_of({:title => 'All the stuff', :description => 'A book about all the stuff.'}) do |key, val| + # %h3= key.humanize + # %p= val + # + # Produces: + # + #
  • + #

    Title

    + #

    All the stuff

    + #
  • + #
  • + #

    Description

    + #

    A book about all the stuff.

    + #
  • + # + def list_of(array, &block) # :yields: item + to_return = array.collect do |i| + result = capture_haml(i, &block) + + if result.count("\n") > 1 + result.gsub!("\n", "\n ") + result = "\n #{result.strip}\n" + else + result.strip! + end + + "
  • #{result}
  • " + end + to_return.join("\n") + end + + # Returns a hash containing default assignments for the xmlns and xml:lang + # attributes of the html HTML element. + # It also takes an optional argument for the value of xml:lang and lang, + # which defaults to 'en-US'. + # For example, + # + # %html{html_attrs} + # + # becomes + # + # + # + def html_attrs(lang = 'en-US') + {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang} + end + + # Increments the number of tabs the buffer automatically adds + # to the lines of the template. + # For example: + # + # %h1 foo + # - tab_up + # %p bar + # - tab_down + # %strong baz + # + # Produces: + # + #

    foo

    + #

    bar

    + # baz + # + def tab_up(i = 1) + buffer.tabulation += i + end + + # Increments the number of tabs the buffer automatically adds + # to the lines of the template. + # + # See tab_up. + def tab_down(i = 1) + buffer.tabulation -= i + end + + # Surrounds the given block of Haml code with the given characters, + # with no whitespace in between. + # For example: + # + # = surround '(', ')' do + # %a{:href => "food"} chicken + # + # Produces: + # + # (chicken) + # + # and + # + # = surround '*' do + # %strong angry + # + # Produces: + # + # *angry* + # + def surround(front, back = nil, &block) + back ||= front + output = capture_haml(&block) + + "#{front}#{output.chomp}#{back}\n" + end + + # Prepends the given character to the beginning of the Haml block, + # with no whitespace between. + # For example: + # + # = precede '*' do + # %span.small Not really + # + # Produces: + # + # *Not really + # + def precede(char, &block) + "#{char}#{capture_haml(&block).chomp}\n" + end + + # Appends the given character to the end of the Haml block, + # with no whitespace between. + # For example: + # + # click + # = succeed '.' do + # %a{:href=>"thing"} here + # + # Produces: + # + # click + # here. + # + def succeed(char, &block) + "#{capture_haml(&block).chomp}#{char}\n" + end + + # Captures the result of the given block of Haml code, + # gets rid of the excess indentation, + # and returns it as a string. + # For example, after the following, + # + # .foo + # - foo = capture_haml(13) do |a| + # %p= a + # + # the local variable foo would be assigned to "

    13

    \n". + # + def capture_haml(*args, &block) + capture_haml_with_buffer(buffer.buffer, *args, &block) + end + + # Outputs text directly to the Haml buffer, with the proper tabulation + def puts(text = "") + buffer.buffer << (' ' * buffer.tabulation) << text.to_s << "\n" + nil + end + + # + # call-seq: + # open(name, attributes = {}) {...} + # open(name, text, attributes = {}) {...} + # + # Creates an HTML tag with the given name and optionally text and attributes. + # Can take a block that will be executed + # between when the opening and closing tags are output. + # If the block is a Haml block or outputs text using puts, + # the text will be properly indented. + # + # For example, + # + # open :table do + # open :tr do + # open :td, {:class => 'cell'} do + # open :strong, "strong!" + # puts "data" + # end + # open :td do + # puts "more_data" + # end + # end + # end + # + # outputs + # + # + # + # + # + # + #
    + # + # strong! + # + # data + # + # more_data + #
    + # + def open(name, attributes = {}, alt_atts = {}, &block) + text = nil + if attributes.is_a? String + text = attributes + attributes = alt_atts + end + + puts "<#{name}#{buffer.build_attributes(attributes)}>" + tab_up + # Print out either the text (using push_text) or call the block and add an endline + if text + puts(text) + elsif block + block.call + end + tab_down + puts "" + nil + end + + private + + # Gets a reference to the current Haml::Buffer object. + def buffer + @haml_stack[-1] + end + + # Gives a proc the same local "_hamlout" and "_erbout" variables + # that the current template has. + def bind_proc(&proc) + _hamlout = buffer + _erbout = _hamlout.buffer + proc { |*args| proc.call(*args) } + end + + # Performs the function of capture_haml, assuming local_buffer + # is where the output of block goes. + def capture_haml_with_buffer(local_buffer, *args, &block) + position = local_buffer.length + + block.call *args + + captured = local_buffer.slice!(position..-1) + + min_tabs = nil + captured.each do |line| + tabs = line.index(/[^ ]/) + min_tabs ||= tabs + min_tabs = min_tabs > tabs ? tabs : min_tabs + end + + result = captured.map do |line| + line[min_tabs..-1] + end + result.to_s + end + + # Returns whether or not the current template is a Haml template. + # + # This function, unlike other Haml::Helpers functions, + # also works in other ActionView templates, + # where it will always return false. + def is_haml? + @haml_is_haml + end + + include ActionViewExtensions if self.const_defined? "ActionViewExtensions" + end +end + +module ActionView + class Base # :nodoc: + def is_haml? + false + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_extensions.rb b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_extensions.rb new file mode 100644 index 0000000..53329b3 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_extensions.rb @@ -0,0 +1,45 @@ +require 'haml/helpers/action_view_mods' + +if defined?(ActionView) + module Haml + module Helpers + # This module contains various useful helper methods + # that either tie into ActionView or the rest of the ActionPack stack, + # or are only useful in that context. + # Thus, the methods defined here are only available + # if ActionView is installed. + module ActionViewExtensions + # Returns a value for the "class" attribute + # unique to this controller/action pair. + # This can be used to target styles specifically at this action or controller. + # For example, if the current action were EntryController#show, + # + # %div{:class => page_class} My Div + # + # would become + # + #
    My Div
    + # + # Then, in a stylesheet + # (shown here as Sass), + # you could refer to this specific action: + # + # .entry.show + # :font-weight bold + # + # or to all actions in the entry controller: + # + # .entry + # :color #00f + # + def page_class + controller.controller_name + " " + controller.action_name + end + + # :stopdoc: + alias_method :generate_content_class_names, :page_class + # :startdoc: + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb new file mode 100644 index 0000000..ee2da7a --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb @@ -0,0 +1,86 @@ +if defined?(ActionView) and not defined?(Merb::Plugins) + module ActionView + class Base # :nodoc: + def render_with_haml(*args, &block) + was_haml = is_haml? + @haml_is_haml = false + res = render_without_haml(*args, &block) + @haml_is_haml = was_haml + res + end + alias_method :render_without_haml, :render + alias_method :render, :render_with_haml + end + + # This overrides various helpers in ActionView + # to make them work more effectively with Haml. + module Helpers + # :stopdoc: + module CaptureHelper + def capture_erb_with_buffer_with_haml(*args, &block) + if is_haml? + capture_haml_with_buffer(*args, &block) + else + capture_erb_with_buffer_without_haml(*args, &block) + end + end + alias_method :capture_erb_with_buffer_without_haml, :capture_erb_with_buffer + alias_method :capture_erb_with_buffer, :capture_erb_with_buffer_with_haml + end + + module TextHelper + def concat_with_haml(string, binding = nil) + if is_haml? + buffer.buffer.concat(string) + else + concat_without_haml(string, binding) + end + end + alias_method :concat_without_haml, :concat + alias_method :concat, :concat_with_haml + end + + module FormTagHelper + def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc) + if is_haml? + if block_given? + oldproc = proc + proc = bind_proc do |*args| + concat "\n" + tab_up + oldproc.call(*args) + tab_down + end + end + res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n" + concat "\n" if block_given? && is_haml? + res + else + form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + end + end + alias_method :form_tag_without_haml, :form_tag + alias_method :form_tag, :form_tag_with_haml + end + + module FormHelper + def form_for_with_haml(object_name, *args, &proc) + if block_given? && is_haml? + oldproc = proc + proc = bind_proc do |*args| + tab_up + oldproc.call(*args) + tab_down + end + end + form_for_without_haml(object_name, *args, &proc) + concat "\n" if block_given? && is_haml? + end + alias_method :form_for_without_haml, :form_for + alias_method :form_for, :form_for_with_haml + end + # :startdoc: + end + end +end + diff --git a/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb.rej b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb.rej new file mode 100644 index 0000000..2c8a0f5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/helpers/action_view_mods.rb.rej @@ -0,0 +1,30 @@ +*************** +*** 1,11 **** +- begin +- require 'rubygems' +- require 'active_support' +- require 'action_controller' +- require 'action_view' +- action_view_included = true +- rescue LoadError +- action_view_included = false + end + + +--- 1,16 ---- ++ ++ # This obviously requires that ActiveSupport be present prior to Haml ++ # being loaded. ++ action_view_included = false ++ if defined?(ActiveSupport) ++ begin ++ require 'rubygems' ++ require 'active_support' ++ require 'action_controller' ++ require 'action_view' ++ action_view_included = true ++ rescue LoadError ++ end + end + + diff --git a/vendor/gems/haml-1.7.2/lib/haml/html.rb b/vendor/gems/haml-1.7.2/lib/haml/html.rb new file mode 100644 index 0000000..da388d1 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/html.rb @@ -0,0 +1,173 @@ +require File.dirname(__FILE__) + '/../haml' + +require 'haml/engine' +require 'rubygems' +require 'hpricot' +require 'cgi' + +module Haml + # This class contains the functionality used in the +html2haml+ utility, + # namely converting HTML documents to Haml templates. + # It depends on Hpricot for HTML parsing (http://code.whytheluckystiff.net/hpricot/). + class HTML + # Creates a new instance of Haml::HTML that will compile the given template, + # which can either be a string containing HTML or an Hpricot node, + # to a Haml string when +render+ is called. + def initialize(template, options = {}) + @@options = options + + if template.is_a? Hpricot::Node + @template = template + else + if template.is_a? IO + template = template.read + end + + if @@options[:rhtml] + match_to_html(template, /<%=(.*?)-?%>/m, 'loud') + match_to_html(template, /<%(.*?)-?%>/m, 'silent') + end + @template = Hpricot(template) + end + end + + # Processes the document and returns the result as a string + # containing the Haml template. + def render + @template.to_haml(0) + end + alias_method :to_haml, :render + + module ::Hpricot::Node + # Returns the Haml representation of the given node, + # at the given tabulation. + def to_haml(tabs = 0) + parse_text(self.to_s, tabs) + end + + private + + def tabulate(tabs) + ' ' * tabs + end + + def parse_text(text, tabs) + text.strip! + if text.empty? + String.new + else + lines = text.split("\n") + + lines.map do |line| + line.strip! + "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n" + end.join + end + end + end + + # :stopdoc: + + def self.options + @@options + end + + TEXT_REGEXP = /^(\s*).*$/ + + class ::Hpricot::Doc + def to_haml(tabs = 0) + output = '' + children.each { |child| output += child.to_haml(0) } + output + end + end + + class ::Hpricot::XMLDecl + def to_haml(tabs = 0) + "#{tabulate(tabs)}!!! XML\n" + end + end + + class ::Hpricot::DocType + def to_haml(tabs = 0) + attrs = public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0] + if attrs == nil + raise Exception.new("Invalid doctype") + end + + type, version, strictness = attrs.map { |a| a.downcase } + if type == "html" + version = "1.0" + strictness = "transitional" + end + + if version == "1.0" || version.empty? + version = nil + end + + if strictness == 'transitional' || strictness.empty? + strictness = nil + end + + version = " #{version}" if version + if strictness + strictness[0] = strictness[0] - 32 + strictness = " #{strictness}" + end + + "#{tabulate(tabs)}!!!#{version}#{strictness}\n" + end + end + + class ::Hpricot::Comment + def to_haml(tabs = 0) + "#{tabulate(tabs)}/\n#{parse_text(self.content, tabs + 1)}" + end + end + + class ::Hpricot::Elem + def to_haml(tabs = 0) + output = "#{tabulate(tabs)}" + if HTML.options[:rhtml] && name[0...5] == 'haml:' + return output + HTML.send("haml_tag_#{name[5..-1]}", self.innerHTML) + end + + output += "%#{name}" unless name == 'div' && (attributes.include?('id') || attributes.include?('class')) + + if attributes + output += "##{attributes['id']}" if attributes['id'] + attributes['class'].split(' ').each { |c| output += ".#{c}" } if attributes['class'] + attributes.delete("id") + attributes.delete("class") + output += attributes.inspect if attributes.length > 0 + end + + output += "/" if children.length == 0 + output += "\n" + + self.children.each do |child| + output += child.to_haml(tabs + 1) + end + + output + end + end + + def self.haml_tag_loud(text) + "= #{text.gsub(/\n\s*/, '; ').strip}\n" + end + + def self.haml_tag_silent(text) + text.split("\n").map { |line| "- #{line.strip}\n" }.join + end + + private + + def match_to_html(string, regex, tag) + string.gsub!(regex) do + "#{CGI.escapeHTML($1)}" + end + end + # :startdoc: + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/template.rb b/vendor/gems/haml-1.7.2/lib/haml/template.rb new file mode 100644 index 0000000..6ad7d65 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/template.rb @@ -0,0 +1,99 @@ +require 'haml/engine' +require 'rubygems' +require 'active_support' +require 'action_view' + +module Haml + # This class interfaces with ActionView + # to make Haml usable as a Ruby on Rails plugin. + # It usually shouldn't need to be used by end users. + # Just in case, though, here's what you might do to render + # templates/index.haml: + # + # ActionView::Base.register_template_handler("haml", Haml::Template) + # base = ActionView::Base.new("templates") + # base.render("index") + # + # Or, if you want to really get into the nitty-gritty: + # + # base = ActionView::Base.new + # template = Haml::Template.new(base) + # template.render("templates/index.haml") + # + class Template + + class << self + @@options = {} + + # Gets various options for Haml. See README for details. + def options + @@options + end + + # Sets various options for Haml. See README for details. + def options=(value) + @@options = value + end + end + + # Creates a new Haml::Template object that uses view + # to render its templates. + def initialize(view) + @view = view + end + + # Renders the file at the location template, + # with local_assigns available as local variables within the template. + # Returns the result as a string. + def render(template, local_assigns={}) + @view.instance_eval do + evaluate_assigns + end + + options = @@options.dup + locals = options[:locals] || {} + locals.merge! local_assigns + options[:locals] = locals + + if @view.haml_inline + engine = Haml::Engine.new(template, options) + else + options[:filename] ||= template + engine = Haml::Engine.new(File.read(template), options) + end + + yield_proc = @view.instance_eval do + proc { |*name| instance_variable_get("@content_for_#{name.first || 'layout'}") } + end + + engine.to_html(@view) { |*args| yield_proc.call(*args) } + + end + end +end + +# This module refers to the ActionView module that's part of Ruby on Rails. +# Haml can be used as an alternate templating engine for it, +# and includes several modifications to make it more Haml-friendly. +# The documentation can be found +# here[http://rubyonrails.org/api/classes/ActionView/Base.html]. +module ActionView + class Base # :nodoc: + attr :haml_inline + + alias_method :read_template_file_old, :read_template_file + def read_template_file(template_path, extension) + if extension =~ /haml/i + template_path + else + read_template_file_old(template_path, extension) + end + end + + alias_method :render_template_old, :render_template + def render_template(template_extension, template, file_path = nil, local_assigns = {}) + @haml_inline = !template.nil? + render_template_old(template_extension, template, file_path, local_assigns) + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/haml/util.rb b/vendor/gems/haml-1.7.2/lib/haml/util.rb new file mode 100644 index 0000000..b899e2e --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/haml/util.rb @@ -0,0 +1,18 @@ +# This file contains various useful bits of code +# that are shared between Haml and Sass. + +class Hash # :nodoc: + # Same as Hash#merge!, + # but recursively merges sub-hashes + def rec_merge!(other) + other.each do |key, value| + myval = self[key] + if value.is_a?(Hash) && myval.is_a?(Hash) + myval.rec_merge!(value) + else + self[key] = value + end + end + self + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass.rb b/vendor/gems/haml-1.7.2/lib/sass.rb new file mode 100644 index 0000000..590f70c --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass.rb @@ -0,0 +1,613 @@ +dir = File.dirname(__FILE__) +$LOAD_PATH << dir unless $LOAD_PATH.include?(dir) + +# = Sass (Syntactically Awesome StyleSheets) +# +# Sass is a meta-language on top of CSS +# that's used to describe the style of a document +# cleanly and structurally, +# with more power than flat CSS allows. +# Sass both provides a simpler, more elegant syntax for CSS +# and implements various features that are useful +# for creating manageable stylesheets. +# +# == Features +# +# * Whitespace active +# * Well-formatted output +# * Elegant input +# * Feature-rich +# +# == Using Sass +# +# Sass can be used in several ways: +# As a plugin for Ruby on Rails or Merb, +# or as a standalone parser. +# Sass is bundled with Haml, +# so if the Haml plugin or RubyGem is installed, +# Sass will already be installed as a plugin or gem, respectively. +# The first step for all of these is to install the Haml gem: +# +# gem install haml +# +# To enable it as a Rails plugin, +# then run +# +# haml --rails path/to/rails/app +# +# To enable Sass in Merb, +# add +# +# dependency "haml" +# +# to config/dependencies.rb. +# +# Sass templates in Rails and Merb don't quite function in the same way as views, +# because they don't contain dynamic content, +# and so only need to be compiled when the template file has been updated. +# By default (see options, below), +# ".sass" files are placed in public/stylesheets/sass. +# Then, whenever necessary, they're compiled into corresponding CSS files in public/stylesheets. +# For instance, public/stylesheets/sass/main.sass would be compiled to public/stylesheets/main.css. +# +# Using Sass in Ruby code is very simple. +# After installing the Haml gem, +# you can use it by running require "sass" +# and using Sass::Engine like so: +# +# engine = Sass::Engine.new("#main\n :background-color #0000ff") +# engine.render #=> "#main { background-color: #0000ff; }\n" +# +# == CSS Rules +# +# Rules in flat CSS have two elements: +# the selector +# (e.g. "#main", "div p", "li a:hover") +# and the attributes +# (e.g. "color: #00ff00;", "width: 5em;"). +# +# Sass has both of these, +# as well as one additional element: nested rules. +# +# === Rules and Selectors +# +# However, some of the syntax is a little different. +# The syntax for selectors is the same, +# but instead of using brackets to delineate the attributes that belong to a particular rule, +# Sass uses two spaces of indentation. +# For example: +# +# #main p +# +# +# ... +# +# === Attributes +# +# There are two different ways to write CSS attrbibutes. +# The first is very similar to the how you're used to writing them: +# with a colon between the name and the value. +# However, Sass attributes don't have semicolons at the end; +# each attribute is on its own line, so they aren't necessary. +# For example: +# +# #main p +# color: #00ff00 +# width: 97% +# +# is compiled to: +# +# #main p { +# color: #00ff00; +# width: 97% } +# +# The second syntax for attributes is slightly different. +# The colon is at the beginning of the attribute, +# rather than between the name and the value, +# so it's easier to tell what elements are attributes just by glancing at them. +# For example: +# +# #main p +# :color #00ff00 +# :width 97% +# +# is compiled to: +# +# #main p { +# color: #00ff00; +# width: 97% } +# +# === Nested Rules +# +# Rules can also be nested within each other. +# This signifies that the inner rule's selector is a child of the outer selector. +# For example: +# +# #main p +# :color #00ff00 +# :width 97% +# +# .redbox +# :background-color #ff0000 +# :color #000000 +# +# is compiled to: +# +# #main p { +# color: #00ff00; +# width: 97%; } +# #main p .redbox { +# background-color: #ff0000; +# color: #000000; } +# +# This makes insanely complicated CSS layouts with lots of nested selectors very simple: +# +# #main +# :width 97% +# +# p, div +# :font-size 2em +# a +# :font-weight bold +# +# pre +# :font-size 3em +# +# is compiled to: +# +# #main { +# width: 97%; } +# #main p, #main div { +# font-size: 2em; } +# #main p a, #main div a { +# font-weight: bold; } +# #main pre { +# font-size: 3em; } +# +# === Referencing Parent Rules +# +# In addition to the default behavior of inserting the parent selector +# as a CSS parent of the current selector +# (e.g. above, "#main" is the parent of "p"), +# you can have more fine-grained control over what's done with the parent selector +# by using the ampersand character "&" in your selectors. +# +# The ampersand is automatically replaced by the parent selector, +# instead of having it prepended. +# This allows you to cleanly create pseudo-attributes: +# +# a +# :font-weight bold +# :text-decoration none +# &:hover +# :text-decoration underline +# &:visited +# :font-weight normal +# +# Which would become: +# +# a { +# font-weight: bold; +# text-decoration: none; } +# a:hover { +# text-decoration: underline; } +# a:visited { +# font-weight: normal; } +# +# It also allows you to add selectors at the base of the hierarchy, +# which can be useuful for targeting certain styles to certain browsers: +# +# #main +# :width 90% +# #sidebar +# :float left +# :margin-left 20% +# .ie6 & +# :margin-left 40% +# +# Which would become: +# +# #main { +# width: 90%; } +# #main #sidebar { +# float: left; +# margin-left: 20%; } +# .ie6 #main #sidebar { +# margin-left: 40%; } +# +# === Attribute Namespaces +# +# CSS has quite a few attributes that are in "namespaces;" +# for instance, "font-family," "font-size," and "font-weight" +# are all in the "font" namespace. +# In CSS, if you want to set a bunch of attributes in the same namespace, +# you have to type it out each time. +# Sass offers a shortcut for this: +# just write the namespace one, +# then indent each of the sub-attributes within it. +# For example: +# +# .funky +# :font +# :family fantasy +# :size 30em +# :weight bold +# +# is compiled to: +# +# .funky { +# font-family: fantasy; +# font-size: 30em; +# font-weight: bold; } +# +# == Constants +# +# Sass has support for setting document-wide constants. +# They're set using an exclamation mark followed by the name, +# an equals sign, and the value. +# An attribute can then be set to the value of a constant +# by following it with another equals sign. +# For example: +# +# !main_color = #00ff00 +# +# #main +# :color = !main_color +# :p +# :background-color = !main_color +# :color #000000 +# +# is compiled to: +# +# #main { +# color: #00ff00; } +# #main p { +# background-color: #00ff00; +# color: #000000; } +# +# === Arithmetic +# +# You can even do basic arithmetic with constants. +# Sass recognizes numbers, colors, +# lengths (numbers with units), +# and strings (everything that's not one of the above), +# and various operators that work on various values. +# All the normal arithmetic operators +# (+, -, *, /, %, and parentheses for grouping) +# are defined as usual +# for numbers, colors, and lengths. +# The "+" operator is also defined for Strings +# as the concatenation operator. +# For example: +# +# !main_width = 10 +# !unit1 = em +# !unit2 = px +# !bg_color = #a5f39e +# +# #main +# :background-color = !bg_color +# p +# :background-color = !bg_color + #202020 +# :width = !main_width + !unit1 +# img.thumb +# :width = (!main_width + 15) + !unit2 +# +# is compiled to: +# +# #main { +# background-color: #a5f39e; } +# #main p { +# background-color: #c5ffbe; +# width: 10em; } +# #main img.thumb { +# width: 25em; } +# +# === Colors +# +# Colors may be written as three- or six-digit hex numbers prefixed +# by a pound sign (#), or as HTML4 color names. For example, +# "#ff0", "#ffff00" and "yellow" all refer to the same color. +# +# Not only can arithmetic be done between colors and other colors, +# but it can be done between colors and normal numbers. +# In this case, the operation is done piecewise one each of the +# Red, Green, and Blue components of the color. +# For example: +# +# !main_color = #a5f39e +# +# #main +# :background-color = !main_color +# p +# :background-color = !main_color + 32 +# +# is compiled to: +# +# #main { +# background-color: #a5f39e; } +# #main p { +# background-color: #c5ffbe; } +# +# === Strings +# +# Strings are the type that's used by default +# when an element in a bit of constant arithmetic isn't recognized +# as another type of constant. +# However, they can also be created explicitly be wrapping a section of code with quotation marks. +# Inside the quotation marks, +# a backslash can be used to +# escape quotation marks that you want to appear in the CSS. +# For example: +# +# !content = "Hello, \"Hubert\" Bean." +# +# #main +# :content = "string(" + !content + ")" +# +# is compiled to: +# +# #main { +# content: string(Hello, "Hubert" Bean.) } +# +# === Default Concatenation +# +# All those plusses and quotes for concatenating strings +# can get pretty messy, though. +# Most of the time, if you want to concatenate stuff, +# you just want individual values with spaces in between them. +# Thus, in Sass, when two values are next to each other without an operator, +# they're simply joined with a space. +# For example: +# +# !font_family = "sans-serif" +# !main_font_size = 1em +# +# #main +# :font +# :family = !font_family +# :size = !main_font_size +# h6 +# :font = italic "small-caps" bold (!main_font_size + 0.1em) !font_family +# +# is compiled to: +# +# #main { +# font-family: sans-serif; +# font-size: 1em; } +# #main h6 { +# font: italic small-caps bold 1.1em sans-serif; } +# +# == Directives +# +# Directives allow the author to directly issue instructions to the Sass compiler. +# They're prefixed with an at sign, "@", +# followed by the name of the directive, +# a space, and any arguments to it - +# just like CSS directives. +# For example: +# +# @import red.sass +# +# === Import +# +# Currently, the only directive is the "import" directive. +# It works in a very similar way to the CSS import directive, +# and sometimes compiles to a literal CSS "@import". +# +# Sass can import either other Sass files or plain CSS files. +# If it imports a Sass file, +# not only are the rules from that file included, +# but all constants in that file are made available in the current file. +# +# Sass looks for other Sass files in the working directory, +# and the Sass file directory under Rails or Merb. +# Additional search directories may be specified +# using the :load_paths option (see below). +# +# Sass can also import plain CSS files. +# In this case, it doesn't literally include the content of the files; +# rather, it uses the built-in CSS "@import" directive to tell the client program +# to import the files. +# +# The import directive can take either a full filename +# or a filename without an extension. +# If an extension isn't provided, +# Sass will try to find a Sass file with the given basename in the load paths, +# and, failing that, will assume a relevant CSS file will be available. +# +# For example, +# +# @import foo.sass +# +# would compile to +# +# .foo +# :color #f00 +# +# whereas +# +# @import foo.css +# +# would compile to +# +# @import foo.css +# +# Finally, +# +# @import foo +# +# might compile to either, +# depending on whether a file called "foo.sass" existed. +# +# == Comments +# +# === Silent Comments +# +# It's simple to add "silent" comments, +# which don't output anything to the CSS document, +# to a Sass document. +# Simply use the familiar C-style notation for a one-line comment, "//", +# at the normal indentation level and all text following it won't be output. +# For example: +# +# // A very awesome rule. +# #awesome.rule +# // An equally awesome attribute. +# :awesomeness very +# +# becomes +# +# #awesome.rule { +# awesomeness: very; } +# +# === Loud Comments +# +# "Loud" comments are just as easy as silent ones. +# These comments output to the document as CSS comments, +# and thus use the same opening sequence: "/*". +# For example: +# +# /* A very awesome rule. +# #awesome.rule +# /* An equally awesome attribute. +# :awesomeness very +# +# becomes +# +# /* A very awesome rule. */ +# #awesome.rule { +# /* An equally awesome attribute. */ +# awesomeness: very; } +# +# == Output Style +# +# Although the default CSS style that Sass outputs is very nice, +# and reflects the structure of the document in a similar way that Sass does, +# sometimes it's good to have other formats available. +# +# Sass allows you to choose between three different output styles +# by setting the :style option. +# In Rails, this is done by setting Sass::Plugin.options[:style]; +# outside Rails, it's done by passing an options hash with :style set. +# +# === :nested +# +# Nested style is the default Sass style, +# because it reflects the structure of the document +# in much the same way Sass does. +# Each attribute has its own line, +# but the indentation isn't constant. +# Each rule is indented based on how deeply it's nested. +# For example: +# +# #main { +# color: #fff; +# background-color: #000; } +# #main p { +# width: 10em; } +# +# .huge { +# font-size: 10em; +# font-weight: bold; +# text-decoration: underline; } +# +# Nested style is very useful when looking at large CSS files +# for the same reason Sass is useful for making them: +# it allows you to very easily grasp the structure of the file +# without actually reading anything. +# +# === :expanded +# +# Expanded is the typical human-made CSS style, +# with each attribute and rule taking up one line. +# Attributes are indented within the rules, +# but the rules aren't indented in any special way. +# For example: +# +# #main { +# color: #fff; +# background-color: #000; +# } +# #main p { +# width: 10em; +# } +# +# .huge { +# font-size: 10em; +# font-weight: bold; +# text-decoration: underline; +# } +# +# === :compact +# +# Compact style, as the name would imply, +# takes up less space than Nested or Expanded. +# However, it's also harder to read. +# Each CSS rule takes up only one line, +# with every attribute defined on that line. +# Nested rules are placed next to each other with no newline, +# while groups of rules have newlines between them. +# For example: +# +# #main { color: #fff; background-color: #000; } +# #main p { width: 10em; } +# +# .huge { font-size: 10em; font-weight: bold; text-decoration: underline; } +# +# == Sass Options +# +# Options can be set by setting the hash Sass::Plugin.options +# from environment.rb in Rails, +# or by passing an options hash to Sass::Engine. +# Available options are: +# +# [:style] Sets the style of the CSS output. +# See the section on Output Style, above. +# +# [:always_update] Whether the CSS files should be updated every +# time a controller is accessed, +# as opposed to only when the template has been modified. +# Defaults to false. +# Only has meaning within Ruby on Rails or Merb. +# +# [:always_check] Whether a Sass template should be checked for updates every +# time a controller is accessed, +# as opposed to only when the Rails server starts. +# If a Sass template has been updated, +# it will be recompiled and will overwrite the corresponding CSS file. +# Defaults to false if Rails is running in production mode, +# true otherwise. +# Only has meaning within Ruby on Rails. +# +# [:full_exception] Whether an error in the Sass code +# should cause Sass to provide a detailed description. +# If set to true, the specific error will be displayed +# along with a line number and source snippet. +# Otherwise, a simple uninformative error message will be displayed. +# Defaults to false in production mode, true otherwise. +# Only has meaning within Ruby on Rails or Merb. +# +# [:template_location] The directory where Sass templates should be read from. +# Defaults to RAILS_ROOT + "/public/stylesheets/sass" +# or MERB_ROOT + "/public/stylesheets/sass". +# Only has meaning within Ruby on Rails or Merb. +# +# [:css_location] The directory where CSS output should be written to. +# Defaults to RAILS_ROOT + "/public/stylesheets" +# or MERB_ROOT + "/public/stylesheets". +# Only has meaning within Ruby on Rails or Merb. +# +# [:filename] The filename of the file being rendered. +# This is used solely for reporting errors, +# and is automatically set when using Rails or Merb. +# +# [:load_paths] An array of filesystem paths which should be searched +# for Sass templates imported with the "@import" directive. +# This defaults to the working directory and, in Rails or Merb, +# whatever :template_location is. +# +module Sass; end + +require 'sass/engine' +require 'sass/plugin' if defined?(Merb::Plugins) diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant.rb b/vendor/gems/haml-1.7.2/lib/sass/constant.rb new file mode 100644 index 0000000..b6e4c6c --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant.rb @@ -0,0 +1,219 @@ +require 'sass/constant/operation' +require 'sass/constant/literal' + +module Sass + module Constant # :nodoc: + # The character that begins a constant. + CONSTANT_CHAR = ?! + + # Whitespace characters + WHITESPACE = [?\ , ?\t, ?\n, ?\r] + + # The character used to escape values + ESCAPE_CHAR = ?\\ + + # The character used to open and close strings + STRING_CHAR = ?" + + # A mapping of syntactically-significant characters + # to parsed symbols + SYMBOLS = { + ?( => :open, + ?) => :close, + ?+ => :plus, + ?- => :minus, + ?* => :times, + ?/ => :div, + ?% => :mod, + STRING_CHAR => :str, + ESCAPE_CHAR => :esc + } + + # The regular expression used to parse constants + MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }}]+)\s*=\s*(.+)/ + + # First-order operations + FIRST_ORDER = [:times, :div, :mod] + + # Second-order operations + SECOND_ORDER = [:plus, :minus] + + class << self + def parse(value, constants, line) + begin + operationalize(parenthesize(tokenize(value)), constants).to_s + rescue Sass::SyntaxError => e + if e.message == "Constant arithmetic error" + e.instance_eval do + @message += ": #{value.dump}" + end + end + e.sass_line = line + raise e + end + end + + private + + def tokenize(value) + escaped = false + is_string = false + negative_okay = true + str = '' + to_return = [] + + reset_str = Proc.new do + to_return << str unless str.empty? + '' + end + + value.each_byte do |byte| + unless escaped + if byte == ESCAPE_CHAR + escaped = true + next + end + + last = to_return[-1] + + # Do we need to open or close a string literal? + if byte == STRING_CHAR + is_string = !is_string + + # Adjacent strings should be concatenated + if is_string && last && (!last.is_a?(Symbol) || last == :close) + to_return << :concat + end + + str = reset_str.call + next + end + + unless is_string + + # Are we looking at whitespace? + if WHITESPACE.include?(byte) + str = reset_str.call + next + end + + symbol = SYMBOLS[byte] + + # Adjacent values without an operator should be concatenated + if (symbol.nil? || symbol == :open) && + last && (!last.is_a?(Symbol) || last == :close) + to_return << :concat + end + + # Time for a unary minus! + if negative_okay && symbol == :minus + negative_okay = true + to_return << :neg + next + end + + # Are we looking at an operator? + if symbol && (str.empty? || symbol != :mod) + str = reset_str.call + negative_okay = true + to_return << symbol + next + end + end + end + + escaped = false + negative_okay = false + str << byte.chr + end + + if is_string + raise Sass::SyntaxError.new("Unterminated string: #{value.dump}") + end + str = reset_str.call + to_return + end + + def parenthesize(value) + parenthesize_helper(0, value, value.length)[0] + end + + def parenthesize_helper(i, value, value_len) + to_return = [] + beginning = i + token = value[i] + + while i < value_len && token != :close + if token == :open + to_return.push(*value[beginning...i]) + sub, i = parenthesize_helper(i + 1, value, value_len) + beginning = i + to_return << sub + elsif token == :neg + if value[i + 1].nil? + raise Sass::SyntaxError("Unterminated unary minus.") + elsif value[i + 1] == :open + to_return.push(*value[beginning...i]) + sub, i = parenthesize_helper(i + 2, value, value_len) + beginning = i + to_return << [:neg, sub] + else + to_return.push(*value[beginning...i]) + to_return << [:neg, value[i + 1]] + beginning = i = i + 2 + end + else + i += 1 + end + + token = value[i] + end + to_return.push(*value[beginning...i]) + return to_return, i + 1 + end + + #-- + # TODO: Don't pass around original value; + # have Constant.parse automatically add it to exception. + #++ + def operationalize(value, constants) + value = [value] unless value.is_a?(Array) + if value.length == 1 + value = value[0] + if value.is_a? Array + operationalize(value, constants) + elsif value.is_a? Operation + value + else + Literal.parse(insert_constant(value, constants)) + end + elsif value.length == 2 + if value[0] == :neg + Operation.new(Sass::Constant::Number.new('0'), operationalize(value[1], constants), :minus) + else + raise SyntaxError.new("Constant arithmetic error") + end + elsif value.length == 3 + Operation.new(operationalize(value[0], constants), operationalize(value[2], constants), value[1]) + else + if SECOND_ORDER.include?(value[1]) && FIRST_ORDER.include?(value[3]) + operationalize([value[0], value[1], operationalize(value[2..4], constants), *value[5..-1]], constants) + else + operationalize([operationalize(value[0..2], constants), *value[3..-1]], constants) + end + end + end + + def insert_constant(value, constants) + to_return = value + if value[0] == CONSTANT_CHAR + to_return = constants[value[1..-1]] + unless to_return + raise SyntaxError.new("Undefined constant: \"#{value}\"") + end + end + to_return + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant/color.rb b/vendor/gems/haml-1.7.2/lib/sass/constant/color.rb new file mode 100644 index 0000000..db59a97 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant/color.rb @@ -0,0 +1,101 @@ +require 'sass/constant/literal' + +module Sass::Constant # :nodoc: + class Color < Literal # :nodoc: + + HTML4_COLORS = { + 'black' => 0x000000, + 'silver' => 0xc0c0c0, + 'gray' => 0x808080, + 'white' => 0xffffff, + 'maroon' => 0x800000, + 'red' => 0xff0000, + 'purple' => 0x800080, + 'fuchsia' => 0xff00ff, + 'green' => 0x008000, + 'lime' => 0x00ff00, + 'olive' => 0x808000, + 'yellow' => 0xffff00, + 'navy' => 0x000080, + 'blue' => 0x0000ff, + 'teal' => 0x008080, + 'aqua' => 0x00ffff + } + + REGEXP = /\##{"([0-9a-fA-F]{1,2})" * 3}/ + + def parse(value) + if (value =~ REGEXP) + @value = value.scan(REGEXP)[0].map { |num| num.ljust(2, num).to_i(16) } + else + color = HTML4_COLORS[value.downcase] + @value = (0..2).map{ |n| color >> (n << 3) & 0xff }.reverse + end + end + + def plus(other) + if other.is_a? Sass::Constant::String + Sass::Constant::String.from_value(self.to_s + other.to_s) + else + piecewise(other, :+) + end + end + + def minus(other) + if other.is_a? Sass::Constant::String + raise NoMethodError.new(nil, :minus) + else + piecewise(other, :-) + end + end + + def times(other) + if other.is_a? Sass::Constant::String + raise NoMethodError.new(nil, :times) + else + piecewise(other, :*) + end + end + + def div(other) + if other.is_a? Sass::Constant::String + raise NoMethodError.new(nil, :div) + else + piecewise(other, :/) + end + end + + def mod(other) + if other.is_a? Sass::Constant::String + raise NoMethodError.new(nil, :mod) + else + piecewise(other, :%) + end + end + + def to_s + red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') } + "##{red}#{green}#{blue}" + end + + protected + + def self.filter_value(value) + value.map { |num| num.to_i } + end + + private + + def piecewise(other, operation) + other_num = other.is_a? Number + other_val = other.value + + rgb = [] + for i in (0...3) + res = @value[i].send(operation, other_num ? other_val : other_val[i]) + rgb[i] = [ [res, 255].min, 0 ].max + end + Color.from_value(rgb) + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant/literal.rb b/vendor/gems/haml-1.7.2/lib/sass/constant/literal.rb new file mode 100644 index 0000000..34fbced --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant/literal.rb @@ -0,0 +1,53 @@ +# Let the subclasses see the superclass +module Sass::Constant; class Literal; end; end; # :nodoc: + +require 'sass/constant/string' +require 'sass/constant/number' +require 'sass/constant/color' + +class Sass::Constant::Literal # :nodoc: + # The regular expression matching numbers. + NUMBER = /^(-?\d*?\.?)(\d+)([^\d\s]*)$/ + + html_color_matcher = Sass::Constant::Color::HTML4_COLORS.keys.map { |c| "^#{c}$" }.join '|' + + # The regular expression matching colors. + COLOR = /^\# (?: [\da-f]{3} | [\da-f]{6} ) | #{html_color_matcher}/ix + + def self.parse(value) + case value + when NUMBER + Sass::Constant::Number.new(value) + when COLOR + Sass::Constant::Color.new(value) + else + Sass::Constant::String.new(value) + end + end + + def initialize(value = nil) + self.parse(value) if value + end + + def perform + self + end + + def concat(other) + Sass::Constant::String.from_value("#{self.to_s} #{other.to_s}") + end + + attr_reader :value + + protected + + def self.filter_value(value) + value + end + + def self.from_value(value) + instance = self.new + instance.instance_variable_set('@value', self.filter_value(value)) + instance + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant/number.rb b/vendor/gems/haml-1.7.2/lib/sass/constant/number.rb new file mode 100644 index 0000000..d822f13 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant/number.rb @@ -0,0 +1,87 @@ +require 'sass/constant/literal' + +module Sass::Constant # :nodoc: + class Number < Literal # :nodoc: + + attr_reader :unit + + def parse(value) + first, second, unit = value.scan(Literal::NUMBER)[0] + @value = first.empty? ? second.to_i : "#{first}#{second}".to_f + @unit = unit unless unit.empty? + end + + def plus(other) + if other.is_a? Number + operate(other, :+) + elsif other.is_a? Color + other.plus(self) + else + Sass::Constant::String.from_value(self.to_s + other.to_s) + end + end + + def minus(other) + if other.is_a? Number + operate(other, :-) + else + raise NoMethodError.new(nil, :minus) + end + end + + def times(other) + if other.is_a? Number + operate(other, :*) + elsif other.is_a? Color + other.times(self) + else + raise NoMethodError.new(nil, :times) + end + end + + def div(other) + if other.is_a? Number + operate(other, :/) + else + raise NoMethodError.new(nil, :div) + end + end + + def mod(other) + if other.is_a? Number + operate(other, :%) + else + raise NoMethodError.new(nil, :mod) + end + end + + def to_s + value = @value + value = value.to_i if value % 1 == 0.0 + "#{value}#{@unit}" + end + + protected + + def self.from_value(value, unit=nil) + instance = super(value) + instance.instance_variable_set('@unit', unit) + instance + end + + def operate(other, operation) + unit = nil + if other.unit.nil? + unit = self.unit + elsif self.unit.nil? + unit = other.unit + elsif other.unit == self.unit + unit = self.unit + else + raise Sass::SyntaxError.new("Incompatible units: #{self.unit} and #{other.unit}") + end + + Number.from_value(self.value.send(operation, other.value), unit) + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant/operation.rb b/vendor/gems/haml-1.7.2/lib/sass/constant/operation.rb new file mode 100644 index 0000000..3033af5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant/operation.rb @@ -0,0 +1,30 @@ +require 'sass/constant/string' +require 'sass/constant/number' +require 'sass/constant/color' + +module Sass::Constant # :nodoc: + class Operation # :nodoc: + def initialize(operand1, operand2, operator) + @operand1 = operand1 + @operand2 = operand2 + @operator = operator + end + + def to_s + self.perform.to_s + end + + protected + + def perform + literal1 = @operand1.perform + literal2 = @operand2.perform + begin + literal1.send(@operator, literal2) + rescue NoMethodError => e + raise e unless e.name.to_s == @operator.to_s + raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\"") + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/constant/string.rb b/vendor/gems/haml-1.7.2/lib/sass/constant/string.rb new file mode 100644 index 0000000..21b7f35 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/constant/string.rb @@ -0,0 +1,18 @@ +require 'sass/constant/literal' + +module Sass::Constant # :nodoc: + class String < Literal # :nodoc: + + def parse(value) + @value = value + end + + def plus(other) + Sass::Constant::String.from_value(self.to_s + other.to_s) + end + + def to_s + @value + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/css.rb b/vendor/gems/haml-1.7.2/lib/sass/css.rb new file mode 100644 index 0000000..c4bfea8 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/css.rb @@ -0,0 +1,197 @@ +require File.dirname(__FILE__) + '/../sass' +require 'sass/tree/node' +require 'strscan' + +module Sass + # :stopdoc: + module Tree + class Node + def to_sass + result = '' + + children.each do |child| + result << "#{child.to_sass(0)}\n" + end + + result + end + end + + class ValueNode + def to_sass(tabs) + "#{value}\n" + end + end + + class RuleNode + def to_sass(tabs) + str = "#{' ' * tabs}#{rule}\n" + + children.each do |child| + str << "#{child.to_sass(tabs + 1)}" + end + + str + end + end + + class AttrNode + def to_sass(tabs) + "#{' ' * tabs}:#{name} #{value}\n" + end + end + end + # :startdoc: + + # This class contains the functionality used in the +css2sass+ utility, + # namely converting CSS documents to Sass templates. + class CSS + # :stopdoc: + + # The Regexp matching a CSS rule + RULE_RE = /\s*([^\{]+)\s*\{/ + + # The Regexp matching a CSS attribute + ATTR_RE = /\s*[^::\{\}]+\s*:\s*[^:;\{\}]+\s*;/ + + # :startdoc: + + # Creates a new instance of Sass::CSS that will compile the given document + # to a Sass string when +render+ is called. + def initialize(template) + if template.is_a? IO + template = template.read + end + + @template = StringScanner.new(template) + end + + # Processes the document and returns the result as a string + # containing the CSS template. + def render + begin + build_tree.to_sass + rescue Exception => err + line = @template.string[0...@template.pos].split("\n").size + + err.backtrace.unshift "(css):#{line}" + raise err + end + end + + private + + def build_tree + root = Tree::Node.new(nil) + whitespace + directives(root) + rules(root) + sort_rules(root) + root + end + + def directives(root) + while @template.scan(/@/) + name = @template.scan /[^\s;]+/ + whitespace + value = @template.scan /[^;]+/ + assert_match /;/ + whitespace + + if name == "import" && value =~ /^(url\()?"?([^\s\(\)\"]+)\.css"?\)?$/ + value = $2 + end + + root << Tree::ValueNode.new("@#{name} #{value};", nil) + end + end + + def rules(root) + rules = [] + while @template.scan(/[^\{\s]+/) + rules << @template[0] + whitespace + + if @template.scan(/\{/) + result = Tree::RuleNode.new(rules.join(' '), nil) + root << result + rules = [] + + whitespace + attributes(result) + end + end + end + + def attributes(rule) + while @template.scan(/[^:\}\s]+/) + name = @template[0] + whitespace + + assert_match /:/ + + value = '' + while @template.scan(/[^;\s]+/) + value << @template[0] << whitespace + end + + assert_match /;/ + rule << Tree::AttrNode.new(name, value, nil) + end + + assert_match /\}/ + end + + def whitespace + space = @template.scan(/\s*/) || '' + + # If we've hit a comment, + # go past it and look for more whitespace + if @template.scan(/\/\*/) + @template.scan_until(/\*\//) + return space + whitespace + end + return space + end + + def assert_match(re) + if !@template.scan(re) + raise Exception.new("Invalid CSS!") + end + whitespace + end + + def sort_rules(root) + root.children.sort! do |c1, c2| + if c1.is_a?(Tree::RuleNode) && c2.is_a?(Tree::RuleNode) + c1.rule <=> c2.rule + elsif !(c1.is_a?(Tree::RuleNode) || c2.is_a?(Tree::RuleNode)) || c2.is_a?(Tree::RuleNode) + -1 + else + 1 + end + end + + prev_rules = [] + prev_rule_values = [] + root.children.each do |child| + if child.is_a? Tree::RuleNode + joined_prev_values = prev_rule_values.join(' ') + until prev_rules.empty? || child.rule =~ /^#{Regexp.escape(joined_prev_values)}/ + prev_rules.pop + prev_rule_values.pop + end + + unless prev_rules.empty? + child.rule.slice!(0..(joined_prev_values.size)) + prev_rules[-1] << child + root.children.delete child + end + + prev_rules << child + prev_rule_values << child.rule + end + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/engine.rb b/vendor/gems/haml-1.7.2/lib/sass/engine.rb new file mode 100644 index 0000000..813a429 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/engine.rb @@ -0,0 +1,354 @@ +require 'sass/tree/node' +require 'sass/tree/value_node' +require 'sass/tree/rule_node' +require 'sass/tree/comment_node' +require 'sass/tree/attr_node' +require 'sass/constant' +require 'sass/error' +require 'haml/util' + +module Sass + # This is the class where all the parsing and processing of the Sass + # template is done. It can be directly used by the user by creating a + # new instance and calling render to render the template. For example: + # + # template = File.load('stylesheets/sassy.sass') + # sass_engine = Sass::Engine.new(template) + # output = sass_engine.render + # puts output + class Engine + # The character that begins a CSS attribute. + ATTRIBUTE_CHAR = ?: + + # The character that designates that + # an attribute should be assigned to the result of constant arithmetic. + SCRIPT_CHAR = ?= + + # The character that designates the beginning of a comment, + # either Sass or CSS. + COMMENT_CHAR = ?/ + + # The character that follows the general COMMENT_CHAR and designates a Sass comment, + # which is not output as a CSS comment. + SASS_COMMENT_CHAR = ?/ + + # The character that follows the general COMMENT_CHAR and designates a CSS comment, + # which is embedded in the CSS document. + CSS_COMMENT_CHAR = ?* + + # The character used to denote a compiler directive. + DIRECTIVE_CHAR = ?@ + + # The regex that matches and extracts data from + # attributes of the form :name attr. + ATTRIBUTE = /^:([^\s=:]+)\s*(=?)(?:\s+|$)(.*)/ + + # The regex that matches attributes of the form name: attr. + ATTRIBUTE_ALTERNATE_MATCHER = /^[^\s:]+\s*[=:](\s|$)/ + + # The regex that matches and extracts data from + # attributes of the form name: attr. + ATTRIBUTE_ALTERNATE = /^([^\s=:]+)(\s*=|:)(?:\s+|$)(.*)/ + + # Creates a new instace of Sass::Engine that will compile the given + # template string when render is called. + # See README for available options. + # + #-- + # + # TODO: Add current options to REFRENCE. Remember :filename! + # + # When adding options, remember to add information about them + # to README! + #++ + # + def initialize(template, options={}) + @options = { + :style => :nested, + :load_paths => ['.'] + }.merge! options + @template = template.split(/\n\r|\n/) + @lines = [] + @constants = {} + end + + # Processes the template and returns the result as a string. + def render + begin + render_to_tree.to_s + rescue SyntaxError => err + unless err.sass_filename + err.add_backtrace_entry(@options[:filename]) + end + raise err + end + end + + alias_method :to_css, :render + + protected + + def constants + @constants + end + + def render_to_tree + split_lines + + root = Tree::Node.new(@options[:style]) + index = 0 + while @lines[index] + child, index = build_tree(index) + + if child.is_a? Tree::Node + child.line = index + root << child + elsif child.is_a? Array + child.each do |c| + root << c + end + end + end + @line = nil + + root + end + + private + + # Readies each line in the template for parsing, + # and computes the tabulation of the line. + def split_lines + @line = 0 + old_tabs = 0 + @template.each_with_index do |line, index| + @line += 1 + + tabs = count_tabs(line) + + if line[0] == COMMENT_CHAR && line[1] == SASS_COMMENT_CHAR && tabs == 0 + tabs = old_tabs + end + + if tabs # if line isn't blank + if tabs - old_tabs > 1 + raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.", @line) + end + @lines << [line.strip, tabs] + + old_tabs = tabs + else + @lines << ['//', old_tabs] + end + end + + @line = nil + end + + # Counts the tabulation of a line. + def count_tabs(line) + spaces = line.index(/[^ ]/) + if spaces + if spaces % 2 == 1 || line[spaces] == ?\t + # Make sure a line with just tabs isn't an error + return nil if line.strip.empty? + + raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.", @line) + end + spaces / 2 + else + nil + end + end + + def build_tree(index) + line, tabs = @lines[index] + index += 1 + @line = index + node = parse_line(line) + + has_children = has_children?(index, tabs) + + # Node is a symbol if it's non-outputting, like a constant assignment + unless node.is_a? Tree::Node + if has_children + if node == :constant + raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath constants.", @line) + elsif node.is_a? Array + raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.", @line) + end + end + + return node, index + end + + if node.is_a? Tree::CommentNode + while has_children + line, index = raw_next_line(index) + node << line + + has_children = has_children?(index, tabs) + end + else + while has_children + child, index = build_tree(index) + + if child == :constant + raise SyntaxError.new("Constants may only be declared at the root of a document.", @line) + elsif child.is_a? Array + raise SyntaxError.new("Import directives may only be used at the root of a document.", @line) + elsif child.is_a? Tree::Node + child.line = @line + node << child + end + + has_children = has_children?(index, tabs) + end + end + + return node, index + end + + def has_children?(index, tabs) + next_line = ['//', 0] + while !next_line.nil? && next_line[0] == '//' && next_line[1] = 0 + next_line = @lines[index] + index += 1 + end + next_line && next_line[1] > tabs + end + + def raw_next_line(index) + [@lines[index][0], index + 1] + end + + def parse_line(line) + case line[0] + when ATTRIBUTE_CHAR + parse_attribute(line, ATTRIBUTE) + when Constant::CONSTANT_CHAR + parse_constant(line) + when COMMENT_CHAR + parse_comment(line) + when DIRECTIVE_CHAR + parse_directive(line) + else + if line =~ ATTRIBUTE_ALTERNATE_MATCHER + parse_attribute(line, ATTRIBUTE_ALTERNATE) + else + Tree::RuleNode.new(line, @options[:style]) + end + end + end + + def parse_attribute(line, attribute_regx) + name, eq, value = line.scan(attribute_regx)[0] + + if name.nil? || value.nil? + raise SyntaxError.new("Invalid attribute: \"#{line}\"", @line) + end + + if eq.strip[0] == SCRIPT_CHAR + value = Sass::Constant.parse(value, @constants, @line).to_s + end + + Tree::AttrNode.new(name, value, @options[:style]) + end + + def parse_constant(line) + name, value = line.scan(Sass::Constant::MATCH)[0] + unless name && value + raise SyntaxError.new("Invalid constant: \"#{line}\"", @line) + end + @constants[name] = Sass::Constant.parse(value, @constants, @line) + :constant + end + + def parse_comment(line) + if line[1] == SASS_COMMENT_CHAR + :comment + elsif line[1] == CSS_COMMENT_CHAR + Tree::CommentNode.new(line, @options[:style]) + else + Tree::RuleNode.new(line, @options[:style]) + end + end + + def parse_directive(line) + directive, value = line[1..-1].split(/\s+/, 2) + + case directive + when "import" + import(value) + else + raise SyntaxError.new("Unknown compiler directive: #{"@#{directive} #{value}".dump}", @line) + end + end + + def import(files) + nodes = [] + + files.split(/,\s*/).each do |filename| + engine = nil + filename = find_file_to_import(filename) + if filename =~ /\.css$/ + nodes << Tree::ValueNode.new("@import url(#{filename});", @options[:style]) + else + File.open(filename) do |file| + new_options = @options.dup + new_options[:filename] = filename + engine = Sass::Engine.new(file.read, @options) + end + + engine.constants.merge! @constants + + begin + root = engine.render_to_tree + rescue Sass::SyntaxError => err + err.add_backtrace_entry(filename) + raise err + end + root.children.each do |child| + child.filename = filename + nodes << child + end + @constants = engine.constants + end + end + + nodes + end + + def find_file_to_import(filename) + was_sass = false + original_filename = filename + new_filename = nil + + if filename[-5..-1] == ".sass" + filename = filename[0...-5] + was_sass = true + elsif filename[-4..-1] == ".css" + return filename + end + + @options[:load_paths].each do |path| + full_path = File.join(path, filename) + '.sass' + + if File.readable?(full_path) + new_filename = full_path + break + end + end + + if new_filename.nil? + if was_sass + raise SyntaxError.new("File to import not found or unreadable: #{original_filename}", @line) + else + return filename + '.css' + end + else + new_filename + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/error.rb b/vendor/gems/haml-1.7.2/lib/sass/error.rb new file mode 100644 index 0000000..8d3ae5d --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/error.rb @@ -0,0 +1,35 @@ +module Sass + # Sass::SyntaxError encapsulates information about the exception, + # such as the line of the Sass template it was raised on + # and the Sass file that was being parsed (if applicable). + # It also provides a handy way to rescue only exceptions raised + # because of a faulty template. + class SyntaxError < StandardError + # The line of the Sass template on which the exception was thrown. + attr_accessor :sass_line + + # The name of the file that was being parsed when the exception was raised. + # This will be nil unless Sass is being used as an ActionView plugin. + attr_reader :sass_filename + + # Creates a new SyntaxError. + # +lineno+ should be the line of the Sass template on which the error occurred. + def initialize(msg, lineno = nil) + @message = msg + @sass_line = lineno + end + + # Adds a properly formatted entry to the exception's backtrace. + # +filename+ should be the file in which the error occurred, + # if applicable (defaults to "(sass)"). + def add_backtrace_entry(filename) # :nodoc: + @sass_filename ||= filename + self.backtrace ||= [] + self.backtrace.unshift "#{@sass_filename || '(sass)'}:#{@sass_line}" + end + + def to_s # :nodoc: + @message + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/plugin.rb b/vendor/gems/haml-1.7.2/lib/sass/plugin.rb new file mode 100644 index 0000000..65741cd --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/plugin.rb @@ -0,0 +1,111 @@ +require 'sass/engine' + +module Sass + # This module contains methods to aid in using Sass + # as a stylesheet-rendering plugin for various systems. + # Currently Rails/ActionController and Merb are supported out of the box. + module Plugin + class << self + @@options = { + :template_location => './public/stylesheets/sass', + :css_location => './public/stylesheets', + :always_update => false, + :always_check => true, + :full_exception => true + } + + # Gets various options for Sass. See README for details. + #-- + # TODO: *DOCUMENT OPTIONS* + #++ + def options + @@options + end + + # Sets various options for Sass. + def options=(value) + @@options.merge!(value) + end + + # Checks each stylesheet in options[:css_location] + # to see if it needs updating, + # and updates it using the corresponding template + # from options[:templates] + # if it does. + def update_stylesheets + Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file| + + # Get the relative path to the file with no extension + name = file.sub(options[:template_location] + "/", "")[0...-5] + + if options[:always_update] || stylesheet_needs_update?(name) + css = css_filename(name) + File.delete(css) if File.exists?(css) + + filename = template_filename(name) + l_options = @@options.dup + l_options[:filename] = filename + l_options[:load_paths] = (l_options[:load_paths] || []) + [l_options[:template_location]] + engine = Engine.new(File.read(filename), l_options) + begin + result = engine.render + rescue Exception => e + if options[:full_exception] + e_string = "#{e.class}: #{e.message}" + + if e.is_a? Sass::SyntaxError + e_string << "\non line #{e.sass_line}" + + if e.sass_filename + e_string << " of #{e.sass_filename}" + + if File.exists?(e.sass_filename) + e_string << "\n\n" + + min = [e.sass_line - 5, 0].max + File.read(e.sass_filename).rstrip.split("\n")[ + min .. e.sass_line + 5 + ].each_with_index do |line, i| + e_string << "#{min + i + 1}: #{line}\n" + end + end + end + end + result = "/*\n#{e_string}\n\nBacktrace:\n#{e.backtrace.join("\n")}\n*/" + else + result = "/* Internal stylesheet error */" + end + end + + # Create any directories that might be necessary + dirs = [l_options[:css_location]] + name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" } + dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) } + + # Finally, write the file + File.open(css, 'w') do |file| + file.print(result) + end + end + end + end + + private + + def template_filename(name) + "#{@@options[:template_location]}/#{name}.sass" + end + + def css_filename(name) + "#{@@options[:css_location]}/#{name}.css" + end + + def stylesheet_needs_update?(name) + !File.exists?(css_filename(name)) || (File.mtime(template_filename(name)) - 2) > File.mtime(css_filename(name)) + end + end + end +end + +require 'sass/plugin/rails' if defined?(ActionController) +require 'sass/plugin/merb' if defined?(Merb::Plugins) diff --git a/vendor/gems/haml-1.7.2/lib/sass/plugin/merb.rb b/vendor/gems/haml-1.7.2/lib/sass/plugin/merb.rb new file mode 100644 index 0000000..d89a923 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/plugin/merb.rb @@ -0,0 +1,20 @@ +unless defined?(Sass::MERB_LOADED) + Sass::MERB_LOADED = true + + Sass::Plugin.options.merge!(:template_location => MERB_ROOT + '/public/stylesheets/sass', + :css_location => MERB_ROOT + '/public/stylesheets', + :always_check => MERB_ENV != "production", + :full_exception => MERB_ENV != "production") + config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {} + config.symbolize_keys! + Sass::Plugin.options.merge!(config) + + class MerbHandler # :nodoc: + def process_with_sass(request, response) + Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check] + process_without_sass(request, response) + end + alias_method :process_without_sass, :process + alias_method :process, :process_with_sass + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/plugin/rails.rb b/vendor/gems/haml-1.7.2/lib/sass/plugin/rails.rb new file mode 100644 index 0000000..f21a8f2 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/plugin/rails.rb @@ -0,0 +1,18 @@ +unless defined?(Sass::RAILS_LOADED) + Sass::RAILS_LOADED = true + + Sass::Plugin.options.merge!(:template_location => RAILS_ROOT + '/public/stylesheets/sass', + :css_location => RAILS_ROOT + '/public/stylesheets', + :always_check => RAILS_ENV != "production", + :full_exception => RAILS_ENV != "production") + + module ActionController # :nodoc: + class Base # :nodoc: + alias_method :sass_old_process, :process + def process(*args) + Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check] + sass_old_process(*args) + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/tree/attr_node.rb b/vendor/gems/haml-1.7.2/lib/sass/tree/attr_node.rb new file mode 100644 index 0000000..6ea0e68 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/tree/attr_node.rb @@ -0,0 +1,52 @@ +require 'sass/tree/node' + +module Sass::Tree + class AttrNode < ValueNode + attr_accessor :name + + def initialize(name, value, style) + @name = name + super(value, style) + end + + def to_s(parent_name = nil) + if value[-1] == ?; + raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump} (This isn't CSS!)", @line) + end + real_name = name + real_name = "#{parent_name}-#{real_name}" if parent_name + + if value.empty? && children.empty? + raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump}", @line) + end + + join_string = @style == :compact ? ' ' : "\n" + to_return = '' + if !value.empty? + to_return << "#{real_name}: #{value};#{join_string}" + end + + children.each do |kid| + if @style == :compact + to_return << "#{kid.to_s(real_name)} " + else + to_return << "#{kid.to_s(real_name)}\n" + end + end + to_return << "\n" unless children.empty? || @style == :compact + to_return[0...-1] + end + + private + + def declaration + ":#{name} #{value}" + end + + def invalid_child?(child) + if !child.is_a?(AttrNode) + "Illegal nesting: Only attributes may be nested beneath attributes." + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/tree/comment_node.rb b/vendor/gems/haml-1.7.2/lib/sass/tree/comment_node.rb new file mode 100644 index 0000000..e741ded --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/tree/comment_node.rb @@ -0,0 +1,14 @@ +require 'sass/tree/node' + +module Sass::Tree + class CommentNode < ValueNode + def initialize(value, style) + super(value[2..-1].strip, style) + end + + def to_s(parent_name = nil) + join_string = @style == :compact ? ' ' : "\n * " + "/* #{value}#{join_string unless children.empty?}#{children.join join_string} */" + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/tree/node.rb b/vendor/gems/haml-1.7.2/lib/sass/tree/node.rb new file mode 100644 index 0000000..20acd72 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/tree/node.rb @@ -0,0 +1,46 @@ +module Sass + module Tree + class Node + attr_accessor :children + attr_accessor :line + attr_accessor :filename + + def initialize(style) + @style = style + @children = [] + end + + def <<(child) + if msg = invalid_child?(child) + raise Sass::SyntaxError.new(msg, child.line) + end + @children << child + end + + def to_s + result = String.new + children.each do |child| + if child.is_a? AttrNode + raise SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line) + end + + begin + result += "#{child.to_s(1)}\n" + rescue SyntaxError => e + raise e + end + end + result[0...-1] + end + + private + + # This method should be overridden by subclasses to return an error message + # if the given child node is invalid, + # and false or nil otherwise. + def invalid_child?(child) + false + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/tree/rule_node.rb b/vendor/gems/haml-1.7.2/lib/sass/tree/rule_node.rb new file mode 100644 index 0000000..75e0773 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/tree/rule_node.rb @@ -0,0 +1,59 @@ +require 'sass/tree/node' +require 'sass/tree/attr_node' + +module Sass::Tree + class RuleNode < ValueNode + # The character used to include the parent selector + PARENT = '&' + + alias_method :rule, :value + alias_method :rule=, :value= + + def to_s(tabs, super_rules = nil) + attributes = [] + sub_rules = [] + total_rule = if super_rules + super_rules.split(/,\s*/).collect! do |s| + self.rule.split(/,\s*/).collect do |r| + if r.include?(PARENT) + r.gsub(PARENT, s) + else + "#{s} #{r}" + end + end.join(", ") + end.join(", ") + elsif self.rule.include?(PARENT) + raise Sass::SyntaxError.new("Base-level rules cannot contain the parent-selector-referencing character '#{PARENT}'", line) + else + self.rule + end + + children.each do |child| + if child.is_a? RuleNode + sub_rules << child + else + attributes << child + end + end + + to_return = '' + unless attributes.empty? + if @style == :compact + to_return << "#{total_rule} { #{attributes.join(' ')} }\n" + else + spaces = (@style == :expanded ? 2 : tabs * 2) + old_spaces = ' ' * (spaces - 2) + spaces = ' ' * spaces + + attributes = attributes.join("\n").gsub("\n", "\n#{spaces}").rstrip + end_attrs = (@style == :expanded ? "\n" : ' ') + to_return << "#{old_spaces}#{total_rule} {\n#{spaces}#{attributes}#{end_attrs}}\n" + end + end + + tabs += 1 unless attributes.empty? + sub_rules.each { |sub| to_return << sub.to_s(tabs, total_rule) } + to_return + end + end +end diff --git a/vendor/gems/haml-1.7.2/lib/sass/tree/value_node.rb b/vendor/gems/haml-1.7.2/lib/sass/tree/value_node.rb new file mode 100644 index 0000000..e7b43d9 --- /dev/null +++ b/vendor/gems/haml-1.7.2/lib/sass/tree/value_node.rb @@ -0,0 +1,16 @@ +require 'sass/tree/node' + +module Sass::Tree + class ValueNode < Node + attr_accessor :value + + def initialize(value, style) + @value = value + super(style) + end + + def to_s(tabs = 0) + value + end + end +end diff --git a/vendor/gems/haml-1.7.2/test/benchmark.rb b/vendor/gems/haml-1.7.2/test/benchmark.rb new file mode 100644 index 0000000..fb22216 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/benchmark.rb @@ -0,0 +1,62 @@ +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/template' +require 'sass/engine' + +require 'benchmark' +require 'stringio' + +module Haml + class Benchmarker + + # Creates a new benchmarker that looks for templates in the base + # directory. + def initialize(base = File.dirname(__FILE__)) + ActionView::Base.register_template_handler("haml", Haml::Template) + unless base.class == ActionView::Base + @base = ActionView::Base.new(base) + else + @base = base + end + end + + # Benchmarks haml against ERb, and Sass on its own. + # + # Returns the results of the benchmarking as a string. + # + def benchmark(runs = 100) + template_name = 'standard' + haml_template = "haml/templates/#{template_name}" + rhtml_template = "haml/rhtml/#{template_name}" + sass_template = File.dirname(__FILE__) + "/sass/templates/complex.sass" + + old_stdout = $stdout + $stdout = StringIO.new + + times = Benchmark.bmbm do |b| + b.report("haml:") { runs.times { @base.render haml_template } } + b.report("erb:") { runs.times { @base.render rhtml_template } } + end + + #puts times[0].inspect, times[1].inspect + ratio = sprintf("%g", times[0].to_a[5] / times[1].to_a[5]) + puts "Haml/ERB: " + ratio + + puts '', '-' * 50, 'Sass on its own', '-' * 50 + + Benchmark.bmbm do |b| + b.report("sass:") { runs.times { Sass::Engine.new(File.read(sass_template)).render } } + end + + $stdout.pos = 0 + to_return = $stdout.read + $stdout = old_stdout + + to_return + end + end +end diff --git a/vendor/gems/haml-1.7.2/test/haml/engine_test.rb b/vendor/gems/haml-1.7.2/test/haml/engine_test.rb new file mode 100644 index 0000000..b7e1bea --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/engine_test.rb @@ -0,0 +1,261 @@ +#!/usr/bin/env ruby + +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' + +require 'test/unit' +require File.dirname(__FILE__) + '/../../lib/haml' +require 'haml/engine' + +class EngineTest < Test::Unit::TestCase + + def render(text, options = {}) + Haml::Engine.new(text, options).to_html + end + + def test_empty_render_should_remain_empty + assert_equal('', render('')) + end + + # This is ugly because Hashes are unordered; we don't always know the order + # in which attributes will be returned. + # There is probably a better way to do this. + def test_attributes_should_render_correctly + assert_equal("
    \n
    ", render(".atlantis{:style => 'ugly'}").chomp) + rescue + assert_equal("
    \n
    ", render(".atlantis{:style => 'ugly'}").chomp) + end + + def test_ruby_code_should_work_inside_attributes + author = 'hcatlin' + assert_equal("

    foo

    ", render("%p{:class => 1+2} foo").chomp) + end + + def test_nil_should_render_empty_tag + assert_equal("
    \n
    ", + render(".no_attributes{:nil => nil}").chomp) + end + + def test_strings_should_get_stripped_inside_tags + assert_equal("
    This should have no spaces in front of it
    ", + render(".stripped This should have no spaces in front of it").chomp) + end + + def test_one_liner_should_be_one_line + assert_equal("

    Hello

    ", render('%p Hello').chomp) + end + + def test_long_liner_should_not_print_on_one_line + assert_equal("
    \n #{'x' * 51}\n
    ", render("%div #{'x' * 51}").chomp) + end + + def test_multi_render + engine = Haml::Engine.new("%strong Hi there!") + assert_equal("Hi there!\n", engine.to_html) + assert_equal("Hi there!\n", engine.to_html) + assert_equal("Hi there!\n", engine.to_html) + end + + def test_double_equals + assert_equal("

    Hello World

    \n", render('%p== Hello #{who}', :locals => {:who => 'World'})) + assert_equal("

    \n Hello World\n

    \n", render("%p\n == Hello \#{who}", :locals => {:who => 'World'})) + end + + def test_nil_tag_value_should_render_as_empty + assert_equal("

    \n", render("%p= nil")) + end + + def test_tag_with_failed_if_should_render_as_empty + assert_equal("

    \n", render("%p= 'Hello' if false")) + end + + # Options tests + + def test_stop_eval + assert_equal("", render("= 'Hello'", :suppress_eval => true)) + assert_equal("", render("- puts 'foo'", :suppress_eval => true)) + assert_equal("
    \n", render("#foo{:yes => 'no'}/", :suppress_eval => true)) + assert_equal("
    \n", render("#foo{:yes => 'no', :call => a_function() }/", :suppress_eval => true)) + assert_equal("
    \n", render("%div[1]/", :suppress_eval => true)) + + begin + assert_equal("", render(":ruby\n puts 'hello'", :suppress_eval => true)) + rescue Haml::HamlError => err + caught = true + assert_equal('Filter "ruby" is not defined!', err.message) + end + assert(caught, "Rendering a ruby filter without evaluating didn't throw an error!") + end + + def test_attr_wrapper + assert_equal("

    \n

    \n", render("%p{ :strange => 'attrs'}", :attr_wrapper => '*')) + assert_equal("

    \n

    \n", render("%p{ :escaped => 'quo\"te'}", :attr_wrapper => '"')) + assert_equal("

    \n

    \n", render("%p{ :escaped => 'q\\'uo\"te'}", :attr_wrapper => '"')) + assert_equal("\n", render("!!! XML", :attr_wrapper => '"')) + end + + def test_attrs_parsed_correctly + assert_equal("

    biddly='bar => baz'>\n

    \n", render("%p{'boom=>biddly' => 'bar => baz'}")) + assert_equal("

    \n

    \n", render("%p{'foo,bar' => 'baz, qux'}")) + assert_equal("

    \n

    \n", render("%p{ :escaped => \"quo\\nte\"}")) + assert_equal("

    \n

    \n", render("%p{ :escaped => \"quo\#{2 + 2}te\"}")) + end + + def test_locals + assert_equal("

    Paragraph!

    \n", render("%p= text", :locals => { :text => "Paragraph!" })) + end + + def test_recompile_with_new_locals + template = "%p= (text == 'first time') ? text : new_text" + assert_equal("

    first time

    \n", render(template, :locals => { :text => "first time" })) + assert_equal("

    second time

    \n", render(template, :locals => { :text => "recompile", :new_text => "second time" })) + + # Make sure the method called will return junk unless recompiled + method_name = Haml::Engine.send(:class_variable_get, '@@method_names')[template] + Haml::Engine::CompiledTemplates.module_eval "def #{method_name}(stuff); @haml_stack[-1].push_text 'NOT RECOMPILED', 0; end" + + assert_equal("NOT RECOMPILED\n", render(template, :locals => { :text => "first time" })) + assert_equal("

    first time

    \n", render(template, :locals => { :text => "first time", :foo => 'bar' })) + end + + def test_dynamc_attrs_shouldnt_register_as_literal_values + assert_equal("

    \n

    \n", render('%p{:a => "b#{1 + 1}c"}')) + assert_equal("

    \n

    \n", render("%p{:a => 'b' + (1 + 1).to_s + 'c'}")) + end + + def test_rec_merge + hash1 = {1=>2, 3=>{5=>7, 8=>9}} + hash2 = {4=>5, 3=>{5=>2, 16=>12}} + hash3 = {1=>2, 4=>5, 3=>{5=>2, 8=>9, 16=>12}} + + hash1.rec_merge!(hash2) + assert_equal(hash3, hash1) + end + + def test_exception_type + begin + render("%p hi\n= undefined") + rescue Exception => e + assert(e.is_a?(Haml::Error)) + assert_equal(2, e.haml_line) + assert_equal(nil, e.haml_filename) + assert_equal('(haml):2', e.backtrace[0]) + else + # Test failed... should have raised an exception + assert(false) + end + end + + def test_syntax_errors + errs = [ "!!!\n a", "a\n b", "a\n:foo\nb", "/ a\n b", + "% a", "%p a\n b", "a\n%p=\nb", "%p=\n a", + "a\n%p~\nb", "a\n~\nb", "a\n~\n b", "%p~\n b", "%p/\n a", + "%p\n \t%a b", "%a\n b\nc", "%a\n b\nc", + ":notafilter\n This isn't\n a filter!", + ".{} a", "\#{} a", ".= 'foo'", "%a/ b", "%p..class", "%p..#." ] + errs.each do |err| + begin + render(err) + rescue Exception => e + assert(e.is_a?(Haml::Error), + "#{err.dump} doesn't produce Haml::SyntaxError!") + else + assert(false, + "#{err.dump} doesn't produce an exception!") + end + end + end + + def test_compile_error + begin + render("a\nb\n- fee do\nc") + rescue Exception => e + assert_equal(3, e.haml_line) + else + assert(false, + '"a\nb\n- fee do\nc" doesn\'t produce an exception!') + end + end + + def test_no_bluecloth + old_markdown = false + if defined?(Haml::Filters::Markdown) + old_markdown = Haml::Filters::Markdown + end + + Kernel.module_eval do + alias_method :haml_old_require, :gem_original_require + + def gem_original_require(file) + raise LoadError if file == 'bluecloth' + haml_old_require(file) + end + end + + if old_markdown + Haml::Filters.instance_eval do + remove_const 'Markdown' + end + end + + # This is purposefully redundant, so it doesn't stop + # haml/filters from being required later on. + require 'haml/../haml/filters' + + assert_equal("

    Foo

    \t

    - a\n- b

    \n", + Haml::Engine.new(":markdown\n Foo\n ===\n - a\n - b").to_html) + + Haml::Filters.instance_eval do + remove_const 'Markdown' + end + + Haml::Filters.const_set('Markdown', old_markdown) if old_markdown + + Kernel.module_eval do + alias_method :gem_original_require, :haml_old_require + end + + NOT_LOADED.delete 'bluecloth' + end + + def test_no_redcloth + Kernel.module_eval do + alias_method :haml_old_require2, :gem_original_require + + def gem_original_require(file) + raise LoadError if file == 'redcloth' + haml_old_require2(file) + end + end + + # This is purposefully redundant, so it doesn't stop + # haml/filters from being required later on. + require 'haml/../haml/../haml/filters' + + begin + Haml::Engine.new(":redcloth\n _foo_").to_html + rescue Haml::HamlError + else + assert(false, "No exception raised!") + end + + Kernel.module_eval do + alias_method :gem_original_require2, :haml_old_require + end + + NOT_LOADED.delete 'redcloth' + end + + def test_local_assigns_dont_modify_class + assert_equal("bar\n", render("= foo", :locals => {:foo => 'bar'})) + assert_equal(nil, defined?(foo)) + end + + def test_object_ref_with_nil_id + user = Struct.new('User', :id).new + assert_equal("

    New User

    \n", + render("%p[user] New User", :locals => {:user => user})) + end +end diff --git a/vendor/gems/haml-1.7.2/test/haml/helper_test.rb b/vendor/gems/haml-1.7.2/test/haml/helper_test.rb new file mode 100644 index 0000000..f0f30d4 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/helper_test.rb @@ -0,0 +1,123 @@ +#!/usr/bin/env ruby + +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' + +require 'test/unit' +require File.dirname(__FILE__) + '/../../lib/haml' +require 'haml/template' + +class HelperTest < Test::Unit::TestCase + include Haml::Helpers + + def setup + ActionView::Base.register_template_handler("haml", Haml::Template) + @base = ActionView::Base.new + @base.controller = ActionController::Base.new + end + + def render(text, options = {}) + if options == :action_view + @base.render :inline => text, :type => :haml + else + scope = options.delete :scope_object + Haml::Engine.new(text, options).to_html(scope ? scope : Object.new) + end + end + + def test_flatten + assert_equal(flatten("FooBar"), "FooBar") + + assert_equal(flatten("Foo\rBar"), "FooBar") + + assert_equal(flatten("Foo\nBar"), "Foo Bar") + + assert_equal(flatten("Hello\nWorld!\nYOU ARE \rFLAT?\n\rOMGZ!"), + "Hello World! YOU ARE FLAT? OMGZ!") + end + + def test_list_of_should_render_correctly + assert_equal("
  • 1
  • \n
  • 2
  • \n", render("= list_of([1, 2]) do |i|\n = i")) + assert_equal("
  • [1]
  • \n", render("= list_of([[1]]) do |i|\n = i.inspect")) + assert_equal("
  • \n

    Fee

    \n

    A word!

    \n
  • \n
  • \n

    Fi

    \n

    A word!

    \n
  • \n
  • \n

    Fo

    \n

    A word!

    \n
  • \n
  • \n

    Fum

    \n

    A word!

    \n
  • \n", + render("= list_of(['Fee', 'Fi', 'Fo', 'Fum']) do |title|\n %h1= title\n %p A word!")) + end + + def test_buffer_access + assert(render("= buffer") =~ /#/) + assert_equal(render("= (buffer == _hamlout)"), "true\n") + end + + def test_tabs + assert_equal(render("foo\n- tab_up\nbar\n- tab_down\nbaz"), "foo\n bar\nbaz\n") + end + + def test_helpers_dont_leak + # Haml helpers shouldn't be accessible from ERB + render("foo") + proper_behavior = false + + begin + ActionView::Base.new.render(:inline => "<%= flatten('Foo\\nBar') %>") + rescue NoMethodError + proper_behavior = true + end + assert(proper_behavior) + + begin + ActionView::Base.new.render(:inline => "<%= concat('foo') %>") + rescue ArgumentError, NameError + proper_behavior = true + end + assert(proper_behavior) + end + + def test_action_view_included + assert(Haml::Helpers.action_view?) + end + + def test_form_tag + result = render("- form_tag 'foo' do\n %p bar\n %strong baz", :action_view) + should_be = "
    \n

    bar

    \n baz\n
    \n" + assert_equal(should_be, result) + end + + def test_capture_haml + assert_equal("\"

    13

    \\n\"\n", render("- foo = capture_haml(13) do |a|\n %p= a\n= foo.dump")) + end + + def test_is_haml + assert(!ActionView::Base.new.is_haml?) + assert_equal("true\n", render("= is_haml?")) + assert_equal("true\n", render("= is_haml?", :action_view)) + assert_equal("false", @base.render(:inline => '<%= is_haml? %>')) + assert_equal("false\n", render("= render :inline => '<%= is_haml? %>'", :action_view)) + end + + def test_page_class + controller = Struct.new(:controller_name, :action_name).new('troller', 'tion') + scope = Struct.new(:controller).new(controller) + result = render("%div{:class => page_class} MyDiv", :scope_object => scope) + expected = "
    MyDiv
    \n" + assert_equal expected, result + end + + def test_indented_capture + assert_equal(" \n Foo\n ", @base.render(:inline => " <% res = capture do %>\n Foo\n <% end %><%= res %>")) + end + + def test_capture_deals_properly_with_collections + Haml::Helpers.module_eval do + def trc(collection, &block) + collection.each do |record| + puts capture_haml(record, &block) + end + end + end + + assert_equal("1\n\n2\n\n3\n\n", render("- trc([1, 2, 3]) do |i|\n = i.inspect")) + end +end + diff --git a/vendor/gems/haml-1.7.2/test/haml/mocks/article.rb b/vendor/gems/haml-1.7.2/test/haml/mocks/article.rb new file mode 100644 index 0000000..805f8ca --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/mocks/article.rb @@ -0,0 +1,6 @@ +class Article + attr_accessor :id, :title, :body + def initialize + @id, @title, @body = 1, 'Hello', 'World' + end +end \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/haml/results/content_for_layout.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/content_for_layout.xhtml new file mode 100644 index 0000000..8761e35 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/content_for_layout.xhtml @@ -0,0 +1,16 @@ + + + + + +
    + Lorem ipsum dolor sit amet +
    +
    + Lorem ipsum dolor sit amet +
    +
    + Lorem ipsum dolor sit amet +
    + + diff --git a/vendor/gems/haml-1.7.2/test/haml/results/eval_suppressed.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/eval_suppressed.xhtml new file mode 100644 index 0000000..8d0bf7b --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/eval_suppressed.xhtml @@ -0,0 +1,8 @@ +

    +

    Me!

    +
    +

    All

    +
    +

    This

    + Should render +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/filters.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/filters.xhtml new file mode 100644 index 0000000..a336a9c --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/filters.xhtml @@ -0,0 +1,57 @@ + +TESTING HAHAHAHA! +

    Foo

    + + +
    This is preformatted!
    +Look at that!
    +Wowie-zowie!
    + + +

    boldilicious!

    +

    Yeah

    + + +

    pretty much the same as above

    +This + Is + Plain + Text + %strong right? + + a + + b + + c + + d + + e + + f + + g + + h + + i + + j +
      +
    • Foo
    • +
    • Bar
    • +
    • BAZ!
    • +
    +Text! +Hello, World! +How are you doing today? + diff --git a/vendor/gems/haml-1.7.2/test/haml/results/helpers.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/helpers.xhtml new file mode 100644 index 0000000..cd27475 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/helpers.xhtml @@ -0,0 +1,84 @@ +&&&&&&&&&&& +
    +

    Title

    +

    + Woah this is really crazy + I mean wow, + man. +

    +
    +
    +

    Title

    +

    + Woah this is really crazy + I mean wow, + man. +

    +
    +
    +

    Title

    +

    + Woah this is really crazy + I mean wow, + man. +

    +
    +

    foo

    +

    + reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooong +

    +
    +
    +
    +

    Big!

    +

    Small

    + +
    +
    +

    foo

    +

    bar

    +
    +
    + (parentheses!) +
    +*Not really +click +here. +

    baz

    +

    boom

    +foo +

    +

    +

    + +
    +
    +
    + Title: + + Body: + +
    +
  • google
  • +

    + foo +

    + bar +
    + boom + baz + boom, again +

    + + + + + +
    + + strong! + + data + + more_data +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/helpful.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/helpful.xhtml new file mode 100644 index 0000000..042291d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/helpful.xhtml @@ -0,0 +1,10 @@ +
    +

    Hello

    +
    World
    +
    +
    id
    +
    class
    +
    id class
    +
    boo
    +
    moo
    +
    foo
    \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/haml/results/just_stuff.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/just_stuff.xhtml new file mode 100644 index 0000000..71b9195 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/just_stuff.xhtml @@ -0,0 +1,59 @@ + + + + + + + + +Boo! +Embedded? false! +Embedded? true! +Embedded? true! +
    wow!
    +stuff followed by whitespace +block with whitespace +

    + Escape + - character + %p foo + yee\ha +

    + + + +

    class attribute shouldn't appear!

    + + + +testtest +
    + + +
    + + +
    + Nested content +
    +

    Blah

    +

    Blah

    +

    Blump

    +Woah inner quotes +

    +

    +

    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/list.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/list.xhtml new file mode 100644 index 0000000..b8ef0b0 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/list.xhtml @@ -0,0 +1,12 @@ +! Not a Doctype ! +

      +
    • a
    • +
    • b
    • +
    • c
    • +
    • d
    • +
    • e
    • +
    • f
    • +
    • g
    • +
    • h
    • +
    • i
    • +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/original_engine.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/original_engine.xhtml new file mode 100644 index 0000000..600fc98 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/original_engine.xhtml @@ -0,0 +1,24 @@ + + + + Stop. haml time +
    +

    This is a title!

    +

    + Lorem ipsum dolor sit amet, consectetur adipisicing elit +

    +

    Cigarettes!

    +

    Man alive!

    +
      +
    • Slippers
    • +
    • Shoes
    • +
    • Bathrobe
    • +
    • Coffee
    • +
    +
    +        This is some text that's in a pre block!
    +        Let's see what happens when it's rendered! What about now, since we're on a new line?
    +      
    +
    + + diff --git a/vendor/gems/haml-1.7.2/test/haml/results/partials.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/partials.xhtml new file mode 100644 index 0000000..3c8c437 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/partials.xhtml @@ -0,0 +1,20 @@ +

    + @foo = + value one +

    +

    + @foo = + value two +

    +

    + @foo = + value two +

    +

    + @foo = + value three +

    +

    + @foo = + value three +

    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/silent_script.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/silent_script.xhtml new file mode 100644 index 0000000..76e90e0 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/silent_script.xhtml @@ -0,0 +1,74 @@ +
    +

    I can count!

    + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +

    I know my ABCs!

    +
      +
    • a
    • +
    • b
    • +
    • c
    • +
    • d
    • +
    • e
    • +
    • f
    • +
    • g
    • +
    • h
    • +
    • i
    • +
    • j
    • +
    • k
    • +
    • l
    • +
    • m
    • +
    • n
    • +
    • o
    • +
    • p
    • +
    • q
    • +
    • r
    • +
    • s
    • +
    • t
    • +
    • u
    • +
    • v
    • +
    • w
    • +
    • x
    • +
    • y
    • +
    • z
    • +
    +

    I can catch errors!

    + Oh no! "undefined method `silly' for String:Class" happened! +

    + "false" is: + false +

    + Even! + Odd! + Even! + Odd! + Even! +
    +
    + foobar +
    +0 +1 +2 +3 +4 +
    +

    boom

    +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/standard.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/standard.xhtml new file mode 100644 index 0000000..f87c158 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/standard.xhtml @@ -0,0 +1,43 @@ + + + + Hampton Catlin Is Totally Awesome + + + + +foo +
    + Yes, ladies and gentileman. He is just that egotistical. + Fantastic! This should be multi-line output + The question is if this would translate! Ahah! + 20 +
    +
    Quotes should be loved! Just like people!
    + Wow.| +

    + Holy cow multiline tags! A pipe (|) even! + PipesIgnored|PipesIgnored|PipesIgnored| + 1|2|3 +

    +
    + this shouldn't evaluate but now it should! +
    +
      +
    • a
    • +
    • b
    • +
    • c
    • +
    • d
    • +
    • e
    • +
    • f
    • +
    +
    with this text
    + hello + + + diff --git a/vendor/gems/haml-1.7.2/test/haml/results/tag_parsing.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/tag_parsing.xhtml new file mode 100644 index 0000000..c1d694c --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/tag_parsing.xhtml @@ -0,0 +1,28 @@ +
    + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 +
    +
    +

    +

    +
    a
    +
    b
    +
    c
    +
    d
    +
    e
    +
    f
    +
    g
    +
    +
    + <{ :a => :b } +
    >{ :c => :d }
    +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/results/very_basic.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/very_basic.xhtml new file mode 100644 index 0000000..9713fb1 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/very_basic.xhtml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/vendor/gems/haml-1.7.2/test/haml/results/whitespace_handling.xhtml b/vendor/gems/haml-1.7.2/test/haml/results/whitespace_handling.xhtml new file mode 100644 index 0000000..2c49b4d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/results/whitespace_handling.xhtml @@ -0,0 +1,94 @@ +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    +
    +
    + Foo bar +
    foo bar
    +
    foo
    bar
    +

    foo
    bar

    +

    + foo + bar +

    +
    +
    + 13 + +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    +
    +
    + Foo bar +
    foo bar
    +
    foo
    bar
    +

    foo
    bar

    +

    + foo + bar +

    +
    +                                                 ___
                                                  ,o88888
                                               ,o8888888'
                         ,:o:o:oooo.        ,8O88Pd8888"
                     ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
                   ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
                  , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
                 , ..:.::o:ooOoOO8O888O8O,COCOO"
                , . ..:.::o:ooOoOOOO8OOOOCOCO"
                 . ..:.::o:ooOoOoOO8O8OCCCC"o
                    . ..:.::o:ooooOoCoCCC"o:o
                    . ..:.::o:o:,cooooCo"oo:o:
                 `   . . ..:.:cocoooo"'o:o:::'
                 .`   . ..::ccccoc"'o:o:o:::'
                :.:.    ,c:cccc"':.:.:.:.:.'
              ..:.:"'`::::c:"'..:.:.:.:.:.'  http://www.chris.com/ASCII/
            ...:.'.:.::::"'    . . . . .'
           .. . ....:."' `   .  . . ''
         . . . ...."'
         .. . ."'     -hrr-
        .
    
    
                                                  It's a planet!
    %strong This shouldn't be bold!
    
    +  
    + This should! + +
    +
    + 13 +
    +
    +       __     ______        __               ______
    .----.|  |--.|__    |.----.|  |--..--------.|  __  |
    |  __||     ||__    ||  __||    < |        ||  __  |
    |____||__|__||______||____||__|__||__|__|__||______|
    
    +
    +
    +foo
    
    +  bar
    +
    diff --git a/vendor/gems/haml-1.7.2/test/haml/rhtml/standard.rhtml b/vendor/gems/haml-1.7.2/test/haml/rhtml/standard.rhtml new file mode 100644 index 0000000..ce1fcee --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/rhtml/standard.rhtml @@ -0,0 +1,55 @@ + + + + Hampton Catlin Is Totally Awesome + + + + + <% concat("Foo", Proc.new {}) %> +
    + Yes, ladies and gentileman. He is just that egotistical. + Fantastic! This should be multi-line output + The question is if this would translate! Ahah! + <%= 1 + 9 + 8 + 2 %> + <%# numbers should work and this should be ignored %> +
    + <% 120.times do |number| -%> + <%= number %> + <% end -%> +
    <%= " Quotes should be loved! Just like people!" %>
    + Wow. +

    + <%= "Holy cow " + + "multiline " + + "tags! " + + "A pipe (|) even!" %> + <%= [1, 2, 3].collect { |n| "PipesIgnored|" } %> + <%= [1, 2, 3].collect { |n| + n.to_s + }.join("|") %> +

    +
    + <% foo = String.new + foo << "this" + foo << " shouldn't" + foo << " evaluate" %> + <%= foo + "but now it should!" %> + <%# Woah crap a comment! %> +
    +
      + <% ('a'..'f').each do |a|%> +
    • <%= a %> + <% end %> +
      <%= @should_eval = "with this text" %>
      + <%= [ 104, 101, 108, 108, 111 ].map do |byte| + byte.chr + end %> + + + diff --git a/vendor/gems/haml-1.7.2/test/haml/runner.rb b/vendor/gems/haml-1.7.2/test/haml/runner.rb new file mode 100644 index 0000000..5567a2d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/runner.rb @@ -0,0 +1,16 @@ +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' +require '../../lib/haml/template' +require 'fileutils' + +haml_template_engine = Haml::Template.new(ActionView::Base.new) +haml_template_engine.render(File.dirname(__FILE__) + '/templates/standard.haml') + +begin + eval(File.read("template_test.rb")) +rescue StandardError => e + puts e.backtrace + puts e.inspect +end diff --git a/vendor/gems/haml-1.7.2/test/haml/template_test.rb b/vendor/gems/haml-1.7.2/test/haml/template_test.rb new file mode 100644 index 0000000..5ee864a --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/template_test.rb @@ -0,0 +1,155 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' + +require File.dirname(__FILE__) + '/../../lib/haml' +require 'haml/template' +require File.dirname(__FILE__) + '/mocks/article' + +class TestFilter + def initialize(text) + @text = text + end + + def render + "TESTING HAHAHAHA!" + end +end + +class TemplateTest < Test::Unit::TestCase + @@templates = %w{ very_basic standard helpers + whitespace_handling original_engine list helpful + silent_script tag_parsing just_stuff partials + filters } + + def setup + ActionView::Base.register_template_handler("haml", Haml::Template) + Haml::Template.options = { :filters => { 'test'=>TestFilter } } + @base = ActionView::Base.new(File.dirname(__FILE__) + "/templates/", {'article' => Article.new, 'foo' => 'value one'}) + end + + def render(text) + Haml::Engine.new(text).to_html(@base) + end + + def load_result(name) + @result = '' + File.new(File.dirname(__FILE__) + "/results/#{name}.xhtml").each_line { |l| @result += l } + @result + end + + def assert_renders_correctly(name) + test = Proc.new do |rendered| + load_result(name).split("\n").zip(rendered.split("\n")).each_with_index do |pair, line| + message = "template: #{name}\nline: #{line}" + assert_equal(pair.first, pair.last, message) + end + end + test.call(@base.render(name)) + + # If eval's suppressed, the partial won't render anyway :p. + unless Haml::Template.options[:suppress_eval] + test.call(@base.render(:file => "partialize", :locals => { :name => name })) + end + end + + def test_empty_render_should_remain_empty + assert_equal('', render('')) + end + + def test_templates_should_render_correctly + @@templates.each do |template| + assert_renders_correctly template + end + end + + def test_action_view_templates_render_correctly + @base.instance_variable_set("@content_for_layout", 'Lorem ipsum dolor sit amet') + assert_renders_correctly 'content_for_layout' + end + + def test_instance_variables_should_work_inside_templates + @base.instance_variable_set("@content_for_layout", 'something') + assert_equal("

      something

      ", render("%p= @content_for_layout").chomp) + + @base.instance_eval("@author = 'Hampton Catlin'") + assert_equal("
      Hampton Catlin
      ", render(".author= @author").chomp) + + @base.instance_eval("@author = 'Hampton'") + assert_equal("Hampton", render("= @author").chomp) + + @base.instance_eval("@author = 'Catlin'") + assert_equal("Catlin", render("= @author").chomp) + end + + def test_instance_variables_should_work_inside_attributes + @base.instance_eval("@author = 'hcatlin'") + assert_equal("

      foo

      ", render("%p{:class => @author} foo").chomp) + end + + def test_template_renders_should_eval + assert_equal("2\n", render("= 1+1")) + end + + def test_rhtml_still_renders + # Make sure it renders normally + res = @base.render("../rhtml/standard") + assert !(res.nil? || res.empty?) + + # Register Haml stuff in @base... + @base.render("standard") + + # Does it still render? + res = @base.render("../rhtml/standard") + assert !(res.nil? || res.empty?) + end + + def test_haml_options + Haml::Template.options = { :suppress_eval => true } + assert_equal({ :suppress_eval => true }, Haml::Template.options) + assert_renders_correctly("eval_suppressed") + Haml::Template.options = {} + end + + def test_exceptions_should_work_correctly + begin + Haml::Template.new(@base).render(File.dirname(__FILE__) + '/templates/breakage.haml') + rescue Exception => e + assert_equal("./test/haml/templates/breakage.haml:4", e.backtrace[0]) + else + assert false + end + + begin + render("- raise 'oops!'") + rescue Exception => e + assert_equal("(haml):1", e.backtrace[0]) + else + assert false + end + + template = < e + assert_equal("(haml):5", e.backtrace[0]) + else + assert false + end + end +end diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/_partial.haml b/vendor/gems/haml-1.7.2/test/haml/templates/_partial.haml new file mode 100644 index 0000000..00e701d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/_partial.haml @@ -0,0 +1,7 @@ +%p + @foo = + = @foo +- @foo = 'value three' +%p + @foo = + = @foo diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/_text_area.haml b/vendor/gems/haml-1.7.2/test/haml/templates/_text_area.haml new file mode 100644 index 0000000..896b975 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/_text_area.haml @@ -0,0 +1,3 @@ +.text_area_test_area + ~ "" += "" diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/breakage.haml b/vendor/gems/haml-1.7.2/test/haml/templates/breakage.haml new file mode 100644 index 0000000..57c1734 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/breakage.haml @@ -0,0 +1,8 @@ +%p + %h1 Hello! + = "lots of lines" + - raise "Oh no!" + %p + this is after the exception + %strong yes it is! +ho ho ho. diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/content_for_layout.haml b/vendor/gems/haml-1.7.2/test/haml/templates/content_for_layout.haml new file mode 100644 index 0000000..fda84a5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/content_for_layout.haml @@ -0,0 +1,10 @@ +!!! +%html + %head + %body + #content + = @content_for_layout + #yieldy + = yield :layout + #nosym + = yield diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/eval_suppressed.haml b/vendor/gems/haml-1.7.2/test/haml/templates/eval_suppressed.haml new file mode 100644 index 0000000..9544ef7 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/eval_suppressed.haml @@ -0,0 +1,10 @@ += "not me!" += "nor me!" +- puts "not even me!" +%p= "NO!" +%h1 Me! +#foo + %p#bar All + %br/ + %p.baz This + Should render diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/filters.haml b/vendor/gems/haml-1.7.2/test/haml/templates/filters.haml new file mode 100644 index 0000000..aedbb2c --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/filters.haml @@ -0,0 +1,53 @@ +%style + :sass + p + :border + :style dotted + :width 10px + :color #ff00ff + h1 + :font-weight normal + +:test + This + Should + Not + Print + +:redcloth + Foo + === + + This is preformatted! + Look at that! + Wowie-zowie! + + *boldilicious!* + +:textile + h1. Yeah + + _pretty much the same as above_ + +:plain + This + Is + Plain + Text + %strong right? + +:erb + <% 10.times do |c| %> + <%= (c+97).chr %> + <% end %> + +:markdown + * Foo + * Bar + * BAZ! + += "Text!" + +:ruby + puts "Hello, World!" + puts "How are you doing today?" diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/helpers.haml b/vendor/gems/haml-1.7.2/test/haml/templates/helpers.haml new file mode 100644 index 0000000..85dd3ac --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/helpers.haml @@ -0,0 +1,63 @@ += h("&&&&&&&&&&&") # This is an ActionView Helper... should load +- foo = capture do # This ActionView Helper is designed for ERB, but should work with haml + %div + %p.title Title + %p.text + Woah this is really crazy + I mean wow, + man. +- 3.times do + = foo +%p foo +- tab_up +%p reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooong +- tab_down +.woah + #funky + = capture_haml do + %div + %h1 Big! + %p Small + / Invisible + = capture do + .dilly + %p foo + %h1 bar + = surround '(', ')' do + %strong parentheses! += precede '*' do + %span.small Not really +click += succeed '.' do + %a{:href=>"thing"} here +%p baz +- buffer.tabulation = 10 +%p boom +- concat "foo\n" +- buffer.tabulation = 0 +- def url_for(*stuff); stuff.join(' '); end +%p + = form_tag 'hello/world' +- form_tag 'heeheeaform' do + %div= submit_tag 'save' +- form_for :article, @article, :url => 'article_url' do |f| + Title: + = f.text_field :title + Body: + = f.text_field :body += list_of({:google => 'http://www.google.com'}) do |name, link| + %a{ :href => link }= name +%p + - puts "foo" + %div + - puts "bar" + - puts "boom" + baz + - puts "boom, again" +- open :table do + - open :tr do + - open :td, {:class => 'cell'} do + - open :strong, "strong!" + - puts "data" + - open :td do + - puts "more_data" diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/helpful.haml b/vendor/gems/haml-1.7.2/test/haml/templates/helpful.haml new file mode 100644 index 0000000..3e44a50 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/helpful.haml @@ -0,0 +1,11 @@ +%div[@article] + %h1= @article.title + %div= @article.body +#id[@article] id +.class[@article] class +#id.class[@article] id class +%div{:class => "article full"}[@article]= "boo" +%div{'class' => "article full"}[@article]= "moo" +%div.articleFull[@article]= "foo" +%span[@not_a_real_variable_and_will_be_nil] + Boo diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/just_stuff.haml b/vendor/gems/haml-1.7.2/test/haml/templates/just_stuff.haml new file mode 100644 index 0000000..45d955b --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/just_stuff.haml @@ -0,0 +1,69 @@ +!!! XML +!!! XML ISO-8859-1 +!!! XML UtF-8 Foo bar +!!! +!!! 1.1 +!!! 1.1 Strict +!!! Strict foo bar +!!! FRAMESET +%strong{:apos => "Foo's bar!"} Boo! +== Embedded? false! +== Embedded? #{true}! +- embedded = true +== Embedded? #{embedded}! +.render= render :inline => "%em= 'wow!'", :type => :haml += "stuff followed by whitespace" + +- if true + + %strong block with whitespace +%p + \Escape + \- character + \%p foo + \yee\ha +/ Short comment +/ This is a really long comment look how long it is it should be on a line of its own don't you think? +/ + This is a block comment + cool, huh? + %strong there can even be sub-tags! + = "Or script!" +-# Haml comment +-# + Nested Haml comment + - raise 'dead' +%p{ :class => "" } class attribute shouldn't appear! +/[if lte IE6] conditional comment! +/[if gte IE7] + %p Block conditional comment + %div + %h1 Cool, eh? +/[if gte IE5.2] + Woah a period. += "test" | + "test" | +-# Hard tabs shouldn't throw errors. + +- case :foo +- when :bar + %br Blah +- when :foo + %br +- case :foo + - when :bar + %meta{ :foo => 'blah'} + - when :foo + %meta{ :foo => 'bar'} +%img +%hr +%link +%script Inline content +%br + Nested content +%p.foo{:class => true ? 'bar' : 'baz'}[@article] Blah +%p.foo{:class => false ? 'bar' : ''}[@article] Blah +%p.qux{:class => 'quux'}[@article] Blump +== #{"Woah inner quotes"} +%p.dynamic_quote{:quotes => "single '", :dyn => 1 + 2} +%p.dynamic_atomic{:dyn => 1 + 2}/ diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/list.haml b/vendor/gems/haml-1.7.2/test/haml/templates/list.haml new file mode 100644 index 0000000..52605b1 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/list.haml @@ -0,0 +1,12 @@ +! Not a Doctype ! +%ul + %li a + %li b + %li c + %li d + %li e + %li f + %li g + %li h + %li i + diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/original_engine.haml b/vendor/gems/haml-1.7.2/test/haml/templates/original_engine.haml new file mode 100644 index 0000000..df31a5a --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/original_engine.haml @@ -0,0 +1,17 @@ +!!! +%html + %head + %title Stop. haml time + #content + %h1 This is a title! + %p Lorem ipsum dolor sit amet, consectetur adipisicing elit + %p{:class => 'foo'} Cigarettes! + %h2 Man alive! + %ul.things + %li Slippers + %li Shoes + %li Bathrobe + %li Coffee + %pre + This is some text that's in a pre block! + Let's see what happens when it's rendered! What about now, since we're on a new line? diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/partialize.haml b/vendor/gems/haml-1.7.2/test/haml/templates/partialize.haml new file mode 100644 index 0000000..327d90d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/partialize.haml @@ -0,0 +1 @@ += render :file => "#{name}.haml" diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/partials.haml b/vendor/gems/haml-1.7.2/test/haml/templates/partials.haml new file mode 100644 index 0000000..3fab791 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/partials.haml @@ -0,0 +1,12 @@ +%p + @foo = + = @foo +- @foo = 'value two' +%p + @foo = + = @foo += render :file => "_partial.haml" +%p + @foo = + = @foo +- @foo = 'value one' diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/silent_script.haml b/vendor/gems/haml-1.7.2/test/haml/templates/silent_script.haml new file mode 100644 index 0000000..45199f0 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/silent_script.haml @@ -0,0 +1,40 @@ +%div + %h1 I can count! + - (1..20).each do |i| + = i + %h1 I know my ABCs! + %ul + - ('a'..'z').each do |i| + %li= i + %h1 I can catch errors! + - begin + - String.silly + - rescue NameError => e + = "Oh no! \"#{e}\" happened!" + %p + "false" is: + - if false + = "true" + - else + = "false" + - if true + - 5.times do |i| + - if i % 2 == 1 + Odd! + - else + Even! + - else + = "This can't happen!" +- 13 | +.foo + %strong foobar +- 5.times | + do | + |a| | + %strong= a +.test + - "foo | + bar | + baz" | + + %p boom diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/standard.haml b/vendor/gems/haml-1.7.2/test/haml/templates/standard.haml new file mode 100644 index 0000000..945b814 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/standard.haml @@ -0,0 +1,43 @@ +!!! +%html{html_attrs} + %head + %title Hampton Catlin Is Totally Awesome + %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"} + %body + / You're In my house now! + - concat("foo\n") + .header + Yes, ladies and gentileman. He is just that egotistical. + Fantastic! This should be multi-line output + The question is if this would translate! Ahah! + = 1 + 9 + 8 + 2 #numbers should work and this should be ignored + #body= " Quotes should be loved! Just like people!" + - 120.times do |number| + - number + Wow.| + %p + = "Holy cow " + | + "multiline " + | + "tags! " + | + "A pipe (|) even!" | + = [1, 2, 3].collect { |n| "PipesIgnored|" } + = [1, 2, 3].collect { |n| | + n.to_s | + }.join("|") | + %div.silent + - foo = String.new + - foo << "this" + - foo << " shouldn't" + - foo << " evaluate" + = foo + " but now it should!" + -# Woah crap a comment! + + -# That was a line that shouldn't close everything. + %ul.really.cool + - ('a'..'f').each do |a| + %li= a + #combo.of_divs_with_underscore= @should_eval = "with this text" + = [ 104, 101, 108, 108, 111 ].map do |byte| + - byte.chr + .footer + %strong.shout= "This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid. \nSo, I'm just making it *really* long. God, I hope this works" diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/tag_parsing.haml b/vendor/gems/haml-1.7.2/test/haml/templates/tag_parsing.haml new file mode 100644 index 0000000..728a738 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/tag_parsing.haml @@ -0,0 +1,24 @@ +%div.tags + %foo 1 + %FOO 2 + %fooBAR 3 + %fooBar 4 + %foo_bar 5 + %foo-bar 6 + %foo:bar 7 + %foo.bar 8 + %fooBAr_baz:boom_bar 9 + %foo13 10 + %foo2u 11 +%div.classes + %p.foo.bar#baz#boom + .fooBar a + .foo-bar b + .foo_bar c + .FOOBAR d + .foo16 e + .123 f + .foo2u g +%div.broken + %foo<{ :a => :b } + .foo>{ :c => :d } diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/very_basic.haml b/vendor/gems/haml-1.7.2/test/haml/templates/very_basic.haml new file mode 100644 index 0000000..93396b9 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/very_basic.haml @@ -0,0 +1,4 @@ +!!! +%html + %head + %body diff --git a/vendor/gems/haml-1.7.2/test/haml/templates/whitespace_handling.haml b/vendor/gems/haml-1.7.2/test/haml/templates/whitespace_handling.haml new file mode 100644 index 0000000..da4b3f5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/haml/templates/whitespace_handling.haml @@ -0,0 +1,87 @@ +#whitespace_test + = render :file => "_text_area.haml", :locals => { :value => "Oneline" } + = render :file => "_text_area.haml", :locals => { :value => "Two\nlines" } + ~ render :file => "_text_area.haml", :locals => { :value => "Oneline" } + ~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" } + #flattened~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" } +.hithere + ~ "Foo bar" + ~ "
      foo bar
      " + ~ "
      foo\nbar
      " + %p~ "
      foo\nbar
      " + %p~ "foo\nbar" +.foo + ~ 13 + ~ ['a', 'b', 'c'].map do |a| + - "" +#whitespace_test + = render :file => "_text_area.haml", :locals => { :value => "Oneline" } + = render :file => "_text_area.haml", :locals => { :value => "Two\nlines" } + = find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Oneline" }) + = find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" }) + #flattened= find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" }) +.hithere + = find_and_preserve("Foo bar") + = find_and_preserve("
      foo bar
      ") + = find_and_preserve("
      foo\nbar
      ") + %p= find_and_preserve("
      foo\nbar
      ") + %p= find_and_preserve("foo\nbar") + %pre + :preserve + ___ + ,o88888 + ,o8888888' + ,:o:o:oooo. ,8O88Pd8888" + ,.::.::o:ooooOoOoO. ,oO8O8Pd888'" + ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O" + , ..:.::o:ooOoOOOO8OOOOo.FdO8O8" + , ..:.::o:ooOoOO8O888O8O,COCOO" + , . ..:.::o:ooOoOOOO8OOOOCOCO" + . ..:.::o:ooOoOoOO8O8OCCCC"o + . ..:.::o:ooooOoCoCCC"o:o + . ..:.::o:o:,cooooCo"oo:o: + ` . . ..:.:cocoooo"'o:o:::' + .` . ..::ccccoc"'o:o:o:::' + :.:. ,c:cccc"':.:.:.:.:.' + ..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/ + ...:.'.:.::::"' . . . . .' + .. . ....:."' ` . . . '' + . . . ...."' + .. . ."' -hrr- + . + + + It's a planet! + %strong This shouldn't be bold! + %strong This should! + %textarea + :preserve + ___ ___ ___ ___ + /\__\ /\ \ /\__\ /\__\ + /:/ / /::\ \ /::| | /:/ / + /:/__/ /:/\:\ \ /:|:| | /:/ / + /::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ / + /:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/ + \/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \ + \::/ / \::/ / /:/ / \:\ \ + /:/ / /:/ / /:/ / \:\ \ + /:/ / /:/ / /:/ / \:\__\ + \/__/ \/__/ \/__/ \/__/ + + Many + thanks + to + http://www.network-science.de/ascii/ + %strong indeed! +.foo + = find_and_preserve(13) +%pre + :preserve + __ ______ __ ______ + .----.| |--.|__ |.----.| |--..--------.| __ | + | __|| ||__ || __|| < | || __ | + |____||__|__||______||____||__|__||__|__|__||______| +%pre + :preserve + foo + bar diff --git a/vendor/gems/haml-1.7.2/test/profile.rb b/vendor/gems/haml-1.7.2/test/profile.rb new file mode 100644 index 0000000..62969e9 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/profile.rb @@ -0,0 +1,65 @@ +require 'rubygems' +require 'active_support' +require 'action_controller' +require 'action_view' + +require File.dirname(__FILE__) + '/../lib/haml' +require 'haml/template' +require 'profiler' +require 'stringio' + +module Haml + # Used by both Haml::Profiler and Sass::Profiler. + # Encapsulates profiling behavior. + module AbstractProfiler + def self.profile(times, &block) + # Runs the profiler, collects information + Profiler__::start_profile + times.times &block + Profiler__::stop_profile + + # Outputs information to a StringIO, returns result + io = StringIO.new + Profiler__::print_profile(io) + io.pos = 0 + result = io.read + io.close + result + end + end + + # A profiler for Haml, mostly for development use. This simply implements + # the Ruby profiler for profiling haml code. + class Profiler + + # Creates a new profiler that looks for templates in the base + # directory. + def initialize(base = File.join(File.dirname(__FILE__), 'haml', 'templates')) + ActionView::Base.register_template_handler("haml", Haml::Template) + unless base.class == ActionView::Base + @base = ActionView::Base.new(base) + else + @base = base + end + end + + # Profiles haml on the given template with the given number of runs. + # The template name shouldn't have a file extension; this will + # automatically look for a haml template. + # + # Returns the results of the profiling as a string. + def profile(runs = 100, template_name = 'standard') + AbstractProfiler.profile(runs) { @base.render template_name } + end + end +end + +module Sass + class Profiler + def profile(runs = 100, template_name = 'complex') + Haml::AbstractProfiler.profile(runs) do + Sass::Engine.new("#{File.dirname(__FILE__)}/sass/templates/#{template_name}.sass").render + end + end + end +end diff --git a/vendor/gems/haml-1.7.2/test/sass/engine_test.rb b/vendor/gems/haml-1.7.2/test/sass/engine_test.rb new file mode 100644 index 0000000..74d3ceb --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/engine_test.rb @@ -0,0 +1,116 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require File.dirname(__FILE__) + '/../../lib/sass' +require 'sass/engine' + +class SassEngineTest < Test::Unit::TestCase + EXCEPTION_MAP = { + "!a = 1 + " => 'Constant arithmetic error: "1 +"', + "!a = 1 + 2 +" => 'Constant arithmetic error: "1 + 2 +"', + "!a = \"b" => 'Unterminated string: "\\"b"', + "!a = #aaa - a" => 'Undefined operation: "#aaaaaa minus a"', + "!a = #aaa / a" => 'Undefined operation: "#aaaaaa div a"', + "!a = #aaa * a" => 'Undefined operation: "#aaaaaa times a"', + "!a = #aaa % a" => 'Undefined operation: "#aaaaaa mod a"', + "!a = 1 - a" => 'Undefined operation: "1 minus a"', + "!a = 1 * a" => 'Undefined operation: "1 times a"', + "!a = 1 / a" => 'Undefined operation: "1 div a"', + "!a = 1 % a" => 'Undefined operation: "1 mod a"', + ":" => 'Invalid attribute: ":"', + ": a" => 'Invalid attribute: ": a"', + ":= a" => 'Invalid attribute: ":= a"', + "a\n :b" => 'Invalid attribute: ":b "', + "a\n :b: c" => 'Invalid attribute: ":b: c"', + "a\n :b:c d" => 'Invalid attribute: ":b:c d"', + "a\n :b=c d" => 'Invalid attribute: ":b=c d"', + "a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!)', + "a\n b : c" => 'Invalid attribute: "b : c"', + "a\n b=c: d" => 'Invalid attribute: "b=c: d"', + ":a" => 'Attributes aren\'t allowed at the root of a document.', + "!" => 'Invalid constant: "!"', + "!a" => 'Invalid constant: "!a"', + "! a" => 'Invalid constant: "! a"', + "!a b" => 'Invalid constant: "!a b"', + "a\n\t:b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", + "a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", + "a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", + "a\n :b c\n !d = 3" => "Constants may only be declared at the root of a document.", + "!a = 1b + 2c" => "Incompatible units: b and c", + "& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'", + "a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.", + "!a = b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath constants.", + "@import foo.sass" => "File to import not found or unreadable: foo.sass", + "@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.", + "foo\n @import templates/basic" => "Import directives may only be used at the root of a document.", + "@foo bar boom" => "Unknown compiler directive: \"@foo bar boom\"", + } + + def test_basic_render + renders_correctly "basic", { :style => :compact } + end + + def test_alternate_styles + renders_correctly "expanded", { :style => :expanded } + renders_correctly "compact", { :style => :compact } + renders_correctly "nested", { :style => :nested } + end + + def test_exceptions + EXCEPTION_MAP.each do |key, value| + begin + Sass::Engine.new(key).render + rescue Sass::SyntaxError => err + assert_equal(value, err.message) + assert(err.sass_line, "Line: #{key}") + assert_match(/\(sass\):[0-9]+/, err.backtrace[0], "Line: #{key}") + else + assert(false, "Exception not raised for\n#{key}") + end + end + end + + def test_exception_line + to_render = "rule\n :attr val\n// comment!\n\n :broken\n" + begin + Sass::Engine.new(to_render).render + rescue Sass::SyntaxError => err + assert_equal(5, err.sass_line) + else + assert(false, "Exception not raised for '#{to_render}'!") + end + end + + def test_imported_exception + [1, 2].each do |i| + i = nil if i == 1 + begin + Sass::Engine.new("@import bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render + rescue Sass::SyntaxError => err + assert_equal(2, err.sass_line) + assert_match(/bork#{i}\.sass$/, err.sass_filename) + else + assert(false, "Exception not raised for imported template: bork#{i}") + end + end + end + + def test_empty_first_line + assert_equal("#a {\n b: c; }\n", Sass::Engine.new("#a\n\n b: c").render) + end + + private + + def renders_correctly(name, options={}) + sass_file = load_file(name, "sass") + css_file = load_file(name, "css") + css_result = Sass::Engine.new(sass_file, options).render + assert_equal css_file, css_result + end + + def load_file(name, type = "sass") + @result = '' + File.new(File.dirname(__FILE__) + "/#{type == 'sass' ? 'templates' : 'results'}/#{name}.#{type}").each_line { |l| @result += l } + @result + end +end diff --git a/vendor/gems/haml-1.7.2/test/sass/plugin_test.rb b/vendor/gems/haml-1.7.2/test/sass/plugin_test.rb new file mode 100644 index 0000000..0239ead --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/plugin_test.rb @@ -0,0 +1,136 @@ +#!/usr/bin/env ruby + +MERB_ENV = RAILS_ENV = 'testing' +RAILS_ROOT = '.' + +require 'test/unit' +require 'fileutils' +require File.dirname(__FILE__) + '/../../lib/sass' +require 'rubygems' + +require 'action_controller' +require 'sass/plugin' + +class SassPluginTest < Test::Unit::TestCase + @@templates = %w{ + complex constants parent_ref import alt + subdir/subdir subdir/nested_subdir/nested_subdir + } + + def setup + FileUtils.mkdir File.dirname(__FILE__) + '/tmp' + set_plugin_opts + Sass::Plugin.update_stylesheets + end + + def teardown + FileUtils.rm_r File.dirname(__FILE__) + '/tmp' + end + + def test_templates_should_render_correctly + @@templates.each { |name| assert_renders_correctly(name) } + end + + def test_no_update + File.delete(tempfile_loc('basic')) + assert Sass::Plugin.stylesheet_needs_update?('basic') + Sass::Plugin.update_stylesheets + assert !Sass::Plugin.stylesheet_needs_update?('basic') + end + + def test_full_exception_handling + File.delete(tempfile_loc('bork')) + Sass::Plugin.update_stylesheets + File.open(tempfile_loc('bork')) do |file| + assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\"\non line 2 of #{File.dirname(__FILE__) + '/templates/bork.sass'}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n")) + end + File.delete(tempfile_loc('bork')) + end + + def test_nonfull_exception_handling + Sass::Plugin.options[:full_exception] = false + + File.delete(tempfile_loc('bork')) + Sass::Plugin.update_stylesheets + assert_equal("/* Internal stylesheet error */", File.read(tempfile_loc('bork'))) + File.delete(tempfile_loc('bork')) + + Sass::Plugin.options[:full_exception] = true + end + + def test_rails_update + File.delete(tempfile_loc('basic')) + assert Sass::Plugin.stylesheet_needs_update?('basic') + + ActionController::Base.new.process + + assert !Sass::Plugin.stylesheet_needs_update?('basic') + end + + def test_merb_update + begin + require 'merb' + rescue LoadError + puts "\nmerb couldn't be loaded, skipping a test" + return + end + + require 'sass/plugin/merb' + MerbHandler.send(:define_method, :process_without_sass) { |*args| } + set_plugin_opts + + File.delete(tempfile_loc('basic')) + assert Sass::Plugin.stylesheet_needs_update?('basic') + + MerbHandler.new('.').process nil, nil + + assert !Sass::Plugin.stylesheet_needs_update?('basic') + end + + + private + + def assert_renders_correctly(name) + File.read(result_loc(name)).split("\n").zip(File.read(tempfile_loc(name)).split("\n")).each_with_index do |pair, line| + message = "template: #{name}\nline: #{line + 1}" + assert_equal(pair.first, pair.last, message) + end + end + + def tempfile_loc(name) + File.dirname(__FILE__) + "/tmp/#{name}.css" + end + + def result_loc(name) + File.dirname(__FILE__) + "/results/#{name}.css" + end + + def set_plugin_opts + Sass::Plugin.options = { + :template_location => File.dirname(__FILE__) + '/templates', + :css_location => File.dirname(__FILE__) + '/tmp', + :style => :compact, + :load_paths => [File.dirname(__FILE__) + '/results'], + :always_update => true, + } + end +end + +module Sass::Plugin + class << self + public :stylesheet_needs_update? + end +end + +class Sass::Engine + alias_method :old_render, :render + + def render + raise "bork bork bork!" if @template[0] == "{bork now!}" + old_render + end +end + +class ActionController::Base + def sass_old_process(*args); end +end diff --git a/vendor/gems/haml-1.7.2/test/sass/results/alt.css b/vendor/gems/haml-1.7.2/test/sass/results/alt.css new file mode 100644 index 0000000..8484343 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/alt.css @@ -0,0 +1,4 @@ +h1 { float: left; width: 274px; height: 75px; margin: 0; background-repeat: no-repeat; background-image: none; } +h1 a:hover, h1 a:visited { color: green; } +h1 b:hover { color: red; background-color: green; } +h1 const { nosp: 3; sp: 3; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/basic.css b/vendor/gems/haml-1.7.2/test/sass/results/basic.css new file mode 100644 index 0000000..b0d1182 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/basic.css @@ -0,0 +1,9 @@ +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/compact.css b/vendor/gems/haml-1.7.2/test/sass/results/compact.css new file mode 100644 index 0000000..bd6bc91 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/compact.css @@ -0,0 +1,5 @@ +#main { width: 15em; color: #0000ff; } +#main p { border-style: dotted; border-width: 2px; } +#main .cool { width: 100px; } + +#left { font-size: 2em; font-weight: bold; float: left; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/complex.css b/vendor/gems/haml-1.7.2/test/sass/results/complex.css new file mode 100644 index 0000000..6b3123b --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/complex.css @@ -0,0 +1,87 @@ +body { margin: 0; font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif; color: #fff; background: url(/images/global_bg.gif); } + +#page { width: 900px; margin: 0 auto; background: #440008; border-top-width: 5px; border-top-style: solid; border-top-color: #ff8500; } + +#header { height: 75px; padding: 0; } +#header h1 { float: left; width: 274px; height: 75px; margin: 0; background-image: url(/images/global_logo.gif); background-repeat: no-repeat; text-indent: -9999px; } +#header .status { float: right; padding-top: .5em; padding-left: .5em; padding-right: .5em; padding-bottom: 0; } +#header .status p { float: left; margin-top: 0; margin-right: 0.5em; margin-bottom: 0; margin-left: 0; } +#header .status ul { float: left; margin: 0; padding: 0; } +#header .status li { list-style-type: none; display: inline; margin: 0 5px; } +#header .status a:link, #header .status a:visited { color: #ff8500; text-decoration: none; } +#header .status a:hover { text-decoration: underline; } +#header .search { float: right; clear: right; margin: 12px 0 0 0; } +#header .search form { margin: 0; } +#header .search input { margin: 0 3px 0 0; padding: 2px; border: none; } + +#menu { clear: both; text-align: right; height: 20px; border-bottom: 5px solid #006b95; background: #00a4e4; } +#menu .contests ul { margin: 0 5px 0 0; padding: 0; } +#menu .contests ul li { list-style-type: none; margin: 0 5px; padding: 5px 5px 0 5px; display: inline; font-size: 1.1em; color: #fff; background: #00a4e4; } +#menu .contests ul li / This rule isn't a comment! { red: green; } +#menu .contests a:link, #menu .contests a:visited { color: #fff; text-decoration: none; font-weight: bold; } +#menu .contests a:hover { text-decoration: underline; } + +#content { clear: both; } +#content .container { clear: both; } +#content .container .column { float: left; } +#content .container .column .right { float: right; } +#content a:link, #content a:visited { color: #93d700; text-decoration: none; } +#content a:hover { text-decoration: underline; } + +#content p, #content div { width: 40em; } +#content p li, #content p dt, #content p dd, #content div li, #content div dt, #content div dd { color: #ddffdd; background-color: #4792bb; } +#content .container.video .column.left { width: 200px; } +#content .container.video .column.left .box { margin-top: 10px; } +#content .container.video .column.left .box p { margin: 0 1em auto 1em; } +#content .container.video .column.left .box.participants img { float: left; margin: 0 1em auto 1em; border: 1px solid #6e000d; border-style: solid; } +#content .container.video .column.left .box.participants h2 { margin: 0 0 10px 0; padding: 0.5em; /* The background image is a gif! */ background: #6e000d url(/images/hdr_participant.gif) 2px 2px no-repeat; /* Okay check this out Multiline comments Wow dude I mean seriously, WOW */ text-indent: -9999px; border-top-width: 5px; border-top-style: solid; border-top-color: #a20013; border-right-width: 1px; border-right-style: dotted; } +#content .container.video .column.middle { width: 500px; } +#content .container.video .column.right { width: 200px; } +#content .container.video .column.right .box { margin-top: 0; } +#content .container.video .column.right .box p { margin: 0 1em auto 1em; } +#content .container.video .column p { margin-top: 0; } + +#content.contests .container.information .column.right .box { margin: 1em 0; } +#content.contests .container.information .column.right .box.videos .thumbnail img { width: 200px; height: 150px; margin-bottom: 5px; } +#content.contests .container.information .column.right .box.videos a:link, #content.contests .container.information .column.right .box.videos a:visited { color: #93d700; text-decoration: none; } +#content.contests .container.information .column.right .box.videos a:hover { text-decoration: underline; } +#content.contests .container.information .column.right .box.votes a { display: block; width: 200px; height: 60px; margin: 15px 0; background: url(/images/btn_votenow.gif) no-repeat; text-indent: -9999px; outline: none; border: none; } +#content.contests .container.information .column.right .box.votes h2 { margin: 52px 0 10px 0; padding: 0.5em; background: #6e000d url(/images/hdr_videostats.gif) 2px 2px no-repeat; text-indent: -9999px; border-top: 5px solid #a20013; } + +#content.contests .container.video .box.videos h2 { margin: 0; padding: 0.5em; background: #6e000d url(/images/hdr_newestclips.gif) 2px 2px no-repeat; text-indent: -9999px; border-top: 5px solid #a20013; } +#content.contests .container.video .box.videos table { width: 100; } +#content.contests .container.video .box.videos table td { padding: 1em; width: 25; vertical-align: top; } +#content.contests .container.video .box.videos table td p { margin: 0 0 5px 0; } +#content.contests .container.video .box.videos table td a:link, #content.contests .container.video .box.videos table td a:visited { color: #93d700; text-decoration: none; } +#content.contests .container.video .box.videos table td a:hover { text-decoration: underline; } +#content.contests .container.video .box.videos .thumbnail { float: left; } +#content.contests .container.video .box.videos .thumbnail img { width: 80px; height: 60px; margin: 0 10px 0 0; border: 1px solid #6e000d; } + +#content .container.comments .column { margin-top: 15px; } +#content .container.comments .column.left { width: 600px; } +#content .container.comments .column.left .box ol { margin: 0; padding: 0; } +#content .container.comments .column.left .box li { list-style-type: none; padding: 10px; margin: 0 0 1em 0; background: #6e000d; border-top: 5px solid #a20013; } +#content .container.comments .column.left .box li div { margin-bottom: 1em; } +#content .container.comments .column.left .box li ul { text-align: right; } +#content .container.comments .column.left .box li ul li { display: inline; border: none; padding: 0; } +#content .container.comments .column.right { width: 290px; padding-left: 10px; } +#content .container.comments .column.right h2 { margin: 0; padding: 0.5em; background: #6e000d url(/images/hdr_addcomment.gif) 2px 2px no-repeat; text-indent: -9999px; border-top: 5px solid #a20013; } +#content .container.comments .column.right .box textarea { width: 290px; height: 100px; border: none; } + +#footer { margin-top: 10px; padding: 1.2em 1.5em; background: #ff8500; } +#footer ul { margin: 0; padding: 0; list-style-type: none; } +#footer ul li { display: inline; margin: 0 0.5em; color: #440008; } +#footer ul.links { float: left; } +#footer ul.links a:link, #footer ul.links a:visited { color: #440008; text-decoration: none; } +#footer ul.links a:hover { text-decoration: underline; } +#footer ul.copyright { float: right; } + +.clear { clear: both; } + +.centered { text-align: center; } + +img { border: none; } + +button.short { width: 60px; height: 22px; padding: 0 0 2px 0; color: #fff; border: none; background: url(/images/btn_short.gif) no-repeat; } + +table { border-collapse: collapse; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/constants.css b/vendor/gems/haml-1.7.2/test/sass/results/constants.css new file mode 100644 index 0000000..d95c676 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/constants.css @@ -0,0 +1,12 @@ +#main { content: Hello!; qstr: Quo"ted"!; hstr: Hyph-en!; width: 30em; background-color: #000; color: #ffffaa; short-color: #112233; named-color: #808000; con: foo bar 9 hi there boom; con2: noquo quo; } +#main #sidebar { background-color: #00ff98; num-normal: 10; num-dec: 10.2; num-dec0: 99; num-neg: -10; esc: 10+12; many: 6; order: 7; complex: #4c9db1hi16; } + +#plus { num-num: 7; num-num-un: 25em; num-num-un2: 23em; num-num-neg: 9.87; num-str: 100px; num-col: #b7b7b7; num-perc: 31%; str-str: hi there; str-str2: hi there; str-col: 14em solid #112233; str-num: times: 13; col-num: #ff7b9d; col-col: #5173ff; } + +#minus { num-num: 900; col-num: #f9f9f4; col-col: #000035; unary-num: -1; unary-const: 10; unary-paren: -11; } + +#times { num-num: 7; num-col: #7496b8; col-num: #092345; col-col: #243648; } + +#div { num-num: 3.33333333333333; num-num2: 3; col-num: #092345; col-col: #0b0d0f; } + +#mod { num-num: 2; col-col: #0f0e05; col-num: #020001; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/expanded.css b/vendor/gems/haml-1.7.2/test/sass/results/expanded.css new file mode 100644 index 0000000..005586e --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/expanded.css @@ -0,0 +1,18 @@ +#main { + width: 15em; + color: #0000ff; +} +#main p { + border-style: dotted; + border-width: 2px; +} +#main .cool { + width: 100px; +} + +#left { + font-size: 2em; + font-weight: bold; + + float: left; +} diff --git a/vendor/gems/haml-1.7.2/test/sass/results/import.css b/vendor/gems/haml-1.7.2/test/sass/results/import.css new file mode 100644 index 0000000..1f5ebbc --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/import.css @@ -0,0 +1,27 @@ +imported { otherconst: hello; myconst: goodbye; } + +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } + +midrule { inthe: middle; } + +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } + +@import url(basic.css); +@import url(../results/complex.css); +nonimported { myconst: hello; otherconst: goodbye; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/nested.css b/vendor/gems/haml-1.7.2/test/sass/results/nested.css new file mode 100644 index 0000000..7f6ad82 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/nested.css @@ -0,0 +1,21 @@ +#main { + width: 15em; + color: #0000ff; } + #main p { + border-style: dotted; + border-width: 2px; } + #main .cool { + width: 100px; } + +#left { + font-size: 2em; + font-weight: bold; + + float: left; } + +#right .header { + border-style: solid; } +#right .body { + border-style: dotted; } +#right .footer { + border-style: dashed; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/parent_ref.css b/vendor/gems/haml-1.7.2/test/sass/results/parent_ref.css new file mode 100644 index 0000000..c502a23 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/parent_ref.css @@ -0,0 +1,13 @@ +a { color: #000; } +a:hover { color: #f00; } + +p, div { width: 100em; } +p foo, div foo { width: 10em; } +p:hover, p bar, div:hover, div bar { height: 20em; } + +#cool { border-style: solid; border-width: 2em; } +.ie7 #cool, .ie6 #cool { content: string(Totally not cool.); } +.firefox #cool { content: string(Quite cool.); } + +.wow, .snazzy { font-family: fantasy; } +.wow:hover, .wow:visited, .snazzy:hover, .snazzy:visited { font-weight: bold; } diff --git a/vendor/gems/haml-1.7.2/test/sass/results/subdir/nested_subdir/nested_subdir.css b/vendor/gems/haml-1.7.2/test/sass/results/subdir/nested_subdir/nested_subdir.css new file mode 100644 index 0000000..7aadcfe --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/subdir/nested_subdir/nested_subdir.css @@ -0,0 +1 @@ +#pi { width: 314px; } \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/sass/results/subdir/subdir.css b/vendor/gems/haml-1.7.2/test/sass/results/subdir/subdir.css new file mode 100644 index 0000000..25c5c19 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/results/subdir/subdir.css @@ -0,0 +1 @@ +#subdir { font-size: 20px; font-weight: bold; } \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/alt.sass b/vendor/gems/haml-1.7.2/test/sass/templates/alt.sass new file mode 100644 index 0000000..f805e18 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/alt.sass @@ -0,0 +1,16 @@ +h1 + :float left + :width 274px + height: 75px + margin: 0 + background: + repeat: no-repeat + :image none + a:hover, a:visited + color: green + b:hover + color: red + :background-color green + const + nosp= 1 + 2 + sp = 1 + 2 diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/basic.sass b/vendor/gems/haml-1.7.2/test/sass/templates/basic.sass new file mode 100644 index 0000000..71117bf --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/basic.sass @@ -0,0 +1,23 @@ + + +body + :font Arial + :background blue + +#page + :width 700px + :height 100 + #header + :height 300px + h1 + :font-size 50px + :color blue + +#content.user.show + #container.top + #column.left + :width 100px + #column.right + :width 600px + #container.bottom + :background brown \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/bork.sass b/vendor/gems/haml-1.7.2/test/sass/templates/bork.sass new file mode 100644 index 0000000..b0d9abe --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/bork.sass @@ -0,0 +1,2 @@ +bork + :bork= !bork diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/bork2.sass b/vendor/gems/haml-1.7.2/test/sass/templates/bork2.sass new file mode 100644 index 0000000..462afb5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/bork2.sass @@ -0,0 +1,2 @@ +bork + :bork: bork; diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/compact.sass b/vendor/gems/haml-1.7.2/test/sass/templates/compact.sass new file mode 100644 index 0000000..675fea4 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/compact.sass @@ -0,0 +1,15 @@ +#main + :width 15em + :color #0000ff + p + :border + :style dotted + :width 2px + .cool + :width 100px + +#left + :font + :size 2em + :weight bold + :float left diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/complex.sass b/vendor/gems/haml-1.7.2/test/sass/templates/complex.sass new file mode 100644 index 0000000..6517815 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/complex.sass @@ -0,0 +1,309 @@ +body + :margin 0 + :font 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif + :color #fff + :background url(/images/global_bg.gif) + +#page + :width 900px + :margin 0 auto + :background #440008 + :border-top + :width 5px + :style solid + :color #ff8500 + +#header + :height 75px + :padding 0 + h1 + :float left + :width 274px + :height 75px + :margin 0 + :background + :image url(/images/global_logo.gif) + :repeat no-repeat + :text-indent -9999px + .status + :float right + :padding + :top .5em + :left .5em + :right .5em + :bottom 0 + p + :float left + :margin + :top 0 + :right 0.5em + :bottom 0 + :left 0 + ul + :float left + :margin 0 + :padding 0 + li + :list-style-type none + :display inline + :margin 0 5px + a:link, a:visited + :color #ff8500 + :text-decoration none + a:hover + :text-decoration underline + .search + :float right + :clear right + :margin 12px 0 0 0 + form + :margin 0 + input + :margin 0 3px 0 0 + :padding 2px + :border none + +#menu + :clear both + :text-align right + :height 20px + :border-bottom 5px solid #006b95 + :background #00a4e4 + .contests + ul + :margin 0 5px 0 0 + :padding 0 + li + :list-style-type none + :margin 0 5px + :padding 5px 5px 0 5px + :display inline +// This comment is in the middle of this rule + :font-size 1.1em + // This comment is properly indented + :color #fff + :background #00a4e4 + / This rule isn't a comment! + :red green + a:link, a:visited + :color #fff + :text-decoration none + :font-weight bold + a:hover + :text-decoration underline + +//General content information +#content + :clear both + .container + :clear both + .column + :float left + .left + .middle + .right + :float right + a:link, a:visited + :color #93d700 + :text-decoration none + a:hover + :text-decoration underline + +// A hard tab: + + +#content + p, div + :width 40em + li, dt, dd + :color #ddffdd + :background-color #4792bb + .container.video + .column.left + :width 200px + .box + :margin-top 10px + p + :margin 0 1em auto 1em + .box.participants + img + :float left + :margin 0 1em auto 1em + :border 1px solid #6e000d + :style solid + h2 + :margin 0 0 10px 0 + :padding 0.5em + /* The background image is a gif! + :background #6e000d url(/images/hdr_participant.gif) 2px 2px no-repeat + /* Okay check this out + Multiline comments + Wow dude + I mean seriously, WOW + :text-indent -9999px + // And also... + Multiline comments that don't output! + Snazzy, no? + :border + :top + :width 5px + :style solid + :color #a20013 + :right + :width 1px + :style dotted + .column.middle + :width 500px + .column.right + :width 200px + .box + :margin-top 0 + p + :margin 0 1em auto 1em + .column + p + :margin-top 0 + +#content.contests + .container.information + .column.right + .box + :margin 1em 0 + .box.videos + .thumbnail img + :width 200px + :height 150px + :margin-bottom 5px + a:link, a:visited + :color #93d700 + :text-decoration none + a:hover + :text-decoration underline + .box.votes + a + :display block + :width 200px + :height 60px + :margin 15px 0 + :background url(/images/btn_votenow.gif) no-repeat + :text-indent -9999px + :outline none + :border none + h2 + :margin 52px 0 10px 0 + :padding 0.5em + :background #6e000d url(/images/hdr_videostats.gif) 2px 2px no-repeat + :text-indent -9999px + :border-top 5px solid #a20013 + +#content.contests + .container.video + .box.videos + h2 + :margin 0 + :padding 0.5em + :background #6e000d url(/images/hdr_newestclips.gif) 2px 2px no-repeat + :text-indent -9999px + :border-top 5px solid #a20013 + table + :width 100 + td + :padding 1em + :width 25 + :vertical-align top + p + :margin 0 0 5px 0 + a:link, a:visited + :color #93d700 + :text-decoration none + a:hover + :text-decoration underline + .thumbnail + :float left + img + :width 80px + :height 60px + :margin 0 10px 0 0 + :border 1px solid #6e000d + +#content + .container.comments + .column + :margin-top 15px + .column.left + :width 600px + .box + ol + :margin 0 + :padding 0 + li + :list-style-type none + :padding 10px + :margin 0 0 1em 0 + :background #6e000d + :border-top 5px solid #a20013 + div + :margin-bottom 1em + ul + :text-align right + li + :display inline + :border none + :padding 0 + .column.right + :width 290px + :padding-left 10px + h2 + :margin 0 + :padding 0.5em + :background #6e000d url(/images/hdr_addcomment.gif) 2px 2px no-repeat + :text-indent -9999px + :border-top 5px solid #a20013 + .box + textarea + :width 290px + :height 100px + :border none + +#footer + :margin-top 10px + :padding 1.2em 1.5em + :background #ff8500 + ul + :margin 0 + :padding 0 + :list-style-type none + li + :display inline + :margin 0 0.5em + :color #440008 + ul.links + :float left + a:link, a:visited + :color #440008 + :text-decoration none + a:hover + :text-decoration underline + ul.copyright + :float right + + +.clear + :clear both + +.centered + :text-align center + +img + :border none + +button.short + :width 60px + :height 22px + :padding 0 0 2px 0 + :color #fff + :border none + :background url(/images/btn_short.gif) no-repeat + +table + :border-collapse collapse diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/constants.sass b/vendor/gems/haml-1.7.2/test/sass/templates/constants.sass new file mode 100644 index 0000000..6f2eda5 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/constants.sass @@ -0,0 +1,88 @@ +!width = 10em + 20 +!color = #00ff98 +!main_text = #ffa +!num = 10 +!dec = 10.2 +!dec_0 = 99.0 +!neg = -10 +!esc= 10\+12 +!str= "Hello!" +!qstr= "Quo\"ted\"!" +!hstr= "Hyph-en!" +!concat = (5 + 4) hi there +!percent= 11% + +#main + :content = !str + :qstr = !qstr + :hstr = !hstr + :width = !width + :background-color #000 + :color= !main_text + :short-color= #123 + :named-color= olive + :con= foo bar (!concat boom) + :con2= noquo "quo" + #sidebar + :background-color= !color + :num + :normal= !num + :dec= !dec + :dec0= !dec_0 + :neg= !neg + :esc= !esc + :many= 1 + 2 + 3 + :order= 1 + 2 * 3 + :complex= ((1 + 2) + 15)+#3a8b9f + (hi+(1 +1+ 2)* 4) + +#plus + :num + :num= 5+2 + :num-un= 10em + 15em + :num-un2= 10 + 13em + :num-neg= 10 + -.13 + :str= 100 + px + :col= 13 + #aaa + :perc = !percent + 20% + :str + :str= hi + \ there + :str2= hi + " there" + :col= "14em solid " + #123 + :num= times:\ + 13 + :col + :num= #f02 + 123.5 + :col= #12A + #405162 + +#minus + :num + :num= 912 - 12 + :col + :num= #fffffa - 5.2 + :col= #abcdef - #fedcba + :unary + :num= -1 + :const= -!neg + :paren= -(5 + 6) + +#times + :num + :num= 2 * 3.5 + :col= 2 * #3a4b5c + :col + :num= #12468a * 0.5 + :col= #121212 * #020304 + +#div + :num + :num= 10 / 3.0 + :num2= 10 / 3 + :col + :num= #12468a / 2 + :col= #abcdef / #0f0f0f + +#mod + :num + :num= 17 % 3 + :col + :col= #5f6e7d % #10200a + :num= #aaabac % 3 diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/expanded.sass b/vendor/gems/haml-1.7.2/test/sass/templates/expanded.sass new file mode 100644 index 0000000..675fea4 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/expanded.sass @@ -0,0 +1,15 @@ +#main + :width 15em + :color #0000ff + p + :border + :style dotted + :width 2px + .cool + :width 100px + +#left + :font + :size 2em + :weight bold + :float left diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/import.sass b/vendor/gems/haml-1.7.2/test/sass/templates/import.sass new file mode 100644 index 0000000..d286c1d --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/import.sass @@ -0,0 +1,8 @@ +!preconst = hello + +@import importee, basic, basic.css, ../results/complex.css + +nonimported + :myconst = !preconst + :otherconst = !postconst + diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/importee.sass b/vendor/gems/haml-1.7.2/test/sass/templates/importee.sass new file mode 100644 index 0000000..631aa25 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/importee.sass @@ -0,0 +1,10 @@ +!postconst = goodbye + +imported + :otherconst = !preconst + :myconst = !postconst + +@import basic + +midrule + :inthe middle \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/nested.sass b/vendor/gems/haml-1.7.2/test/sass/templates/nested.sass new file mode 100644 index 0000000..1adb4be --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/nested.sass @@ -0,0 +1,23 @@ +#main + :width 15em + :color #0000ff + p + :border + :style dotted + :width 2px + .cool + :width 100px + +#left + :font + :size 2em + :weight bold + :float left + +#right + .header + :border-style solid + .body + :border-style dotted + .footer + :border-style dashed diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/parent_ref.sass b/vendor/gems/haml-1.7.2/test/sass/templates/parent_ref.sass new file mode 100644 index 0000000..6b261d7 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/parent_ref.sass @@ -0,0 +1,25 @@ +a + :color #000 + &:hover + :color #f00 + +p, div + :width 100em + & foo + :width 10em + &:hover, bar + :height 20em + +#cool + :border + :style solid + :width 2em + .ie7 &, .ie6 & + :content string(Totally not cool.) + .firefox & + :content string(Quite cool.) + +.wow, .snazzy + :font-family fantasy + &:hover, &:visited + :font-weight bold diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/subdir/nested_subdir/nested_subdir.sass b/vendor/gems/haml-1.7.2/test/sass/templates/subdir/nested_subdir/nested_subdir.sass new file mode 100644 index 0000000..aae9eeb --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/subdir/nested_subdir/nested_subdir.sass @@ -0,0 +1,3 @@ +#pi + :width 314px + \ No newline at end of file diff --git a/vendor/gems/haml-1.7.2/test/sass/templates/subdir/subdir.sass b/vendor/gems/haml-1.7.2/test/sass/templates/subdir/subdir.sass new file mode 100644 index 0000000..bbe9810 --- /dev/null +++ b/vendor/gems/haml-1.7.2/test/sass/templates/subdir/subdir.sass @@ -0,0 +1,6 @@ +#subdir + :font + :size 20px + :weight bold + + \ No newline at end of file