mustache 0.99.5 → 0.99.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -23
- data/Rakefile +1 -1
- data/bin/mustache +30 -12
- data/lib/mustache.rb +4 -11
- data/lib/mustache/blah.rb +116 -0
- data/lib/mustache/context.rb +28 -15
- data/lib/mustache/enumerable.rb +3 -0
- data/lib/mustache/generator.rb +16 -11
- data/lib/mustache/parser.rb +83 -33
- data/lib/mustache/sinatra.rb +1 -1
- data/lib/mustache/template.rb +52 -0
- data/lib/mustache/version.rb +1 -1
- data/man/mustache.1 +4 -4
- data/man/mustache.1.html +6 -6
- data/man/mustache.1.ron +3 -3
- data/man/mustache.5 +8 -8
- data/man/mustache.5.html +11 -9
- data/man/mustache.5.ron +9 -7
- data/test/fixtures/liberal.mustache +1 -0
- data/test/fixtures/liberal.rb +22 -0
- data/test/fixtures/simply_complicated.mustache +25 -0
- data/test/mustache_test.rb +67 -2
- data/test/parser_test.rb +15 -0
- data/test/partial_test.rb +1 -1
- data/test/spec_test.rb +6 -2
- data/test/template_test.rb +33 -0
- metadata +87 -11
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e3c1091a71418634c3e493d6b3aae1e5a8f0d0f0
         | 
| 4 | 
            +
              data.tar.gz: 87936c1b015243222b2c95c29693106a9ea646a1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a422377f6020f923eac84ca194e46b78d05ad611428faa4dede440c090c61e2a30d5d15618286ae72b8ebf486e9aae4b351fee521f5bdc4e13ecc99d1a1677e4
         | 
| 7 | 
            +
              data.tar.gz: 30d05bc44030071c322a18ff64235c7bd8da19b03c1cbb4bc68dd3deba33c21d82af75dc435aa2c9845705ea8c7989130aa7626aced0ffb119d6bc18344fa420
         | 
    
        data/README.md
    CHANGED
    
    | @@ -8,7 +8,7 @@ As ctemplates says, "It emphasizes separating logic from presentation: | |
| 8 8 | 
             
            it is impossible to embed application logic in this template language."
         | 
| 9 9 |  | 
| 10 10 | 
             
            For a list of implementations (other than Ruby) and tips, see
         | 
| 11 | 
            -
            <http://mustache.github. | 
| 11 | 
            +
            <http://mustache.github.io/>.
         | 
| 12 12 |  | 
| 13 13 |  | 
| 14 14 | 
             
            Overview
         | 
| @@ -99,16 +99,16 @@ Tag Types | |
| 99 99 |  | 
| 100 100 | 
             
            For a language-agnostic overview of Mustache's template syntax, see
         | 
| 101 101 | 
             
            the `mustache(5)` manpage or
         | 
| 102 | 
            -
            <http://mustache.github. | 
| 102 | 
            +
            <http://mustache.github.io/mustache.5.html>.
         | 
| 103 103 |  | 
| 104 104 |  | 
| 105 105 | 
             
            Escaping
         | 
| 106 106 | 
             
            --------
         | 
| 107 107 |  | 
| 108 108 | 
             
            Mustache does escape all values when using the standard double
         | 
| 109 | 
            -
            Mustache syntax. Characters which will be escaped: `& \ " <  | 
| 110 | 
            -
            disable escaping, simply use triple | 
| 111 | 
            -
            `{{{unescaped_variable}}}`.
         | 
| 109 | 
            +
            Mustache syntax. Characters which will be escaped: `& \ " < >` (as 
         | 
| 110 | 
            +
            well as `'` in Ruby `>= 2.0`). To disable escaping, simply use triple
         | 
| 111 | 
            +
            mustaches like `{{{unescaped_variable}}}`.
         | 
| 112 112 |  | 
| 113 113 | 
             
            Example: Using `{{variable}}` inside a template for `5 > 2` will
         | 
