From a80ba17d67141a51459bb89b1fb51e8b0a4ff2de Mon Sep 17 00:00:00 2001 From: dave Date: Sat, 20 Nov 2004 15:02:57 +0000 Subject: [PATCH] 1. Force --inline-source if --one-file given 2. Add new :section: directive which starts a new section in the output. The title following :section: is used as the section heading, and the remainder of the comment containing the section is used as introductory text. Subsequent methods, aliases, attributes, and classes will be documented in this section. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 13 + lib/rdoc/README | 7 + lib/rdoc/code_objects.rb | 35 +- lib/rdoc/generators/html_generator.rb | 132 +++-- lib/rdoc/generators/template/html/html.rb | 591 ++++++++++++---------- lib/rdoc/options.rb | 2 +- lib/rdoc/parsers/parse_rb.rb | 23 +- 7 files changed, 481 insertions(+), 322 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb105f291a..7129c64a8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Sat Nov 20 23:57:33 2004 Dave Thomas + + * lib/rdoc/README (et al): Add a new directive, :section:, and + change the output format to accomodate. :section: allows to to + group together methods, attributes, constants, etc under + headings in the output. If used, a table of contents is + generated. + +Sat Nov 20 23:56:54 2004 Dave Thomas + + * lib/rdoc/options.rb (Options::parse): Force --inline-source if + --one-file option given + Sat Nov 20 23:25:12 2004 Minero Aoki * io.c (rb_io_getline): f.gets("") did not work. [ruby-core:03771] diff --git a/lib/rdoc/README b/lib/rdoc/README index 5e90d792a2..583f7f3b0c 100644 --- a/lib/rdoc/README +++ b/lib/rdoc/README @@ -422,6 +422,13 @@ this margin are formatted verbatim. 12. Comment blocks can contain other directives: + [:section: title] + Starts a new section in the output. The title following + :section: is used as the section heading, and the + remainder of the comment containing the section is used as + introductory text. Subsequent methods, aliases, attributes, + and classes will be documented in this section. + [call-seq:] lines up to the next blank line in the comment are treated as the method's calling sequence, overriding the diff --git a/lib/rdoc/code_objects.rb b/lib/rdoc/code_objects.rb index bd713ab92b..134ac398e9 100644 --- a/lib/rdoc/code_objects.rb +++ b/lib/rdoc/code_objects.rb @@ -23,6 +23,9 @@ module RDoc attr_accessor :done_documenting + # Which section are we in + + attr_accessor :section # do we document ourselves? @@ -111,7 +114,25 @@ module RDoc class Context < CodeObject attr_reader :name, :method_list, :attributes, :aliases, :constants attr_reader :requires, :includes, :in_files, :visibility - + + attr_reader :sections + + class Section + attr_reader :title, :comment, :sequence + + @@sequence = "SEC00000" + + def initialize(title, comment) + @title = title + @@sequence.succ! + @sequence = @@sequence.dup + if comment + @comment = comment.sub(/.*$/, '') + @comment = nil if @comment.empty? + end + end + end + def initialize super() @@ -123,6 +144,9 @@ module RDoc @parent = nil @visibility = :public + @current_section = Section.new(nil, nil) + @sections = [ @current_section ] + initialize_methods_etc initialize_classes_and_modules end @@ -236,6 +260,7 @@ module RDoc # collection[name] = cls if @document_self && !@done_documenting collection[name] = cls if !@done_documenting cls.parent = self + cls.section = @current_section end cls end @@ -243,6 +268,7 @@ module RDoc def add_to(array, thing) array << thing if @document_self && !@done_documenting thing.parent = self + thing.section = @current_section end # If a class's documentation is turned off after we've started @@ -374,6 +400,13 @@ module RDoc find_module_named(symbol) end + # Handle sections + + def set_current_section(title, comment) + @current_section = Section.new(title, comment) + @sections << @current_section + end + private # Find a named method, or return nil diff --git a/lib/rdoc/generators/html_generator.rb b/lib/rdoc/generators/html_generator.rb index fbfc596cc3..f9c72a4df2 100644 --- a/lib/rdoc/generators/html_generator.rb +++ b/lib/rdoc/generators/html_generator.rb @@ -336,8 +336,10 @@ module Generators # Build a list of aliases for which we couldn't find a # corresponding method - def build_alias_summary_list - @context.aliases.map do |al| + def build_alias_summary_list(section) + values = [] + @context.aliases.each do |al| + next unless al.section == section res = { 'old_name' => al.old_name, 'new_name' => al.new_name, @@ -345,20 +347,24 @@ module Generators if al.comment && !al.comment.empty? res['desc'] = markup(al.comment, true) end - res + values << res end + values end # Build a list of constants - def build_constants_summary_list - @context.constants.map do |co| + def build_constants_summary_list(section) + values = [] + @context.constants.each do |co| + next unless co.section == section res = { 'name' => co.name, 'value' => CGI.escapeHTML(co.value) } res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty? - res + values << res end + values end def build_requires_list(context) @@ -416,7 +422,7 @@ module Generators # methods, the other for instance methods. The inner arrays contain # a hash for each method - def build_method_detail_list + def build_method_detail_list(section) outer = [] methods = @methods.sort @@ -424,7 +430,10 @@ module Generators for vis in [ :public, :protected, :private ] res = [] methods.each do |m| - if m.document_self and m.visibility == vis and m.singleton == singleton + if m.section == section and + m.document_self and + m.visibility == vis and + m.singleton == singleton row = {} if m.call_seq row["callseq"] = m.call_seq.gsub(/->/, '→') @@ -478,11 +487,12 @@ module Generators # Build the structured list of classes and modules contained # in this context. - def build_class_list(level, from, infile=nil) + def build_class_list(level, from, section, infile=nil) res = "" prefix = "  ::" * level; from.modules.sort.each do |mod| + next unless mod.section == section next if infile && !mod.defined_in?(infile) if mod.document_self res << @@ -490,11 +500,12 @@ module Generators "Module " << href(url(mod.viewer.path), "link", mod.full_name) << "
\n" << - build_class_list(level + 1, mod, infile) + build_class_list(level + 1, mod, section, infile) end end from.classes.sort.each do |cls| + next unless cls.section == section next if infile && !cls.defined_in?(infile) if cls.document_self res << @@ -502,7 +513,7 @@ module Generators "Class " << href(url(cls.viewer.path), "link", cls.full_name) << "
\n" << - build_class_list(level + 1, cls, infile) + build_class_list(level + 1, cls, section, infile) end end @@ -541,6 +552,24 @@ module Generators end res end + + # create table of contents if we contain sections + + def add_table_of_sections + toc = [] + @context.sections.each do |section| + if section.title + toc << { + 'secname' => section.title, + 'href' => section.sequence + } + end + end + + @values['toc'] = toc unless toc.empty? + end + + end ##################################################################### @@ -604,6 +633,7 @@ module Generators def value_hash class_attribute_values + add_table_of_sections @values["charset"] = @options.charset @values["style_url"] = style_url(path, @options.css) @@ -614,30 +644,43 @@ module Generators ml = build_method_summary_list @values["methods"] = ml unless ml.empty? - al = build_alias_summary_list - @values["aliases"] = al unless al.empty? - - co = build_constants_summary_list - @values["constants"] = co unless co.empty? - il = build_include_list(@context) @values["includes"] = il unless il.empty? - al = build_attribute_list - @values["attributes"] = al unless al.empty? - - cl = build_class_list(0, @context) - @values["classlist"] = cl unless cl.empty? + @values["sections"] = @context.sections.map do |section| + + secdata = { + "sectitle" => section.title, + "secsequence" => section.sequence, + "seccomment" => markup(section.comment) + } + + al = build_alias_summary_list(section) + secdata["aliases"] = al unless al.empty? + + co = build_constants_summary_list(section) + secdata["constants"] = co unless co.empty? + + al = build_attribute_list(section) + secdata["attributes"] = al unless al.empty? + + cl = build_class_list(0, @context, section) + secdata["classlist"] = cl unless cl.empty? + + mdl = build_method_detail_list(section) + secdata["method_list"] = mdl unless mdl.empty? + + secdata + end - mdl = build_method_detail_list - @values["method_list"] = mdl unless mdl.empty? @values end - def build_attribute_list + def build_attribute_list(section) atts = @context.attributes.sort res = [] atts.each do |att| + next unless att.section == section if att.visibility == :public || @options.show_all entry = { "name" => CGI.escapeHTML(att.name), @@ -701,7 +744,6 @@ module Generators end @values['infiles'] = files - end def <=>(other) @@ -759,6 +801,7 @@ module Generators def value_hash file_attribute_values + add_table_of_sections @values["charset"] = @options.charset @values["href"] = path @@ -778,23 +821,36 @@ module Generators rl = build_requires_list(@context) @values["requires"] = rl unless rl.empty? - co = build_constants_summary_list - @values["constants"] = co unless co.empty? - - al = build_alias_summary_list - @values["aliases"] = al unless al.empty? - if @options.promiscuous file_context = nil else file_context = @context end - cl = build_class_list(0, @context, file_context) - @values["classlist"] = cl unless cl.empty? - mdl = build_method_detail_list - @values["method_list"] = mdl unless mdl.empty? + @values["sections"] = @context.sections.map do |section| + + secdata = { + "sectitle" => section.title, + "secsequence" => section.sequence, + "seccomment" => markup(section.comment) + } + + cl = build_class_list(0, @context, section, file_context) + @values["classlist"] = cl unless cl.empty? + + mdl = build_method_detail_list(section) + secdata["method_list"] = mdl unless mdl.empty? + + al = build_alias_summary_list(section) + secdata["aliases"] = al unless al.empty? + + co = build_constants_summary_list(section) + @values["constants"] = co unless co.empty? + + secdata + end + @values end @@ -885,6 +941,10 @@ module Generators @context.name end + def section + @context.section + end + def index_name "#{@context.name} (#{@html_class.name})" end diff --git a/lib/rdoc/generators/template/html/html.rb b/lib/rdoc/generators/template/html/html.rb index e0a8880004..fd9917b43a 100644 --- a/lib/rdoc/generators/template/html/html.rb +++ b/lib/rdoc/generators/template/html/html.rb @@ -20,19 +20,22 @@ # module RDoc - module Page + module Page - FONTS = "Verdana,Arial,Helvetica,sans-serif" + FONTS = "Verdana,Arial,Helvetica,sans-serif" STYLE = %{ body { + font-family: Verdana,Arial,Helvetica,sans-serif; + font-size: 90%; margin: 0; + margin-left: 40px; padding: 0; background: white; } h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; } -h1 { font-size: 120%; } +h1 { font-size: 150%; } h2,h3,h4 { margin-top: 1em; } a { background: #eef; color: #039; text-decoration: none; } @@ -40,61 +43,75 @@ a:hover { background: #039; color: #eef; } /* Override the base stylesheet's Anchor inside a table cell */ td > a { - background: transparent; - color: #039; - text-decoration: none; + background: transparent; + color: #039; + text-decoration: none; +} + +/* and inside a section title */ +.section-title > a { + background: transparent; + color: #eee; + text-decoration: none; } /* === Structural elements =================================== */ div#index { margin: 0; + margin-left: -40px; padding: 0; - font-size: 0.9em; + font-size: 90%; } + div#index a { margin-left: 0.7em; } -div#classHeader { +div#index .section-bar { + margin-left: 0px; + padding-left: 0.7em; + background: #ccc; + font-size: small; +} + + +div#classHeader, div#fileHeader { width: auto; - background: #039; color: white; padding: 0.5em 1.5em 0.5em 1.5em; margin: 0; + margin-left: -40px; border-bottom: 3px solid #006; } -div#classHeader a { +div#classHeader a, div#fileHeader a { background: inherit; color: white; } -div#classHeader td { +div#classHeader td, div#fileHeader td { background: inherit; color: white; } + div#fileHeader { - width: auto; - background: #039; - color: white; - padding: 0.5em 1.5em 0.5em 1.5em; - margin: 0; - border-bottom: 3px solid #006; + background: #057; } -div#fileHeader a { - background: inherit; - color: white; +div#classHeader { + background: #048; } -div#fileHeader td { - background: inherit; - color: white; + +.class-name-in-header { + font-size: 180%; + font-weight: bold; } + div#bodyContent { padding: 0 1.5em 0 1.5em; } @@ -105,7 +122,7 @@ div#description { border: 1px dotted #999; } -div#description h1,h2,h3,h4,h5,h6 { +div#description h1,h3,h3,h4,h5,h6 { color: black; background: transparent; } @@ -137,35 +154,51 @@ table.header-table { color: #DEDEDE; } -.section-bar { +.xxsection-bar { background: #eee; color: #333; padding: 3px; +} + +.section-bar { + color: #333; + border-bottom: 1px solid #999; + margin-left: -20px; +} + + +.section-title { + background: #79a; + color: #eee; + padding: 3px; + margin-top: 2em; + margin-left: -30px; border: 1px solid #999; } -.top-aligned-row { vertical-align: vertical-align: top } +.top-aligned-row { vertical-align: top } +.bottom-aligned-row { vertical-align: bottom } /* --- Context section classes ----------------------- */ .context-row { } .context-item-name { font-family: monospace; font-weight: bold; color: black; } -.context-item-value { font-size: x-small; color: #448; } -.context-item-desc { background: #efefef; } +.context-item-value { font-size: small; color: #448; } +.context-item-desc { color: #333; padding-left: 2em; } /* --- Method classes -------------------------- */ .method-detail { - background: #EFEFEF; + background: #efefef; padding: 0; margin-top: 0.5em; - margin-bottom: 0.5em; - border: 1px dotted #DDD; + margin-bottom: 1em; + border: 1px dotted #ccc; } .method-heading { - color: black; - background: #AAA; - border-bottom: 1px solid #666; - padding: 0.2em 0.5em 0 0.5em; + color: black; + background: #ccc; + border-bottom: 1px solid #666; + padding: 0.2em 0.5em 0 0.5em; } .method-signature { color: black; background: inherit; } .method-name { font-weight: bold; } @@ -178,7 +211,7 @@ a.source-toggle { font-size: 90%; } div.method-source-code { background: #262626; color: #ffdead; - margin: 1em; + margin: 1em; padding: 0.5em; border: 1px dashed #999; overflow: hidden; @@ -190,20 +223,20 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } .standalone-code { background: #221111; color: #ffdead; overflow: hidden; } -.ruby-constant { color: #7fffd4; background: transparent; } -.ruby-keyword { color: #00ffff; background: transparent; } -.ruby-ivar { color: #eedd82; background: transparent; } -.ruby-operator { color: #00ffee; background: transparent; } +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } .ruby-identifier { color: #ffdead; background: transparent; } -.ruby-node { color: #ffa07a; background: transparent; } -.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } -.ruby-regexp { color: #ffa07a; background: transparent; } -.ruby-value { color: #7fffd4; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } } ##################################################################### -### H E A D E R T E M P L A T E +### H E A D E R T E M P L A T E ##################################################################### XHTML_PREAMBLE = %{ @@ -215,41 +248,41 @@ XHTML_PREAMBLE = %{ HEADER = XHTML_PREAMBLE + %{ - %title% - - - - + return true; + } + + // Make codeblocks hidden by default + document.writeln( "" ) + + // ]]> + @@ -257,129 +290,15 @@ HEADER = XHTML_PREAMBLE + %{ ##################################################################### -### C O N T E X T C O N T E N T T E M P L A T E +### C O N T E X T C O N T E N T T E M P L A T E ##################################################################### CONTEXT_CONTENT = %{ -
-IF:diagram -
- %diagram% -
-ENDIF:diagram - -IF:description -
- %description% -
-ENDIF:description - -IF:requires -
-

