hirb 0.2.10 → 0.3.0
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.
- data/CHANGELOG.rdoc +14 -0
- data/README.rdoc +67 -63
- data/Rakefile +3 -0
- data/lib/hirb.rb +25 -18
- data/lib/hirb/console.rb +3 -3
- data/lib/hirb/dynamic_view.rb +112 -0
- data/lib/hirb/formatter.rb +61 -140
- data/lib/hirb/helpers.rb +11 -1
- data/lib/hirb/helpers/auto_table.rb +20 -12
- data/lib/hirb/helpers/object_table.rb +2 -2
- data/lib/hirb/helpers/table.rb +15 -14
- data/lib/hirb/helpers/tree.rb +19 -15
- data/lib/hirb/import_object.rb +1 -1
- data/lib/hirb/menu.rb +1 -1
- data/lib/hirb/util.rb +1 -1
- data/lib/hirb/version.rb +3 -0
- data/lib/hirb/view.rb +74 -19
- data/lib/hirb/views.rb +8 -0
- data/lib/hirb/views/couch_db.rb +11 -0
- data/lib/hirb/views/misc_db.rb +15 -0
- data/lib/hirb/views/mongo_db.rb +15 -0
- data/lib/hirb/views/orm.rb +11 -0
- data/lib/hirb/views/rails.rb +19 -0
- data/test/dynamic_view_test.rb +96 -0
- data/test/formatter_test.rb +36 -48
- data/test/table_test.rb +41 -4
- data/test/tree_test.rb +17 -0
- data/test/view_test.rb +6 -0
- data/test/views_test.rb +15 -0
- metadata +24 -11
- data/VERSION.yml +0 -5
- data/lib/hirb/hash_struct.rb +0 -17
- data/lib/hirb/helpers/active_record_table.rb +0 -26
- data/lib/hirb/views/activerecord_base.rb +0 -9
- data/test/active_record_table_test.rb +0 -35
    
        data/CHANGELOG.rdoc
    CHANGED
    
    | @@ -1,3 +1,17 @@ | |
| 1 | 
            +
            == 0.3.0
         | 
| 2 | 
            +
            * Added dynamic views.
         | 
| 3 | 
            +
            * Added default table views for the following database classes/modules:
         | 
| 4 | 
            +
              CouchFoo::Base, CouchPotato::Persistence, CouchRest::ExtendedDocument,
         | 
| 5 | 
            +
              DBI::Row, DataMapper::Resource, Friendly::Document, MongoMapper::Document, MongoMapper::EmbeddedDocument,
         | 
| 6 | 
            +
              Mongoid::Document, Ripple::Document and Sequel::Model.
         | 
| 7 | 
            +
            * Added Hirb.add_view and Hirb.add_dynamic_view for easier view manipulation.
         | 
| 8 | 
            +
            * Added :multi_line_nodes option for Tree.
         | 
| 9 | 
            +
            * Fixed :change_fields option bug in Table.
         | 
| 10 | 
            +
            * Fixed no headers and nil fields bug in Table.
         | 
| 11 | 
            +
            * Removed deprecations in Hirb.config_file + View.enable.
         | 
| 12 | 
            +
            * Removed Views classes and View.format_class.
         | 
| 13 | 
            +
            * Removed :return_rows option for Table.
         | 
| 14 | 
            +
             | 
| 1 15 | 
             
            == 0.2.10
         | 
| 2 16 | 
             
            * Added multiple options to Menu, most importantly :two_d and :action.
         | 
| 3 17 | 
             
            * Improved table resizing algorithm.
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -1,12 +1,14 @@ | |
| 1 1 | 
             
            == Description
         | 
| 2 2 |  | 
| 3 | 
            -
            Hirb  | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 3 | 
            +
            Hirb provides a mini view framework for console applications and uses it to improve irb's default inspect output.
         | 
| 4 | 
            +
            Given an object or array of objects, hirb renders a view based on the object's class and/or ancestry. Hirb offers reusable
         | 
| 5 | 
            +
            views in the form of helper classes. The two main helpers, Hirb::Helpers::Table and Hirb::Helpers::Tree, provide several options
         | 
| 6 | 
            +
            for generating ascii tables and trees. Using Hirb::Helpers::AutoTable, hirb has useful default views for at least ten popular database gems
         | 
| 7 | 
            +
            i.e. Rails' ActiveRecord::Base. Other than views, hirb offers a smart pager and a console menu. The smart pager
         | 
| 8 | 
            +
            only pages when the output exceeds the current screen size. The menu is used in conjunction with tables to offer
         | 
