rdoc-markdown 0.8.0 → 0.10.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: 35702d5815f56256651a8994111e772ee761a19a0df97052816431c15247b73b
4
- data.tar.gz: 3720a080b24825ea96ea487d5b264dcbe2cf2f4c5e8ea25be677e9c54a0b0f4e
3
+ metadata.gz: a3af6b5292a9333e8e0749195f1b799f80015a2b23bc7c8bd47068f315671d5c
4
+ data.tar.gz: 759122408198407ee3f300ee7effa75e4f7d02cf765a989f30db4ee1d79b4fa9
5
5
  SHA512:
6
- metadata.gz: de2608fb5a61247ef9fd33153a8ab75bbfb21b9e3200078a1d59237340a0511cbee0866e90dce2d4a6d73408aed16bd2bb53e09f3e78118c083dd388b411c366
7
- data.tar.gz: d5c8e5de4664c1300b8997c13948b296bd2ed39768396f5a5928cfea176f91130b51359f8ee982e24f2ef2a5284b10f53c2c4dbb6249d0e3726f9225a0e1212c
6
+ metadata.gz: e259a75c590f3414e036763c213a3b19e8df9d78a964155ba20ebb6b5ec440b25cca3b4a925fc39181100267079cd89e30db711aabb087b34245b72dc3ca9873
7
+ data.tar.gz: e70488f82388bdbb6e1bd8a99e32864da66c86adf2e8cf58f2ee3775523a9283002b30aa31f8a8d080cc70812d6efcee5300bffb665b4bf432b2fd8643db5a86
data/Appraisals ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rdoc_7" do
4
+ gem "rdoc", "~> 7.0"
5
+ end
6
+
7
+ appraise "rdoc_8" do
8
+ gem "rdoc", "~> 8.0"
9
+ end
10
+
11
+ appraise "rdoc_head" do
12
+ gem "rdoc", git: "https://github.com/ruby/rdoc.git", branch: "master"
13
+ end
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.10.0
6
+
7
+ - Reworked RDoc 8 support
8
+
9
+ ## 0.9.0
10
+
11
+ ### Fixed
12
+ - Render RDoc 8 inline and sidecar RBS signatures in Markdown method headings.
13
+ - Resolve explicit relative `.rbs` inputs against the directory where RDoc started, not the output directory.
14
+
15
+ ### Changed
16
+ - Run CI against both RDoc 7 and RDoc 8 dependency sets.
17
+
5
18
  ## 0.8.0
6
19
 
7
20
  ### Added
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
9
 
10
+ gem "appraisal"
10
11
  gem "erb_lint", require: false
11
12
  gem "minitest", "~> 5.0"
12
13
  gem "standard"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rdoc-markdown (0.8.0)
4
+ rdoc-markdown (0.10.0)
5
5
  csv
6
6
  erb
7
7
  rdoc
@@ -29,6 +29,10 @@ GEM
29
29
  securerandom (>= 0.3)
30
30
  tzinfo (~> 2.0, >= 2.0.5)
31
31
  uri (>= 0.13.1)
32
+ appraisal (2.5.0)
33
+ bundler
34
+ rake
35
+ thor (>= 0.14.0)
32
36
  ast (2.4.3)
33
37
  base64 (0.3.0)
34
38
  better_html (2.2.0)
@@ -112,6 +116,10 @@ GEM
112
116
  nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
113
117
  rainbow (3.1.1)
114
118
  rake (13.4.2)
119
+ rbs (4.0.2)
120
+ logger
121
+ prism (>= 1.6.0)
122
+ tsort
115
123
  rdiscount (2.2.7.4)
116
124
  rdoc (7.2.0)
117
125
  erb
@@ -163,6 +171,7 @@ GEM
163
171
  lint_roller (~> 1.1)
164
172
  rubocop-performance (~> 1.26.0)
165
173
  stringio (3.2.0)
174
+ thor (1.5.0)
166
175
  tsort (0.2.0)