Required files

- -
-START:requires - HREF:aref:name:   -END:requires -
-
-ENDIF:requires - -IF:methods -
-

Methods

- -
-START:methods - HREF:aref:name:   -END:methods -
-
-ENDIF:methods - -IF:constants -
-

Constants

- -
- -START:constants - - - - - -IF:desc - - - - -ENDIF:desc -END:constants -
%name%=%value%
 %desc%
-
-
-ENDIF:constants - -IF:aliases -
-

External Aliases

- -
- -START:aliases - - - - - -IF:desc - - - - -ENDIF:desc -END:aliases -
%old_name%->%new_name%
 %desc%
-
-
-ENDIF:aliases - - -IF:attributes -
-

Attributes

- -
- -START:attributes - - - - - -END:attributes -
%name% [%rw%] %a_desc%
-
-
-ENDIF:attributes - -IF:classlist -
-

Classes and Modules

- - %classlist% -
-ENDIF:classlist - -
- } ##################################################################### -### F O O T E R T E M P L A T E +### F O O T E R T E M P L A T E ##################################################################### FOOTER = %{
@@ -392,38 +311,41 @@ FOOTER = %{ ##################################################################### -### F I L E P A G E H E A D E R T E M P L A T E +### F I L E P A G E H E A D E R T E M P L A T E ##################################################################### FILE_PAGE = %{ -
-

%short_name%

- - - - + + + + + +
Path:%full_path% +
+

%short_name%

+ + + + - - - - - -
Path:%full_path% IF:cvsurl -  (CVS) +  (CVS) ENDIF:cvsurl -
Last Update:%dtm_modified%
-
+
Last Update:%dtm_modified%
+
} ##################################################################### -### C L A S S P A G E H E A D E R T E M P L A T E +### C L A S S P A G E H E A D E R T E M P L A T E ##################################################################### CLASS_PAGE = %{
-

