[Pkg-javascript-commits] [mustache.js] 01/31: Imported Upstream version 0.3.0
Martín Ferrari
tincho at debian.org
Sun Nov 13 22:20:12 UTC 2016
This is an automated email from the git hooks/post-receive script.
tincho pushed a commit to branch master
in repository mustache.js.
commit c39ac95d8751c95e5a4c900faa2c2dc1a2d1674f
Author: David Paleino <dapal at debian.org>
Date: Wed Nov 2 10:53:40 2011 +0100
Imported Upstream version 0.3.0
---
.gitignore | 5 +
CHANGES.md | 38 +++
LICENSE | 21 ++
README.md | 286 ++++++++++++++++++
Rakefile | 56 ++++
THANKS.md | 20 ++
examples/array_of_partials_implicit_partial.2.html | 1 +
examples/array_of_partials_implicit_partial.html | 4 +
examples/array_of_partials_implicit_partial.js | 3 +
examples/array_of_partials_implicit_partial.txt | 5 +
examples/array_of_partials_partial.2.html | 1 +
examples/array_of_partials_partial.html | 4 +
examples/array_of_partials_partial.js | 3 +
examples/array_of_partials_partial.txt | 5 +
examples/array_of_strings.html | 1 +
examples/array_of_strings.js | 1 +
examples/array_of_strings.txt | 1 +
examples/array_of_strings_options.html | 2 +
examples/array_of_strings_options.js | 1 +
examples/array_of_strings_options.txt | 1 +
examples/array_partial.2.html | 4 +
examples/array_partial.html | 1 +
examples/array_partial.js | 5 +
examples/array_partial.txt | 6 +
examples/bug_11_eating_whitespace.html | 1 +
examples/bug_11_eating_whitespace.js | 3 +
examples/bug_11_eating_whitespace.txt | 1 +
examples/comments.html | 1 +
examples/comments.js | 5 +
examples/comments.txt | 1 +
examples/complex.html | 16 +
examples/complex.js | 19 ++
examples/complex.txt | 6 +
examples/delimiters.html | 7 +
examples/delimiters.js | 6 +
examples/delimiters.txt | 5 +
examples/empty_partial.2.html | 1 +
examples/empty_partial.html | 2 +
examples/empty_partial.js | 3 +
examples/empty_partial.txt | 2 +
examples/empty_template.html | 1 +
examples/empty_template.js | 1 +
examples/empty_template.txt | 1 +
examples/error_not_found.html | 1 +
examples/error_not_found.js | 1 +
examples/error_not_found.txt | 1 +
examples/escaped.html | 2 +
examples/escaped.js | 6 +
examples/escaped.txt | 2 +
examples/higher_order_sections.html | 1 +
examples/higher_order_sections.js | 9 +
examples/higher_order_sections.txt | 1 +
examples/inverted_section.html | 2 +
examples/inverted_section.js | 3 +
examples/inverted_section.txt | 1 +
examples/null_string.html | 5 +
examples/null_string.js | 9 +
examples/null_string.txt | 5 +
examples/partial_recursion.2.html | 4 +
examples/partial_recursion.html | 4 +
examples/partial_recursion.js | 11 +
examples/partial_recursion.txt | 3 +
examples/recursion_with_same_names.html | 7 +
examples/recursion_with_same_names.js | 8 +
examples/recursion_with_same_names.txt | 6 +
examples/reuse_of_enumerables.html | 8 +
examples/reuse_of_enumerables.js | 6 +
examples/reuse_of_enumerables.txt | 8 +
examples/section_as_context.html | 9 +
examples/section_as_context.js | 7 +
examples/section_as_context.txt | 6 +
examples/simple.html | 5 +
examples/simple.js | 8 +
examples/simple.txt | 3 +
examples/template_partial.2.html | 1 +
examples/template_partial.html | 2 +
examples/template_partial.js | 8 +
examples/template_partial.txt | 2 +
examples/two_in_a_row.html | 1 +
examples/two_in_a_row.js | 4 +
examples/two_in_a_row.txt | 1 +
examples/unescaped.html | 1 +
examples/unescaped.js | 5 +
examples/unescaped.txt | 1 +
examples/unknown_pragma.html | 1 +
examples/unknown_pragma.js | 1 +
examples/unknown_pragma.txt | 1 +
examples/view_partial.2.html | 5 +
examples/view_partial.html | 3 +
examples/view_partial.js | 19 ++
examples/view_partial.txt | 6 +
examples/whitespace_partial.2.html | 5 +
examples/whitespace_partial.html | 3 +
examples/whitespace_partial.js | 19 ++
examples/whitespace_partial.txt | 6 +
mustache-commonjs/mustache.js.tpl.post | 7 +
mustache-commonjs/mustache.js.tpl.pre | 6 +
mustache-commonjs/package.json | 7 +
mustache-dojo/mustache.js.tpl.post | 5 +
mustache-dojo/mustache.js.tpl.pre | 9 +
mustache-jquery/jquery.mustache.js.tpl.post | 6 +
mustache-jquery/jquery.mustache.js.tpl.pre | 9 +
mustache-yui3/mustache.js.tpl.post | 4 +
mustache-yui3/mustache.js.tpl.pre | 1 +
mustache.js | 324 +++++++++++++++++++++
test/mustache_spec.rb | 156 ++++++++++
106 files changed, 1338 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a7ed15c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+runner.js
+jquery.mustache.js
+dojox
+yui3
+commonjs.mustache.js
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..60be170
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,38 @@
+# mustache.js Changes
+
+## 0.3.0 (21-07-2010)
+
+* Improved whitespace handling.
+* Make IMPLICIT ITERATORS a first class feature.
+* Fix Rhino compat.
+* CommonJS packaging is no longer a special case.
+* DRY Rakefile.
+* Allow whitespace around tag names.
+* Fix partial scope.
+* Fix Comments.
+* Added inverted sections.
+* Avoid double encoding of entities.
+* Use sections to dereference subcontexts.
+* Added higher order sections.
+
+
+## 0.2.3 (28-03-2010)
+
+* Better error message for missing partials.
+* Added more robust type detection.
+* Parse pragmas only once.
+* Throw exception when encountering an unknown pragma.
+* Ignore undefined partial contexts. Returns verbatim partials.
+* Added yui3 packaging.
+
+
+## 0.2.2 (11-02-2010)
+
+* ctemplate compat: Partials are indicated by >, not <.
+* Add support for {{%PRAGMA}} to enable features.
+* Made array of strings an option. Enable with `{{%JSTACHE-ENABLE-STRING-ARRAYS}}`.
+* mustache compat: Don't barf on unknown variables.
+* Add `rake dojo` target to create a dojo package.
+* Add streaming api.
+* Rename JSTACHE-ENABLE-STRING-ARRAYS to IMPLICIT-ITERATOR.
+* Add support for pragma options.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e9f38ab
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2009 Chris Wanstrath (Ruby)
+Copyright (c) 2010 Jan Lehnardt (JavaScript)
+
+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/README.md b/README.md
new file mode 100644
index 0000000..7434356
--- /dev/null
+++ b/README.md
@@ -0,0 +1,286 @@
+# mustache.js — Logic-less templates with JavaScript
+
+> What could be more logical awesome than no logic at all?
+
+For a list of implementations (other than JavaScript) and editor
+plugins, see <http://mustache.github.com/>.
+
+
+## Where to Use?
+
+You can use mustache.js rendering stuff in various scenarios. E.g. you can
+render templates in your browser, or rendering server-side stuff with
+[node.js][node.js], use it for rendering stuff in [CouchDB][couchdb]’s views.
+
+
+## Who Uses Mustache?
+
+An updated list is kept on the Github wiki. Add yourself, if you use
+mustache.js: <http://wiki.github.com/janl/mustache.js/beard-competition>
+
+
+## Usage
+
+A quick example how to use mustache.js:
+
+ var view = {
+ title: "Joe",
+ calc: function() {
+ return 2 + 4;
+ }
+ }
+
+ var template = "{{title}} spends {{calc}}";
+
+ var html = Mustache.to_html(template, view);
+
+`template` is a simple string with mustache tags and `view` is a JavaScript
+object containing the data and any code to render the template.
+
+
+## Template Tag Types
+
+There are several types of tags currently implemented in mustache.js.
+
+For a language-agnostic overview of Mustache’s template syntax, see the
+`mustache(5)` manpage or <http://mustache.github.com/mustache.5.html>.
+
+### Simple Tags
+
+Tags are always surrounded by mustaches like this `{{foobar}}`.
+
+ var view = {name: "Joe", say_hello: function(){ return "hello" }}
+
+ template = "{{say_hello}}, {{name}}"
+
+
+### Conditional Sections
+
+Conditional sections begin with `{{#condition}}` and end with
+`{{/condition}}`. When `condition` evaluates to true, the section is rendered,
+otherwise the hole block will output nothing at all. `condition` may be a
+function returning true/false or a simple boolean.
+
+ var view = {condition: function() {
+ // [...your code goes here...]
+ return true;
+ }}
+
+ {{#condition}}
+ I will be visible if condition is true
+ {{/condition}}
+
+
+### Enumerable Sections
+
+Enumerable Sections use the same syntax as condition sections do.
+`{{#shopping_items}}` and `{{/shopping_items}}`. Actually the view decides how
+mustache.js renders the section. If the view returns an array, it will
+iterator over the items. Use `{{.}}` to access the current item inside the
+enumeration section.
+
+ var view = {name: "Joe's shopping card",
+ items: ["bananas", "apples"]}
+
+ var template = "{{name}}: <ul> {{#items}}<li>{{.}}</li>{{/items}} </ul>"
+
+ Outputs:
+ Joe's shopping card: <ul><li>bananas</li><li>apples</li></ul>
+
+
+### Higher Order Sections
+
+If a section key returns a function, it will be called and passed both the
+unrendered block of text and a renderer convenience function.
+
+Given this JS:
+
+ "name": "Tater",
+ "bolder": function() {
+ return function(text, render) {
+ return "<b>" + render(text) + '</b>'
+ }
+ }
+
+And this template:
+
+ {{#bolder}}Hi {{name}}.{{/bolder}}
+
+We'll get this output:
+
+ <b>Hi Tater.</b>
+
+As you can see, we’re pre-processing the text in the block. This can be used
+to implement caching, filters (like syntax highlighting), etc.
+
+You can use `this.name` to access the attribute `name` from your view.
+
+### Dereferencing Section
+
+If you have a nested object structure in your view, it can sometimes be easier
+to use sections like this:
+
+ var objects = {
+ a_object: {
+ title: 'this is an object',
+ description: 'one of its attributes is a list',
+ a_list: [{label: 'listitem1'}, {label: 'listitem2'}]
+ }
+ };
+
+This is our template:
+
+ {{#a_object}}
+ <h1>{{title}}</h1>
+ <p>{{description}}</p>
+ <ul>
+ {{#a_list}}
+ <li>{{label}}</li>
+ {{/a_list}}
+ </ul>
+ {{/a_object}}
+
+Here is the result:
+
+ <h1>this is an object</h1>
+ <p>one of its attributes is a list</p>
+ <ul>
+ <li>listitem1</li>
+ <li>listitem2</li>
+ </ul>
+
+### Inverted Sections
+
+An inverted section opens with `{{^section}}` instead of `{{#section}}` and
+uses a boolean negative to evaluate. Empty arrays are considered falsy.
+
+View:
+
+ var inverted_section = {
+ "repo": []
+ }
+
+Template:
+
+ {{#repo}}<b>{{name}}</b>{{/repo}}
+ {{^repo}}No repos :({{/repo}}
+
+Result:
+
+ No repos :(
+
+
+### View Partials
+
+mustache.js supports a quite powerful but yet simple view partial mechanism.
+Use the following syntax for partials: `{{>partial_name}}`
+
+ var view = {
+ name: "Joe",
+ winnings: {
+ value: 1000,
+ taxed_value: function() {
+ return this.value - (this.value * 0.4);
+ }
+ }
+ };
+
+ var template = "Welcome, {{name}}! {{>winnings}}"
+ var partials = {
+ winnings: "You just won ${{value}} (which is ${{taxed_value}} after tax)"};
+
+ var output = Mustache.to_html(template, view, partials)
+
+ output will be:
+ Welcome, Joe! You just won $1000 (which is $600 after tax)
+
+You invoke a partial with `{{>winnings}}`. Invoking the partial `winnings`
+will tell mustache.js to look for a object in the context's property
+`winnings`. It will then use that object as the context for the template found
+in `partials` for `winnings`.
+
+
+## Escaping
+
+mustache.js does escape all values when using the standard double mustache
+syntax. Characters which will be escaped: `& \ " < >`. To disable escaping,
+simply use tripple mustaches like `{{{unescaped_variable}}}`.
+
+Example: Using `{{variable}}` inside a template for `5 > 2` will result in `5 > 2`, where as the usage of `{{{variable}}}` will result in `5 > 2`.
+
+
+## Streaming
+
+To stream template results out of mustache.js, you can pass an optional
+`send()` callback to the `to_html()` call:
+
+ Mustache.to_html(template, view, partials, function(line) {
+ print(line);
+ });
+
+
+## Pragmas
+
+Pragma tags let you alter the behaviour of mustache.js. They have the format
+of
+
+ {{%PRAGMANAME}}
+
+and they accept options:
+
+ {{%PRAGMANAME option=value}}
+
+
+### IMPLICIT-ITERATOR
+
+When using a block to iterate over an enumerable (Array), mustache.js expects
+an objects as enumerable items. The implicit iterator pragma enables optional
+behaviour of allowing literals as enumerable items. Consider this view:
+
+ var view = {
+ foo: [1, 2, 3, 4, 5, "french"]
+ };
+
+The following template can iterate over the member `foo`:
+
+ {{%IMPLICIT-ITERATOR}}
+ {{#foo}}
+ {{.}}
+ {{/foo}}
+
+If you don't like the dot in there, the pragma accepts an option to set your
+own iteration marker:
+
+ {{%IMPLICIT-ITERATOR iterator=bob}}
+ {{#foo}}
+ {{bob}}
+ {{/foo}}
+
+## FaQ
+
+### Why doesn’t Mustache allow dot notation like `{{variable.member}}`?
+
+The reason is given in the [mustache.rb
+bugtracker](http://github.com/defunkt/mustache/issues/issue/6).
+
+Mustache implementations strive to be template-compatible.
+
+
+## More Examples and Documentation
+
+See `examples/` for more goodies and read the [original mustache docs][m]
+
+## Command Line
+
+See `mustache(1)` man page or
+<http://defunkt.github.com/mustache/mustache.1.html>
+for command line docs.
+
+Or just install it as a RubyGem:
+
+ $ gem install mustache
+ $ mustache -h
+
+[m]: http://github.com/defunkt/mustache/#readme
+[node.js]: http://nodejs.org
+[couchdb]: http://couchdb.apache.org
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..4629c97
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,56 @@
+require 'rake'
+require 'spec/rake/spectask'
+
+task :default => :spec
+
+Spec::Rake::SpecTask.new(:spec) do |t|
+ #t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
+ t.spec_files = FileList['test/*_spec.rb']
+end
+
+desc "Run all specs"
+task :spec
+
+def templated_build(name, opts={})
+ # Create a rule that uses the .tmpl.{pre,post} stuff to make a final,
+ # wrapped, output file.
+ # There is some extra complexity because Dojo and YUI3 use different
+ # template files and final locations.
+ short = name.downcase
+ source = "mustache-#{short}"
+ dependencies = ["mustache.js"] + Dir.glob("#{source}/*.tpl.*")
+
+ desc "Package for #{name}"
+ task short.to_sym => dependencies do
+ target_js = opts[:location] ? "mustache.js" : "#{short}.mustache.js"
+
+ puts "Packaging for #{name}"
+ sh "mkdir -p #{opts[:location]}" if opts[:location]
+ sh "cat #{source}/#{target_js}.tpl.pre mustache.js \
+ #{source}/#{target_js}.tpl.post > #{opts[:location] || '.'}/#{target_js}"
+
+ # extra
+ if opts[:extra]
+ sh "sed -e 's/{{version}}/#{version}/' #{source}/#{opts[:extra]} \
+ > #{opts[:location]}/#{opts[:extra]}"
+ end
+
+ puts "Done, see #{opts[:location] || '.'}/#{target_js}"
+
+ end
+end
+
+templated_build "CommonJS", :location => "lib", :extra => "package.json"
+templated_build "jQuery"
+templated_build "Dojo", :location => "dojox/string"
+templated_build "YUI3", :location => "yui3/mustache"
+
+def version
+ File.read("mustache.js").match('version: "([^\"]+)",$')[1]
+end
+
+
+desc "Remove temporary files."
+task :clean do
+ sh "git clean -fdx"
+end
diff --git a/THANKS.md b/THANKS.md
new file mode 100644
index 0000000..6dac939
--- /dev/null
+++ b/THANKS.md
@@ -0,0 +1,20 @@
+# Thanks
+
+Mustache.js wouldn't kick ass if it weren't for these fine souls:
+
+ * Chris Wanstrath / defunkt
+ * Alexander Lang / langalex
+ * Sebastian Cohnen / tisba
+ * J Chris Anderson / jchris
+ * Tom Robinson / tlrobinson
+ * Aaron Quint / quirkey
+ * Douglas Crockford
+ * Nikita Vasilyev / NV
+ * Elise Wood / glytch
+ * Damien Mathieu / dmathieu
+ * Jakub Kuźma / qoobaa
+ * Will Leinweber / will
+ * dpree
+ * Jason Smith / jhs
+ * Aaron Gibralter / agibralter
+ * Ross Boucher / boucher
diff --git a/examples/array_of_partials_implicit_partial.2.html b/examples/array_of_partials_implicit_partial.2.html
new file mode 100644
index 0000000..12f7159
--- /dev/null
+++ b/examples/array_of_partials_implicit_partial.2.html
@@ -0,0 +1 @@
+{{.}}
diff --git a/examples/array_of_partials_implicit_partial.html b/examples/array_of_partials_implicit_partial.html
new file mode 100644
index 0000000..1af6d68
--- /dev/null
+++ b/examples/array_of_partials_implicit_partial.html
@@ -0,0 +1,4 @@
+Here is some stuff!
+{{#numbers}}
+{{>partial}}
+{{/numbers}}
diff --git a/examples/array_of_partials_implicit_partial.js b/examples/array_of_partials_implicit_partial.js
new file mode 100644
index 0000000..fcdf3b0
--- /dev/null
+++ b/examples/array_of_partials_implicit_partial.js
@@ -0,0 +1,3 @@
+var partial_context = {
+ numbers: ['1', '2', '3', '4']
+};
diff --git a/examples/array_of_partials_implicit_partial.txt b/examples/array_of_partials_implicit_partial.txt
new file mode 100644
index 0000000..f622375
--- /dev/null
+++ b/examples/array_of_partials_implicit_partial.txt
@@ -0,0 +1,5 @@
+Here is some stuff!
+1
+2
+3
+4
diff --git a/examples/array_of_partials_partial.2.html b/examples/array_of_partials_partial.2.html
new file mode 100644
index 0000000..bdde77d
--- /dev/null
+++ b/examples/array_of_partials_partial.2.html
@@ -0,0 +1 @@
+{{i}}
diff --git a/examples/array_of_partials_partial.html b/examples/array_of_partials_partial.html
new file mode 100644
index 0000000..1af6d68
--- /dev/null
+++ b/examples/array_of_partials_partial.html
@@ -0,0 +1,4 @@
+Here is some stuff!
+{{#numbers}}
+{{>partial}}
+{{/numbers}}
diff --git a/examples/array_of_partials_partial.js b/examples/array_of_partials_partial.js
new file mode 100644
index 0000000..45611cf
--- /dev/null
+++ b/examples/array_of_partials_partial.js
@@ -0,0 +1,3 @@
+var partial_context = {
+ numbers: [{i: '1'}, {i: '2'}, {i: '3'}, {i: '4'}]
+};
diff --git a/examples/array_of_partials_partial.txt b/examples/array_of_partials_partial.txt
new file mode 100644
index 0000000..f622375
--- /dev/null
+++ b/examples/array_of_partials_partial.txt
@@ -0,0 +1,5 @@
+Here is some stuff!
+1
+2
+3
+4
diff --git a/examples/array_of_strings.html b/examples/array_of_strings.html
new file mode 100644
index 0000000..2898705
--- /dev/null
+++ b/examples/array_of_strings.html
@@ -0,0 +1 @@
+{{#array_of_strings}}{{.}} {{/array_of_strings}}
\ No newline at end of file
diff --git a/examples/array_of_strings.js b/examples/array_of_strings.js
new file mode 100644
index 0000000..12c4992
--- /dev/null
+++ b/examples/array_of_strings.js
@@ -0,0 +1 @@
+var array_of_strings = {array_of_strings: ['hello', 'world']};
diff --git a/examples/array_of_strings.txt b/examples/array_of_strings.txt
new file mode 100644
index 0000000..4a1f475
--- /dev/null
+++ b/examples/array_of_strings.txt
@@ -0,0 +1 @@
+hello world
diff --git a/examples/array_of_strings_options.html b/examples/array_of_strings_options.html
new file mode 100644
index 0000000..6b28278
--- /dev/null
+++ b/examples/array_of_strings_options.html
@@ -0,0 +1,2 @@
+{{%IMPLICIT-ITERATOR iterator=rob}}
+{{#array_of_strings_options}}{{rob}} {{/array_of_strings_options}}
\ No newline at end of file
diff --git a/examples/array_of_strings_options.js b/examples/array_of_strings_options.js
new file mode 100644
index 0000000..2e29adf
--- /dev/null
+++ b/examples/array_of_strings_options.js
@@ -0,0 +1 @@
+var array_of_strings_options = {array_of_strings_options: ['hello', 'world']};
diff --git a/examples/array_of_strings_options.txt b/examples/array_of_strings_options.txt
new file mode 100644
index 0000000..4a1f475
--- /dev/null
+++ b/examples/array_of_strings_options.txt
@@ -0,0 +1 @@
+hello world
diff --git a/examples/array_partial.2.html b/examples/array_partial.2.html
new file mode 100644
index 0000000..235dd5f
--- /dev/null
+++ b/examples/array_partial.2.html
@@ -0,0 +1,4 @@
+Here's a non-sense array of values
+{{#array}}
+ {{.}}
+{{/array}}
\ No newline at end of file
diff --git a/examples/array_partial.html b/examples/array_partial.html
new file mode 100644
index 0000000..7a336fe
--- /dev/null
+++ b/examples/array_partial.html
@@ -0,0 +1 @@
+{{>partial}}
\ No newline at end of file
diff --git a/examples/array_partial.js b/examples/array_partial.js
new file mode 100644
index 0000000..88d7592
--- /dev/null
+++ b/examples/array_partial.js
@@ -0,0 +1,5 @@
+var partial_context = {
+ partial: {
+ array: ['1', '2', '3', '4']
+ }
+};
\ No newline at end of file
diff --git a/examples/array_partial.txt b/examples/array_partial.txt
new file mode 100644
index 0000000..fd5f48e
--- /dev/null
+++ b/examples/array_partial.txt
@@ -0,0 +1,6 @@
+Here's a non-sense array of values
+ 1
+ 2
+ 3
+ 4
+
diff --git a/examples/bug_11_eating_whitespace.html b/examples/bug_11_eating_whitespace.html
new file mode 100644
index 0000000..8d5cd92
--- /dev/null
+++ b/examples/bug_11_eating_whitespace.html
@@ -0,0 +1 @@
+{{tag}} foo
diff --git a/examples/bug_11_eating_whitespace.js b/examples/bug_11_eating_whitespace.js
new file mode 100644
index 0000000..78ce975
--- /dev/null
+++ b/examples/bug_11_eating_whitespace.js
@@ -0,0 +1,3 @@
+var bug_11_eating_whitespace = {
+ tag: "yo"
+};
diff --git a/examples/bug_11_eating_whitespace.txt b/examples/bug_11_eating_whitespace.txt
new file mode 100644
index 0000000..f5bbc85
--- /dev/null
+++ b/examples/bug_11_eating_whitespace.txt
@@ -0,0 +1 @@
+yo foo
diff --git a/examples/comments.html b/examples/comments.html
new file mode 100644
index 0000000..5036801
--- /dev/null
+++ b/examples/comments.html
@@ -0,0 +1 @@
+<h1>{{title}}{{! just something interesting... or not... }}</h1>
diff --git a/examples/comments.js b/examples/comments.js
new file mode 100644
index 0000000..f85f979
--- /dev/null
+++ b/examples/comments.js
@@ -0,0 +1,5 @@
+var comments = {
+ title: function() {
+ return "A Comedy of Errors";
+ }
+};
diff --git a/examples/comments.txt b/examples/comments.txt
new file mode 100644
index 0000000..0133517
--- /dev/null
+++ b/examples/comments.txt
@@ -0,0 +1 @@
+<h1>A Comedy of Errors</h1>
diff --git a/examples/complex.html b/examples/complex.html
new file mode 100644
index 0000000..23bec3c
--- /dev/null
+++ b/examples/complex.html
@@ -0,0 +1,16 @@
+<h1>{{header}}</h1>
+{{#list}}
+ <ul>
+ {{#item}}
+ {{#current}}
+ <li><strong>{{name}}</strong></li>
+ {{/current}}
+ {{#link}}
+ <li><a href="{{url}}">{{name}}</a></li>
+ {{/link}}
+ {{/item}}
+ </ul>
+{{/list}}
+{{#empty}}
+ <p>The list is empty.</p>
+{{/empty}}
\ No newline at end of file
diff --git a/examples/complex.js b/examples/complex.js
new file mode 100644
index 0000000..a0dfb63
--- /dev/null
+++ b/examples/complex.js
@@ -0,0 +1,19 @@
+var complex = {
+ header: function() {
+ return "Colors";
+ },
+ item: [
+ {name: "red", current: true, url: "#Red"},
+ {name: "green", current: false, url: "#Green"},
+ {name: "blue", current: false, url: "#Blue"}
+ ],
+ link: function() {
+ return this["current"] !== true;
+ },
+ list: function() {
+ return this.item.length !== 0;
+ },
+ empty: function() {
+ return this.item.length === 0;
+ }
+};
diff --git a/examples/complex.txt b/examples/complex.txt
new file mode 100644
index 0000000..b51ca10
--- /dev/null
+++ b/examples/complex.txt
@@ -0,0 +1,6 @@
+<h1>Colors</h1>
+ <ul>
+ <li><strong>red</strong></li>
+ <li><a href="#Green">green</a></li>
+ <li><a href="#Blue">blue</a></li>
+ </ul>
diff --git a/examples/delimiters.html b/examples/delimiters.html
new file mode 100644
index 0000000..a73e061
--- /dev/null
+++ b/examples/delimiters.html
@@ -0,0 +1,7 @@
+{{=<% %>=}}*
+<% first %>
+* <% second %>
+<%=| |=%>
+* | third |
+|={{ }}=|
+* {{ fourth }}
\ No newline at end of file
diff --git a/examples/delimiters.js b/examples/delimiters.js
new file mode 100644
index 0000000..220d0d2
--- /dev/null
+++ b/examples/delimiters.js
@@ -0,0 +1,6 @@
+var delimiters = {
+ first: "It worked the first time.",
+ second: "And it worked the second time.",
+ third: "Then, surprisingly, it worked the third time.",
+ fourth: "Fourth time also fine!."
+}
diff --git a/examples/delimiters.txt b/examples/delimiters.txt
new file mode 100644
index 0000000..698a6bb
--- /dev/null
+++ b/examples/delimiters.txt
@@ -0,0 +1,5 @@
+*
+It worked the first time.
+* And it worked the second time.
+* Then, surprisingly, it worked the third time.
+* Fourth time also fine!.
diff --git a/examples/empty_partial.2.html b/examples/empty_partial.2.html
new file mode 100644
index 0000000..b920295
--- /dev/null
+++ b/examples/empty_partial.2.html
@@ -0,0 +1 @@
+yo
\ No newline at end of file
diff --git a/examples/empty_partial.html b/examples/empty_partial.html
new file mode 100644
index 0000000..a710047
--- /dev/null
+++ b/examples/empty_partial.html
@@ -0,0 +1,2 @@
+hey {{foo}}
+{{>partial}}
diff --git a/examples/empty_partial.js b/examples/empty_partial.js
new file mode 100644
index 0000000..9cc53c6
--- /dev/null
+++ b/examples/empty_partial.js
@@ -0,0 +1,3 @@
+var partial_context = {
+ foo: 1
+};
diff --git a/examples/empty_partial.txt b/examples/empty_partial.txt
new file mode 100644
index 0000000..90d2b9f
--- /dev/null
+++ b/examples/empty_partial.txt
@@ -0,0 +1,2 @@
+hey 1
+yo
diff --git a/examples/empty_template.html b/examples/empty_template.html
new file mode 100644
index 0000000..bb2367a
--- /dev/null
+++ b/examples/empty_template.html
@@ -0,0 +1 @@
+<html><head></head><body><h1>Test</h1></body></html>
\ No newline at end of file
diff --git a/examples/empty_template.js b/examples/empty_template.js
new file mode 100644
index 0000000..564c9e2
--- /dev/null
+++ b/examples/empty_template.js
@@ -0,0 +1 @@
+var empty_template = {};
diff --git a/examples/empty_template.txt b/examples/empty_template.txt
new file mode 100644
index 0000000..60652b6
--- /dev/null
+++ b/examples/empty_template.txt
@@ -0,0 +1 @@
+<html><head></head><body><h1>Test</h1></body></html>
diff --git a/examples/error_not_found.html b/examples/error_not_found.html
new file mode 100644
index 0000000..24369f7
--- /dev/null
+++ b/examples/error_not_found.html
@@ -0,0 +1 @@
+{{foo}}
\ No newline at end of file
diff --git a/examples/error_not_found.js b/examples/error_not_found.js
new file mode 100644
index 0000000..6cdbdb3
--- /dev/null
+++ b/examples/error_not_found.js
@@ -0,0 +1 @@
+var error_not_found = {bar: 2};
\ No newline at end of file
diff --git a/examples/error_not_found.txt b/examples/error_not_found.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/examples/error_not_found.txt
@@ -0,0 +1 @@
+
diff --git a/examples/escaped.html b/examples/escaped.html
new file mode 100644
index 0000000..ea25951
--- /dev/null
+++ b/examples/escaped.html
@@ -0,0 +1,2 @@
+<h1>{{title}}</h1>
+But not {{entities}}.
diff --git a/examples/escaped.js b/examples/escaped.js
new file mode 100644
index 0000000..7a8baef
--- /dev/null
+++ b/examples/escaped.js
@@ -0,0 +1,6 @@
+var escaped = {
+ title: function() {
+ return "Bear > Shark";
+ },
+ entities: """
+};
diff --git a/examples/escaped.txt b/examples/escaped.txt
new file mode 100644
index 0000000..73ac5ce
--- /dev/null
+++ b/examples/escaped.txt
@@ -0,0 +1,2 @@
+<h1>Bear > Shark</h1>
+But not ".
diff --git a/examples/higher_order_sections.html b/examples/higher_order_sections.html
new file mode 100644
index 0000000..04f5318
--- /dev/null
+++ b/examples/higher_order_sections.html
@@ -0,0 +1 @@
+{{#bolder}}Hi {{name}}.{{/bolder}}
diff --git a/examples/higher_order_sections.js b/examples/higher_order_sections.js
new file mode 100644
index 0000000..c7e558e
--- /dev/null
+++ b/examples/higher_order_sections.js
@@ -0,0 +1,9 @@
+var higher_order_sections = {
+ "name": "Tater",
+ "helper": "To tinker?",
+ "bolder": function() {
+ return function(text, render) {
+ return "<b>" + render(text) + '</b> ' + this.helper;
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/higher_order_sections.txt b/examples/higher_order_sections.txt
new file mode 100644
index 0000000..9db786a
--- /dev/null
+++ b/examples/higher_order_sections.txt
@@ -0,0 +1 @@
+<b>Hi Tater.</b> To tinker?
diff --git a/examples/inverted_section.html b/examples/inverted_section.html
new file mode 100644
index 0000000..beec558
--- /dev/null
+++ b/examples/inverted_section.html
@@ -0,0 +1,2 @@
+{{#repo}}<b>{{name}}</b>{{/repo}}
+{{^repo}}No repos :({{/repo}}
diff --git a/examples/inverted_section.js b/examples/inverted_section.js
new file mode 100644
index 0000000..cb96ecf
--- /dev/null
+++ b/examples/inverted_section.js
@@ -0,0 +1,3 @@
+var inverted_section = {
+ "repo": []
+}
diff --git a/examples/inverted_section.txt b/examples/inverted_section.txt
new file mode 100644
index 0000000..5fd0de1
--- /dev/null
+++ b/examples/inverted_section.txt
@@ -0,0 +1 @@
+No repos :(
diff --git a/examples/null_string.html b/examples/null_string.html
new file mode 100644
index 0000000..12bcb08
--- /dev/null
+++ b/examples/null_string.html
@@ -0,0 +1,5 @@
+Hello {{name}}
+glytch {{glytch}}
+binary {{binary}}
+value {{value}}
+numeric {{numeric}}
\ No newline at end of file
diff --git a/examples/null_string.js b/examples/null_string.js
new file mode 100644
index 0000000..93414a1
--- /dev/null
+++ b/examples/null_string.js
@@ -0,0 +1,9 @@
+var null_string = {
+ name: "Elise",
+ glytch: true,
+ binary: false,
+ value: null,
+ numeric: function() {
+ return NaN;
+ }
+};
diff --git a/examples/null_string.txt b/examples/null_string.txt
new file mode 100644
index 0000000..827569b
--- /dev/null
+++ b/examples/null_string.txt
@@ -0,0 +1,5 @@
+Hello Elise
+glytch true
+binary false
+value
+numeric NaN
diff --git a/examples/partial_recursion.2.html b/examples/partial_recursion.2.html
new file mode 100644
index 0000000..457d2a0
--- /dev/null
+++ b/examples/partial_recursion.2.html
@@ -0,0 +1,4 @@
+{{name}}
+{{#children}}
+{{>partial}}
+{{/children}}
\ No newline at end of file
diff --git a/examples/partial_recursion.html b/examples/partial_recursion.html
new file mode 100644
index 0000000..d965a6a
--- /dev/null
+++ b/examples/partial_recursion.html
@@ -0,0 +1,4 @@
+{{name}}
+{{#kids}}
+{{>partial}}
+{{/kids}}
\ No newline at end of file
diff --git a/examples/partial_recursion.js b/examples/partial_recursion.js
new file mode 100644
index 0000000..ad1f2eb
--- /dev/null
+++ b/examples/partial_recursion.js
@@ -0,0 +1,11 @@
+var partial_context = {
+ name: '1',
+ kids: [
+ {
+ name: '1.1',
+ children: [
+ {name: '1.1.1'}
+ ]
+ }
+ ]
+};
diff --git a/examples/partial_recursion.txt b/examples/partial_recursion.txt
new file mode 100644
index 0000000..0f70515
--- /dev/null
+++ b/examples/partial_recursion.txt
@@ -0,0 +1,3 @@
+1
+1.1
+1.1.1
diff --git a/examples/recursion_with_same_names.html b/examples/recursion_with_same_names.html
new file mode 100644
index 0000000..c331d04
--- /dev/null
+++ b/examples/recursion_with_same_names.html
@@ -0,0 +1,7 @@
+{{ name }}
+{{ description }}
+
+{{#terms}}
+ {{name}}
+ {{index}}
+{{/terms}}
diff --git a/examples/recursion_with_same_names.js b/examples/recursion_with_same_names.js
new file mode 100644
index 0000000..5cceb08
--- /dev/null
+++ b/examples/recursion_with_same_names.js
@@ -0,0 +1,8 @@
+var recursion_with_same_names = {
+ name: 'name',
+ description: 'desc',
+ terms: [
+ {name: 't1', index: 0},
+ {name: 't2', index: 1},
+ ]
+};
\ No newline at end of file
diff --git a/examples/recursion_with_same_names.txt b/examples/recursion_with_same_names.txt
new file mode 100644
index 0000000..c23bb65
--- /dev/null
+++ b/examples/recursion_with_same_names.txt
@@ -0,0 +1,6 @@
+name
+desc
+ t1
+ 0
+ t2
+ 1
diff --git a/examples/reuse_of_enumerables.html b/examples/reuse_of_enumerables.html
new file mode 100644
index 0000000..cc0cb7a
--- /dev/null
+++ b/examples/reuse_of_enumerables.html
@@ -0,0 +1,8 @@
+{{#terms}}
+ {{name}}
+ {{index}}
+{{/terms}}
+{{#terms}}
+ {{name}}
+ {{index}}
+{{/terms}}
diff --git a/examples/reuse_of_enumerables.js b/examples/reuse_of_enumerables.js
new file mode 100644
index 0000000..543e121
--- /dev/null
+++ b/examples/reuse_of_enumerables.js
@@ -0,0 +1,6 @@
+var reuse_of_enumerables = {
+ terms: [
+ {name: 't1', index: 0},
+ {name: 't2', index: 1},
+ ]
+};
\ No newline at end of file
diff --git a/examples/reuse_of_enumerables.txt b/examples/reuse_of_enumerables.txt
new file mode 100644
index 0000000..6d05d96
--- /dev/null
+++ b/examples/reuse_of_enumerables.txt
@@ -0,0 +1,8 @@
+ t1
+ 0
+ t2
+ 1
+ t1
+ 0
+ t2
+ 1
diff --git a/examples/section_as_context.html b/examples/section_as_context.html
new file mode 100644
index 0000000..59990f6
--- /dev/null
+++ b/examples/section_as_context.html
@@ -0,0 +1,9 @@
+{{#a_object}}
+ <h1>{{title}}</h1>
+ <p>{{description}}</p>
+ <ul>
+ {{#a_list}}
+ <li>{{label}}</li>
+ {{/a_list}}
+ </ul>
+{{/a_object}}
diff --git a/examples/section_as_context.js b/examples/section_as_context.js
new file mode 100644
index 0000000..81ca1be
--- /dev/null
+++ b/examples/section_as_context.js
@@ -0,0 +1,7 @@
+var section_as_context = {
+ a_object: {
+ title: 'this is an object',
+ description: 'one of its attributes is a list',
+ a_list: [{label: 'listitem1'}, {label: 'listitem2'}]
+ }
+};
diff --git a/examples/section_as_context.txt b/examples/section_as_context.txt
new file mode 100644
index 0000000..53ee336
--- /dev/null
+++ b/examples/section_as_context.txt
@@ -0,0 +1,6 @@
+ <h1>this is an object</h1>
+ <p>one of its attributes is a list</p>
+ <ul>
+ <li>listitem1</li>
+ <li>listitem2</li>
+ </ul>
diff --git a/examples/simple.html b/examples/simple.html
new file mode 100644
index 0000000..03df206
--- /dev/null
+++ b/examples/simple.html
@@ -0,0 +1,5 @@
+Hello {{name}}
+You have just won ${{value}}!
+{{#in_ca}}
+Well, ${{ taxed_value }}, after taxes.
+{{/in_ca}}
\ No newline at end of file
diff --git a/examples/simple.js b/examples/simple.js
new file mode 100644
index 0000000..30f9834
--- /dev/null
+++ b/examples/simple.js
@@ -0,0 +1,8 @@
+var simple = {
+ name: "Chris",
+ value: 10000,
+ taxed_value: function() {
+ return this.value - (this.value * 0.4);
+ },
+ in_ca: true
+};
diff --git a/examples/simple.txt b/examples/simple.txt
new file mode 100644
index 0000000..5d75d65
--- /dev/null
+++ b/examples/simple.txt
@@ -0,0 +1,3 @@
+Hello Chris
+You have just won $10000!
+Well, $6000, after taxes.
diff --git a/examples/template_partial.2.html b/examples/template_partial.2.html
new file mode 100644
index 0000000..54bdd7d
--- /dev/null
+++ b/examples/template_partial.2.html
@@ -0,0 +1 @@
+Again, {{again}}!
\ No newline at end of file
diff --git a/examples/template_partial.html b/examples/template_partial.html
new file mode 100644
index 0000000..6a09372
--- /dev/null
+++ b/examples/template_partial.html
@@ -0,0 +1,2 @@
+<h1>{{title}}</h1>
+{{>partial}}
\ No newline at end of file
diff --git a/examples/template_partial.js b/examples/template_partial.js
new file mode 100644
index 0000000..68a4317
--- /dev/null
+++ b/examples/template_partial.js
@@ -0,0 +1,8 @@
+var partial_context = {
+ title: function() {
+ return "Welcome";
+ },
+ partial: {
+ again: "Goodbye"
+ }
+}
diff --git a/examples/template_partial.txt b/examples/template_partial.txt
new file mode 100644
index 0000000..692698f
--- /dev/null
+++ b/examples/template_partial.txt
@@ -0,0 +1,2 @@
+<h1>Welcome</h1>
+Again, Goodbye!
diff --git a/examples/two_in_a_row.html b/examples/two_in_a_row.html
new file mode 100644
index 0000000..dc38602
--- /dev/null
+++ b/examples/two_in_a_row.html
@@ -0,0 +1 @@
+{{greeting}}, {{name}}!
\ No newline at end of file
diff --git a/examples/two_in_a_row.js b/examples/two_in_a_row.js
new file mode 100644
index 0000000..09c1809
--- /dev/null
+++ b/examples/two_in_a_row.js
@@ -0,0 +1,4 @@
+var two_in_a_row = {
+ name: "Joe",
+ greeting: "Welcome"
+};
diff --git a/examples/two_in_a_row.txt b/examples/two_in_a_row.txt
new file mode 100644
index 0000000..c6d6a9b
--- /dev/null
+++ b/examples/two_in_a_row.txt
@@ -0,0 +1 @@
+Welcome, Joe!
diff --git a/examples/unescaped.html b/examples/unescaped.html
new file mode 100644
index 0000000..9982708
--- /dev/null
+++ b/examples/unescaped.html
@@ -0,0 +1 @@
+<h1>{{{title}}}</h1>
\ No newline at end of file
diff --git a/examples/unescaped.js b/examples/unescaped.js
new file mode 100644
index 0000000..0bd20b8
--- /dev/null
+++ b/examples/unescaped.js
@@ -0,0 +1,5 @@
+var unescaped = {
+ title: function() {
+ return "Bear > Shark";
+ }
+};
diff --git a/examples/unescaped.txt b/examples/unescaped.txt
new file mode 100644
index 0000000..089ad79
--- /dev/null
+++ b/examples/unescaped.txt
@@ -0,0 +1 @@
+<h1>Bear > Shark</h1>
diff --git a/examples/unknown_pragma.html b/examples/unknown_pragma.html
new file mode 100644
index 0000000..113810d
--- /dev/null
+++ b/examples/unknown_pragma.html
@@ -0,0 +1 @@
+{{%I-HAVE-THE-GREATEST-MUSTACHE}}
diff --git a/examples/unknown_pragma.js b/examples/unknown_pragma.js
new file mode 100644
index 0000000..68344a5
--- /dev/null
+++ b/examples/unknown_pragma.js
@@ -0,0 +1 @@
+var unknown_pragma = {};
diff --git a/examples/unknown_pragma.txt b/examples/unknown_pragma.txt
new file mode 100644
index 0000000..a34840d
--- /dev/null
+++ b/examples/unknown_pragma.txt
@@ -0,0 +1 @@
+ERROR: This implementation of mustache doesn't understand the 'I-HAVE-THE-GREATEST-MUSTACHE' pragma
diff --git a/examples/view_partial.2.html b/examples/view_partial.2.html
new file mode 100644
index 0000000..2fea632
--- /dev/null
+++ b/examples/view_partial.2.html
@@ -0,0 +1,5 @@
+Hello {{name}}
+You have just won ${{value}}!
+{{#in_ca}}
+Well, ${{ taxed_value }}, after taxes.
+{{/in_ca}}
diff --git a/examples/view_partial.html b/examples/view_partial.html
new file mode 100644
index 0000000..8f0c08d
--- /dev/null
+++ b/examples/view_partial.html
@@ -0,0 +1,3 @@
+<h1>{{greeting}}</h1>
+{{>partial}}
+<h3>{{farewell}}</h3>
\ No newline at end of file
diff --git a/examples/view_partial.js b/examples/view_partial.js
new file mode 100644
index 0000000..30ade55
--- /dev/null
+++ b/examples/view_partial.js
@@ -0,0 +1,19 @@
+var partial_context = {
+ greeting: function() {
+ return "Welcome";
+ },
+
+ farewell: function() {
+ return "Fair enough, right?";
+ },
+
+ partial: {
+ name: "Chris",
+ value: 10000,
+ taxed_value: function() {
+ return this.value - (this.value * 0.4);
+ },
+ in_ca: true
+ }
+};
+
diff --git a/examples/view_partial.txt b/examples/view_partial.txt
new file mode 100644
index 0000000..160b0b6
--- /dev/null
+++ b/examples/view_partial.txt
@@ -0,0 +1,6 @@
+<h1>Welcome</h1>
+Hello Chris
+You have just won $10000!
+Well, $6000, after taxes.
+
+<h3>Fair enough, right?</h3>
diff --git a/examples/whitespace_partial.2.html b/examples/whitespace_partial.2.html
new file mode 100644
index 0000000..9c46084
--- /dev/null
+++ b/examples/whitespace_partial.2.html
@@ -0,0 +1,5 @@
+Hello {{ name}}
+You have just won ${{value }}!
+{{# in_ca }}
+Well, ${{ taxed_value }}, after taxes.
+{{/ in_ca }}
diff --git a/examples/whitespace_partial.html b/examples/whitespace_partial.html
new file mode 100644
index 0000000..ce43cb3
--- /dev/null
+++ b/examples/whitespace_partial.html
@@ -0,0 +1,3 @@
+<h1>{{ greeting }}</h1>
+{{> partial }}
+<h3>{{ farewell }}</h3>
\ No newline at end of file
diff --git a/examples/whitespace_partial.js b/examples/whitespace_partial.js
new file mode 100644
index 0000000..30ade55
--- /dev/null
+++ b/examples/whitespace_partial.js
@@ -0,0 +1,19 @@
+var partial_context = {
+ greeting: function() {
+ return "Welcome";
+ },
+
+ farewell: function() {
+ return "Fair enough, right?";
+ },
+
+ partial: {
+ name: "Chris",
+ value: 10000,
+ taxed_value: function() {
+ return this.value - (this.value * 0.4);
+ },
+ in_ca: true
+ }
+};
+
diff --git a/examples/whitespace_partial.txt b/examples/whitespace_partial.txt
new file mode 100644
index 0000000..160b0b6
--- /dev/null
+++ b/examples/whitespace_partial.txt
@@ -0,0 +1,6 @@
+<h1>Welcome</h1>
+Hello Chris
+You have just won $10000!
+Well, $6000, after taxes.
+
+<h3>Fair enough, right?</h3>
diff --git a/mustache-commonjs/mustache.js.tpl.post b/mustache-commonjs/mustache.js.tpl.post
new file mode 100644
index 0000000..885803f
--- /dev/null
+++ b/mustache-commonjs/mustache.js.tpl.post
@@ -0,0 +1,7 @@
+
+exports.name = Mustache.name;
+exports.version = Mustache.version;
+
+exports.to_html = function() {
+ return Mustache.to_html.apply(this, arguments);
+};
diff --git a/mustache-commonjs/mustache.js.tpl.pre b/mustache-commonjs/mustache.js.tpl.pre
new file mode 100644
index 0000000..5e33b34
--- /dev/null
+++ b/mustache-commonjs/mustache.js.tpl.pre
@@ -0,0 +1,6 @@
+/*
+ * CommonJS-compatible mustache.js module
+ *
+ * See http://github.com/janl/mustache.js for more info.
+ */
+
diff --git a/mustache-commonjs/package.json b/mustache-commonjs/package.json
new file mode 100644
index 0000000..74d3aba
--- /dev/null
+++ b/mustache-commonjs/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "mustache",
+ "author": "http://mustache.github.com/",
+ "description": "{{ mustache }} in JavaScript — Logic-less templates.",
+ "keywords": ["template"],
+ "version": "{{version}}"
+}
diff --git a/mustache-dojo/mustache.js.tpl.post b/mustache-dojo/mustache.js.tpl.post
new file mode 100644
index 0000000..f659e2f
--- /dev/null
+++ b/mustache-dojo/mustache.js.tpl.post
@@ -0,0 +1,5 @@
+
+ d.mustache = function(template, view, partials) {
+ return Mustache.to_html(template, view, partials);
+ };
+})(dojo);
\ No newline at end of file
diff --git a/mustache-dojo/mustache.js.tpl.pre b/mustache-dojo/mustache.js.tpl.pre
new file mode 100644
index 0000000..ac9a308
--- /dev/null
+++ b/mustache-dojo/mustache.js.tpl.pre
@@ -0,0 +1,9 @@
+/*
+Shameless port of a shameless port
+ at defunkt => @janl => @aq => @voodootikigod
+
+See http://github.com/defunkt/mustache for more info.
+*/
+
+dojo.provide("dojox.string.mustache");
+;(function(d) {
diff --git a/mustache-jquery/jquery.mustache.js.tpl.post b/mustache-jquery/jquery.mustache.js.tpl.post
new file mode 100644
index 0000000..1fe2887
--- /dev/null
+++ b/mustache-jquery/jquery.mustache.js.tpl.post
@@ -0,0 +1,6 @@
+
+ $.mustache = function(template, view, partials) {
+ return Mustache.to_html(template, view, partials);
+ };
+
+})(jQuery);
diff --git a/mustache-jquery/jquery.mustache.js.tpl.pre b/mustache-jquery/jquery.mustache.js.tpl.pre
new file mode 100644
index 0000000..b4d8af5
--- /dev/null
+++ b/mustache-jquery/jquery.mustache.js.tpl.pre
@@ -0,0 +1,9 @@
+/*
+Shameless port of a shameless port
+ at defunkt => @janl => @aq
+
+See http://github.com/defunkt/mustache for more info.
+*/
+
+;(function($) {
+
diff --git a/mustache-yui3/mustache.js.tpl.post b/mustache-yui3/mustache.js.tpl.post
new file mode 100644
index 0000000..373d827
--- /dev/null
+++ b/mustache-yui3/mustache.js.tpl.post
@@ -0,0 +1,4 @@
+
+ Y.mustache = Mustache.to_html;
+
+}, "0");
diff --git a/mustache-yui3/mustache.js.tpl.pre b/mustache-yui3/mustache.js.tpl.pre
new file mode 100644
index 0000000..280de86
--- /dev/null
+++ b/mustache-yui3/mustache.js.tpl.pre
@@ -0,0 +1 @@
+YUI.add("mustache", function(Y) {
diff --git a/mustache.js b/mustache.js
new file mode 100644
index 0000000..0996227
--- /dev/null
+++ b/mustache.js
@@ -0,0 +1,324 @@
+/*
+ mustache.js — Logic-less templates in JavaScript
+
+ See http://mustache.github.com/ for more info.
+*/
+
+var Mustache = function() {
+ var Renderer = function() {};
+
+ Renderer.prototype = {
+ otag: "{{",
+ ctag: "}}",
+ pragmas: {},
+ buffer: [],
+ pragmas_implemented: {
+ "IMPLICIT-ITERATOR": true
+ },
+ context: {},
+
+ render: function(template, context, partials, in_recursion) {
+ // reset buffer & set context
+ if(!in_recursion) {
+ this.context = context;
+ this.buffer = []; // TODO: make this non-lazy
+ }
+
+ // fail fast
+ if(!this.includes("", template)) {
+ if(in_recursion) {
+ return template;
+ } else {
+ this.send(template);
+ return;
+ }
+ }
+
+ template = this.render_pragmas(template);
+ var html = this.render_section(template, context, partials);
+ if(in_recursion) {
+ return this.render_tags(html, context, partials, in_recursion);
+ }
+
+ this.render_tags(html, context, partials, in_recursion);
+ },
+
+ /*
+ Sends parsed lines
+ */
+ send: function(line) {
+ if(line != "") {
+ this.buffer.push(line);
+ }
+ },
+
+ /*
+ Looks for %PRAGMAS
+ */
+ render_pragmas: function(template) {
+ // no pragmas
+ if(!this.includes("%", template)) {
+ return template;
+ }
+
+ var that = this;
+ var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
+ this.ctag);
+ return template.replace(regex, function(match, pragma, options) {
+ if(!that.pragmas_implemented[pragma]) {
+ throw({message:
+ "This implementation of mustache doesn't understand the '" +
+ pragma + "' pragma"});
+ }
+ that.pragmas[pragma] = {};
+ if(options) {
+ var opts = options.split("=");
+ that.pragmas[pragma][opts[0]] = opts[1];
+ }
+ return "";
+ // ignore unknown pragmas silently
+ });
+ },
+
+ /*
+ Tries to find a partial in the curent scope and render it
+ */
+ render_partial: function(name, context, partials) {
+ name = this.trim(name);
+ if(!partials || partials[name] === undefined) {
+ throw({message: "unknown_partial '" + name + "'"});
+ }
+ if(typeof(context[name]) != "object") {
+ return this.render(partials[name], context, partials, true);
+ }
+ return this.render(partials[name], context[name], partials, true);
+ },
+
+ /*
+ Renders inverted (^) and normal (#) sections
+ */
+ render_section: function(template, context, partials) {
+ if(!this.includes("#", template) && !this.includes("^", template)) {
+ return template;
+ }
+
+ var that = this;
+ // CSW - Added "+?" so it finds the tighest bound, not the widest
+ var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
+ "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
+ "\\s*", "mg");
+
+ // for each {{#foo}}{{/foo}} section do...
+ return template.replace(regex, function(match, type, name, content) {
+ var value = that.find(name, context);
+ if(type == "^") { // inverted section
+ if(!value || that.is_array(value) && value.length === 0) {
+ // false or empty list, render it
+ return that.render(content, context, partials, true);
+ } else {
+ return "";
+ }
+ } else if(type == "#") { // normal section
+ if(that.is_array(value)) { // Enumerable, Let's loop!
+ return that.map(value, function(row) {
+ return that.render(content, that.create_context(row),
+ partials, true);
+ }).join("");
+ } else if(that.is_object(value)) { // Object, Use it as subcontext!
+ return that.render(content, that.create_context(value),
+ partials, true);
+ } else if(typeof value === "function") {
+ // higher order section
+ return value.call(context, content, function(text) {
+ return that.render(text, context, partials, true);
+ });
+ } else if(value) { // boolean section
+ return that.render(content, context, partials, true);
+ } else {
+ return "";
+ }
+ }
+ });
+ },
+
+ /*
+ Replace {{foo}} and friends with values from our view
+ */
+ render_tags: function(template, context, partials, in_recursion) {
+ // tit for tat
+ var that = this;
+
+ var new_regex = function() {
+ return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
+ that.ctag + "+", "g");
+ };
+
+ var regex = new_regex();
+ var tag_replace_callback = function(match, operator, name) {
+ switch(operator) {
+ case "!": // ignore comments
+ return "";
+ case "=": // set new delimiters, rebuild the replace regexp
+ that.set_delimiters(name);
+ regex = new_regex();
+ return "";
+ case ">": // render partial
+ return that.render_partial(name, context, partials);
+ case "{": // the triple mustache is unescaped
+ return that.find(name, context);
+ default: // escape the value
+ return that.escape(that.find(name, context));
+ }
+ };
+ var lines = template.split("\n");
+ for(var i = 0; i < lines.length; i++) {
+ lines[i] = lines[i].replace(regex, tag_replace_callback, this);
+ if(!in_recursion) {
+ this.send(lines[i]);
+ }
+ }
+
+ if(in_recursion) {
+ return lines.join("\n");
+ }
+ },
+
+ set_delimiters: function(delimiters) {
+ var dels = delimiters.split(" ");
+ this.otag = this.escape_regex(dels[0]);
+ this.ctag = this.escape_regex(dels[1]);
+ },
+
+ escape_regex: function(text) {
+ // thank you Simon Willison
+ if(!arguments.callee.sRE) {
+ var specials = [
+ '/', '.', '*', '+', '?', '|',
+ '(', ')', '[', ']', '{', '}', '\\'
+ ];
+ arguments.callee.sRE = new RegExp(
+ '(\\' + specials.join('|\\') + ')', 'g'
+ );
+ }
+ return text.replace(arguments.callee.sRE, '\\$1');
+ },
+
+ /*
+ find `name` in current `context`. That is find me a value
+ from the view object
+ */
+ find: function(name, context) {
+ name = this.trim(name);
+
+ // Checks whether a value is thruthy or false or 0
+ function is_kinda_truthy(bool) {
+ return bool === false || bool === 0 || bool;
+ }
+
+ var value;
+ if(is_kinda_truthy(context[name])) {
+ value = context[name];
+ } else if(is_kinda_truthy(this.context[name])) {
+ value = this.context[name];
+ }
+
+ if(typeof value === "function") {
+ return value.apply(context);
+ }
+ if(value !== undefined) {
+ return value;
+ }
+ // silently ignore unkown variables
+ return "";
+ },
+
+ // Utility methods
+
+ /* includes tag */
+ includes: function(needle, haystack) {
+ return haystack.indexOf(this.otag + needle) != -1;
+ },
+
+ /*
+ Does away with nasty characters
+ */
+ escape: function(s) {
+ s = String(s === null ? "" : s);
+ return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
+ switch(s) {
+ case "&": return "&";
+ case "\\": return "\\\\";
+ case '"': return '\"';
+ case "<": return "<";
+ case ">": return ">";
+ default: return s;
+ }
+ });
+ },
+
+ // by @langalex, support for arrays of strings
+ create_context: function(_context) {
+ if(this.is_object(_context)) {
+ return _context;
+ } else {
+ var iterator = ".";
+ if(this.pragmas["IMPLICIT-ITERATOR"]) {
+ iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
+ }
+ var ctx = {};
+ ctx[iterator] = _context;
+ return ctx;
+ }
+ },
+
+ is_object: function(a) {
+ return a && typeof a == "object";
+ },
+
+ is_array: function(a) {
+ return Object.prototype.toString.call(a) === '[object Array]';
+ },
+
+ /*
+ Gets rid of leading and trailing whitespace
+ */
+ trim: function(s) {
+ return s.replace(/^\s*|\s*$/g, "");
+ },
+
+ /*
+ Why, why, why? Because IE. Cry, cry cry.
+ */
+ map: function(array, fn) {
+ if (typeof array.map == "function") {
+ return array.map(fn);
+ } else {
+ var r = [];
+ var l = array.length;
+ for(var i = 0; i < l; i++) {
+ r.push(fn(array[i]));
+ }
+ return r;
+ }
+ }
+ };
+
+ return({
+ name: "mustache.js",
+ version: "0.3.0",
+
+ /*
+ Turns a template and view into HTML
+ */
+ to_html: function(template, view, partials, send_fun) {
+ var renderer = new Renderer();
+ if(send_fun) {
+ renderer.send = send_fun;
+ }
+ renderer.render(template, view, partials);
+ if(!send_fun) {
+ return renderer.buffer.join("\n");
+ }
+ }
+ });
+}();
diff --git a/test/mustache_spec.rb b/test/mustache_spec.rb
new file mode 100644
index 0000000..9ede6c8
--- /dev/null
+++ b/test/mustache_spec.rb
@@ -0,0 +1,156 @@
+require 'rubygems'
+require 'json'
+
+__DIR__ = File.dirname(__FILE__)
+
+testnames = Dir.glob(__DIR__ + '/../examples/*.js').map do |name|
+ File.basename name, '.js'
+end
+
+non_partials = testnames.select{|t| not t.include? "partial"}
+partials = testnames.select{|t| t.include? "partial"}
+
+def load_test(dir, name, partial=false)
+ view = File.read(dir + "/../examples/#{name}.js")
+ template = File.read(dir + "/../examples/#{name}.html").to_json
+ expect = File.read(dir + "/../examples/#{name}.txt")
+ if not partial
+ [view, template, expect]
+ else
+ partial = File.read(dir + "/../examples/#{name}.2.html").to_json
+ [view, template, partial, expect]
+ end
+end
+
+describe "mustache" do
+ before(:all) do
+ @mustache = File.read(__DIR__ + "/../mustache.js")
+ end
+
+ it "should return the same when invoked multiple times" do
+ js = <<-JS
+ #{@mustache}
+ Mustache.to_html("x")
+ print(Mustache.to_html("x"));
+ JS
+ run_js(js).should == "x\n"
+
+ end
+
+ it "should clear the context after each run" do
+ js = <<-JS
+ #{@mustache}
+ Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{x: 1}]})
+ try {
+ print(Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{}]}));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+ run_js(js).should == "\n"
+ end
+
+ non_partials.each do |testname|
+ describe testname do
+ it "should generate the correct html" do
+
+ view, template, expect = load_test(__DIR__, testname)
+
+ runner = <<-JS
+ try {
+ #{@mustache}
+ #{view}
+ var template = #{template};
+ var result = Mustache.to_html(template, #{testname});
+ print(result);
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(runner).should == expect
+ end
+ it "should sendFun the correct html" do
+
+ view, template, expect = load_test(__DIR__, testname)
+
+ runner = <<-JS
+ try {
+ #{@mustache}
+ #{view}
+ var chunks = [];
+ var sendFun = function(chunk) {
+ if (chunk != "") {
+ chunks.push(chunk);
+ }
+ }
+ var template = #{template};
+ Mustache.to_html(template, #{testname}, null, sendFun);
+ print(chunks.join("\\n"));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(runner).strip.should == expect.strip
+ end
+ end
+ end
+
+ partials.each do |testname|
+ describe testname do
+ it "should generate the correct html" do
+
+ view, template, partial, expect =
+ load_test(__DIR__, testname, true)
+
+ runner = <<-JS
+ try {
+ #{@mustache}
+ #{view}
+ var template = #{template};
+ var partials = {"partial": #{partial}};
+ var result = Mustache.to_html(template, partial_context, partials);
+ print(result);
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(runner).should == expect
+ end
+ it "should sendFun the correct html" do
+
+ view, template, partial, expect =
+ load_test(__DIR__, testname, true)
+
+ runner = <<-JS
+ try {
+ #{@mustache}
+ #{view};
+ var template = #{template};
+ var partials = {"partial": #{partial}};
+ var chunks = [];
+ var sendFun = function(chunk) {
+ if (chunk != "") {
+ chunks.push(chunk);
+ }
+ }
+ Mustache.to_html(template, partial_context, partials, sendFun);
+ print(chunks.join("\\n"));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(runner).strip.should == expect.strip
+ end
+ end
+ end
+
+ def run_js(js)
+ File.open("runner.js", 'w') {|f| f << js}
+ `js runner.js`
+ end
+end
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/mustache.js.git
More information about the Pkg-javascript-commits
mailing list