167
176
  tzinfo (2.0.6)
168
177
  concurrent-ruby (~> 1.0)
@@ -184,6 +193,7 @@ PLATFORMS
184
193
  x86_64-linux-gnu
185
194
 
186
195
  DEPENDENCIES
196
+ appraisal
187
197
  bundler (>= 2.0)
188
198
  commonmarker
189
199
  erb_lint
@@ -193,6 +203,7 @@ DEPENDENCIES
193
203
  mutant-minitest
194
204
  mutex_m
195
205
  rake (~> 13.0)
206
+ rbs
196
207
  rdiscount (~> 2.0)
197
208
  rdoc-markdown!
198
209
  simplecov (~> 0.22)
data/Rakefile CHANGED
@@ -21,7 +21,10 @@ task default: [:test]
21
21
  namespace :erb do
22
22
  desc "Lint markdown ERB templates"
23
23
  task :lint do
24
- sh "bundle exec erb_lint --lint-all"
24
+ files = Dir["lib/templates/**/*.{md,markdown}.erb"]
25
+ raise "No markdown ERB templates found" if files.empty?
26
+
27
+ sh "bundle", "exec", "erb_lint", *files
25
28
  end
26
29
  end
27
30
 
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake", "~> 13.0"
6
+ gem "appraisal"
7
+ gem "erb_lint", require: false
8
+ gem "minitest", "~> 5.0"
9
+ gem "standard"
10
+ gem "yard-lint"
11
+
12
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.3")
13
+ gem "mutant"
14
+ gem "mutant-minitest"
15
+ gem "mutex_m"
16
+ end
17
+
18
+ gem "rdoc", "~> 7.0"
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake", "~> 13.0"
6
+ gem "appraisal"
7
+ gem "erb_lint", require: false
8
+ gem "minitest", "~> 5.0"
9
+ gem "standard"
10
+ gem "yard-lint"
11
+
12
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.3")
13
+ gem "mutant"
14
+ gem "mutant-minitest"
15
+ gem "mutex_m"
16
+ end
17
+
18
+ gem "rdoc", "~> 8.0"
19
+
20
+ gemspec path: "../"
@@ -1,5 +1,20 @@
1
- # frozen_string_literal: true
1
+ # This file was generated by Appraisal
2
2
 
3
- eval_gemfile "../Gemfile"
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake", "~> 13.0"
6
+ gem "appraisal"
7
+ gem "erb_lint", require: false
8
+ gem "minitest", "~> 5.0"
9
+ gem "standard"
10
+ gem "yard-lint"
11
+
12
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.3")
13
+ gem "mutant"
14
+ gem "mutant-minitest"
15
+ gem "mutex_m"
16
+ end
4
17
 