%full_name% (%classmod%)

+ + + + @@ -463,121 +385,258 @@ ENDIF:parent ##################################################################### -### M E T H O D L I S T T E M P L A T E +### M E T H O D L I S T T E M P L A T E ##################################################################### METHOD_LIST = %{ - -IF:includes -
-

Included Modules

+
+IF:diagram +
+ %diagram% +
+ENDIF:diagram -
+IF:description +
+ %description% +
+ENDIF:description + +IF:requires +
+

Required files

+ +
+START:requires + HREF:aref:name:   +END:requires +
+
+ENDIF:requires + +IF:toc +
+

Contents

+ +ENDIF:toc +
+ +IF:methods +
+

Methods

+ +
+START:methods + HREF:aref:name:   +END:methods +
+
+ENDIF:methods + +
+ + + +IF:includes +
+

Included Modules

+ +
START:includes - HREF:aref:name: + HREF:aref:name: END:includes -
-
+
+
ENDIF:includes +START:sections +
+IF:sectitle +

%sectitle%

+IF:seccomment +
+ %seccomment% +
+ENDIF:seccomment +ENDIF:sectitle - +IF:classlist +
+

Classes and Modules

+ + %classlist% +
+ENDIF:classlist + +IF:constants +
+

Constants

+ +
+
%classmod%%full_name%
In: @@ -436,9 +358,9 @@ IF:full_path_url ENDIF:full_path_url IF:cvsurl -  (CVS) +  (CVS) ENDIF:cvsurl -
+
END:infiles
+START:constants + + + + +IF:desc + + +ENDIF:desc + +END:constants +
%name%=%value% %desc%
+
+
+ENDIF:constants + +IF:aliases +
+

