rdoc 6.17.0 → 7.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2bb82d9eff1cf5ae3ee5276c97b12d57694d28c64a70ee9f318d4468c904999e
4
- data.tar.gz: f7073f27e9b4a15e3b7792f777bb8b2bc991bde74409e15cdb5bd7be1900f2db
3
+ metadata.gz: '09f66eb1c281e4323e70183c119a58a9c97c8fef86ba4f1ae42691d614a484be'
4
+ data.tar.gz: eb7605a8633beab318d2bc9ee4fb66c420397a3ab48bdd5ef8c9d4c533c12ffc
5
5
  SHA512:
6
- metadata.gz: 76a11b7a7529c4b008488ba22f4aa0c8c5dd2cbfff19ec795f0fa5f16e0d7c7f4913d69c2cc11d18653f8d0a4bde559f2b2a893b9dba9d8aec34faaec557b935
7
- data.tar.gz: 5af47e79dc6fde12b8aa9809a0eb845db18031a907140484ea95ef16399a592c879445b8f725ae4eabfbfe5d3250656926698fa2a35b3426605420ca9961579f
6
+ metadata.gz: 722cd4f102ad66df12a9db58c4807545a1d489090f7e82b9d3b84422a82975c7e20dc32c263fd6ae1c5c5421e9d65a599e1dce70431dc963991292bf328f0990
7
+ data.tar.gz: 328b307c3ae2fd5057e40afa1f0e72da247f455aab4427698f15d51606aa469097f4816a607a518087f8284270822d8de9b30af86720c87011e1cc78b25121b0
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,187 @@
1
+ # Contributing to RDoc
2
+
3
+ Thank you for your interest in contributing to RDoc! This document provides guidelines and instructions for contributing.
4
+
5
+ ## Reporting Bugs
6
+
7
+ If you think you found a bug, open an issue on the [issue tracker](https://github.com/ruby/rdoc/issues) on GitHub.
8
+
9
+ When reporting a bug:
10
+
11
+ - Include a sample file that illustrates the problem, or link to the repository/gem associated with the bug
12
+ - Include steps to reproduce the issue
13
+
14
+ ## Development Setup
15
+
16
+ RDoc uses Bundler for development. To get started:
17
+
18
+ ```bash
19
+ bundle install
20
+ bundle exec rake
21
+ ```
22
+
23
+ This will install dependencies and run the tests.
24
+
25
+ If you're working on CSS or templates, you'll also want Node dependencies for the CSS linter:
26
+
27
+ ```bash
28
+ npm install
29
+ ```
30
+
31
+ If tests don't pass on the first run, check the [GitHub Actions page](https://github.com/ruby/rdoc/actions) to see if there are any known failures.
32
+
33
+ **Note:** Generated parser files are committed to the repository. If you delete them (for example via `bundle exec rake clean`) or you change any `.ry`/`.kpeg` parser sources, run `bundle exec rake generate` before running tests.
34
+
35
+ ## Running Tests
36
+
37
+ ```bash
38
+ # Run all tests (default task)
39
+ bundle exec rake
40
+
41
+ # Run unit tests only (excludes RubyGems integration)
42
+ bundle exec rake normal_test
43
+
44
+ # Run RubyGems integration tests only
45
+ bundle exec rake rubygems_test
46
+
47
+ # Verify generated parser files are current (CI check)
48
+ bundle exec rake verify_generated
49
+ ```
50
+
51
+ - **Test Framework:** [`test-unit`](https://github.com/test-unit/test-unit)
52
+ - **Test Location:** `test/` directory
53
+ - **Test Helper:** `test/lib/helper.rb`
54
+
55
+ ## Linting
56
+
57
+ ### RuboCop (Ruby Code)
58
+
59
+ ```bash
60
+ # Check Ruby code style
61
+ bundle exec rubocop
62
+
63
+ # Auto-fix style issues
64
+ bundle exec rubocop -A
65
+ ```
66
+
67
+ ### Herb Linter (ERB/RHTML Templates)
68
+
69
+ ```bash
70
+ # Lint ERB template files
71
+ npx @herb-tools/linter "**/*.rhtml"
72
+
73
+ # Lint specific directory
74
+ npx @herb-tools/linter "lib/**/*.rhtml"
75
+ ```
76
+
77
+ **Template Location:** `lib/rdoc/generator/template/**/*.rhtml`
78
+
79
+ ### Stylelint (CSS Files)
80
+
81
+ ```bash
82
+ # Lint CSS files
83
+ npm run lint:css
84
+
85
+ # Auto-fix style issues
86
+ npm run lint:css -- --fix
87
+ ```
88
+
89
+ ## Parser Generation
90
+
91
+ RDoc uses generated parsers for Markdown and RD formats.
92
+
93
+ ```bash
94
+ # Generate all parser files from sources
95
+ bundle exec rake generate
96
+
97
+ # Remove generated parser files
98
+ bundle exec rake clean
99
+
100
+ # Verify generated files are in sync with sources (CI check)
101
+ bundle exec rake verify_generated
102
+ ```
103
+
104
+ **Source Files** (edit these):
105
+
106
+ - `lib/rdoc/rd/block_parser.ry` → generates `block_parser.rb` via racc
107
+ - `lib/rdoc/rd/inline_parser.ry` → generates `inline_parser.rb` via racc
108
+ - `lib/rdoc/markdown.kpeg` → generates `markdown.rb` via kpeg
109
+ - `lib/rdoc/markdown/literals.kpeg` → generates `literals.rb` via kpeg
110
+
111
+ **Important:**
112
+
113
+ - Generated parser files **should be committed** to the repository
114
+ - Do not edit generated `.rb` parser files directly
115
+ - After modifying `.ry` or `.kpeg` source files, run `bundle exec rake generate`
116
+ - CI runs `rake verify_generated` to ensure generated files are in sync with their sources
117
+
118
+ ## Documentation Generation
119
+
120
+ ```bash
121
+ # Generate documentation (creates _site directory)
122
+ bundle exec rake rdoc
123
+
124
+ # Force regenerate documentation
125
+ bundle exec rake rerdoc
126
+
127
+ # Show documentation coverage
128
+ bundle exec rake rdoc:coverage
129
+ bundle exec rake coverage
130
+ ```
131
+
132
+ - **Output Directory:** `_site/` (GitHub Pages compatible)
133
+ - **Configuration:** `.rdoc_options` and `.document`
134
+
135
+ ## Themes
136
+
137
+ RDoc ships with two HTML themes:
138
+
139
+ - **Aliki** (default) - Modern theme with improved styling and navigation
140
+ - **Darkfish** (deprecated) - Classic theme, will be removed in v8.0
141
+
142
+ New feature development should focus on the Aliki theme. Darkfish will continue to receive bug fixes but no new features.
143
+
144
+ Theme templates are located at `lib/rdoc/generator/template/<theme>/`.
145
+
146
+ ## Project Structure
147
+
148
+ ```
149
+ lib/rdoc/
150
+ ├── rdoc.rb # Main entry point (RDoc::RDoc class)
151
+ ├── version.rb # Version constant
152
+ ├── task.rb # Rake task integration
153
+ ├── parser/ # Source code parsers
154
+ │ ├── ruby.rb # Ruby code parser
155
+ │ ├── c.rb # C extension parser
156
+ │ ├── prism_ruby.rb # Prism-based Ruby parser
157
+ │ └── ...
158
+ ├── generator/ # Documentation generators
159
+ │ ├── aliki.rb # HTML generator (default theme)
160
+ │ ├── darkfish.rb # HTML generator (deprecated, will be removed in v8.0)
161
+ │ ├── markup.rb # Markup format generator
162
+ │ ├── ri.rb # RI command generator
163
+ │ └── template/ # ERB templates
164
+ │ ├── aliki/ # Aliki theme (default)
165
+ │ └── darkfish/ # Darkfish theme (deprecated)
166
+ ├── markup/ # Markup parsing and formatting
167
+ ├── code_object/ # AST objects for documented items
168
+ ├── markdown.kpeg # Parser source (edit this)
169
+ ├── markdown.rb # Generated parser (do not edit)
170
+ ├── markdown/ # Markdown parsing
171
+ │ ├── literals.kpeg # Parser source (edit this)
172
+ │ └── literals.rb # Generated parser (do not edit)
173
+ ├── rd/ # RD format parsing
174
+ │ ├── block_parser.ry # Parser source (edit this)
175
+ │ ├── block_parser.rb # Generated parser (do not edit)
176
+ │ ├── inline_parser.ry # Parser source (edit this)
177
+ │ └── inline_parser.rb # Generated parser (do not edit)
178
+ └── ri/ # RI (Ruby Info) tool
179
+
180
+ test/ # Test files
181
+ ├── lib/helper.rb # Test helpers
182
+ └── rdoc/ # Main test directory
183
+ ```
184
+
185
+ ## Code of Conduct
186
+
187
+ Please be respectful and constructive in all interactions. We're all here to make RDoc better!
data/LEGAL.rdoc CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  The files in this distribution are covered by the Ruby license (see LICENSE) except the features mentioned below:
6
6
 
7
+ Aliki::
8
+ Aliki was written by Stan Lo and is included under the MIT license.
9
+
10
+ * lib/rdoc/generator/aliki.rb
11
+ * lib/rdoc/generator/template/aliki/*
12
+
7
13
  Darkfish::
8
14
  Darkfish was written by Michael Granger and is included under the BSD 3-Clause
9
15
  license. Darkfish contains images from the Silk Icons set by Mark James.
data/README.md CHANGED
@@ -48,7 +48,7 @@ require 'rdoc/rdoc'
48
48
 
49
49
  options = RDoc::Options.new
50
50
  options.files = ['a.rb', 'b.rb']
51
- options.setup_generator 'darkfish'
51
+ options.setup_generator 'aliki'
52
52
  # see RDoc::Options
53
53
 
54
54
  rdoc = RDoc::RDoc.new
@@ -90,7 +90,24 @@ To determine how well your project is documented run `rdoc -C lib` to get a docu
90
90
 
91
91
  ## Theme Options
92
92
 
93
- There are a few community-maintained themes for RDoc:
93
+ RDoc ships with two built-in themes:
94
+
95
+ - **Aliki** (default) - A modern, clean theme with improved navigation and search
96
+ - **Darkfish** (deprecated) - The classic theme, will be removed in v8.0
97
+
98
+ To use the Darkfish theme instead of the default Aliki theme:
99
+
100
+ ```shell
101
+ rdoc --format darkfish
102
+ ```
103
+
104
+ Or in your `.rdoc_options` file:
105
+
106
+ ```yaml
107
+ generator_name: darkfish
108
+ ```
109
+
110
+ There are also a few community-maintained themes for RDoc:
94
111
 
95
112
  - [rorvswild-theme-rdoc](https://github.com/BaseSecrete/rorvswild-theme-rdoc)
96
113
  - [hanna](https://github.com/jeremyevans/hanna) (a fork maintained by [Jeremy Evans](https://github.com/jeremyevans))
@@ -99,7 +116,7 @@ Please follow the theme's README for usage instructions.
99
116
 
100
117
  ## Bugs
101
118
 
102
- See CONTRIBUTING.rdoc for information on filing a bug report. It's OK to file a bug report for anything you're having a problem with. If you can't figure out how to make RDoc produce the output you like that is probably a documentation bug.
119
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for information on filing a bug report. It's OK to file a bug report for anything you're having a problem with. If you can't figure out how to make RDoc produce the output you like that is probably a documentation bug.
103
120
 
104
121
  ## License
105
122
 
@@ -351,7 +351,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
351
351
  return call_seq unless is_alias_for || !aliases.empty?
352
352
 
353
353
  method_name = self.name
354
- method_name = method_name[0, 1] if method_name =~ /\A\[/
355
354
 
356
355
  entries = call_seq.split "\n"
357
356
 
@@ -360,15 +359,24 @@ class RDoc::AnyMethod < RDoc::MethodAttr
360
359
  ignore << is_alias_for.name
361
360
  ignore.concat is_alias_for.aliases.map(&:name)
362
361
  end
363
- ignore.map! { |n| n =~ /\A\[/ ? /\[.*\]/ : n}
362
+
364
363
  ignore.delete(method_name)
365
- ignore = Regexp.union(ignore)
364
+ ignore_bracket_methods, ignore_other_methods = ignore.partition {|i| i.start_with?('[') }
366
365
 
367
- matching = entries.reject do |entry|
368
- entry =~ /^\w*\.?#{ignore}[$\(\s]/ or
369
- entry =~ /\s#{ignore}\s/
366
+ if ignore_other_methods.any?
367
+ ignore_union = Regexp.union(ignore_other_methods)
368
+ entries.reject! do |entry|
369
+ /\A(?:\w*\.)?#{ignore_union}(?:[(\s]|\z)/.match?(entry) ||
370
+ /\s#{ignore_union}\s/.match?(entry)
371
+ end
372
+ end
373
+ if ignore_bracket_methods.any?
374
+ entries.reject! do |entry|
375
+ # Ignore `receiver[arg] -> return_type` `[](arg)` `[]`
376
+ /\A\w*\[.*?\](?:[(\s]|\z)/.match?(entry)
377
+ end
370
378
  end
371
379
 
372
- matching.empty? ? nil : matching.join("\n")
380
+ entries.empty? ? nil : entries.join("\n")
373
381
  end
374
382
  end
@@ -689,6 +689,9 @@ class RDoc::ClassModule < RDoc::Context
689
689
 
690
690
  ##
691
691
  # Search record used by RDoc::Generator::JsonIndex
692
+ #
693
+ # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator.
694
+ # Use #search_snippet instead for getting documentation snippets.
692
695
 
693
696
  def search_record
694
697
  [
@@ -702,6 +705,16 @@ class RDoc::ClassModule < RDoc::Context
702
705
  ]
703
706
  end
704
707
 
708
+ ##
709
+ # Returns an HTML snippet of the first comment for search results.
710
+
711
+ def search_snippet
712
+ first_comment = @comment_location.first&.first
713
+ return '' unless first_comment && !first_comment.empty?
714
+
715
+ snippet(first_comment)
716
+ end
717
+
705
718
  ##
706
719
  # Sets the store for this class or module and its contained code objects.
707
720
 
@@ -154,6 +154,15 @@ class RDoc::Constant < RDoc::CodeObject
154
154
  "#{@parent.path}##{@name}"
155
155
  end
156
156
 
157
+ ##
158
+ # Returns an HTML snippet of the comment for search results.
159
+
160
+ def search_snippet
161
+ return '' if comment.empty?
162
+
163
+ snippet(comment)
164
+ end
165
+
157
166
  def pretty_print(q) # :nodoc:
158
167
  q.group 2, "[#{self.class.name} #{full_name}", "]" do
159
168
  unless comment.empty? then
@@ -375,6 +375,9 @@ class RDoc::MethodAttr < RDoc::CodeObject
375
375
  ##
376
376
  # Used by RDoc::Generator::JsonIndex to create a record for the search
377
377
  # engine.
378
+ #
379
+ # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator.
380
+ # Use #search_snippet instead for getting documentation snippets.
378
381
 
379
382
  def search_record
380
383
  [
@@ -384,10 +387,19 @@ class RDoc::MethodAttr < RDoc::CodeObject
384
387
  @parent.full_name,
385
388
  path,
386
389
  params,
387
- snippet(@comment),
390
+ search_snippet,
388
391
  ]
389
392
  end
390
393
 
394
+ ##
395
+ # Returns an HTML snippet of the comment for search results.
396
+
397
+ def search_snippet
398
+ return '' if @comment.empty?
399
+
400
+ snippet(@comment)
401
+ end
402
+
391
403
  def to_s # :nodoc:
392
404
  if @is_alias_for
393
405
  "#{self.class.name}: #{full_name} -> #{is_alias_for}"
@@ -237,6 +237,9 @@ class RDoc::TopLevel < RDoc::Context
237
237
 
238
238
  ##
239
239
  # Search record used by RDoc::Generator::JsonIndex
240
+ #
241
+ # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator.
242
+ # Use #search_snippet instead for getting documentation snippets.
240
243
 
241
244
  def search_record
242
245
  return unless @parser < RDoc::Parser::Text
@@ -248,10 +251,19 @@ class RDoc::TopLevel < RDoc::Context
248
251
  '',
249
252
  path,
250
253
  '',
251
- snippet(@comment),
254
+ search_snippet,
252
255
  ]
253
256
  end
254
257
 
258
+ ##
259
+ # Returns an HTML snippet of the comment for search results.
260
+
261
+ def search_snippet
262
+ return '' if @comment.empty?
263
+
264
+ snippet(@comment)
265
+ end
266
+
255
267
  ##
256
268
  # Is this TopLevel from a text file instead of a source code file?
257
269
 
@@ -15,6 +15,30 @@ class RDoc::Generator::Aliki < RDoc::Generator::Darkfish
15
15
  @template_dir = Pathname.new(aliki_template_dir)
16
16
  end
17
17
 
18
+ ##
19
+ # Generate documentation. Overrides Darkfish to use Aliki's own search index
20
+ # instead of the JsonIndex generator.
21
+
22
+ def generate
23
+ setup
24
+
25
+ write_style_sheet
26
+ generate_index
27
+ generate_class_files
28
+ generate_file_files
29
+ generate_table_of_contents
30
+ write_search_index
31
+
32
+ copy_static
33
+
34
+ rescue => e
35
+ debug_msg "%s: %s\n %s" % [
36
+ e.class.name, e.message, e.backtrace.join("\n ")
37
+ ]
38
+
39
+ raise
40
+ end
41
+
18
42
  ##
19
43
  # Copy only the static assets required by the Aliki theme. Unlike Darkfish we
20
44
  # don't ship embedded fonts or image sprites, so limit the asset list to keep
@@ -39,4 +63,104 @@ class RDoc::Generator::Aliki < RDoc::Generator::Darkfish
39
63
  install_rdoc_static_file @template_dir + path, dst, options
40
64
  end
41
65
  end
66
+
67
+ ##
68
+ # Build a search index array for Aliki's searcher.
69
+
70
+ def build_search_index
71
+ setup
72
+
73
+ index = []
74
+
75
+ @classes.each do |klass|
76
+ next unless klass.display?
77
+
78
+ index << build_class_module_entry(klass)
79
+
80
+ klass.constants.each do |const|
81
+ next unless const.display?
82
+
83
+ index << build_constant_entry(const, klass)
84
+ end
85
+ end
86
+
87
+ @methods.each do |method|
88
+ next unless method.display?
89
+
90
+ index << build_method_entry(method)
91
+ end
92
+
93
+ index
94
+ end
95
+
96
+ ##
97
+ # Write the search index as a JavaScript file
98
+ # Format: var search_data = { index: [...] }
99
+ #
100
+ # We still write to a .js instead of a .json because loading a JSON file triggers CORS check in browsers.
101
+ # And if we simply inspect the generated pages using file://, which is often the case due to lack of the server mode,
102
+ # the JSON file will be blocked by the browser.
103
+
104
+ def write_search_index
105
+ debug_msg "Writing Aliki search index"
106
+
107
+ index = build_search_index
108
+
109
+ FileUtils.mkdir_p 'js' unless @dry_run
110
+
111
+ search_index_path = 'js/search_data.js'
112
+ return if @dry_run
113
+
114
+ data = { index: index }
115
+ File.write search_index_path, "var search_data = #{JSON.generate(data)};"
116
+ end
117
+
118
+ private
119
+
120
+ def build_class_module_entry(klass)
121
+ type = case klass
122
+ when RDoc::NormalClass then 'class'
123
+ when RDoc::NormalModule then 'module'
124
+ else 'class'
125
+ end
126
+
127
+ entry = {
128
+ name: klass.name,
129
+ full_name: klass.full_name,
130
+ type: type,
131
+ path: klass.path
132
+ }
133
+
134
+ snippet = klass.search_snippet
135
+ entry[:snippet] = snippet unless snippet.empty?
136
+ entry
137
+ end
138
+
139
+ def build_method_entry(method)
140
+ type = method.singleton ? 'class_method' : 'instance_method'
141
+
142
+ entry = {
143
+ name: method.name,
144
+ full_name: method.full_name,
145
+ type: type,
146
+ path: method.path
147
+ }
148
+
149
+ snippet = method.search_snippet
150
+ entry[:snippet] = snippet unless snippet.empty?
151
+ entry
152
+ end
153
+
154
+ def build_constant_entry(const, parent)
155
+ entry = {
156
+ name: const.name,
157
+ full_name: "#{parent.full_name}::#{const.name}",
158
+ type: 'constant',
159
+ path: parent.path
160
+ }
161
+
162
+ snippet = const.search_snippet
163
+ entry[:snippet] = snippet unless snippet.empty?
164
+ entry
165
+ end
42
166
  end
@@ -116,22 +116,22 @@
116
116
  ></script>
117
117
 
118
118
  <script
119
- src="<%= h asset_rel_prefix %>/js/navigation.js?v=<%= h RDoc::VERSION %>"
119
+ src="<%= h asset_rel_prefix %>/js/search_navigation.js?v=<%= h RDoc::VERSION %>"
120
120
  defer
121
121
  ></script>
122
122
 
123
123
  <script
124
- src="<%= h asset_rel_prefix %>/js/search.js?v=<%= h RDoc::VERSION %>"
124
+ src="<%= h asset_rel_prefix %>/js/search_data.js?v=<%= h RDoc::VERSION %>"
125
125
  defer
126
126
  ></script>
127
127
 
128
128
  <script
129
- src="<%= h asset_rel_prefix %>/js/search_index.js?v=<%= h RDoc::VERSION %>"
129
+ src="<%= h asset_rel_prefix %>/js/search_ranker.js?v=<%= h RDoc::VERSION %>"
130
130
  defer
131
131
  ></script>
132
132
 
133
133
  <script
134
- src="<%= h asset_rel_prefix %>/js/searcher.js?v=<%= h RDoc::VERSION %>"
134
+ src="<%= h asset_rel_prefix %>/js/search_controller.js?v=<%= h RDoc::VERSION %>"
135
135
  defer
136
136
  ></script>
137
137
 
@@ -156,15 +156,13 @@
156
156
  <summary>Source</summary>
157
157
  </details>
158
158
  </div>
159
+ <div class="method-source-code" id="<%= method.html_name %>-source">
160
+ <pre class="<%= method.source_language %>" data-language="<%= method.source_language %>"><%= method.markup_code %></pre>
161
+ </div>
159
162
  <%- end %>
160
163
 
161
164
  <%- unless method.skip_description? then %>
162
165
  <div class="method-description">
163
- <%- if method.token_stream then %>
164
- <div class="method-source-code" id="<%= method.html_name %>-source">
165
- <pre class="<%= method.source_language %>" data-language="<%= method.source_language %>"><%= method.markup_code %></pre>
166
- </div>
167
- <%- end %>
168
166
  <%- if method.mixin_from then %>
169
167
  <div class="mixin-from">
170
168
  <%= method.singleton ? "Extended" : "Included" %> from <a href="<%= klass.aref_to(method.mixin_from.path) %>"><%= method.mixin_from.full_name %></a>