| 9 | 
            +
            {two dimensional menus}[http://tagaholic.me/2010/02/16/two-dimensional-console-menus-with-hirb.html].
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Note: To read a linked version of this README, {click here}[http://tagaholic.me/hirb/doc/].
         | 
| 10 12 |  | 
| 11 13 | 
             
            == Install
         | 
| 12 14 |  | 
| @@ -14,40 +16,28 @@ Install the gem with: | |
| 14 16 |  | 
| 15 17 | 
             
                sudo gem install hirb
         | 
| 16 18 |  | 
| 17 | 
            -
            ==  | 
| 18 | 
            -
             | 
| 19 | 
            -
            Hirb has both pager and formatter functionality enabled by default.
         | 
| 20 | 
            -
            If you want to turn off the functionality of either you can pass that in at startup:
         | 
| 19 | 
            +
            == View Tutorials
         | 
| 21 20 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 21 | 
            +
            * To create and configure views, see Hirb::View or {here if on the web}[http://tagaholic.me/hirb/doc/classes/Hirb/View.html].
         | 
| 22 | 
            +
            * To create dynamic views, see Hirb::DynamicView or {here if on the web}[http://tagaholic.me/hirb/doc/classes/Hirb/DynamicView.html].
         | 
| 24 23 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
              Hirb::View.toggle_pager
         | 
| 28 | 
            -
              Hirb::View.toggle_formatter
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            == Create and Configure Views
         | 
| 31 | 
            -
             | 
| 32 | 
            -
            If you'd like to learn how to create and configure views, {read the docs}[http://tagaholic.me/hirb/doc/classes/Hirb/Formatter.html].
         | 
| 33 | 
            -
             | 
| 34 | 
            -
            == Rails Formatter Example
         | 
| 24 | 
            +
            == Rails Example
         | 
| 35 25 |  | 
| 36 26 | 
             
            Let's load and enable the view framework:
         | 
| 37 | 
            -
               | 
| 38 | 
            -
              Loading local environment (Rails 2. | 
| 39 | 
            -
               | 
| 27 | 
            +
              $ script/console
         | 
| 28 | 
            +
              Loading local environment (Rails 2.3.5)
         | 
| 29 | 
            +
              >> require 'hirb'
         | 
| 40 30 | 
             
              => true
         | 
| 41 | 
            -
               | 
| 31 | 
            +
              >> Hirb.enable
         | 
| 42 32 | 
             
              => nil
         | 
| 43 33 |  | 
| 44 34 | 
             
            The default configuration provides table views for ActiveRecord::Base descendants.
         | 
| 45 35 | 
             
            If a class isn't configured, Hirb reverts to irb's default echo mode.
         | 
| 46 | 
            -
               | 
| 47 | 
            -
              => { | 
| 36 | 
            +
              >> Hirb::Formatter.dynamic_config['ActiveRecord::Base']
         | 
| 37 | 
            +
              => {:class=>Hirb::Helpers::AutoTable, :ancestor=>true}
         | 
| 48 38 |  | 
| 49 39 | 
             
              # Tag is a model class and descendant of ActiveRecord::Base
         | 
| 50 | 
            -
               | 
| 40 | 
            +
              >> Tag.last
         | 
| 51 41 | 
             
              +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
         | 
| 52 42 | 
             
              | id  | created_at              | description | name          | namespace | predicate | value |
         | 
| 53 43 | 
             
              +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
         | 
| @@ -55,19 +45,22 @@ If a class isn't configured, Hirb reverts to irb's default echo mode. | |
| 55 45 | 
             
              +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
         | 
| 56 46 | 
             
              1 row in set
         | 
| 57 47 |  | 
| 58 | 
            -
               | 
| 48 | 
            +
              >> Hirb::Formatter.dynamic_config['String']
         | 
| 49 | 
            +
              => nil
         | 
| 50 | 
            +
              >> 'plain ol irb'
         | 
| 59 51 | 
             
              => 'plain ol irb'
         | 
| 60 | 
            -
               | 
| 52 | 
            +
              >> Hirb::Formatter.dynamic_config['Symbol']
         | 
| 53 | 
            +
              => nil
         | 
| 54 | 
            +
              >> :blah
         | 
| 61 55 | 
             
              => :blah
         | 
| 62 56 |  | 
| 63 | 
            -
            From above you can see there  | 
| 64 | 
            -
            irb's echo mode.  | 
| 65 | 
            -
             | 
| 57 | 
            +
            From above you can see there are no views configured for a String or a Symbol so Hirb defaults to
         | 
| 58 | 
            +
            irb's echo mode. On the other hand, Tag has a view thanks to being a descendant of ActiveRecord::Base
         | 
| 59 | 
            +
            and there being an :ancestor option.
         | 
| 66 60 |  | 
| 67 | 
            -
             | 
| 68 | 
            -
            you may appreciate it also detects configured output objects in an array:
         | 
| 61 | 
            +
            Having seen hirb display views based on an output object's class, let's see it handle an array of objects:
         | 
| 69 62 |  | 
| 70 | 
            -
               | 
| 63 | 
            +
              >> Tag.all :limit=>3, :order=>"id DESC"
         | 
| 71 64 | 
             
              +-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
         | 
| 72 65 | 
             
              | id  | created_at              | description | name              | namespace | predicate | value    |
         | 
| 73 66 | 
             
              +-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
         | 
| @@ -78,9 +71,9 @@ you may appreciate it also detects configured output objects in an array: | |
| 78 71 | 
             
              3 rows in set
         | 
| 79 72 |  | 
| 80 73 | 
             
            At any time you can disable Hirb if you really like irb's lovely echo mode:
         | 
| 81 | 
            -
               | 
| 74 | 
            +
              >> Hirb.disable
         | 
| 82 75 | 
             
              => nil
         | 
| 83 | 
            -
               | 
| 76 | 
            +
              >> Tag.all :limit=>3, :order=>"id DESC"
         | 
| 84 77 | 
             
              => [#<Tag id: 907, name: "gem:tags=yaml", description: nil, created_at: "2009-03-06 21:10:41",
         | 
| 85 78 | 
             
              namespace: "gem", predicate: "tags", value: "yaml">, #<Tag id: 906, name: "gem:tags=nomonkey",
         | 
| 86 79 | 
             
              description: nil, created_at: "2009-03-06 08:47:04", namespace: "gem", predicate: "tags", value:
         | 
| @@ -92,15 +85,15 @@ While preconfigured tables are great for database records, sometimes you just wa | |
| 92 85 | 
             
            tables/views for any output object:
         | 
| 93 86 |  | 
| 94 87 | 
             
              #These examples don't need to have Hirb::View enabled.
         | 
| 95 | 
            -
               | 
| 96 | 
            -
              =>nil
         | 
| 88 | 
            +
              >> Hirb.disable
         | 
| 89 | 
            +
              => nil
         | 
| 97 90 |  | 
| 98 91 | 
             
              # Imports table() and view()
         | 
| 99 | 
            -
               | 
| 100 | 
            -
              =>main
         | 
| 92 | 
            +
              >> extend Hirb::Console
         | 
| 93 | 
            +
              => main
         | 
| 101 94 |  | 
| 102 95 | 
             
              # Create a table of Dates comparing them with different formats.
         | 
| 103 | 
            -
               | 
| 96 | 
            +
              >> table [Date.today, Date.today.next_month], :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
         | 
| 104 97 | 
             
              +------------+--------+-----------+-------+--------------------------+
         | 
| 105 98 | 
             
              | to_s       | ld     | ajd       | amjd  | asctime                  |
         | 
| 106 99 | 
             
              +------------+--------+-----------+-------+--------------------------+
         | 
| @@ -110,44 +103,56 @@ tables/views for any output object: | |
| 110 103 | 
             
              2 rows in set
         | 
| 111 104 |  | 
| 112 105 | 
             
              # Same table as the previous method. However view() will be able to call any helper.
         | 
| 113 | 
            -
               | 
| 106 | 
            +
              >> view [Date.today, Date.today.next_month], :class=>:object_table,
         | 
| 114 107 | 
             
                :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
         | 
| 115 108 |  | 
| 116 109 | 
             
            If these console methods weren't convenient enough, try:
         | 
| 117 110 |  | 
| 118 111 | 
             
              # Imports view() to all objects.
         | 
| 119 | 
            -
               | 
| 112 | 
            +
              >> require 'hirb/import_object'
         | 
| 120 113 | 
             
              =>true
         | 
| 121 114 | 
             
              # Yields same table as above examples.
         | 
| 122 | 
            -
               | 
| 115 | 
            +
              >> [Date.today, Date.today.next_month].view :class=>:object_table,
         | 
| 123 116 | 
             
                :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
         | 
| 124 117 |  | 
| 125 118 | 
             
            Although views by default are printed to STDOUT, they can be easily modified to write anywhere:
         | 
| 126 119 | 
             
              # Setup views to write to file 'console.log'.
         | 
| 127 | 
            -
               | 
| 120 | 
            +
              >> Hirb::View.render_method = lambda {|output| File.open("console.log", 'w') {|f| f.write(output) } }
         | 
| 128 121 |  | 
| 129 122 | 
             
              # Writes to file with same table output as above example.
         | 
| 130 | 
            -
               | 
| 123 | 
            +
              >> view [Date.today, Date.today.next_month], :class=>:object_table,
         | 
| 131 124 | 
             
                :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
         | 
| 132 125 |  | 
| 133 | 
            -
              # Doesn't write to file because Symbol  | 
| 134 | 
            -
               | 
| 126 | 
            +
              # Doesn't write to file because Symbol doesn't have a view and thus defaults to irb's echo mode.
         | 
| 127 | 
            +
              >> :blah
         | 
| 135 128 | 
             
              =>:blah
         | 
| 136 129 |  | 
| 137 130 | 
             
              # Go back to printing Hirb views to STDOUT.
         | 
| 138 | 
            -
               | 
| 131 | 
            +
              >> Hirb::View.reset_render_method
         | 
| 132 | 
            +
             | 
| 133 | 
            +
            == Pager
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            Hirb has both pager and formatter functionality enabled by default.
         | 
| 136 | 
            +
            If you want to turn off the functionality of either you can pass that in at startup:
         | 
| 137 | 
            +
             | 
| 138 | 
            +
              Hirb.enable :pager=>false
         | 
| 139 | 
            +
              Hirb.enable :formatter=>false
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            or toggle their state at runtime:
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              Hirb::View.toggle_pager
         | 
| 144 | 
            +
              Hirb::View.toggle_formatter
         | 
| 139 145 |  | 
| 140 | 
            -
            == Sharing Views
         | 
| 141 | 
            -
            If you have tested  | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 146 | 
            +
            == Sharing Helpers and Views
         | 
| 147 | 
            +
            If you have tested helpers you'd like to share, fork Hirb and put them under lib/hirb/helpers. To share
         | 
| 148 | 
            +
            views for certain classes, put them under lib/hirb/views. Please submit views for gems that have a nontrivial
         | 
| 149 | 
            +
            number of users.
         | 
| 144 150 |  | 
| 145 151 | 
             
            == Limitations
         | 
| 146 152 | 
             
            If using Wirble, you should call Hirb after it since they both override irb's default output.
         | 
| 147 153 |  | 
| 148 154 | 
             
            == Motivation
         | 
| 149 | 
            -
            Table code from http://gist.github.com/72234 and {my console
         | 
| 150 | 
            -
            app's needs}[http://github.com/cldwalker/tag-tree].
         | 
| 155 | 
            +
            Table code from http://gist.github.com/72234 and {my console app's needs}[http://github.com/cldwalker/tag-tree].
         | 
| 151 156 |  | 
| 152 157 | 
             
            == Credits
         | 
| 153 158 | 
             
            * Chrononaut for vertical table helper.
         | 
| @@ -162,7 +167,6 @@ Please report them {on github}[http://github.com/cldwalker/hirb/issues]. | |
| 162 167 | 
             
            * http://tagaholic.me/2009/06/19/page-irb-output-and-improve-ri-with-hirb.html
         | 
| 163 168 |  | 
| 164 169 | 
             
            == Todo
         | 
| 165 | 
            -
            * Consider  | 
| 166 | 
            -
            *  | 
| 167 | 
            -
            *  | 
| 168 | 
            -
            * Consider adding a template system as needed.
         | 
| 170 | 
            +
            * Consider generating views based on methods an object responds to.
         | 
| 171 | 
            +
            * Provide helper methods to all views.
         | 
| 172 | 
            +
            * Consider adding a template helper.
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -16,8 +16,11 @@ end | |
| 16 16 |  | 
| 17 17 | 
             
            begin
         | 
| 18 18 | 
             
              require 'jeweler'
         | 
| 19 | 
            +
              require File.dirname(__FILE__) + "/lib/hirb/version"
         | 
| 20 | 
            +
             | 
| 19 21 | 
             
              Jeweler::Tasks.new do |s|
         | 
| 20 22 | 
             
                s.name = "hirb"
         | 
| 23 | 
            +
                s.version = Hirb::VERSION
         | 
| 21 24 | 
             
                s.summary = "A mini view framework for console/irb that's easy to use, even while under its influence."
         | 
| 22 25 | 
             
                s.description = "Hirb currently provides a mini view framework for console applications, designed to improve irb's default output.  Hirb improves console output by providing a smart pager and auto-formatting output. The smart pager detects when an output exceeds a screenful and thus only pages output as needed. Auto-formatting adds a view to an output's class. This is helpful in separating views from content (MVC anyone?). The framework encourages reusing views by letting you package them in classes and associate them with any number of output classes."
         | 
| 23 26 | 
             
                s.email = "gabriel.horner@gmail.com"
         | 
    
        data/lib/hirb.rb
    CHANGED
    
    | @@ -6,28 +6,29 @@ $KCODE = 'u' if RUBY_VERSION < '1.9' | |
| 6 6 |  | 
| 7 7 | 
             
            require 'hirb/util'
         | 
| 8 8 | 
             
            require 'hirb/string'
         | 
| 9 | 
            -
            require 'hirb/ | 
| 9 | 
            +
            require 'hirb/formatter' # must come before helpers/auto_table
         | 
| 10 | 
            +
            require 'hirb/dynamic_view'
         | 
| 10 11 | 
             
            require 'hirb/helpers'
         | 
| 12 | 
            +
            require 'hirb/views'
         | 
| 11 13 | 
             
            require 'hirb/view'
         | 
| 12 | 
            -
            require 'hirb/views/activerecord_base'
         | 
| 13 14 | 
             
            require 'hirb/console'
         | 
| 14 | 
            -
            require 'hirb/formatter'
         | 
| 15 15 | 
             
            require 'hirb/pager'
         | 
| 16 16 | 
             
            require 'hirb/menu'
         | 
| 17 | 
            +
            require 'hirb/version'
         | 
| 17 18 |  | 
| 18 | 
            -
            # Most of Hirb's functionality  | 
| 19 | 
            -
            # For  | 
| 19 | 
            +
            # Most of Hirb's functionality is in Hirb::View.
         | 
| 20 | 
            +
            # For a tutorial  on configuring and creating views see Hirb::View. For a tutorial on dynamic views see Hirb::DynamicView.
         | 
| 21 | 
            +
            #
         | 
| 22 | 
            +
            # == Config Files
         | 
| 20 23 | 
             
            # Hirb can have multiple config files defined by config_files(). These config files
         | 
| 21 24 | 
             
            # have the following top level keys:
         | 
| 22 | 
            -
            # [ | 
| 23 | 
            -
            # [ | 
| 24 | 
            -
            # [ | 
| 25 | 
            -
            # [ | 
| 26 | 
            -
            # [ | 
| 27 | 
            -
            # [ | 
| 28 | 
            -
            # | 
| 29 | 
            -
            #
         | 
| 30 | 
            -
             | 
| 25 | 
            +
            # [*:output*] This hash is used by the formatter object. See Hirb::Formatter.config for its format.
         | 
| 26 | 
            +
            # [*:width*]  Width of the terminal/console. Defaults to Hirb::View::DEFAULT_WIDTH or possibly autodetected when Hirb is enabled.
         | 
| 27 | 
            +
            # [*:height*]  Height of the terminal/console. Defaults to Hirb::View::DEFAULT_HEIGHT or possibly autodetected when Hirb is enabled.
         | 
| 28 | 
            +
            # [*:formatter*] Boolean which determines if the formatter is enabled. Defaults to true.
         | 
| 29 | 
            +
            # [*:pager*] Boolean which determines if the pager is enabled. Defaults to true.
         | 
| 30 | 
            +
            # [*:pager_command*] Command to be used for paging. Command can have options after it i.e. 'less -r'.
         | 
| 31 | 
            +
            #                    Defaults to common pagers i.e. less and more if detected.
         | 
| 31 32 | 
             
            module Hirb
         | 
| 32 33 | 
             
              class <<self
         | 
| 33 34 | 
             
                attr_accessor :config_files, :config
         | 
| @@ -42,6 +43,16 @@ module Hirb | |
| 42 43 | 
             
                  View.disable
         | 
| 43 44 | 
             
                end
         | 
| 44 45 |  | 
| 46 | 
            +
                # Adds views. See Hirb::View.add for details.
         | 
| 47 | 
            +
                def add_view(view, options, &block)
         | 
| 48 | 
            +
                  View.add(view, options, &block)
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                # Adds views. See Hirb::DynamicView.add for details.
         | 
| 52 | 
            +
                def add_dynamic_view(view, options, &block)
         | 
| 53 | 
            +
                  DynamicView.add(view, options, &block)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 45 56 | 
             
                # Array of config files which are merged sequentially to produce config.
         | 
| 46 57 | 
             
                # Defaults to config/hirb.yml and ~/.hirb_yml
         | 
| 47 58 | 
             
                def config_files
         | 
| @@ -49,10 +60,6 @@ module Hirb | |
| 49 60 | 
             
                end
         | 
| 50 61 |  | 
| 51 62 | 
             
                #:stopdoc:
         | 
| 52 | 
            -
                def config_file
         | 
| 53 | 
            -
                  puts "Hirb.config_file is *deprecated*. Use Hirb.config_files"
         | 
| 54 | 
            -
                end
         | 
| 55 | 
            -
             | 
| 56 63 | 
             
                def default_config_files
         | 
| 57 64 | 
             
                  [File.join(Util.find_home, ".hirb.yml")] +
         | 
| 58 65 | 
             
                    (File.exists?('config/hirb.yml') ? ['config/hirb.yml'] : [])
         | 
    
        data/lib/hirb/console.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            module Hirb
         | 
| 2 2 | 
             
              # This module is meant to be extended to provide methods for use in a console/irb shell.
         | 
| 3 3 | 
             
              # For example:
         | 
| 4 | 
            -
              #     | 
| 5 | 
            -
              #     | 
| 6 | 
            -
              #     | 
| 4 | 
            +
              #    >> extend Hirb::Console
         | 
| 5 | 
            +
              #    >> view 'some string', :class=>Some::String::Formatter
         | 
| 6 | 
            +
              #    >> table [[:row1], [:row2]]
         | 
| 7 7 | 
             
              module Console
         | 
| 8 8 | 
             
                class<<self
         | 
| 9 9 | 
             
                  # A console version of render_output() which takes its same options but allows for shorthand. All options are passed to
         | 
| @@ -0,0 +1,112 @@ | |
| 1 | 
            +
            module Hirb
         | 
| 2 | 
            +
              # This module extends a Helper with the ability to have dynamic views for configured output classes.
         | 
| 3 | 
            +
              # After a Helper has extended this module, it can use it within a render() by calling
         | 
| 4 | 
            +
              # dynamic_options() to get dynamically generated options for the object it's rendering. See Hirb::Helpers::AutoTable as an example.
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              # == Dynamic Views
         | 
| 7 | 
            +
              # Whereas normal views are generated from helpers with static helper options, dynamic views are generated from helpers and
         | 
| 8 | 
            +
              # dynamically generated helper options. Let's look at an example for Rails' ActiveRecord classes:
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              #   Hirb.add_dynamic_view("ActiveRecord::Base", :helper=>:auto_table) {|obj|
         | 
| 11 | 
            +
              #    {:fields=>obj.class.column_names} }
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              # From this dynamic view definition, _any_ ActiveRecord model class will render a table with the correct fields, since the fields
         | 
| 14 | 
            +
              # are extracted from the output object's class at runtime. Note that dynamic view definitions should return a hash of helper options.
         | 
| 15 | 
            +
              #
         | 
| 16 | 
            +
              # To define multiple dynamic views, create a Views module where each method ending in '\_view' maps to a class/module:
         | 
| 17 | 
            +
              #
         | 
| 18 | 
            +
              #   module Hirb::Views::ORM
         | 
| 19 | 
            +
              #     def data_mapper__resource_view(obj)
         | 
| 20 | 
            +
              #       {:fields=>obj.class.properties.map {|e| e.name }}
         | 
| 21 | 
            +
              #     end
         | 
| 22 | 
            +
              #
         | 
| 23 | 
            +
              #     def sequel__model_view(obj)
         | 
| 24 | 
            +
              #       {:fields=>obj.class.columns}
         | 
| 25 | 
            +
              #     end
         | 
| 26 | 
            +
              #   end
         | 
| 27 | 
            +
              #
         | 
| 28 | 
            +
              #   Hirb.add_dynamic_view Hirb::Views::ORM, :helper=>:auto_table
         | 
| 29 | 
            +
              #
         | 
| 30 | 
            +
              # In this example, 'data_mapper__resource_view' maps to DataMapper::Resource and 'sequel__model_view' maps to Sequel::Model.
         | 
| 31 | 
            +
              # Note that when mapping method names to class names, '__' maps to '::' and '_' signals the next letter to be capitalized.
         | 
| 32 | 
            +
              module DynamicView
         | 
| 33 | 
            +
                # Add dynamic views to output class(es) for a given helper. If defining one view, the first argument is the output class
         | 
| 34 | 
            +
                # and a block defines the dynamic view. If defining multiple views, the first argument should be a Views::* module where
         | 
| 35 | 
            +
                # each method in the module ending in _view defines a view for an output class. To map output classes to method names in
         | 
| 36 | 
            +
                # a Views module, translate'::' to '__' and a capital letter translates to a '_' and a lowercase letter.
         | 
| 37 | 
            +
                # ==== Options:
         | 
| 38 | 
            +
                # [*:helper*] Required option. Helper class that view(s) use to format. Hirb::Helpers::AutoTable is the only valid
         | 
| 39 | 
            +
                #             helper among default helpers. Can be given in aliased form i.e. :auto_table -> Hirb::Helpers::AutoTable.
         | 
| 40 | 
            +
                #
         | 
| 41 | 
            +
                # Examples:
         | 
| 42 | 
            +
                #    Hirb.add_dynamic_view Hirb::Views::ORM, :helper=>:auto_table
         | 
| 43 | 
            +
                #    Hirb.add_dynamic_view("ActiveRecord::Base", :helper=>:auto_table) {|obj| {:fields=>obj.class.column_names} }
         | 
| 44 | 
            +
                def self.add(view, options, &block)
         | 
| 45 | 
            +
                  raise ArgumentError, ":helper option is required" unless options[:helper]
         | 
| 46 | 
            +
                  helper = Helpers.helper_class options[:helper]
         | 
| 47 | 
            +
                  unless helper.is_a?(Module) && class << helper; self.ancestors; end.include?(self)
         | 
| 48 | 
            +
                    raise ArgumentError, ":helper option must be a helper that has extended DynamicView"
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  mod = block ? generate_single_view_module(view, &block) : view
         | 
| 51 | 
            +
                  raise ArgumentError, "'#{mod}' must be a module" unless mod.is_a?(Module)
         | 
| 52 | 
            +
                  helper.add_module mod
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def self.generate_single_view_module(output_mod, &block) #:nodoc:
         | 
| 56 | 
            +
                  mod_name = class_to_method output_mod.to_s
         | 
| 57 | 
            +
                  Views::Single.send(:remove_const, mod_name) if Views::Single.const_defined?(mod_name)
         | 
| 58 | 
            +
                  mod = Views::Single.const_set(mod_name, Module.new)
         | 
| 59 | 
            +
                  mod.send(:define_method, mod_name.downcase, block)
         | 
| 60 | 
            +
                  mod
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def self.class_to_method(mod) #:nodoc:
         | 
| 64 | 
            +
                  mod.gsub("::","__").gsub(/([A-Z])/, '_\1').gsub(/(^|::)_/,'\1') + '_view'
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                # Returns a hash of options based on dynamic views defined for the object's ancestry. If no config is found returns nil.
         | 
| 68 | 
            +
                def dynamic_options(obj)
         | 
| 69 | 
            +
                  view_methods.each do |meth|
         | 
| 70 | 
            +
                    if obj.class.ancestors.map {|e| e.to_s }.include?(method_to_class(meth))
         | 
| 71 | 
            +
                      begin
         | 
| 72 | 
            +
                        return send(meth, obj)
         | 
| 73 | 
            +
                      rescue
         | 
| 74 | 
            +
                        raise "View failed to generate for '#{method_to_class(meth)}' "+
         | 
| 75 | 
            +
                          "while in '#{meth}' with error:\n#{$!.message}"
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                  nil
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                #:stopdoc:
         | 
| 83 | 
            +
                def add_module(mod)
         | 
| 84 | 
            +
                  new_methods = mod.instance_methods.select {|e| e.to_s =~ /_view$/ }.map {|e| e.to_s}
         | 
| 85 | 
            +
                  return if new_methods.empty?
         | 
| 86 | 
            +
                  extend mod
         | 
| 87 | 
            +
                  view_methods.replace(view_methods + new_methods).uniq!
         | 
| 88 | 
            +
                  update_config(new_methods)
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                def update_config(meths)
         | 
| 92 | 
            +
                  output_config = meths.inject({}) {|t,e|
         | 
| 93 | 
            +
                    t[method_to_class(e)] = {:class=>self, :ancestor=>true}; t
         | 
| 94 | 
            +
                  }
         | 
| 95 | 
            +
                  Formatter.dynamic_config.merge! output_config
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def method_to_class(meth)
         | 
| 99 | 
            +
                  view_method_classes[meth] ||= Util.camelize meth.sub(/_view$/, '').gsub('__', '/')
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                def view_method_classes
         | 
| 103 | 
            +
                  @view_method_classes ||= {}
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
                #:startdoc:
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                # Stores view methods that a Helper has been given via DynamicView.add
         | 
| 108 | 
            +
                def view_methods
         | 
| 109 | 
            +
                  @view_methods ||= []
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
            end
         | 
    
        data/lib/hirb/formatter.rb
    CHANGED
    
    | @@ -1,160 +1,77 @@ | |
| 1 1 | 
             
            module Hirb
         | 
| 2 | 
            -
             | 
| 3 | 
            -
               | 
| 4 | 
            -
              The formatter object looks for an output's class config in Hirb::Formatter.config and if found applies a helper to the output.
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              == Create and Configure Views
         | 
| 7 | 
            -
              Let's create a simple view and configure it in different ways to be Hash's default view:
         | 
| 8 | 
            -
             | 
| 9 | 
            -
              === Setup
         | 
| 10 | 
            -
                irb>> require 'hirb'
         | 
| 11 | 
            -
                =>true
         | 
| 12 | 
            -
                irb>> Hirb.enable
         | 
| 13 | 
            -
                =>nil
         | 
| 14 | 
            -
                irb>> require 'yaml'
         | 
| 15 | 
            -
                =>true
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              === Configure As View Method
         | 
| 18 | 
            -
              A view method is the smallest reuseable view.
         | 
| 19 | 
            -
                # Create yaml view method
         | 
| 20 | 
            -
                irb>> def yaml(output); output.to_yaml; end
         | 
| 21 | 
            -
                =>nil
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                # Configure view
         | 
| 24 | 
            -
                irb>>Hirb::View.format_class Hash, :method=>:yaml
         | 
| 25 | 
            -
                =>true
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                # Hashes now appear as yaml
         | 
| 28 | 
            -
                irb>>{:a=>1, :b=>{:c=>3}}
         | 
| 29 | 
            -
                ---
         | 
| 30 | 
            -
                :a : 1
         | 
| 31 | 
            -
                :b : 
         | 
| 32 | 
            -
                  :c : 3
         | 
| 33 | 
            -
                => true
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              === Configure As View Class
         | 
| 36 | 
            -
              A view class is suited for more complex views. View classes can be under any namespace
         | 
| 37 | 
            -
              and are expected to provide a render method. However, if a class is under the Hirb::Views namespace,
         | 
| 38 | 
            -
              it will be automatically loaded with no configuration. Something to think about when
         | 
| 39 | 
            -
              sharing views with others.
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                # Create yaml view class
         | 
| 42 | 
            -
                irb>> class Hirb::Views::Hash; def self.render(output, options={}); output.to_yaml; end ;end
         | 
| 43 | 
            -
                =>nil
         | 
| 44 | 
            -
                # Just reload since no configuration is necessary
         | 
| 45 | 
            -
                irb>>Hirb::View.formatter.reload
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                # Hashes now appear as yaml ...
         | 
| 48 | 
            -
             | 
| 49 | 
            -
              Although the Hirb::Views namespace is great for quick classes that just plug and play, you
         | 
| 50 | 
            -
              often want view classes that can be reused with multiple outputs. For this case, it's recommended to
         | 
| 51 | 
            -
              use the Hirb::Helpers namespace.
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                # Create yaml view class
         | 
| 54 | 
            -
                irb>> class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
         | 
| 55 | 
            -
                =>nil
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                # Configure view and reload it
         | 
| 58 | 
            -
                irb>>Hirb::View.format_class Hash, :class=>"Hirb::Helpers::Yaml"
         | 
| 59 | 
            -
                =>true
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                # Hashes now appear as yaml ...
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                == Configure At Startup
         | 
| 64 | 
            -
                Once you know what views are associated with what output classes, you can configure
         | 
| 65 | 
            -
                them at startup by passing Hirb.enable an options hash:
         | 
| 66 | 
            -
                  # In .irbrc
         | 
| 67 | 
            -
                  require 'hirb'
         | 
| 68 | 
            -
                  # View class needs to come before enable()
         | 
| 69 | 
            -
                  class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
         | 
| 70 | 
            -
                  Hirb.enable :output=>{"Hash"=>{:class=>"Hirb::Helpers::Yaml"}}
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                Or by creating a config file at config/hirb.yml or ~/.hirb.yml:
         | 
| 73 | 
            -
                  # The config file for the yaml example would look like:
         | 
| 74 | 
            -
                  # ---
         | 
| 75 | 
            -
                  # :output :
         | 
| 76 | 
            -
                  #   Hash :
         | 
| 77 | 
            -
                  #    :class : Hirb::Helpers::Yaml
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  # In .irbrc
         | 
| 80 | 
            -
                  require 'hirb'
         | 
| 81 | 
            -
                  # View class needs to come before enable()
         | 
| 82 | 
            -
                  class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
         | 
| 83 | 
            -
                  Hirb.enable
         | 
| 84 | 
            -
            =end 
         | 
| 85 | 
            -
              
         | 
| 2 | 
            +
              # A Formatter object formats an output object (using Formatter.format_output) into a string based on the views defined
         | 
| 3 | 
            +
              # for its class and/or ancestry.
         | 
| 86 4 | 
             
              class Formatter
         | 
| 87 | 
            -
                 | 
| 5 | 
            +
                class<<self
         | 
| 6 | 
            +
                  # This config is used by Formatter.format_output to lazily load dynamic views defined with Hirb::DynamicView.
         | 
| 7 | 
            +
                  # This hash has the same format as Formatter.config.
         | 
| 8 | 
            +
                  attr_accessor :dynamic_config
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                self.dynamic_config = {}
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def initialize(additional_config={}) #:nodoc:
         | 
| 88 13 | 
             
                  @klass_config = {}
         | 
| 89 | 
            -
                  @config =  | 
| 14 | 
            +
                  @config = additional_config || {}
         | 
| 90 15 | 
             
                end
         | 
| 91 16 |  | 
| 92 | 
            -
                # A hash of Ruby class strings mapped to  | 
| 93 | 
            -
                # or :class option for a  | 
| 94 | 
            -
                # [ | 
| 95 | 
            -
                # [ | 
| 96 | 
            -
                # | 
| 97 | 
            -
                # [ | 
| 98 | 
            -
                # | 
| 99 | 
            -
                # [ | 
| 100 | 
            -
                # [ | 
| 101 | 
            -
                # | 
| 17 | 
            +
                # A hash of Ruby class strings mapped to view hashes. A view hash must have at least a :method, :output_method
         | 
| 18 | 
            +
                # or :class option for a view to be applied to an output. A view hash has the following keys:
         | 
| 19 | 
            +
                # [*:method*] Specifies a global (Kernel) method to do the formatting.
         | 
| 20 | 
            +
                # [*:class*] Specifies a class to do the formatting, using its render() class method. If a symbol it's converted to a corresponding
         | 
| 21 | 
            +
                #            Hirb::Helpers::* class if it exists.
         | 
| 22 | 
            +
                # [*:output_method*] Specifies a method or proc to call on output before passing it to a helper. If the output is an array, it's applied
         | 
| 23 | 
            +
                #                    to every element in the array.
         | 
| 24 | 
            +
                # [*:options*] Options to pass the helper method or class.
         | 
| 25 | 
            +
                # [*:ancestor*] Boolean which when true causes subclasses of the output class to inherit its config. This doesn't effect the current
         | 
| 26 | 
            +
                #               output class. Defaults to false. This is used by ActiveRecord classes.
         | 
| 102 27 | 
             
                # 
         | 
| 103 28 | 
             
                #   Examples:
         | 
| 104 29 | 
             
                #     {'WWW::Delicious::Element'=>{:class=>'Hirb::Helpers::ObjectTable', :ancestor=>true, :options=>{:max_width=>180}}}
         | 
| 105 30 | 
             
                #     {'Date'=>{:class=>:auto_table, :ancestor=>true}}
         | 
| 31 | 
            +
                #     {'Hash'=>{:method=>:puts}}
         | 
| 106 32 | 
             
                def config
         | 
| 107 33 | 
             
                  @config
         | 
| 108 34 | 
             
                end
         | 
| 109 35 |  | 
| 110 | 
            -
                #  | 
| 111 | 
            -
                def  | 
| 36 | 
            +
                # Adds the view for the given class and view hash config. See Formatter.config for valid keys for view hash.
         | 
| 37 | 
            +
                def add_view(klass, view_config)
         | 
| 112 38 | 
             
                  @klass_config.delete(klass)
         | 
| 113 | 
            -
                  @config[klass.to_s] =  | 
| 39 | 
            +
                  @config[klass.to_s] = view_config
         | 
| 114 40 | 
             
                  true
         | 
| 115 41 | 
             
                end
         | 
| 116 42 |  | 
| 117 | 
            -
                #  | 
| 118 | 
            -
                 | 
| 119 | 
            -
             | 
| 120 | 
            -
                 | 
| 121 | 
            -
             | 
| 122 | 
            -
                # This is the main method of this class. The formatter looks for the first helper in its config for the given output class.
         | 
| 123 | 
            -
                # If a helper is found, the output is converted by the helper into a string and returned. If not, nil is returned. The options
         | 
| 124 | 
            -
                # this class takes are a helper config hash as described in config. These options will be merged with any existing helper config hash
         | 
| 125 | 
            -
                # an output class has in config. Any block given is passed along to a helper class.
         | 
| 43 | 
            +
                # This method looks for an output object's view in Formatter.config and then Formatter.dynamic_config.
         | 
| 44 | 
            +
                # If a view is found, a stringified view is returned based on the object. If no view is found, nil is returned. The options this
         | 
| 45 | 
            +
                # class takes are a view hash as described in Formatter.config. These options will be merged with any existing helper
         | 
| 46 | 
            +
                # config hash an output class has in Formatter.config. Any block given is passed along to a helper class.
         | 
| 126 47 | 
             
                def format_output(output, options={}, &block)
         | 
| 127 48 | 
             
                  output_class = determine_output_class(output)
         | 
| 128 49 | 
             
                  options = parse_console_options(options) if options.delete(:console)
         | 
| 129 50 | 
             
                  options = Util.recursive_hash_merge(klass_config(output_class), options)
         | 
| 130 | 
            -
                   | 
| 51 | 
            +
                  _format_output(output, options, &block)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                #:stopdoc:
         | 
| 55 | 
            +
                def _format_output(output, options, &block)
         | 
| 56 | 
            +
                  output = options[:output_method] ? (output.is_a?(Array) ?
         | 
| 57 | 
            +
                    output.map {|e| call_output_method(options[:output_method], e) } :
         | 
| 131 58 | 
             
                    call_output_method(options[:output_method], output) ) : output
         | 
| 132 59 | 
             
                  args = [output]
         | 
| 133 60 | 
             
                  args << options[:options] if options[:options] && !options[:options].empty?
         | 
| 134 61 | 
             
                  if options[:method]
         | 
| 135 | 
            -
                     | 
| 136 | 
            -
                  elsif options[:class] && (helper_class =  | 
| 137 | 
            -
                     | 
| 62 | 
            +
                    send(options[:method],*args)
         | 
| 63 | 
            +
                  elsif options[:class] && (helper_class = Helpers.helper_class(options[:class]))
         | 
| 64 | 
            +
                    helper_class.render(*args, &block)
         | 
| 138 65 | 
             
                  elsif options[:output_method]
         | 
| 139 | 
            -
                     | 
| 66 | 
            +
                    output
         | 
| 140 67 | 
             
                  end
         | 
| 141 | 
            -
                  new_output
         | 
| 142 68 | 
             
                end
         | 
| 143 69 |  | 
| 144 | 
            -
                #:stopdoc:
         | 
| 145 70 | 
             
                def parse_console_options(options) #:nodoc:
         | 
| 146 71 | 
             
                  real_options = [:method, :class, :output_method].inject({}) do |h, e|
         | 
| 147 72 | 
             
                    h[e] = options.delete(e) if options[e]; h
         | 
| 148 73 | 
             
                  end
         | 
| 149 74 | 
             
                  real_options.merge! :options=>options
         | 
| 150 | 
            -
                  real_options
         | 
| 151 | 
            -
                end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                def determine_helper_class(klass)
         | 
| 154 | 
            -
                  if (helper_class = Helpers.constants.find {|e| e.to_s == Util.camelize(klass.to_s)})
         | 
| 155 | 
            -
                    klass = "Hirb::Helpers::#{helper_class}"
         | 
| 156 | 
            -
                  end
         | 
| 157 | 
            -
                  Util.any_const_get(klass)
         | 
| 158 75 | 
             
                end
         | 
| 159 76 |  | 
| 160 77 | 
             
                def determine_output_class(output)
         | 
| @@ -168,28 +85,32 @@ module Hirb | |
| 168 85 | 
             
                # Internal view options built from user-defined ones. Options are built by recursively merging options from oldest
         | 
| 169 86 | 
             
                # ancestors to the most recent ones.
         | 
| 170 87 | 
             
                def klass_config(output_class)
         | 
| 171 | 
            -
                  @klass_config[output_class] ||=  | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 88 | 
            +
                  @klass_config[output_class] ||= build_klass_config(output_class)
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                def build_klass_config(output_class)
         | 
| 92 | 
            +
                  output_ancestors = output_class.ancestors.map {|e| e.to_s}.reverse
         | 
| 93 | 
            +
                  output_ancestors.pop
         | 
| 94 | 
            +
                  hash = output_ancestors.inject({}) {|h, klass|
         | 
| 95 | 
            +
                    add_klass_config_if_true(h, klass) {|c,klass| c[klass] && c[klass][:ancestor] }
         | 
| 96 | 
            +
                  }
         | 
| 97 | 
            +
                  add_klass_config_if_true(hash, output_class.to_s) {|c,klass| c[klass] }
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def add_klass_config_if_true(hash, klass)
         | 
| 101 | 
            +
                  if yield(@config, klass)
         | 
| 102 | 
            +
                    Util.recursive_hash_merge hash, @config[klass]
         | 
| 103 | 
            +
                  elsif yield(self.class.dynamic_config, klass)
         | 
| 104 | 
            +
                    @config[klass] = self.class.dynamic_config[klass].dup # copy to local
         | 
| 105 | 
            +
                    Util.recursive_hash_merge hash, self.class.dynamic_config[klass]
         | 
| 106 | 
            +
                  else
         | 
| 107 | 
            +
                    hash
         | 
| 176 108 | 
             
                  end
         | 
| 177 109 | 
             
                end
         | 
| 178 110 |  | 
| 179 111 | 
             
                def reset_klass_config
         | 
| 180 112 | 
             
                  @klass_config = {}
         | 
| 181 113 | 
             
                end
         | 
| 182 | 
            -
             | 
| 183 | 
            -
                def default_config
         | 
| 184 | 
            -
                  Views.constants.inject({}) {|h,e|
         | 
| 185 | 
            -
                    output_class = e.to_s.gsub("_", "::")
         | 
| 186 | 
            -
                    if (views_class = Views.const_get(e)) && views_class.respond_to?(:render)
         | 
| 187 | 
            -
                      default_options = views_class.respond_to?(:default_options) ? views_class.default_options : {}
         | 
| 188 | 
            -
                      h[output_class] = default_options.merge({:class=>"Hirb::Views::#{e}"})
         | 
| 189 | 
            -
                    end
         | 
| 190 | 
            -
                    h
         | 
| 191 | 
            -
                  }
         | 
| 192 | 
            -
                end
         | 
| 193 114 | 
             
                #:startdoc:
         | 
| 194 115 | 
             
              end
         | 
| 195 | 
            -
            end
         | 
| 116 | 
            +
            end
         |