External Aliases

+ +
+ +START:aliases + + + + + +IF:desc + + + + +ENDIF:desc +END:aliases +
%old_name%->%new_name%
 %desc%
+
+
+ENDIF:aliases + + +IF:attributes +
+

Attributes

+ +
+ +START:attributes + + + + + +END:attributes +
%name% [%rw%] %a_desc%
+
+
+ENDIF:attributes + + + + IF:method_list -
+
START:method_list IF:methods -

%type% %category% methods

+

%type% %category% methods

START:methods -
- +
+ -
+ - -
+
+ +
IF:m_desc - %m_desc% + %m_desc% ENDIF:m_desc IF:sourcecode -

[Source]

-
+

[Source]

+
 %sourcecode%
 
-
+
ENDIF:sourcecode -
-
+
+
END:methods ENDIF:methods END:method_list -
+
ENDIF:method_list +END:sections } ##################################################################### -### B O D Y T E M P L A T E +### B O D Y T E M P L A T E ##################################################################### BODY = HEADER + %{ !INCLUDE! -
+
-} + CONTEXT_CONTENT + METHOD_LIST + %{ +} + METHOD_LIST + %{ -
+
} + FOOTER ##################################################################### -### S O U R C E C O D E T E M P L A T E +### S O U R C E C O D E T E M P L A T E ##################################################################### SRC_PAGE = XHTML_PREAMBLE + %{ - %title% - - + %title% + + -
%code%
+
%code%
} ##################################################################### -### I N D E X F I L E T E M P L A T E S +### I N D E X F I L E T E M P L A T E S ##################################################################### FR_INDEX_BODY = %{ @@ -592,19 +651,19 @@ FILE_INDEX = XHTML_PREAMBLE + %{ --> - %list_title% - - - + %list_title% + + +
-

