DesigningPatterns-hanna 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
1
+ # Hanna -- a better RDoc template
2
+
3
+ Hanna is an RDoc template that scales. It's implemented in Haml, making the
4
+ sources clean and readable. It's built with simplicity, beauty and ease of
5
+ browsing in mind. (See more in [the wiki][wiki].)
6
+
7
+ Hanna was made by [Mislav][] and is available from [GitHub][]:
8
+
9
+ gem install mislav-hanna
10
+
11
+
12
+ ## Usage
13
+
14
+ After installing, you have three options. You can use the command-line tool:
15
+
16
+ hanna -h
17
+
18
+ For repeated generation of API docs, it's better to set up a Rake task. If you
19
+ already have an `RDocTask` set up, the only thing you need to change is this:
20
+
21
+ # replace this:
22
+ require 'rake/rdoctask'
23
+ # with this:
24
+ require 'hanna/rdoctask'
25
+
26
+ Tip: you can do this in the Rakefile of your Rails project before running `rake
27
+ doc:rails`.
28
+
29
+ Here is an example of a task for the [will_paginate library][wp]:
30
+
31
+ # instead of 'rake/rdoctask':
32
+ require 'hanna/rdoctask'
33
+
34
+ desc 'Generate RDoc documentation for the will_paginate plugin.'
35
+ Rake::RDocTask.new(:rdoc) do |rdoc|
36
+ rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'CHANGELOG').
37
+ include('lib/**/*.rb').
38
+ exclude('lib/will_paginate/named_scope*').
39
+ exclude('lib/will_paginate/array.rb').
40
+ exclude('lib/will_paginate/version.rb')
41
+
42
+ rdoc.main = "README.rdoc" # page to start on
43
+ rdoc.title = "will_paginate documentation"
44
+
45
+ rdoc.rdoc_dir = 'doc' # rdoc output folder
46
+ rdoc.options << '--webcvs=http://github.com/mislav/will_paginate/tree/master/'
47
+ end
48
+
49
+ Either way, it's the same as using RDoc.
50
+
51
+ The last thing you can do with Hanna is generate documentation for installed
52
+ gems. This is a replacement for the "gem rdoc" command.
53
+
54
+ [sudo] hanna --gems haml will_paginate
55
+
56
+ Hanna also can be used with standard rdoc options:
57
+ --inline-source -T hanna
58
+
59
+ ## A work in progress
60
+
61
+ Hanna is far from done, but it is the first RDoc template that's actually
62
+ _maintainable_. First thing I have done is converted the original HTML
63
+ template to Haml and Sass, cleaning up and removing the (ridiculous amount of)
64
+ duplication.
65
+
66
+ Also, the template fragments are now in _separate files_. You would have
67
+ fainted if you seen how it was before. (It's really no wonder why there are no
68
+ other RDoc templates around ... save one: [Allison][].)
69
+
70
+ Ultimately, I'd like to lose the frameset. Currently that is far from possible
71
+ because the whole RDoc HTML Generator is built for frames. Still, that is my
72
+ goal.
73
+
74
+ ## You can help
75
+
76
+ Don't like something? Think you can design better? (You probably can.)
77
+
78
+ This is git. I welcome all submissions towards my goal.
79
+
80
+
81
+ [wiki]: http://github.com/mislav/hanna/wikis/home "Hanna wiki"
82
+ [GitHub]: http://gems.github.com/ "GitHub gem source"
83
+ [wp]: http://github.com/mislav/will_paginate
84
+ [Mislav]: http://mislav.caboo.se/ "Mislav Marohnić"
85
+ [Allison]: http://blog.evanweaver.com/files/doc/fauna/allison/ "A modern, pretty RDoc template"
@@ -0,0 +1,25 @@
1
+ desc %{Update ".manifest" with the latest list of project filenames. Respect .gitignore by excluding everything that git ignores. Update `files` and `test_files` arrays in "*.gemspec" file if it's present.}
2
+ task :manifest do
3
+ list = Dir['**/*'].sort
4
+ spec_file = Dir['*.gemspec'].first
5
+ list -= [spec_file] if spec_file
6
+
7
+ File.read('.gitignore').each_line do |glob|
8
+ glob = glob.chomp.sub(/^\//, '')
9
+ list -= Dir[glob]
10
+ list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
11
+ puts "excluding #{glob}"
12
+ end if File.exists?('.gitignore')
13
+
14
+ if spec_file
15
+ spec = File.read spec_file
16
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
17
+ assignment = $1
18
+ bunch = $2 ? list.grep(/^test\//) : list
19
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
20
+ end
21
+
22
+ File.open(spec_file, 'w') {|f| f << spec }
23
+ end
24
+ File.open('.manifest', 'w') {|f| f << list.join("\n") }
25
+ end
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/ruby
2
+ if ARGV.size == 1 and ARGV.first == '-h'
3
+ puts <<-HELP
4
+ Hanna -- a better RDoc template
5
+ Synopsis:
6
+ hanna [options] [file names...]
7
+ [sudo] hanna --gems [gem names...]
8
+
9
+ Example usage:
10
+
11
+ hanna lib/**/*.rb
12
+
13
+ Hanna passes all arguments to RDoc. To find more about RDoc options, see
14
+ "rdoc -h". Default options are:
15
+
16
+ -o doc --inline-source --charset=UTF-8
17
+
18
+ The second form, with the "--gems" argument, serves the same purpose as
19
+ the "gem rdoc" command: it generates documentation for installed gems.
20
+ When no gem names are given, "hanna --gems" will install docs for EACH of
21
+ the gems, which can, uh, take a little while.
22
+
23
+ HELP
24
+ exit 0
25
+ end
26
+
27
+ require 'rubygems'
28
+ begin
29
+ gem 'rdoc', '~> 2.0.0'
30
+ rescue Gem::LoadError
31
+ $stderr.puts "Hanna requires the RDoc 2.0 gem."
32
+ exit 1
33
+ else
34
+ require 'rdoc/rdoc'
35
+ end
36
+
37
+ hanna_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
38
+ $:.unshift(hanna_dir) unless $:.include?(hanna_dir)
39
+
40
+ options = []
41
+
42
+ options << '-T' << 'hanna/hanna.rb'
43
+ options << '--inline-source' << '--charset=UTF-8'
44
+
45
+ if ARGV.first == '--gems'
46
+ require 'rubygems/doc_manager'
47
+ Gem::DocManager.configured_args = options
48
+
49
+ gem_names = ARGV.dup
50
+ gem_names.shift
51
+
52
+ unless gem_names.empty?
53
+ specs = gem_names.inject([]) do |arr, name|
54
+ found = Gem::SourceIndex.from_installed_gems.search(name)
55
+ spec = found.sort_by {|s| s.version }.last
56
+ arr << spec if spec
57
+ arr
58
+ end
59
+ else
60
+ specs = Gem::SourceIndex.from_installed_gems.inject({}) do |all, pair|
61
+ full_name, spec = pair
62
+ if spec.has_rdoc? and (!all[spec.name] or spec.version > all[spec.name].version)
63
+ all[spec.name] = spec
64
+ end
65
+ all
66
+ end
67
+ specs = specs.values
68
+ puts "Hanna is installing documentation for #{specs.size} gem#{specs.size > 1 ? 's' : ''} ..."
69
+ end
70
+
71
+ specs.each do |spec|
72
+ Gem::DocManager.new(spec).generate_rdoc
73
+ end
74
+ else
75
+ options << '-o' << 'doc' unless ARGV.include?('-o') or ARGV.include?('--op')
76
+ options.concat ARGV
77
+
78
+ RDoc::RDoc.new.document(options)
79
+ end
@@ -0,0 +1 @@
1
+ require 'hanna/hanna'
@@ -0,0 +1,55 @@
1
+ require 'haml'
2
+ require 'sass'
3
+ require 'rdoc/generator/html'
4
+ require 'hanna/template_page_patch'
5
+
6
+ # = A better RDoc HTML template
7
+ #
8
+ # Many different kinds of awesome.
9
+ #
10
+ # Author: Mislav Marohnić <mislav.marohnic@gmail.com>
11
+ # Based on the work of Michael Granger <ged@FaerieMUD.org>
12
+
13
+ module RDoc::Generator::HTML::HANNA
14
+ class << self
15
+ def dir
16
+ @dir ||= File.join File.dirname(__FILE__), 'template_files'
17
+ end
18
+
19
+ def read(*names)
20
+ extension = nil
21
+
22
+ content = names.map { |name|
23
+ if extension
24
+ name += '.' + extension
25
+ else
26
+ extension = name =~ /\.(\w+)$/ && $1
27
+ end
28
+ File.read File.join(dir, name)
29
+ }.join('')
30
+
31
+ case extension
32
+ when 'sass'
33
+ Sass::Engine.new(content)
34
+ when 'haml'
35
+ Haml::Engine.new(content)
36
+ else
37
+ content
38
+ end
39
+ end
40
+ end
41
+
42
+ STYLE = read('styles.sass')
43
+
44
+ CLASS_PAGE = read('page.haml')
45
+ FILE_PAGE = CLASS_PAGE
46
+ METHOD_LIST = read('method_list.haml', 'sections')
47
+
48
+ FR_INDEX_BODY = BODY = read('layout.haml')
49
+
50
+ FILE_INDEX = read('file_index.haml')
51
+ CLASS_INDEX = read('class_index.haml')
52
+ METHOD_INDEX = FILE_INDEX
53
+
54
+ INDEX = read('index.haml')
55
+ end
@@ -0,0 +1,45 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+
4
+ Rake::RDocTask.class_eval do
5
+ # don't allow it
6
+ undef :external=
7
+
8
+ # Create the tasks defined by this task lib.
9
+ def define
10
+ unless @template and @template != 'html'
11
+ @template = File.dirname(__FILE__) + '/hanna'
12
+ end
13
+ options << '--inline-source' unless options.include? '--inline-source' or options.include? '-S'
14
+ options << '--charset=UTF-8' if options.grep(/^(--charset$|-c\b)/).empty?
15
+
16
+ desc "Build the HTML documentation"
17
+ task name
18
+
19
+ desc "Force a rebuild of the RDOC files"
20
+ task paste("re", name) => [paste("clobber_", name), name]
21
+
22
+ desc "Remove rdoc products"
23
+ task paste("clobber_", name) do
24
+ rm_r rdoc_dir rescue nil
25
+ end
26
+
27
+ task :clobber => [paste("clobber_", name)]
28
+
29
+ directory @rdoc_dir
30
+ task name => [rdoc_target]
31
+ file rdoc_target => @rdoc_files + [$rakefile] do
32
+ rm_r @rdoc_dir rescue nil
33
+
34
+ begin
35
+ gem 'rdoc', '~> 2.0.0'
36
+ rescue Gem::LoadError
37
+ $stderr.puts "Couldn't load RDoc 2.0 gem"
38
+ end
39
+ require 'rdoc/rdoc'
40
+
41
+ RDoc::RDoc.new.document(option_list + @rdoc_files)
42
+ end
43
+ self
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ %h1= values["list_title"]
2
+ %ol#index-entries.classes
3
+ = render_class_tree make_class_tree(values["entries"])
@@ -0,0 +1,13 @@
1
+ %h1= values["list_title"]
2
+ - type = values["list_title"].downcase
3
+ - any_hidden = false
4
+
5
+ %ol#index-entries{ :class => type }
6
+ - for entry in values["entries"]
7
+ - hide = type == 'files' && entry['name'] =~ /\.rb$/
8
+ - any_hidden = true if hide
9
+ %li{ :class => hide ? 'other' : nil }= link_to entry['name'], entry['href']
10
+
11
+ - if any_hidden
12
+ %li
13
+ %a.show{ :href => '#', :onclick => 'this.parentNode.parentNode.className += " expanded"; this.parentNode.removeChild(this); return false' } show all
@@ -0,0 +1,11 @@
1
+ !!! Frameset
2
+ %html{ "xml:lang" => "en", :lang => "en", :xmlns => "http://www.w3.org/1999/xhtml" }
3
+ %head
4
+ %title= values["title"]
5
+ %meta{ :content => "text/html; charset=#{values['charset']}", "http-equiv" => "Content-Type" }
6
+ %frameset{ :cols => "20%, *" }
7
+ %frameset{ :rows => "15%, 35%, 50%" }
8
+ %frame{ :name => "Files", :title => "Files", :src => "fr_file_index.html" }
9
+ %frame{ :name => "Classes", :src => "fr_class_index.html" }
10
+ %frame{ :name => "Methods", :src => "fr_method_index.html" }
11
+ %frame{ :name => "docwin", :src => values['initial_page'] }
@@ -0,0 +1,37 @@
1
+ !!! strict
2
+ - index = values['list_title']
3
+ %html{ :xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => "en", :lang => "en" }
4
+ %head
5
+ %title= index || values['title']
6
+ %meta{ 'http-equiv' => "Content-Type", :content => "text/html; charset=#{values['charset']}" }
7
+ %link{ :rel => "stylesheet", :href => values["style_url"], :type => "text/css", :media => "screen" }
8
+ - unless index
9
+ %script{ :type => "text/javascript" }
10
+ :plain
11
+ function popupCode(url) {
12
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
13
+ }
14
+
15
+ function toggleCode(id) {
16
+ var code = document.getElementById(id)
17
+
18
+ code.style.display = code.style.display != 'block' ? 'block' : 'none'
19
+ return true
20
+ }
21
+
22
+ // Make codeblocks hidden by default
23
+ document.writeln('<' + 'style type="text/css">.method .source pre { display: none }<\/style>')
24
+ - else
25
+ %base{ :target => 'docwin' }/
26
+
27
+ %body{ :class => index ? 'list' : 'page' }
28
+ - if index
29
+ #index= yield
30
+ - else
31
+ #wrapper{ :class => values["classmod"] ? 'class' : 'file' }
32
+ = yield
33
+ #footer-push
34
+ #footer
35
+ = link_to '<strong>Hanna</strong> RDoc template', 'http://github.com/mislav/hanna'
36
+ hand-crafted by
37
+ %strong= link_to 'Mislav', 'http://mislav.caboo.se/'
@@ -0,0 +1,34 @@
1
+ - methods = methods_from_sections values["sections"]
2
+ - unless methods.empty?
3
+ #method-list
4
+ %h2 Methods
5
+ - for type in ['public class', 'protected class', 'public instance', 'protected instance']
6
+ - unless (list = methods[type]).empty?
7
+ %h3= type
8
+ %ol
9
+ - for method in list
10
+ %li= link_to method["name"], '#' + method["aref"]
11
+
12
+ - if values["requires"] or values["toc"] or values["includes"]
13
+ #context
14
+ - if values["requires"]
15
+ #requires
16
+ %h2 Required files
17
+ %ol
18
+ - for req in values["requires"]
19
+ %li= link_to req["name"], req["aref"]
20
+
21
+ - if values["toc"]
22
+ #contents
23
+ %h2 Contents
24
+ %ol
25
+ - for item in values["toc"]
26
+ %li= link_to values["secname"], values["href"]
27
+
28
+ - if values["includes"]
29
+ #includes
30
+ %h2 Included modules
31
+ %ol
32
+ - for inc in values["includes"]
33
+ %li= link_to inc["name"], inc["aref"]
34
+
@@ -0,0 +1,50 @@
1
+ - file_page = !values["classmod"]
2
+ - title_in_description = values["description"] && values["description"] =~ /^\s*<h1>/m
3
+
4
+ .header
5
+ - title = capture_haml do
6
+ - if file_page
7
+ = values["short_name"]
8
+ - else
9
+ %span.type= values["classmod"]
10
+ = values["full_name"]
11
+ - if title_in_description
12
+ .name= title
13
+ - else
14
+ %h1.name= title
15
+
16
+ - if file_page
17
+ .paths
18
+ = values["full_path"]
19
+ - if values["cvsurl"]
20
+ == (#{link_to 'view online', values["cvsurl"]})
21
+ - else
22
+ %ol.paths
23
+ - values["infiles"].each_with_index do |file, index|
24
+ %li{ :class => index > 0 ? 'other' : nil }
25
+ = link_to file["full_path"], file["full_path_url"]
26
+ - if file["cvsurl"]
27
+ == (#{link_to 'view online', file["cvsurl"]})
28
+ - if values["infiles"].size > 1
29
+ %li
30
+ %a.show{ :href => '#', :onclick => 'this.parentNode.parentNode.className += " expanded"; this.parentNode.removeChild(this); return false' } show all
31
+
32
+ - if values["parent"] then
33
+ .parent
34
+ Parent:
35
+ %strong= link_to values["parent"], values["par_url"]
36
+
37
+ - if values["dtm_modified"]
38
+ .last-update
39
+ Last Update:
40
+ %span.datetime= values["dtm_modified"]
41
+
42
+ #content
43
+ - if values["diagram"]
44
+ #diagram= values["diagram"]
45
+
46
+ #text
47
+ - if values["description"]
48
+ #description~ values["description"]
49
+
50
+ = yield
@@ -0,0 +1,97 @@
1
+ - for section in values["sections"]
2
+ #section
3
+ - if section["sectitle"]
4
+ %h2= link_to section["sectitle"], section["secsequence"]
5
+ - if section["seccomment"]
6
+ .section-comment= section["seccomment"]
7
+ - if section["classlist"]
8
+ #class-list
9
+ %h3 Classes and Modules
10
+ = section["classlist"]
11
+
12
+ - if section["constants"]
13
+ #constants-list
14
+ %h3.section-bar Constants
15
+ .name-list
16
+ %table{ :summary => "Constants" }
17
+ - for const in section["constants"]
18
+ %tr.top-aligned-row.context-row
19
+ %td.context-item-name
20
+ = const["name"]
21
+ %td
22
+ \=
23
+ %td.context-item-value
24
+ = const["value"]
25
+ - if const["desc"] then
26
+ %td{ :width => "3em" }
27
+ &nbsp;
28
+ %td.context-item-desc
29
+ = const["desc"]
30
+
31
+ - if section["aliases"]
32
+ #aliases-list
33
+ %h3.section-bar External Aliases
34
+ .name-list
35
+ %table{ :summary => "aliases" }
36
+ - for alia in section["aliases"]
37
+ %tr.top-aligned-row.context-row
38
+ %td.context-item-name
39
+ = alia["old_name"]
40
+ %td
41
+ \-&gt;
42
+ %td.context-item-value
43
+ = alia["new_name"]
44
+ - if alia["desc"] then
45
+ %tr.top-aligned-row.context-row
46
+ %td
47
+ &nbsp;
48
+ %td.context-item-desc{ :colspan => "2" }
49
+ = alia["desc"]
50
+
51
+ - if section["attributes"]
52
+ #attribute-list
53
+ %h3.section-bar Attributes
54
+ .name-list
55
+ %table
56
+ - for attr in section["attributes"]
57
+ %tr.top-aligned-row.context-row
58
+ %td.context-item-name
59
+ = attr["name"]
60
+ - if attr["rw"] then
61
+ %td.context-item-value
62
+ = "[#{attr['rw']}]"
63
+ - else
64
+ %td.context-item-value &nbsp;
65
+ %td.context-item-desc
66
+ = attr["a_desc"]
67
+
68
+ - if section["method_list"]
69
+ #methods
70
+ - for list in section["method_list"]
71
+ - if list["methods"] then
72
+ %h3== #{list["type"]} #{list["category"].downcase} methods
73
+
74
+ - for method in list["methods"]
75
+ .method{ :id => "method-#{method['aref']}", :class => "#{list['type']}-#{list['category']}".downcase }
76
+ %a{ :name => method["aref"] }
77
+ .synopsis
78
+ - method_html = capture_haml do
79
+ - if method["callseq"]
80
+ %span.name= method["callseq"]
81
+ - else
82
+ %span.name= method["name"]
83
+ %span.arguments= method["params"]
84
+ - if method["codeurl"]
85
+ %a.method-signature{ :href => method["codeurl"], :onclick => "popupCode(this.href); return false", :target => "Code" }
86
+ = method_html
87
+ - else
88
+ = method_html
89
+ - if method["m_desc"]
90
+ .description
91
+ ~ method["m_desc"]
92
+ - if method["sourcecode"]
93
+ .source
94
+ - name = "#{method['aref']}-source"
95
+ %a.source-toggle{ :href => "#", :onclick => "toggleCode('#{name}'); return false" }
96
+ [show source]
97
+ ~ "<pre id='#{name}'>#{method["sourcecode"]}</pre>"
@@ -0,0 +1,334 @@
1
+ !title_font = Georgia, serif
2
+ !code_font_family = Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace
3
+ !code_font_size = 14px
4
+ !code_font = !code_font_size !code_font_family
5
+
6
+ !light_link = #369
7
+ !link = !light_link - 40
8
+ !light_text = #666
9
+ !dark_blue_text = #0E3062
10
+
11
+ html, body
12
+ :height 100%
13
+ body
14
+ :font-family Verdana, Arial, Helvetica, sans-serif
15
+ :font-size 90%
16
+ :margin 0
17
+ :padding 0
18
+ :background white
19
+
20
+ #wrapper
21
+ :min-height 100%
22
+ :height auto !important
23
+ :height 100%
24
+ :margin 0 auto -43px
25
+ #footer-push
26
+ :height 43px
27
+ div.header, #footer
28
+ :background #eee
29
+ #footer
30
+ :border-top 1px solid silver
31
+ :margin-top 12px
32
+ :padding 0 2em
33
+ :line-height 30px
34
+ :text-align center
35
+ :font-variant small-caps
36
+ :font-size 95%
37
+
38
+ // self-clearing
39
+ .clearing
40
+ &:after
41
+ :content "."
42
+ :visibility hidden
43
+ :height 0
44
+ :display block
45
+ :clear both
46
+ * html &
47
+ :height 1px
48
+ *:first-child + html
49
+ :overflow hidden
50
+
51
+ h1, h2, h3, h4, h5, h6
52
+ :margin 0
53
+ :font-weight normal
54
+
55
+ a
56
+ :color = !link
57
+ &:hover
58
+ :background = !light_link
59
+ :text-decoration none
60
+ :color #eef
61
+ #description, .method .description, .header
62
+ a
63
+ :color = !light_link
64
+ &:hover
65
+ :color #eee
66
+ h1, h2, h3, h4, h5, h6
67
+ a
68
+ :color = !link
69
+
70
+ ol
71
+ :margin 0
72
+ :padding 0
73
+ :list-style none
74
+ li
75
+ :margin-left 0
76
+ :white-space nowrap
77
+ &.other
78
+ :display none
79
+ ol.expanded li.other
80
+ :display list-item
81
+
82
+ table
83
+ :margin-bottom 1em
84
+ :font-size 1em
85
+ :border-collapse collapse
86
+ td, th
87
+ :padding .4em .8em
88
+ thead
89
+ :background-color #e8e8e8
90
+ th
91
+ :font-variant small-caps
92
+ :color = !light_text
93
+ tr
94
+ :border-bottom 1px solid silver
95
+
96
+ #index, div.header
97
+ a.show
98
+ :text-decoration underline
99
+ :font-style italic
100
+ :color = !light_text
101
+ &:after
102
+ :content " ..."
103
+ &:hover
104
+ :color black
105
+ :background #ffe
106
+
107
+ #index
108
+ :font 85%/1.2 Arial, Helvetica, sans-serif
109
+ a
110
+ :text-decoration none
111
+ h1
112
+ :padding .2em .5em .1em
113
+ :background #ccc
114
+ :font = "small-caps 1.2em" !title_font
115
+ :color #333
116
+ :border-bottom 1px solid gray
117
+ ol
118
+ :padding .4em .5em
119
+ li
120
+ :white-space nowrap
121
+ #index-entries.classes
122
+ :font-size 1.1em
123
+ ol
124
+ :padding 0
125
+ span.nodoc
126
+ :display none
127
+ span.nodoc, a
128
+ :font-weight bold
129
+ .parent
130
+ :font-weight normal
131
+
132
+ div.header
133
+ :font-size 80%
134
+ :padding .5em 2%
135
+ :font-family Arial, Helvetica, sans-serif
136
+ :border-bottom 1px solid silver
137
+ .name
138
+ :font-size 1.6em
139
+ :font-family = !title_font
140
+ .type
141
+ :color = !light_text
142
+ :font-size 80%
143
+ :font-variant small-caps
144
+ h1.name
145
+ :font-size 2.2em
146
+ .paths, .last-update, .parent
147
+ :color = !light_text
148
+ .last-update .datetime
149
+ :color = !light_text - 30
150
+ .parent
151
+ :margin-top .3em
152
+ strong
153
+ :font-weight normal
154
+ :color = !light_text - 30
155
+
156
+ #content
157
+ :padding 12px 2%
158
+ div.class &
159
+ :position relative
160
+ :width 72%
161
+
162
+ pre, .method .synopsis
163
+ :font = !code_font
164
+ pre
165
+ :color black
166
+ :background #eee
167
+ :border 1px solid silver
168
+ :padding 0 .5em .8em .5em
169
+ :overflow auto
170
+ p, li, dd
171
+ code, tt
172
+ :font = !code_font
173
+ :background #ffffe3
174
+ :padding 2px 3px
175
+ h1, h2, h3, h4, h5, h6
176
+ code, tt
177
+ :font-size 1.1em
178
+
179
+ #text
180
+ :position relative
181
+
182
+ #description
183
+ // :max-width 60em
184
+ p
185
+ :margin-top .5em
186
+ h1, h2, h3, h4, h5, h6
187
+ :font-family = !title_font
188
+ h1
189
+ :font-size 2.2em
190
+ :margin-bottom .2em
191
+ :border-bottom 3px double #d8d8d8
192
+ :padding-bottom .1em
193
+ h2
194
+ :font-size 1.8em
195
+ :color = !dark_blue_text
196
+ :margin .8em 0 .3em 0
197
+ h3
198
+ :font-size 1.6em
199
+ :margin .8em 0 .3em 0
200
+ :color = !light_text
201
+ h4
202
+ :font-size 1.4em
203
+ :margin .8em 0 .3em 0
204
+ h5
205
+ :font-size 1.2em
206
+ :margin .8em 0 .3em 0
207
+ :color = !dark_blue_text
208
+ h6
209
+ :font-size 1.0em
210
+ :margin .8em 0 .3em 0
211
+ :color = !light_text
212
+
213
+ #description, .method .description
214
+ ul
215
+ :margin .8em 0
216
+ :padding-left 1.5em
217
+
218
+ #method-list
219
+ :position absolute
220
+ :top 0px
221
+ :right -33%
222
+ :width 28%
223
+ :background #eee
224
+ :border 1px solid silver
225
+ :padding .4em 1%
226
+ :overflow hidden
227
+ h2
228
+ :font-size 1.3em
229
+ h3
230
+ :font-variant small-caps
231
+ :text-transform capitalize
232
+ :font-family = !title_font
233
+ :color #666
234
+ :font-size 1.1em
235
+ ol
236
+ :padding 0 0 .5em .5em
237
+
238
+ #context
239
+ :font-size 85%
240
+ :padding-left 1.5em
241
+ :border-top 1px dashed silver
242
+ :margin-top 1em
243
+ h2
244
+ :color #333
245
+ :font = "bold small-caps 1.3em" !title_font
246
+ :margin .5em 0 .1em 0
247
+
248
+ #methods
249
+ h3
250
+ :font = "small-caps 1.2em" !title_font
251
+ :color #444
252
+ :margin 1em 0 .2em 0
253
+ h4
254
+ :font = "1.1em" !title_font
255
+ :color = !dark_blue_text
256
+ :margin 1em 0 .2em 0
257
+
258
+ .method
259
+ :border 1px solid silver
260
+ :margin-top .5em
261
+ :background #eee
262
+ .synopsis
263
+ :color black
264
+ :background silver
265
+ :padding .2em 1em
266
+ .name
267
+ :font-weight bold
268
+ a
269
+ :text-decoration none
270
+ .description
271
+ :padding 0 1em
272
+ pre
273
+ :background #f8f8f8
274
+ .source
275
+ :margin .5em 0
276
+ .source-toggle
277
+ :font-size 85%
278
+ :margin-left 1em
279
+ .public-class
280
+ :background #ffffe4
281
+ .public-instance .synopsis
282
+ :color #eee
283
+ :background = !light_link
284
+
285
+ #content .method .source pre
286
+ :background #262626
287
+ :color #ffdead
288
+ :margin 1em
289
+ :padding 0.5em
290
+ :border 1px dashed #999
291
+ :overflow hidden
292
+
293
+ .standalone-code
294
+ :background #221111
295
+ :color #ffdead
296
+ :overflow hidden
297
+
298
+ .ruby-constant
299
+ :color #7fffd4
300
+ :background transparent
301
+
302
+ .ruby-keyword
303
+ :color #00ffff
304
+ :background transparent
305
+
306
+ .ruby-ivar
307
+ :color #eedd82
308
+ :background transparent
309
+
310
+ .ruby-operator
311
+ :color #00ffee
312
+ :background transparent
313
+
314
+ .ruby-identifier
315
+ :color #ffdead
316
+ :background transparent
317
+
318
+ .ruby-node
319
+ :color #ffa07a
320
+ :background transparent
321
+
322
+ .ruby-comment
323
+ :color #b22222
324
+ :font-weight bold
325
+ :background transparent
326
+
327
+ .ruby-regexp
328
+ :color #ffa07a
329
+ :background transparent
330
+
331
+ .ruby-value
332
+ :color #7fffd4
333
+ :background transparent
334
+
@@ -0,0 +1,66 @@
1
+ require 'yaml'
2
+ require 'cgi'
3
+
4
+ module Hanna
5
+ module TemplateHelpers
6
+ protected
7
+
8
+ def link_to(text, url = nil, classname = nil)
9
+ class_attr = classname ? %[ class="#{classname}"] : ''
10
+
11
+ if url
12
+ %[<a href="#{url}"#{class_attr}>#{text}</a>]
13
+ elsif classname
14
+ %[<span#{class_attr}>#{text}</span>]
15
+ else
16
+ text
17
+ end
18
+ end
19
+
20
+ def debug(text)
21
+ "<pre>#{h YAML::dump(text)}</pre>"
22
+ end
23
+
24
+ def h(html)
25
+ CGI::escapeHTML html
26
+ end
27
+
28
+ def methods_from_sections(sections)
29
+ sections.inject(Hash.new {|h, k| h[k] = []}) do |methods, section|
30
+ section['method_list'].each do |ml|
31
+ methods["#{ml['type']} #{ml['category']}".downcase].concat ml['methods']
32
+ end if section['method_list']
33
+ methods
34
+ end
35
+ end
36
+
37
+ def make_class_tree(entries)
38
+ entries.inject({}) do |tree, entry|
39
+ if entry['href']
40
+ leaf = entry['name'].split('::').inject(tree) do |branch, klass|
41
+ branch[klass] ||= {}
42
+ end
43
+ leaf['_href'] = entry['href']
44
+ end
45
+ tree
46
+ end
47
+ end
48
+
49
+ def render_class_tree(tree, parent = nil)
50
+ parent = parent + '::' if parent
51
+ tree.keys.sort.inject('') do |out, name|
52
+ unless name == '_href'
53
+ subtree = tree[name]
54
+ text = parent ? %[<span class="parent">#{parent}</span>#{name}] : name
55
+ out << '<li>'
56
+ out << (subtree['_href'] ? link_to(text, subtree['_href']) : %[<span class="nodoc">#{text}</span>])
57
+ if subtree.keys.size > 1
58
+ out << "\n<ol>" << render_class_tree(subtree, parent.to_s + name) << "\n</ol>"
59
+ end
60
+ out << '</li>'
61
+ end
62
+ out
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,35 @@
1
+ require 'hanna/template_helpers'
2
+
3
+ RDoc::TemplatePage.class_eval do
4
+
5
+ include Hanna::TemplateHelpers
6
+
7
+ # overwrite the original method
8
+ def write_html_on(io, values)
9
+ result = @templates.reverse.inject(nil) do |previous, template|
10
+ case template
11
+ when Haml::Engine
12
+ template.to_html(get_binding, :values => values) { previous }
13
+ when Sass::Engine
14
+ template.to_css
15
+ when String
16
+ ERB.new(template).result(get_binding(values){ previous })
17
+ when nil
18
+ previous
19
+ else
20
+ raise "don't know how to handle a template of class '#{template.class.name}'"
21
+ end
22
+ end
23
+
24
+ io.write result
25
+ rescue
26
+ $stderr.puts "error while writing to #{io.inspect}"
27
+ raise
28
+ end
29
+
30
+ private
31
+
32
+ def get_binding(values = nil)
33
+ binding
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: DesigningPatterns-hanna
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - "Mislav Marohni\xC4\x87"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-03 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rdoc
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.1.0
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: haml
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.8.2
32
+ version:
33
+ description: Hanna is an RDoc template that scales. It's implemented in Haml, making its source clean and maintainable. It's built with simplicity, beauty and ease of browsing in mind.
34
+ email: mislav.marohnic@gmail.com
35
+ executables:
36
+ - hanna
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - README.markdown
43
+ - Rakefile
44
+ - bin
45
+ - bin/hanna
46
+ - lib
47
+ - lib/hanna.rb
48
+ - lib/hanna
49
+ - lib/hanna/hanna.rb
50
+ - lib/hanna/rdoctask.rb
51
+ - lib/hanna/template_files
52
+ - lib/hanna/template_files/class_index.haml
53
+ - lib/hanna/template_files/file_index.haml
54
+ - lib/hanna/template_files/index.haml
55
+ - lib/hanna/template_files/layout.haml
56
+ - lib/hanna/template_files/method_list.haml
57
+ - lib/hanna/template_files/page.haml
58
+ - lib/hanna/template_files/sections.haml
59
+ - lib/hanna/template_files/styles.sass
60
+ - lib/hanna/template_helpers.rb
61
+ - lib/hanna/template_page_patch.rb
62
+ has_rdoc: false
63
+ homepage: http://github.com/mislav/hanna
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.2.0
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: An RDoc template that rocks
88
+ test_files: []
89
+