5
18
  gem "rdoc", git: "https://github.com/ruby/rdoc.git", branch: "master"
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Optional lookup of method signatures parsed from RBS files.
4
+ class RDoc::Generator::Markdown::RbsSignatureIndex
5
+ # Builds a signature index from RBS files included in an RDoc run.
6
+ #
7
+ # @param files [Array<String>] Input files passed to RDoc.
8
+ # @param base_dir [String, Pathname, nil] Directory where RDoc started.
9
+ # @param store [RDoc::Store, nil] Store containing Ruby code objects and RDoc 8 sidecar signatures.
10
+ #
11
+ # @return [RDoc::Generator::Markdown::RbsSignatureIndex] Signature index.
12
+ def self.build(files, base_dir = nil, store = nil)
13
+ rbs_files = files.select { |file| File.extname(file) == ".rbs" }
14
+ new(signatures_from_store(store).merge(signatures_from(rbs_files, base_dir)))
15
+ end
16
+
17
+ # Builds signatures by reusing RBS's own RDoc parser.
18
+ #
19
+ # @param files [Array<String>] RBS files to parse.
20
+ # @param base_dir [String, Pathname, nil] Directory where RDoc started.
21
+ #
22
+ # @return [Hash{Array => Array<String>}] Signature lookup keyed by class and method.
23
+ def self.signatures_from(files, base_dir)
24
+ files.each_with_object({}) do |file, signatures|
25
+ parsed_classes(file, base_dir).each do |klass|
26
+ klass.method_list.each do |method|
27
+ add_method_signature_lines(signatures, klass: klass, method: method, lines: rbs_signature_lines_from_method(method))
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # Builds signatures already merged into an RDoc store.
34
+ #
35
+ # @param store [RDoc::Store, nil] Store containing Ruby code objects and RDoc 8 sidecar signatures.
36
+ #
37
+ # @return [Hash{Array => Array<String>}] Signature lookup keyed by class and method.
38
+ def self.signatures_from_store(store)
39
+ return {} unless store
40
+
41
+ store.all_classes_and_modules.each_with_object({}) do |klass, signatures|
42
+ klass.method_list.each do |method|
43
+ add_method_signature_lines(signatures, klass: klass, method: method, lines: store_signature_lines_from_method(method, store))
44
+ end
45
+ end
46
+ end
47
+
48
+ # Parses one RBS file into RDoc class/module objects.
49
+ #
50
+ # @param file [String] RBS file path.
51
+ # @param base_dir [String, Pathname, nil] Directory where RDoc started.
52
+ #
53
+ # @return [Array<RDoc::Context>] Classes and modules parsed from RBS.
54
+ def self.parsed_classes(file, base_dir)
55
+ file_path = rbs_file_path(file, base_dir)
56
+ store = RDoc::Store.new(RDoc::Options.new)
57
+ top_level = store.add_file(file_path)
58
+ parser = RDoc::Parser.for(top_level, File.read(file_path), store.options, nil)
59
+ parser.scan
60
+ store.all_classes_and_modules
61
+ end
62
+
63
+ # Resolves an RBS file path against the directory RDoc started from.
64
+ # RDoc changes into the output directory before generators run.
65
+ #
66
+ # @param file [String] RBS file path passed to RDoc.
67
+ # @param base_dir [String, Pathname, nil] Directory where RDoc started.
68
+ #
69
+ # @return [String] Absolute or already absolute RBS file path.
70
+ def self.rbs_file_path(file, base_dir)
71
+ Pathname.new(file).expand_path(base_dir).to_s
72
+ end
73
+
74
+ # Adds resolved method signature lines to the lookup.
75
+ #
76
+ # @param signatures [Hash{Array => Array<String>}] Signature lookup being populated.
77
+ # @param klass [RDoc::Context] Method owner.
78
+ # @param method [RDoc::AnyMethod] Method object.
79
+ # @param lines [Array<String>] Signature text lines.
80
+ #
81
+ # @return [void]
82
+ def self.add_method_signature_lines(signatures, klass:, method:, lines:)
83
+ return if lines.empty?
84
+
85
+ signatures[[klass.full_name, method.singleton, method.name]] = lines
86
+
87
+ return unless method.name == "initialize" && !method.singleton
88
+
89
+ signatures[[klass.full_name, true, "new"]] = lines
90
+ end
91
+
92
+ # Extracts explicit RBS method signature lines from RDoc parser output.
93
+ # RDoc 7 exposes parsed RBS signatures through `param_seq`; RDoc 8 stores
94
+ # them as `type_signature_lines`.
95
+ #
96
+ # @param method [RDoc::AnyMethod] Method parsed by RDoc's RBS parser.
97
+ #
98
+ # @return [Array<String>] RBS signature lines.
99
+ def self.rbs_signature_lines_from_method(method)
100
+ lines = method_type_signature_lines(method)
101
+ lines = method.param_seq if lines.empty?
102
+ nonblank_lines(lines)
103
+ end
104
+
105
+ # Extracts RBS method signature lines already merged into a Ruby store.
106
+ # Unlike explicit RBS parser output, ordinary Ruby `param_seq` is not a type
107
+ # signature and must not populate the index.
108
+ #
109
+ # @param method [RDoc::AnyMethod] Method object from the Ruby store.
110
+ # @param store [RDoc::Store] Store with sidecar RBS signatures.
111
+ #
112
+ # @return [Array<String>] RBS signature lines.
113
+ def self.store_signature_lines_from_method(method, store)
114
+ lines = method_type_signature_lines(method)
115
+ lines = store_type_signature_lines(method, store) if lines.empty?
116
+ lines
117
+ end
118
+
119
+ # Extracts RDoc 8 inline type signatures from a method.
120
+ #
121
+ # @param method [RDoc::AnyMethod] Method object.
122
+ #
123
+ # @return [Array<String>] Signature lines.
124
+ def self.method_type_signature_lines(method)
125
+ return [] unless method.respond_to?(:type_signature_lines)
126
+
127
+ nonblank_lines(method.type_signature_lines)
128
+ end
129
+
130
+ # Extracts RDoc 8 sidecar signatures from a store.
131
+ #
132
+ # @param method [RDoc::AnyMethod] Method object.
133
+ # @param store [RDoc::Store, nil] Optional RDoc store with sidecar RBS signatures.
134
+ #
135
+ # @return [Array<String>] Signature lines.
136
+ def self.store_type_signature_lines(method, store)
137
+ return [] unless store.respond_to?(:rbs_signature_for)
138
+
139
+ nonblank_lines(store.rbs_signature_for(method))
140
+ end
141
+
142
+ # Normalizes a signature-line value to non-blank strings.
143
+ #
144
+ # @param lines [Array<String>, String, nil] Signature text lines.
145
+ #
146
+ # @return [Array<String>] Non-blank signature lines.
147
+ def self.nonblank_lines(lines)
148
+ Array(lines).select { |line| line&.match?(/\S/) }
149
+ end
150
+
151
+ # @param signatures [Hash{Array => Array<String>}] Signature lookup.
152
+ def initialize(signatures)
153
+ @signatures = signatures
154
+ end
155
+
156
+ # Looks up the RBS signature lines for an RDoc method.
157
+ #
158
+ # @param method [RDoc::AnyMethod] Method object to render.
159
+ #
160
+ # @return [Array<String>] RBS method type lines when available.
161
+ def signature_lines_for(method)
162
+ @signatures.fetch([method.parent.full_name, method.singleton, method.name], [])
163
+ end
164
+
165
+ # Checks whether any RBS signatures were parsed.
166
+ #
167
+ # @return [Boolean] True when type signatures are available.
168
+ def any?
169
+ @signatures.any?
170
+ end
171
+
172
+ private_class_method \
173
+ :signatures_from,
174
+ :signatures_from_store,
175
+ :parsed_classes,
176
+ :rbs_file_path,
177
+ :add_method_signature_lines,
178
+ :rbs_signature_lines_from_method,
179
+ :store_signature_lines_from_method,
180
+ :method_type_signature_lines,
181
+ :store_type_signature_lines,
182
+ :nonblank_lines
183
+ end
@@ -12,6 +12,8 @@ require "optparse"
12
12
  class RDoc::Generator::Markdown