%list_title%

-
+

%list_title%

+
START:entries - %name%
+ %name%
END:entries -
+
@@ -625,8 +684,8 @@ INDEX = %{ --> - %title% - + %title% + @@ -641,7 +700,7 @@ INDEX = %{ - end # module Page + end # module Page end # class RDoc require 'rdoc/generators/template/html/one_page_html' diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb index 62c6dabff0..53eee992e2 100644 --- a/lib/rdoc/options.rb +++ b/lib/rdoc/options.rb @@ -391,7 +391,7 @@ class Options when "--line-numbers" then @include_line_numbers = true when "--main" then @main_page = arg when "--merge" then @merge = true - when "--one-file" then @all_one_file = true + when "--one-file" then @all_one_file = @inline_source = true when "--op" then @op_dir = arg when "--opname" then @op_name = arg when "--promiscuous" then @promiscuous = true diff --git a/lib/rdoc/parsers/parse_rb.rb b/lib/rdoc/parsers/parse_rb.rb index b8367b5641..8f1206409a 100644 --- a/lib/rdoc/parsers/parse_rb.rb +++ b/lib/rdoc/parsers/parse_rb.rb @@ -1580,23 +1580,6 @@ module RDoc non_comment_seen = true unless tk.kind_of?(TkCOMMENT) -# $stderr.puts "===== #{tk.inspect}" -# blank_line_seen = true -# while tk.kind_of?(TkNL) -# skip_tkspace(false) -# if peek_tk.kind_of?(TkCOMMENT) -# if blank_line_seen -# comment = '' -# blank_line_seen = false -# end -# tk = get_tk -# comment << tk.text << "\n" -# else -# blank_line_seen = true -# end -# tk = get_tk -# end - case tk when TkNL @@ -2326,6 +2309,10 @@ module RDoc options.title = param "" + when "section" + context.set_current_section(param, comment) + comment.clear + "" else warn "Unrecognized directive '#{directive}'" break @@ -2548,7 +2535,7 @@ module RDoc break when TkCOMMA else - warn("unexpected token: '#{tk.inspect}'") + warn("unexpected token: '#{tk2.inspect}'") if $DEBBUG break end end