| 114 114 | 
             
            result in `5 > 2`, where as the usage of `{{{variable}}}` will
         | 
| @@ -283,16 +283,16 @@ Sinatra | |
| 283 283 |  | 
| 284 284 | 
             
            Mustache ships with Sinatra integration. Please see
         | 
| 285 285 | 
             
            `lib/mustache/sinatra.rb` or
         | 
| 286 | 
            -
            < | 
| 286 | 
            +
            <https://github.com/defunkt/mustache/blob/master/lib/mustache/sinatra.rb>
         | 
| 287 287 | 
             
            for complete documentation.
         | 
| 288 288 |  | 
| 289 289 | 
             
            An example Sinatra application is also provided:
         | 
| 290 | 
            -
            < | 
| 290 | 
            +
            <https://github.com/defunkt/mustache-sinatra-example>
         | 
| 291 291 |  | 
| 292 292 | 
             
            If you are upgrading to Sinatra 1.0 and Mustache 0.9.0+ from Mustache
         | 
| 293 293 | 
             
            0.7.0 or lower, the settings have changed. But not that much.
         | 
| 294 294 |  | 
| 295 | 
            -
            See [this diff]( | 
| 295 | 
            +
            See [this diff](https://gist.github.com/defunkt/345490) for what you need to
         | 
| 296 296 | 
             
            do. Basically, things are named properly now and all should be
         | 
| 297 297 | 
             
            contained in a hash set using `set :mustache, hash`.
         | 
| 298 298 |  | 
| @@ -317,11 +317,7 @@ Using Rails? Add this to your initializer or environment file: | |
| 317 317 | 
             
            Vim
         | 
| 318 318 | 
             
            ---
         | 
| 319 319 |  | 
| 320 | 
            -
             | 
| 321 | 
            -
            is included under the contrib/ directory.
         | 
| 322 | 
            -
             | 
| 323 | 
            -
            See <http://gist.github.com/323622> for installation instructions.
         | 
| 324 | 
            -
             | 
| 320 | 
            +
            vim-mustache-handlebars is available at https://github.com/mustache/vim-mustache-handlebars
         | 
| 325 321 |  | 
| 326 322 | 
             
            Emacs
         | 
| 327 323 | 
             
            -----
         | 
| @@ -332,16 +328,16 @@ mustache-mode.el is available at https://github.com/mustache/emacs | |
| 332 328 | 
             
            TextMate
         | 
| 333 329 | 
             
            --------
         | 
| 334 330 |  | 
| 335 | 
            -
            [Mustache.tmbundle]( | 
| 331 | 
            +
            [Mustache.tmbundle](https://github.com/defunkt/Mustache.tmbundle)
         | 
| 336 332 |  | 
| 337 | 
            -
            See < | 
| 333 | 
            +
            See <https://gist.github.com/defunkt/323624> for installation instructions.
         | 
| 338 334 |  | 
| 339 335 |  | 
| 340 336 | 
             
            Command Line
         | 
| 341 337 | 
             
            ------------
         | 
| 342 338 |  | 
| 343 339 | 
             
            See `mustache(1)` man page or
         | 
| 344 | 
            -
            <http://mustache.github. | 
| 340 | 
            +
            <http://mustache.github.io/mustache.1.html>
         | 
| 345 341 | 
             
            for command line docs.
         | 
| 346 342 |  | 
| 347 343 |  | 
| @@ -356,8 +352,8 @@ Installation | |
| 356 352 | 
             
            Acknowledgements
         | 
| 357 353 | 
             
            ----------------
         | 
| 358 354 |  | 
| 359 | 
            -
            Thanks to [Tom Preston-Werner]( | 
| 360 | 
            -
            me ctemplate and [Leah Culver]( | 
| 355 | 
            +
            Thanks to [Tom Preston-Werner](https://github.com/mojombo) for showing
         | 
| 356 | 
            +
            me ctemplate and [Leah Culver](https://github.com/leah) for the name "Mustache."
         | 
| 361 357 |  | 
| 362 358 | 
             
            Special thanks to [Magnus Holm](http://judofyr.net/) for all his
         | 
| 363 359 | 
             
            awesome work on Mustache's parser.
         | 
| @@ -391,9 +387,9 @@ The archive can be found at <http://librelist.com/browser/>. | |
| 391 387 | 
             
            Meta
         | 
| 392 388 | 
             
            ----
         | 
| 393 389 |  | 
| 394 | 
            -
            * Code: `git clone  | 
| 395 | 
            -
            * Home: <http://mustache.github. | 
| 396 | 
            -
            * Bugs: < | 
| 390 | 
            +
            * Code: `git clone https://github.com/defunkt/mustache.git`
         | 
| 391 | 
            +
            * Home: <http://mustache.github.io>
         | 
| 392 | 
            +
            * Bugs: <https://github.com/defunkt/mustache/issues>
         | 
| 397 393 | 
             
            * List: <mustache@librelist.com>
         | 
| 398 394 | 
             
            * Gems: <http://rubygems.org/gems/mustache>
         | 
| 399 395 |  | 
| @@ -402,8 +398,8 @@ You can also find us in `#{` on irc.freenode.net. | |
| 402 398 | 
             
            [1]: http://code.google.com/p/google-ctemplate/
         | 
| 403 399 | 
             
            [2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html
         | 
| 404 400 | 
             
            [3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
         | 
| 405 | 
            -
            [4]:  | 
| 401 | 
            +
            [4]: https://github.com/brynary/rack-bug/
         | 
| 406 402 | 
             
            [5]: http://img.skitch.com/20091027-n8pxwwx8r61tc318a15q1n6m14.png
         | 
| 407 403 | 
             
            [cb]: http://wiki.github.com/defunkt/resque/contributing
         | 
| 408 404 | 
             
            [fk]: http://help.github.com/forking/
         | 
| 409 | 
            -
            [is]:  | 
| 405 | 
            +
            [is]: https://github.com/defunkt/mustache/issues
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/bin/mustache
    CHANGED
    
    | @@ -64,20 +64,38 @@ class Mustache | |
| 64 64 | 
             
                  opts.parse!(args)
         | 
| 65 65 | 
             
                end
         | 
| 66 66 |  | 
| 67 | 
            -
                 | 
| 68 | 
            -
             | 
| 69 | 
            -
                 | 
| 70 | 
            -
                  doc = input_stream.read
         | 
| 67 | 
            +
                def self.yaml_is_array?(yaml)
         | 
| 68 | 
            +
                    yaml.is_a? Array and yaml.length == 1 and yaml[0].is_a? Array
         | 
| 69 | 
            +
                end
         | 
| 71 70 |  | 
| 72 | 
            -
             | 
| 73 | 
            -
                    yaml  | 
| 74 | 
            -
             | 
| 71 | 
            +
                def self.yaml_is_object?(yaml)
         | 
| 72 | 
            +
                    yaml.is_a? Array and yaml.length == 1 and yaml[0].is_a? Hash
         | 
| 73 | 
            +
                end
         | 
| 75 74 |  | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
                   | 
| 75 | 
            +
                # Does the dirty work of reading files from the command line then
         | 
| 76 | 
            +
                # processing them. The meat of this script, if you will.
         | 
| 77 | 
            +
                def self.process_files(input_files)
         | 
| 78 | 
            +
                  doc = input_files.file.read
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  yaml = nil
         | 
| 81 | 
            +
                  begin
         | 
| 82 | 
            +
                    yaml = RUBY_VERSION >= '1.9.3' ? YAML.load_stream(doc) : YAML.each_document(doc)
         | 
| 83 | 
            +
                  rescue
         | 
| 84 | 
            +
                    puts "Unable to parse yaml!"
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  if yaml.nil?
         | 
| 80 88 | 
             
                    puts Mustache.render(doc)
         | 
| 89 | 
            +
                  else
         | 
| 90 | 
            +
                    template = input_files.skip.file.read
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    if self.yaml_is_array?(yaml)
         | 
| 93 | 
            +
                      puts Mustache.render(template, yaml[0].reduce({}) {|hash, currentHash| hash.merge(currentHash)})
         | 
| 94 | 
            +
                    elsif self.yaml_is_object?(yaml)
         | 
| 95 | 
            +
                      puts Mustache.render(template, yaml[0])
         | 
| 96 | 
            +
                    else
         | 
| 97 | 
            +
                      puts Mustache.render(template, yaml)
         | 
| 98 | 
            +
                    end
         | 
| 81 99 | 
             
                  end
         | 
| 82 100 | 
             
                end
         | 
| 83 101 | 
             
              end
         | 
| @@ -89,6 +107,6 @@ ARGV << '-h' if ARGV.empty? && $stdin.tty? | |
| 89 107 | 
             
            # Process options
         | 
| 90 108 | 
             
            Mustache::CLI.parse_options(ARGV) if $stdin.tty?
         | 
| 91 109 |  | 
| 92 | 
            -
            # Still here - process ARGF
         | 
| 110 | 
            +
            # Still here - process rest of ARGF
         | 
| 93 111 | 
             
            Mustache::CLI.process_files(ARGF)
         | 
| 94 112 |  | 
    
        data/lib/mustache.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            require 'mustache/enumerable'
         | 
| 1 2 | 
             
            require 'mustache/template'
         | 
| 2 3 | 
             
            require 'mustache/context'
         | 
| 3 4 | 
             
            require 'mustache/settings'
         | 
| @@ -202,14 +203,10 @@ class Mustache | |
| 202 203 | 
             
              #   Mustache.view_namespace = Hurl::Views
         | 
| 203 204 | 
             
              #   Mustache.view_class(:Partial) # => Hurl::Views::Partial
         | 
| 204 205 | 
             
              def self.view_class(name)
         | 
| 205 | 
            -
                 | 
| 206 | 
            -
                  name = classify(name.to_s)
         | 
| 207 | 
            -
                end
         | 
| 206 | 
            +
                name = classify(name.to_s)
         | 
| 208 207 |  | 
| 209 208 | 
             
                # Emptiness begets emptiness.
         | 
| 210 | 
            -
                if name.to_s == ''
         | 
| 211 | 
            -
                  return Mustache
         | 
| 212 | 
            -
                end
         | 
| 209 | 
            +
                return Mustache if name.to_s == ''
         | 
| 213 210 |  | 
| 214 211 | 
             
                file_name = underscore(name)
         | 
| 215 212 | 
             
                name = "#{view_namespace}::#{name}"
         | 
| @@ -280,11 +277,7 @@ class Mustache | |
| 280 277 | 
             
              # Turns a string into a Mustache::Template. If passed a Template,
         | 
| 281 278 | 
             
              # returns it.
         | 
| 282 279 | 
             
              def self.templateify(obj)
         | 
| 283 | 
            -
                 | 
| 284 | 
            -
                  obj
         | 
| 285 | 
            -
                else
         | 
| 286 | 
            -
                  Template.new(obj.to_s)
         | 
| 287 | 
            -
                end
         | 
| 280 | 
            +
                obj.is_a?(Template) ? obj : Template.new(obj.to_s)
         | 
| 288 281 | 
             
              end
         | 
| 289 282 |  | 
| 290 283 | 
             
              def templateify(obj)
         | 
| @@ -0,0 +1,116 @@ | |
| 1 | 
            +
            require 'mustache'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Mustache::Template
         | 
| 4 | 
            +
              def token_names
         | 
| 5 | 
            +
                def recursor(toks, section)
         | 
| 6 | 
            +
                  toks.map do |token|
         | 
| 7 | 
            +
                    next unless token.is_a? Array
         | 
| 8 | 
            +
                    if token[0] == :mustache && [:etag,:utag].include? token[1]
         | 
| 9 | 
            +
                      (section + [token[2][2][0]]).join '.'
         | 
| 10 | 
            +
                    elsif token[0] == :mustache && [:section,:inverted_section].include? token[1]
         | 
| 11 | 
            +
                      recursor(token[4], section + [token[2][2][0]])
         | 
| 12 | 
            +
                    else
         | 
| 13 | 
            +
                      recursor(token, section)
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                recursor(tokens, []).flatten.reject(&:nil?).uniq
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def section_names
         | 
| 21 | 
            +
                def recursor(toks, section)
         | 
| 22 | 
            +
                  sections = []
         | 
| 23 | 
            +
                  toks.each do |token|
         | 
| 24 | 
            +
                    next unless token.is_a? Array
         | 
| 25 | 
            +
                    if token[0] == :mustache && [:section,:inverted_section].include? token[1]
         | 
| 26 | 
            +
                      new_section = section + [token[2][2][0]]
         | 
| 27 | 
            +
                      sections += [ new_section.join('.') ] + recursor(token[4], new_section)
         | 
| 28 | 
            +
                    else
         | 
| 29 | 
            +
                      sections += recursor(token, section)
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                  sections
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
                recursor(tokens,[]).reject(&:nil?).uniq
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              def partial_names
         | 
| 38 | 
            +
                def recursor(toks)
         | 
| 39 | 
            +
                  partials = []
         | 
| 40 | 
            +
                  toks.each do |token|
         | 
| 41 | 
            +
                    next unless token.is_a? Array
         | 
| 42 | 
            +
                    partials += if token[0..1] == [:mustache, :partial]
         | 
| 43 | 
            +
                      [token[2]] # partial here
         | 
| 44 | 
            +
                    else
         | 
| 45 | 
            +
                      recursor(token)
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                  partials
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
                recursor(tokens).reject(&:nil?).uniq
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            if __FILE__ == $0
         | 
| 56 | 
            +
              require "test/unit"
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              class TestMustacheTokenNames < Test::Unit::TestCase
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def setup
         | 
| 61 | 
            +
                  @template = Mustache::Template.new(@@template_text ||= DATA.read)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def test_token_names
         | 
| 65 | 
            +
                  assert_equal(@template.token_names,
         | 
| 66 | 
            +
                    [ "yourname",
         | 
| 67 | 
            +
                      "HOME",
         | 
| 68 | 
            +
                      "friend.name",
         | 
| 69 | 
            +
                      "friend.morr.word",
         | 
| 70 | 
            +
                      "friend.morr.up",
         | 
| 71 | 
            +
                      "friend.morr.awesomesauce",
         | 
| 72 | 
            +
                      "friend.morr.hiss",
         | 
| 73 | 
            +
                      "friend.notinmorr",
         | 
| 74 | 
            +
                      "friend.person",
         | 
| 75 | 
            +
                      "love",
         | 
| 76 | 
            +
                      "triplestash"
         | 
| 77 | 
            +
                    ]
         | 
| 78 | 
            +
                  )
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                def test_partial_names
         | 
| 82 | 
            +
                  assert_equal(@template.partial_names, ["partial1", "partial2"])
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def test_section_names
         | 
| 86 | 
            +
                  assert_equal(@template.section_names, ["friend", "friend.morr"])
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
            end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            __END__
         | 
| 92 | 
            +
            Hi there {{yourname}}.  Your home directory is {{HOME}}.
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            {{#friend}}
         | 
| 95 | 
            +
            Your friend is named {{name}}
         | 
| 96 | 
            +
              {{#morr}}
         | 
| 97 | 
            +
               Hey {{word}} {{up}} {{{awesomesauce}}}.
         | 
| 98 | 
            +
               {{/morr}}
         | 
| 99 | 
            +
               {{^morr}}
         | 
| 100 | 
            +
               Booooo.  {{hiss}}
         | 
| 101 | 
            +
               {{/morr}}
         | 
| 102 | 
            +
               {{notinmorr}}
         | 
| 103 | 
            +
               {{> partial1}}
         | 
| 104 | 
            +
            {{/friend}}
         | 
| 105 | 
            +
            {{^friend}}
         | 
| 106 | 
            +
            You have no friends, {{person}}.  You suck.
         | 
| 107 | 
            +
            {{/friend}}
         | 
| 108 | 
            +
             | 
| 109 | 
            +
            {{> partial2}}
         | 
| 110 | 
            +
            {{! comments are awesome }}
         | 
| 111 | 
            +
             | 
| 112 | 
            +
            {{={% %}=}}
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            {%love%}
         | 
| 115 | 
            +
            {%={{ }}=%}
         | 
| 116 | 
            +
            {{{triplestash}}}
         | 
    
        data/lib/mustache/context.rb
    CHANGED
    
    | @@ -31,7 +31,7 @@ class Mustache | |
| 31 31 | 
             
                  part = mustache.partial(name).to_s.gsub(/^/, indentation)
         | 
| 32 32 |  | 
| 33 33 | 
             
                  # Call the Mustache's `partial` method and render the result.
         | 
| 34 | 
            -
                   | 
| 34 | 
            +
                  mustache.render(part, self)
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 37 | 
             
                # Find the first Mustache in the stack. If we're being rendered
         | 
| @@ -80,7 +80,7 @@ class Mustache | |
| 80 80 | 
             
                # Do we know about a particular key? In other words, will calling
         | 
| 81 81 | 
             
                # `context[key]` give us a result that was set. Basically.
         | 
| 82 82 | 
             
                def has_key?(key)
         | 
| 83 | 
            -
                  !!fetch(key)
         | 
| 83 | 
            +
                  !!fetch(key, false)
         | 
| 84 84 | 
             
                rescue ContextMiss
         | 
| 85 85 | 
             
                  false
         | 
| 86 86 | 
             
                end
         | 
| @@ -97,9 +97,7 @@ class Mustache | |
| 97 97 | 
             
                    next if frame == self
         | 
| 98 98 |  | 
| 99 99 | 
             
                    value = find(frame, name, :__missing)
         | 
| 100 | 
            -
                    if value != :__missing
         | 
| 101 | 
            -
                      return value
         | 
| 102 | 
            -
                    end
         | 
| 100 | 
            +
                    return value if value != :__missing
         | 
| 103 101 | 
             
                  end
         | 
| 104 102 |  | 
| 105 103 | 
             
                  if default == :__raise || mustache_in_stack.raise_on_context_miss?
         | 
| @@ -121,22 +119,37 @@ class Mustache | |
| 121 119 | 
             
                #
         | 
| 122 120 | 
             
                # Returns the value of key in obj if it is found and default otherwise.
         | 
| 123 121 | 
             
                def find(obj, key, default = nil)
         | 
| 124 | 
            -
                  hash = obj.respond_to?(: | 
| 122 | 
            +
                  hash = obj.respond_to?(:to_hash)
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  if !hash
         | 
| 125 | 
            +
                    # If a class, we need to find tags (methods) per Parser::ALLOWED_CONTENT.
         | 
| 126 | 
            +
                    if key.to_s.include?('-')
         | 
| 127 | 
            +
                      key = key.to_s.gsub('-', '_')
         | 
| 128 | 
            +
                    end
         | 
| 125 129 |  | 
| 126 | 
            -
             | 
| 130 | 
            +
                    if obj.respond_to?(key)
         | 
| 131 | 
            +
                      meth = obj.method(key) rescue proc { obj.send(key) }
         | 
| 132 | 
            +
                      if meth.arity == 1
         | 
| 133 | 
            +
                        meth.to_proc
         | 
| 134 | 
            +
                      else
         | 
| 135 | 
            +
                        meth[]
         | 
| 136 | 
            +
                      end
         | 
| 137 | 
            +
                    else
         | 
| 138 | 
            +
                      default
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
                  elsif hash && obj.has_key?(key)
         | 
| 127 141 | 
             
                    obj[key]
         | 
| 128 142 | 
             
                  elsif hash && obj.has_key?(key.to_s)
         | 
| 129 143 | 
             
                    obj[key.to_s]
         | 
| 130 | 
            -
                  elsif !hash && obj.respond_to?(key)
         | 
| 131 | 
            -
                    meth = obj.method(key) rescue proc { obj.send(key) }
         | 
| 132 | 
            -
                    if meth.arity == 1
         | 
| 133 | 
            -
                      meth.to_proc
         | 
| 134 | 
            -
                    else
         | 
| 135 | 
            -
                      meth[]
         | 
| 136 | 
            -
                    end
         | 
| 137 144 | 
             
                  else
         | 
| 138 | 
            -
                    default
         | 
| 145 | 
            +
                    obj[key] || default
         | 
| 139 146 | 
             
                  end
         | 
| 140 147 | 
             
                end
         | 
| 141 148 | 
             
              end
         | 
| 142 149 | 
             
            end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            class Hash
         | 
| 152 | 
            +
              def to_hash
         | 
| 153 | 
            +
                self
         | 
| 154 | 
            +
              end unless method_defined?(:to_hash)
         | 
| 155 | 
            +
            end
         | 
    
        data/lib/mustache/generator.rb
    CHANGED
    
    | @@ -64,17 +64,22 @@ class Mustache | |
| 64 64 | 
             
                #
         | 
| 65 65 | 
             
                #   [:multi,
         | 
| 66 66 | 
             
                #    [:static, "Hello "],
         | 
| 67 | 
            -
                #    [:mustache, :etag, | 
| 67 | 
            +
                #    [:mustache, :etag,
         | 
| 68 | 
            +
                #     [:mustache, :fetch, ["name"]]],
         | 
| 68 69 | 
             
                #    [:static, "\nYou have just won $"],
         | 
| 69 | 
            -
                # | 
| 70 | 
            -
                #    [: | 
| 71 | 
            -
                # | 
| 72 | 
            -
                # | 
| 73 | 
            -
                # | 
| 74 | 
            -
                # | 
| 75 | 
            -
                # | 
| 76 | 
            -
                # | 
| 77 | 
            -
                # | 
| 70 | 
            +
                #   [:mustache, :etag,
         | 
| 71 | 
            +
                #    [:mustache, :fetch, ["value"]]],
         | 
| 72 | 
            +
                #   [:static, "!\n"],
         | 
| 73 | 
            +
                #   [:mustache,
         | 
| 74 | 
            +
                #    :section,
         | 
| 75 | 
            +
                #    [:mustache, :fetch, ["in_ca"]],
         | 
| 76 | 
            +
                #   [:multi,
         | 
| 77 | 
            +
                #    [:static, "Well, $"],
         | 
| 78 | 
            +
                #    [:mustache, :etag,
         | 
| 79 | 
            +
                #     [:mustache, :fetch, ["taxed_value"]]],
         | 
| 80 | 
            +
                #    [:static, ", after taxes.\n"]],
         | 
| 81 | 
            +
                #    "Well, ${{taxed_value}}, after taxes.\n",
         | 
| 82 | 
            +
                #    ["{{", "}}"]]]
         | 
| 78 83 | 
             
                def compile!(exp)
         | 
| 79 84 | 
             
                  case exp.first
         | 
| 80 85 | 
             
                  when :multi
         | 
| @@ -111,7 +116,7 @@ class Mustache | |
| 111 116 | 
             
                      t.render(ctx.dup)
         | 
| 112 117 | 
             
                    else
         | 
| 113 118 | 
             
                      # Shortcut when passed non-array
         | 
| 114 | 
            -
                      v = [v] unless v.is_a?(Array) || defined?(Enumerator) && v.is_a?(Enumerator)
         | 
| 119 | 
            +
                      v = [v] unless v.is_a?(Array) || v.is_a?(Mustache::Enumerable) || defined?(Enumerator) && v.is_a?(Enumerator)
         | 
| 115 120 |  | 
| 116 121 | 
             
                      v.map { |h| ctx.push(h); r = #{code}; ctx.pop; r }.join
         | 
| 117 122 | 
             
                    end
         |