13
13
  RDoc::RDoc.add_generator self
14
14
 
15
+ require_relative "markdown/rbs_signature_index"
16
+
15
17
  # Directory containing ERB templates.
16
18
  TEMPLATE_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))
17
19
 
@@ -384,13 +386,28 @@ class RDoc::Generator::Markdown
384
386
  #
385
387
  # @return [String] Normalized method signature.
386
388
  def method_signature(method)
387
- signature = method.param_seq
388
- return "()" unless signature.match?(/\S/)
389
+ signatures = @rbs_method_signatures.signature_lines_for(method)
390
+ signatures = [method.param_seq] if signatures.empty?
391
+
392
+ signatures = signatures.filter_map do |signature|
393
+ next unless signature&.match?(/\S/)
394
+
395
+ signature = signature.gsub("->", " -> ")
396
+ signature = signature.gsub(/\s+/, " ").strip
397
+ signature = " #{signature}" if signature.start_with?("->")
398
+ merge_method_signature_arguments(signature, method.params)
399
+ end
389
400
 
390
- signature = signature.gsub("->", " -> ")
391
- signature = signature.gsub(/\s+/, " ").strip
392
- signature = " #{signature}" if signature.start_with?("->")
393
- merge_method_signature_arguments(signature, method.params)
401
+ return "()" if signatures.empty?
402
+
403
+ signatures.join(" | ")
404
+ end
405
+
406
+ # Checks whether this documentation set has parsed RBS signatures.
407
+ #
408
+ # @return [Boolean] True when type signatures are available.
409
+ def types_available?
410
+ @rbs_method_signatures.any?
394
411
  end
395
412
 
396
413
  # Merges RDoc parameter names into a type-only signature.
@@ -813,6 +830,7 @@ class RDoc::Generator::Markdown
813
830
  @class_docs_by_object_id = @class_docs.to_h { |doc| [doc.fetch(:klass).object_id, doc] }
814
831
  @classes = @class_docs.map { |doc| doc.fetch(:klass) }
815
832
  @pages = @store.all_files.select(&:text?).select(&:display?).sort_by(&:base_name)
833
+ @rbs_method_signatures = RbsSignatureIndex.build(Array(@options.files), @base_dir, @store)
816
834
 
817
835
  @known_output_paths = Set.new
818
836
  @class_docs.each do |doc|
@@ -5,6 +5,6 @@ module Rdoc
5
5
  # Version namespace for rdoc-markdown.
6
6
  module Markdown
7
7
  # Current gem version.
8
- VERSION = "0.8.0"
8
+ VERSION = "0.10.0"
9
9
  end
10
10
  end
@@ -1,5 +1,9 @@
1
1
  # <%= klass.type.capitalize %> <%= display_name(klass) %>
2
2
  <%= anchor(klass.aref.strip) %>
3
+ <%- if types_available? -%>
4
+
5
+ _Type signatures available._
6
+ <%- end -%>
3
7
  <%- class_description = describe(klass) -%>
4
8
  <%- unless class_description.empty? -%>
5
9
 
@@ -41,6 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency "minitest", "~> 5.0"
42
42
  spec.add_development_dependency "minitest-strict", "~> 1.0"
43
43
  spec.add_development_dependency "rake", "~> 13.0"
44
+ spec.add_development_dependency "rbs"
44
45
  spec.add_development_dependency "rdiscount", "~> 2.0"
45
46
  spec.add_development_dependency "simplecov", "~> 0.22"
46
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdoc-markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stanislav (Stas) Katkov
@@ -135,6 +135,20 @@ dependencies:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
137
  version: '13.0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: rbs
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
138
152
  - !ruby/object:Gem::Dependency
139
153
  name: rdiscount
140
154
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +192,7 @@ files:
178
192
  - ".standard.yml"
179
193
  - ".yard-lint.yml"
180
194
  - AGENTS.md
195
+ - Appraisals
181
196
  - CHANGELOG.md
182
197
  - CODE_OF_CONDUCT.md
183
198
  - Gemfile
@@ -202,10 +217,13 @@ files:
202
217
  - example/jekyll-seo-tag/Liquid.md
203
218
  - example/jekyll-seo-tag/Liquid/Tag.md
204
219
  - example/jekyll-seo-tag/index.csv
220
+ - gemfiles/rdoc_7.gemfile
221
+ - gemfiles/rdoc_8.gemfile
205
222
  - gemfiles/rdoc_head.gemfile
206
223
  - lib/markdown.rb
207
224
  - lib/rdoc/discover.rb
208
225
  - lib/rdoc/generator/markdown.rb
226
+ - lib/rdoc/generator/markdown/rbs_signature_index.rb
209
227
  - lib/rdoc/markdown/version.rb
210
228
  - lib/templates/classfile.md.erb
211
229
  - mutant.yml