rdoc-markdown 0.13.2 → 0.14.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 +4 -4
- data/.erb_lint.yml +0 -4
- data/AGENTS.md +4 -3
- data/CHANGELOG.md +7 -0
- data/Gemfile +2 -9
- data/Gemfile.lock +6 -18
- data/README.md +5 -12
- data/Rakefile +7 -19
- data/lib/rdoc/generator/markdown/crossref.rb +33 -0
- data/lib/rdoc/generator/markdown.rb +82 -85
- data/lib/rdoc/markdown/version.rb +1 -1
- data/lib/templates/classfile.md.erb +0 -1
- data/mutant.yml +0 -1
- data/rdoc-markdown.gemspec +2 -3
- metadata +5 -24
- data/Appraisals +0 -13
- data/gemfiles/rdoc_7.gemfile +0 -20
- data/gemfiles/rdoc_8.gemfile +0 -20
- data/gemfiles/rdoc_head.gemfile +0 -20
- data/lib/rdoc/generator/markdown/rbs_signature_index.rb +0 -187
- data/lib/rdoc/generator/markdown/rdoc_markdown_pre.rb +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 868f92bb775186af57b719c6aa821b0e69ba3cd27988ac3e3eb549c2e10600cb
|
|
4
|
+
data.tar.gz: 30fcdb498301cbdddf420b12792e53d2f9f427a30f9e16d5f67527dbf0137e6e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92914fc1b0e03ecb0fb09dd2fb1bca56c6222a27beb7c9eb63882a8644567ffa7de863ece0476d688fb91cefcc9b89fcc2949722299724ea90ea3bc768dc2d2d
|
|
7
|
+
data.tar.gz: 61672973b235fa35b149ff24ab9dc1fd22ccf2eb0d907bad436bde63f73c76ec1f116b143d009adb39d482c59529f2a69929f5786f2e6d48bb49b38ea7b8fc06
|
data/.erb_lint.yml
CHANGED
data/AGENTS.md
CHANGED
|
@@ -39,10 +39,11 @@ the user.
|
|
|
39
39
|
|
|
40
40
|
You are done when all of these are green and not reporting any issues:
|
|
41
41
|
|
|
42
|
-
```
|
|
42
|
+
```bash
|
|
43
43
|
bundle exec rake test
|
|
44
|
-
|
|
44
|
+
# don't run again if fail-fast has already passed
|
|
45
|
+
bundle exec mutant run --fail-fast --since origin/main
|
|
45
46
|
bundle exec rake markdown:validate
|
|
46
47
|
bundle exec yard-lint
|
|
47
|
-
bundle exec erb:lint
|
|
48
|
+
bundle exec rake erb:lint
|
|
48
49
|
```
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
## Unreleased
|
|
4
5
|
|
|
6
|
+
## 0.14.0
|
|
7
|
+
|
|
8
|
+
- BREAKING: Removing RDoc 7 compatibility code. Support RDoc 8 only.
|
|
9
|
+
- Remove extra spacing between method group headings and content.
|
|
10
|
+
- Reworked documentation cross-linking. Tests will fail, if cross-linked document can't be found.
|
|
11
|
+
|
|
5
12
|
## 0.13.2
|
|
6
13
|
|
|
7
14
|
- Don't add emtpy line break instead of missing metadata
|
data/Gemfile
CHANGED
|
@@ -5,16 +5,9 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in rdoc-markdown.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem "rake", "~> 13.0"
|
|
9
|
-
|
|
10
|
-
gem "appraisal"
|
|
11
8
|
gem "erb_lint", require: false
|
|
12
|
-
gem "minitest", "~> 5.0"
|
|
13
9
|
gem "standard"
|
|
14
10
|
gem "yard-lint"
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
gem "mutant-minitest"
|
|
19
|
-
gem "mutex_m"
|
|
20
|
-
end
|
|
12
|
+
gem "mutant"
|
|
13
|
+
gem "mutant-minitest"
|
data/Gemfile.lock
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rdoc-markdown (0.
|
|
4
|
+
rdoc-markdown (0.14.0)
|
|
5
5
|
csv
|
|
6
6
|
erb
|
|
7
|
-
rdoc
|
|
7
|
+
rdoc (>= 8.0)
|
|
8
8
|
reverse_markdown
|
|
9
9
|
|
|
10
10
|
GEM
|
|
@@ -29,10 +29,6 @@ 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)
|
|
36
32
|
ast (2.4.3)
|
|
37
33
|
base64 (0.3.0)
|
|
38
34
|
better_html (2.2.0)
|
|
@@ -49,11 +45,10 @@ GEM
|
|
|
49
45
|
connection_pool (3.0.2)
|
|
50
46
|
crass (1.0.6)
|
|
51
47
|
csv (3.3.5)
|
|
52
|
-
date (3.5.1)
|
|
53
48
|
diff-lcs (2.0.0)
|
|
54
49
|
docile (1.4.1)
|
|
55
50
|
drb (2.2.3)
|
|
56
|
-
erb (6.0.
|
|
51
|
+
erb (6.0.6)
|
|
57
52
|
erb_lint (0.9.0)
|
|
58
53
|
activesupport
|
|
59
54
|
better_html (>= 2.0.1)
|
|
@@ -103,9 +98,6 @@ GEM
|
|
|
103
98
|
prettyprint
|
|
104
99
|
prettyprint (0.2.0)
|
|
105
100
|
prism (1.9.0)
|
|
106
|
-
psych (5.3.1)
|
|
107
|
-
date
|
|
108
|
-
stringio
|
|
109
101
|
racc (1.8.1)
|
|
110
102
|
rails-dom-testing (2.3.0)
|
|
111
103
|
activesupport (>= 5.0.0)
|
|
@@ -121,9 +113,10 @@ GEM
|
|
|
121
113
|
prism (>= 1.6.0)
|
|
122
114
|
tsort
|
|
123
115
|
rdiscount (2.2.7.4)
|
|
124
|
-
rdoc (
|
|
116
|
+
rdoc (8.0.0)
|
|
125
117
|
erb
|
|
126
|
-
|
|
118
|
+
prism (>= 1.6.0)
|
|
119
|
+
rbs (>= 4.0.0)
|
|
127
120
|
tsort
|
|
128
121
|
regexp_parser (2.12.0)
|
|
129
122
|
reline (0.6.3)
|
|
@@ -170,8 +163,6 @@ GEM
|
|
|
170
163
|
standard-performance (1.9.0)
|
|
171
164
|
lint_roller (~> 1.1)
|
|
172
165
|
rubocop-performance (~> 1.26.0)
|
|
173
|
-
stringio (3.2.0)
|
|
174
|
-
thor (1.5.0)
|
|
175
166
|
tsort (0.2.0)
|
|
176
167
|
tzinfo (2.0.6)
|
|
177
168
|
concurrent-ruby (~> 1.0)
|
|
@@ -193,7 +184,6 @@ PLATFORMS
|
|
|
193
184
|
x86_64-linux-gnu
|
|
194
185
|
|
|
195
186
|
DEPENDENCIES
|
|
196
|
-
appraisal
|
|
197
187
|
bundler (>= 2.0)
|
|
198
188
|
commonmarker
|
|
199
189
|
erb_lint
|
|
@@ -201,9 +191,7 @@ DEPENDENCIES
|
|
|
201
191
|
minitest-strict (~> 1.0)
|
|
202
192
|
mutant
|
|
203
193
|
mutant-minitest
|
|
204
|
-
mutex_m
|
|
205
194
|
rake (~> 13.0)
|
|
206
|
-
rbs
|
|
207
195
|
rdiscount (~> 2.0)
|
|
208
196
|
rdoc-markdown!
|
|
209
197
|
simplecov (~> 0.22)
|
data/README.md
CHANGED
|
@@ -13,6 +13,8 @@ It's a pitty that rdoc can't output a proper markdown file. Somebody has to try
|
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
+
rdoc-markdown requires Ruby 3.3 or newer and RDoc 8 or newer.
|
|
17
|
+
|
|
16
18
|
Install gem and add to application's Gemfile by executing:
|
|
17
19
|
|
|
18
20
|
$ bundle add rdoc-markdown
|
|
@@ -40,7 +42,7 @@ rdoc-markdown uses `reverse_markdown` to convert RDoc's HTML fragments to Markdo
|
|
|
40
42
|
rdoc --format=markdown --markdown-unknown-tags=raise
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
Accepted values are `pass_through`, `drop`, `bypass`, and `raise`. The default is `pass_through
|
|
45
|
+
Accepted values are `pass_through`, `drop`, `bypass`, and `raise`. The default is `pass_through`.
|
|
44
46
|
|
|
45
47
|
The same setting can be stored in RDoc's `.rdoc_options` file:
|
|
46
48
|
|
|
@@ -57,7 +59,6 @@ There are decent tools that offer search through structured plain-text files. Bu
|
|
|
57
59
|
In my personal use-case, I use SQLite. All other databases seem to have a good support for CSV imports.
|
|
58
60
|
|
|
59
61
|
## Development
|
|
60
|
-
Biggest issue is testing this locally, but that's not as hard to do these days.
|
|
61
62
|
|
|
62
63
|
```
|
|
63
64
|
gem build rdoc-markdown.gemspec
|
|
@@ -78,8 +79,6 @@ Following command should run entire testsuit:
|
|
|
78
79
|
```
|
|
79
80
|
rake test
|
|
80
81
|
```
|
|
81
|
-
The test suite loads `minitest-strict`, so boolean and nil assertions only pass on exact `true`, `false`, and `nil` values.
|
|
82
|
-
Testing is not excessive, just verifies that basic functionality is operational.
|
|
83
82
|
|
|
84
83
|
To validate generated markdown against GitHub Flavored Markdown and check local links/anchors:
|
|
85
84
|
|
|
@@ -96,12 +95,6 @@ This task validates:
|
|
|
96
95
|
- vendored rails docs (Active Support, Active Record, Action Pack, Railties slices).
|
|
97
96
|
|
|
98
97
|
Validation artifacts are written to `tmp/markdown-validate/` inside this repository.
|
|
99
|
-
To fail on every unresolved vendor local link/anchor, run with:
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
MARKDOWN_VALIDATE_STRICT_VENDOR=1 rake markdown:validate
|
|
103
|
-
```
|
|
104
|
-
|
|
105
98
|
This task is also executed in CI.
|
|
106
99
|
|
|
107
100
|
To lint markdown ERB templates:
|
|
@@ -110,7 +103,7 @@ To lint markdown ERB templates:
|
|
|
110
103
|
bundle exec rake erb:lint
|
|
111
104
|
```
|
|
112
105
|
|
|
113
|
-
### Integration
|
|
106
|
+
### Integration: minitest
|
|
114
107
|
To run the integration harness against minitest (aligned with docs.seattlerb.org/minitest):
|
|
115
108
|
|
|
116
109
|
```
|
|
@@ -120,7 +113,7 @@ bundle exec rake test
|
|
|
120
113
|
|
|
121
114
|
The harness validates markdown formatting quality, generated page files, class/module paths, and search index output.
|
|
122
115
|
|
|
123
|
-
### Integration
|
|
116
|
+
### Integration: rails
|
|
124
117
|
To run the rails harness (focused on Active Support + Active Record API docs with sdoc-like structure):
|
|
125
118
|
|
|
126
119
|
```
|
data/Rakefile
CHANGED
|
@@ -31,7 +31,6 @@ end
|
|
|
31
31
|
namespace :markdown do
|
|
32
32
|
desc "Validate generated markdown as GitHub Flavored Markdown"
|
|
33
33
|
task :validate do
|
|
34
|
-
strict_vendor_links = ENV["MARKDOWN_VALIDATE_STRICT_VENDOR"] == "1"
|
|
35
34
|
validation_root = File.expand_path("tmp/markdown-validate", __dir__)
|
|
36
35
|
FileUtils.rm_rf(validation_root)
|
|
37
36
|
FileUtils.mkdir_p(validation_root)
|
|
@@ -57,18 +56,14 @@ namespace :markdown do
|
|
|
57
56
|
output: minitest_output,
|
|
58
57
|
files: minitest_docs_files(minitest_root)
|
|
59
58
|
)
|
|
60
|
-
|
|
61
|
-
minitest_count = minitest_validator.validate!
|
|
59
|
+
minitest_count = MarkdownValidator.new(minitest_output).validate!
|
|
62
60
|
puts "Validated #{minitest_count} markdown files in #{minitest_output}"
|
|
63
|
-
puts "Skipped #{minitest_validator.unresolved_links} unresolved local links in vendored minitest docs"
|
|
64
61
|
|
|
65
62
|
Rake::Task["vendor:setup:jekyll_seo_tag"].invoke
|
|
66
63
|
jekyll_seo_tag_output = File.join(validation_root, JEKYLL_SEO_TAG_NAME)
|
|
67
64
|
generate_jekyll_seo_tag_docs(output: jekyll_seo_tag_output)
|
|
68
|
-
|
|
69
|
-
jekyll_seo_tag_count = jekyll_seo_tag_validator.validate!
|
|
65
|
+
jekyll_seo_tag_count = MarkdownValidator.new(jekyll_seo_tag_output).validate!
|
|
70
66
|
puts "Validated #{jekyll_seo_tag_count} markdown files in #{jekyll_seo_tag_output}"
|
|
71
|
-
puts "Skipped #{jekyll_seo_tag_validator.unresolved_links} unresolved local links in vendored jekyll-seo-tag docs"
|
|
72
67
|
|
|
73
68
|
Rake::Task["vendor:setup:rails"].invoke
|
|
74
69
|
rails_root = File.expand_path("vendor/rails", __dir__)
|
|
@@ -79,10 +74,8 @@ namespace :markdown do
|
|
|
79
74
|
output: rails_output,
|
|
80
75
|
files: rails_validation_files(rails_root)
|
|
81
76
|
)
|
|
82
|
-
|
|
83
|
-
rails_count = rails_validator.validate!
|
|
77
|
+
rails_count = MarkdownValidator.new(rails_output).validate!
|
|
84
78
|
puts "Validated #{rails_count} markdown files in #{rails_output}"
|
|
85
|
-
puts "Skipped #{rails_validator.unresolved_links} unresolved local links in vendored rails docs"
|
|
86
79
|
|
|
87
80
|
puts "Markdown validation artifacts written to #{validation_root}"
|
|
88
81
|
end
|
|
@@ -181,15 +174,10 @@ def rails_validation_files(root)
|
|
|
181
174
|
files.concat(Dir[File.join(root, "actionpack/lib/**/*.rb")])
|
|
182
175
|
files.concat(Dir[File.join(root, "railties/lib/**/*.rb")])
|
|
183
176
|
|
|
184
|
-
[
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
"railties/RDOC_MAIN.md"
|
|
189
|
-
].each do |relative_path|
|
|
190
|
-
file = File.join(root, relative_path)
|
|
191
|
-
files << file if File.file?(file)
|
|
192
|
-
end
|
|
177
|
+
files.concat(Dir[File.join(root, "{active*,action*,railties}/README.{rdoc,md,markdown}")])
|
|
178
|
+
|
|
179
|
+
main_page = File.join(root, "railties/RDOC_MAIN.md")
|
|
180
|
+
files << main_page if File.file?(main_page)
|
|
193
181
|
|
|
194
182
|
files.uniq
|
|
195
183
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Prevents RDoc from linking to code objects omitted from Markdown output.
|
|
4
|
+
module RDoc::Generator::Markdown::CrossrefExtension
|
|
5
|
+
# Cross-reference resolver scoped to this formatter instance.
|
|
6
|
+
attr_writer :markdown_cross_reference
|
|
7
|
+
|
|
8
|
+
# Object IDs emitted by the active Markdown generator.
|
|
9
|
+
attr_writer :markdown_output_object_ids
|
|
10
|
+
|
|
11
|
+
# Renders a cross-reference only when its owning object is emitted.
|
|
12
|
+
#
|
|
13
|
+
# @param name [String, nil] Cross-reference target.
|
|
14
|
+
# @param text [String] Visible link text.
|
|
15
|
+
# @param code [Boolean] Whether to format code objects as code.
|
|
16
|
+
# @param rdoc_ref [Boolean] Whether the target uses the rdoc-ref scheme.
|
|
17
|
+
#
|
|
18
|
+
# @return [String] HTML link or unlinked text.
|
|
19
|
+
def link(name, text, code = true, rdoc_ref: false)
|
|
20
|
+
return super unless @markdown_cross_reference
|
|
21
|
+
|
|
22
|
+
ref = @markdown_cross_reference.resolve(name) if name
|
|
23
|
+
return super unless RDoc::CodeObject === ref
|
|
24
|
+
|
|
25
|
+
context = ref
|
|
26
|
+
context = context.parent until RDoc::ClassModule === context || RDoc::TopLevel === context
|
|
27
|
+
return super if @markdown_output_object_ids.include?(context.object_id)
|
|
28
|
+
|
|
29
|
+
return text if RDoc::TopLevel === ref || !code
|
|
30
|
+
|
|
31
|
+
"<code>#{text}</code>"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# shareable_constant_value: literal
|
|
3
3
|
|
|
4
|
-
gem "rdoc"
|
|
5
|
-
|
|
6
4
|
require "erb"
|
|
7
5
|
require "reverse_markdown"
|
|
8
6
|
require "csv"
|
|
9
7
|
require "optparse"
|
|
10
|
-
require_relative "markdown/rdoc_markdown_pre"
|
|
11
8
|
|
|
12
9
|
# Generates Markdown output and a CSV search index from an RDoc store.
|
|
13
10
|
class RDoc::Generator::Markdown
|
|
14
11
|
RDoc::RDoc.add_generator self
|
|
15
12
|
|
|
16
|
-
require_relative "markdown/
|
|
13
|
+
require_relative "markdown/crossref"
|
|
17
14
|
|
|
18
15
|
# Supported reverse_markdown unknown-tag modes.
|
|
19
16
|
MARKDOWN_UNKNOWN_TAGS = %i[pass_through drop bypass raise]
|
|
@@ -109,11 +106,6 @@ class RDoc::Generator::Markdown
|
|
|
109
106
|
# @return [RDoc::Store]
|
|
110
107
|
attr_reader :store
|
|
111
108
|
|
|
112
|
-
# Working directory captured when the generator is created.
|
|
113
|
-
#
|
|
114
|
-
# @return [Pathname]
|
|
115
|
-
attr_reader :base_dir
|
|
116
|
-
|
|
117
109
|
# Classes and modules selected for output.
|
|
118
110
|
#
|
|
119
111
|
# @return [Array<RDoc::Context>, nil]
|
|
@@ -124,15 +116,6 @@ class RDoc::Generator::Markdown
|
|
|
124
116
|
# @return [Array<RDoc::TopLevel>, nil]
|
|
125
117
|
attr_reader :pages
|
|
126
118
|
|
|
127
|
-
# Required by RDoc's generator interface; markdown output has no class subdirectory.
|
|
128
|
-
#
|
|
129
|
-
# @return [nil]
|
|
130
|
-
def class_dir
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# this alias is required for rdoc to work
|
|
134
|
-
alias_method :file_dir, :class_dir
|
|
135
|
-
|
|
136
119
|
# Creates a generator for an RDoc store and options.
|
|
137
120
|
#
|
|
138
121
|
# @param store [RDoc::Store] Source documentation store.
|
|
@@ -142,7 +125,6 @@ class RDoc::Generator::Markdown
|
|
|
142
125
|
@options = rdoc_options
|
|
143
126
|
@markdown_unknown_tags = self.class.validate_markdown_unknown_tags(rdoc_options.markdown_unknown_tags)
|
|
144
127
|
|
|
145
|
-
@base_dir = Pathname.pwd
|
|
146
128
|
@expanded_root = Pathname(@options.root.to_s).expand_path
|
|
147
129
|
end
|
|
148
130
|
|
|
@@ -254,16 +236,9 @@ class RDoc::Generator::Markdown
|
|
|
254
236
|
@classes.each do |klass|
|
|
255
237
|
content = template.result(binding)
|
|
256
238
|
output_path = output_path_for(klass)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
out_file.dirname.mkpath
|
|
261
|
-
File.write(out_file, finalize_markdown(
|
|
262
|
-
content,
|
|
263
|
-
canonical_output_path: output_path,
|
|
264
|
-
current_output_path: destination_path
|
|
265
|
-
))
|
|
266
|
-
end
|
|
239
|
+
out_file = Pathname.new("#{output_dir}/#{output_path}")
|
|
240
|
+
out_file.dirname.mkpath
|
|
241
|
+
File.write(out_file, finalize_markdown(content, current_output_path: output_path))
|
|
267
242
|
end
|
|
268
243
|
end
|
|
269
244
|
|
|
@@ -275,10 +250,9 @@ class RDoc::Generator::Markdown
|
|
|
275
250
|
out_file = Pathname.new("#{output_dir}/#{page_output_path(page)}")
|
|
276
251
|
out_file.dirname.mkpath
|
|
277
252
|
|
|
278
|
-
content = markdownify(page
|
|
253
|
+
content = markdownify(render_description(page))
|
|
279
254
|
File.write(out_file, finalize_markdown(
|
|
280
255
|
content,
|
|
281
|
-
canonical_output_path: page_output_path(page),
|
|
282
256
|
current_output_path: page_output_path(page)
|
|
283
257
|
))
|
|
284
258
|
end
|
|
@@ -346,15 +320,6 @@ class RDoc::Generator::Markdown
|
|
|
346
320
|
class_doc_for(code_object).fetch(:output_path)
|
|
347
321
|
end
|
|
348
322
|
|
|
349
|
-
# Returns compatibility paths that should mirror the canonical output.
|
|
350
|
-
#
|
|
351
|
-
# @param code_object [RDoc::Context] Class or module object.
|
|
352
|
-
#
|
|
353
|
-
# @return [Array<String>] Legacy Markdown paths.
|
|
354
|
-
def legacy_paths_for(code_object)
|
|
355
|
-
class_doc_for(code_object).fetch(:legacy_paths)
|
|
356
|
-
end
|
|
357
|
-
|
|
358
323
|
# Renders a class or module reference, linking it when its documentation is emitted.
|
|
359
324
|
#
|
|
360
325
|
# @param target [RDoc::ClassModule, String] Resolved RDoc object or unresolved name.
|
|
@@ -391,28 +356,61 @@ class RDoc::Generator::Markdown
|
|
|
391
356
|
# - bypass - Ignore the unknown tag but try to convert its content
|
|
392
357
|
# - raise - Raise an error to let you know
|
|
393
358
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
# Flatten headings whose visible text is wrapped in a self-link.
|
|
397
|
-
md.gsub!(/^(#+)\s\[([^\]]+)\]\((?:#[^)]+)\)$/) { "#{Regexp.last_match(1)} #{Regexp.last_match(2)}" }
|
|
359
|
+
fragment = Nokogiri::HTML.fragment(input)
|
|
398
360
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
"]
|
|
361
|
+
fragment.css("pre").each do |pre|
|
|
362
|
+
language = pre["class"].to_s[/\A(?!highlight\z)[A-Za-z][A-Za-z0-9_+-]*\z/]
|
|
363
|
+
pre["class"] = "brush: #{language};" if language
|
|
364
|
+
pre.inner_html = pre.text
|
|
402
365
|
end
|
|
403
366
|
|
|
404
|
-
|
|
405
|
-
|
|
367
|
+
fragment.css("h1, h2, h3, h4, h5, h6").each do |heading|
|
|
368
|
+
link = heading.xpath("./a[starts-with(@href, '#') and string-length(@href) > 1]").find do |anchor|
|
|
369
|
+
anchor.text.match?(/\S/) &&
|
|
370
|
+
anchor.xpath("preceding-sibling::node()").none? { |sibling| sibling.text.match?(/\S/) }
|
|
371
|
+
end
|
|
372
|
+
next unless link
|
|
373
|
+
|
|
374
|
+
id = link["href"].delete_prefix("#")
|
|
375
|
+
link.replace(link.children)
|
|
376
|
+
next if id == RDoc::Text.to_anchor(heading.text)
|
|
377
|
+
|
|
378
|
+
heading.add_child(fragment.document.create_element("span", "class" => "legacy-anchor", "id" => id))
|
|
379
|
+
end
|
|
406
380
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
"]
|
|
381
|
+
anchor_aliases = fragment.css("span.legacy-anchor[id]").map.with_index do |span, index|
|
|
382
|
+
token = "RDocMarkdownAnchor#{index}End"
|
|
383
|
+
id = span["id"]
|
|
384
|
+
span.replace(token)
|
|
385
|
+
[token, id]
|
|
410
386
|
end
|
|
411
|
-
|
|
412
|
-
|
|
387
|
+
|
|
388
|
+
fragment.css("a").each do |link|
|
|
389
|
+
receiver = link.text
|
|
390
|
+
href = link["href"].to_s
|
|
391
|
+
|
|
392
|
+
if receiver.match?(/\A(?:[A-Z][A-Za-z0-9_]*(?:::[A-Z][A-Za-z0-9_]*)*|[a-z_][A-Za-z0-9_]*)\z/) &&
|
|
393
|
+
href.match?(/\A(?::.+|".+")\z/)
|
|
394
|
+
link.replace(fragment.document.create_element("code") { |code| code.content = "#{receiver}[#{href}]" })
|
|
395
|
+
elsif href.start_with?("www.")
|
|
396
|
+
link["href"] = "https://#{href}"
|
|
397
|
+
elsif !href.match?(/\A(?:https?:\/\/|mailto:|#)/i)
|
|
398
|
+
href = href.sub(/\.html(?=[?#]|\z)/i, ".md")
|
|
399
|
+
href = href.sub(%r{\A/(?=.+\.md(?:[?#]|\z))}, "")
|
|
400
|
+
href = href.sub(%r{\A((?:\.\./)*)(?:files|classes|modules)/(?=.+\.md(?:[?#]|\z))}, '\1')
|
|
401
|
+
link["href"] = href
|
|
402
|
+
end
|
|
413
403
|
end
|
|
414
|
-
|
|
415
|
-
|
|
404
|
+
|
|
405
|
+
md = ReverseMarkdown.convert(
|
|
406
|
+
fragment,
|
|
407
|
+
github_flavored: true,
|
|
408
|
+
unknown_tags: @markdown_unknown_tags
|
|
409
|
+
).dup
|
|
410
|
+
anchor_aliases.each do |token, id|
|
|
411
|
+
anchor = %(<a id="#{id}"></a>)
|
|
412
|
+
md.gsub!("#{token}\n\n#", "#{anchor}\n#")
|
|
413
|
+
md.gsub!(token, anchor)
|
|
416
414
|
end
|
|
417
415
|
|
|
418
416
|
normalize_definition_list_code_blocks(md).rstrip
|
|
@@ -430,6 +428,25 @@ class RDoc::Generator::Markdown
|
|
|
430
428
|
%(<a id="#{id}"></a>)
|
|
431
429
|
end
|
|
432
430
|
|
|
431
|
+
# Renders an RDoc description with links limited to emitted objects.
|
|
432
|
+
#
|
|
433
|
+
# @param code_object [RDoc::CodeObject, RDoc::Context::Section] Object whose description is rendered.
|
|
434
|
+
#
|
|
435
|
+
# @return [String, nil] HTML description, or nil for an empty section.
|
|
436
|
+
def render_description(code_object)
|
|
437
|
+
return if RDoc::Context::Section === code_object && code_object.comments.empty?
|
|
438
|
+
|
|
439
|
+
formatter = code_object.formatter
|
|
440
|
+
formatter.extend(CrossrefExtension)
|
|
441
|
+
begin
|
|
442
|
+
formatter.markdown_cross_reference = RDoc::CrossReference.new(formatter.context)
|
|
443
|
+
formatter.markdown_output_object_ids = @markdown_output_object_ids
|
|
444
|
+
code_object.description
|
|
445
|
+
ensure
|
|
446
|
+
formatter.markdown_cross_reference = nil
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
433
450
|
# Renders an RDoc object's description as Markdown.
|
|
434
451
|
#
|
|
435
452
|
# @param code_object [RDoc::CodeObject] Object with an RDoc description.
|
|
@@ -438,7 +455,7 @@ class RDoc::Generator::Markdown
|
|
|
438
455
|
#
|
|
439
456
|
# @return [String] Rendered description or fallback text.
|
|
440
457
|
def describe(code_object, fallback: nil, heading_level_offset: 0)
|
|
441
|
-
description = code_object
|
|
458
|
+
description = render_description(code_object)
|
|
442
459
|
return fallback.to_s if description.empty?
|
|
443
460
|
|
|
444
461
|
shift_headings(markdownify(description), heading_level_offset)
|
|
@@ -451,7 +468,7 @@ class RDoc::Generator::Markdown
|
|
|
451
468
|
#
|
|
452
469
|
# @return [String] Rendered section description.
|
|
453
470
|
def section_description(section, heading_level_offset:)
|
|
454
|
-
shift_headings(markdownify(section
|
|
471
|
+
shift_headings(markdownify(render_description(section)), heading_level_offset)
|
|
455
472
|
end
|
|
456
473
|
|
|
457
474
|
# Builds the visible method signature used in headings.
|
|
@@ -460,8 +477,7 @@ class RDoc::Generator::Markdown
|
|
|
460
477
|
#
|
|
461
478
|
# @return [String] Normalized method signature.
|
|
462
479
|
def method_signature(method)
|
|
463
|
-
signatures = @
|
|
464
|
-
signatures = [method.param_seq] if signatures.empty?
|
|
480
|
+
signatures = method.type_signature_lines || @store.rbs_signature_for(method) || [method.param_seq]
|
|
465
481
|
|
|
466
482
|
signatures = signatures.filter_map do |signature|
|
|
467
483
|
next unless signature&.match?(/\S/)
|
|
@@ -617,17 +633,12 @@ class RDoc::Generator::Markdown
|
|
|
617
633
|
# Applies final whitespace and link normalization before writing Markdown.
|
|
618
634
|
#
|
|
619
635
|
# @param content [String] Markdown content.
|
|
620
|
-
# @param canonical_output_path [String] Canonical output path used to resolve links.
|
|
621
636
|
# @param current_output_path [String] Output path for the file being written.
|
|
622
637
|
#
|
|
623
638
|
# @return [String] Final Markdown ending with one newline.
|
|
624
|
-
def finalize_markdown(content,
|
|
639
|
+
def finalize_markdown(content, current_output_path:)
|
|
625
640
|
output = content.lines.map(&:rstrip).join("\n")
|
|
626
|
-
output = normalize_internal_links(
|
|
627
|
-
output,
|
|
628
|
-
canonical_output_path: canonical_output_path,
|
|
629
|
-
current_output_path: current_output_path
|
|
630
|
-
)
|
|
641
|
+
output = normalize_internal_links(output, current_output_path: current_output_path)
|
|
631
642
|
output = output.sub(/\n{3,}/, "\n\n")
|
|
632
643
|
"#{output}\n"
|
|
633
644
|
end
|
|
@@ -704,12 +715,10 @@ class RDoc::Generator::Markdown
|
|
|
704
715
|
# Rewrites local Markdown links relative to the current output file.
|
|
705
716
|
#
|
|
706
717
|
# @param markdown [String] Markdown content.
|
|
707
|
-
# @param canonical_output_path [String] Canonical output path used to resolve links.
|
|
708
718
|
# @param current_output_path [String] Output path for the file being written.
|
|
709
719
|
#
|
|
710
720
|
# @return [String] Markdown with normalized internal links.
|
|
711
|
-
def normalize_internal_links(markdown,
|
|
712
|
-
canonical_dir = Pathname.new(canonical_output_path).dirname
|
|
721
|
+
def normalize_internal_links(markdown, current_output_path:)
|
|
713
722
|
current_dir = Pathname.new(current_output_path).dirname
|
|
714
723
|
|
|
715
724
|
markdown.gsub(%r{\]\(([^)]+)\)}) do
|
|
@@ -717,7 +726,7 @@ class RDoc::Generator::Markdown
|
|
|
717
726
|
path = target.sub(/[?#].*\z/, "")
|
|
718
727
|
suffix = target[path.length..]
|
|
719
728
|
|
|
720
|
-
resolved = resolve_output_path(path,
|
|
729
|
+
resolved = resolve_output_path(path, current_dir)
|
|
721
730
|
rewritten = resolved ? Pathname.new(resolved).relative_path_from(current_dir) : path
|
|
722
731
|
"](#{rewritten}#{suffix})"
|
|
723
732
|
end
|
|
@@ -780,14 +789,12 @@ class RDoc::Generator::Markdown
|
|
|
780
789
|
classes.select(&:display?).each do |klass|
|
|
781
790
|
display_name = normalized_full_name(klass.full_name)
|
|
782
791
|
output_path = turn_to_path(display_name)
|
|
783
|
-
legacy_path = turn_to_path(klass.full_name)
|
|
784
792
|
score = class_content_score(klass)
|
|
785
793
|
|
|
786
794
|
candidate = {
|
|
787
795
|
klass: klass,
|
|
788
796
|
display_name: display_name,
|
|
789
797
|
output_path: output_path,
|
|
790
|
-
legacy_paths: [legacy_path],
|
|
791
798
|
score: score
|
|
792
799
|
}
|
|
793
800
|
|
|
@@ -796,12 +803,7 @@ class RDoc::Generator::Markdown
|
|
|
796
803
|
if existing.nil?
|
|
797
804
|
docs_by_name[display_name] = candidate
|
|
798
805
|
elsif candidate.fetch(:score) > existing.fetch(:score)
|
|
799
|
-
if existing.fetch(:score).positive?
|
|
800
|
-
candidate[:legacy_paths] |= existing.fetch(:legacy_paths)
|
|
801
|
-
end
|
|
802
806
|
docs_by_name[display_name] = candidate
|
|
803
|
-
elsif candidate.fetch(:score).positive?
|
|
804
|
-
existing[:legacy_paths] |= candidate.fetch(:legacy_paths)
|
|
805
807
|
end
|
|
806
808
|
end
|
|
807
809
|
|
|
@@ -892,13 +894,8 @@ class RDoc::Generator::Markdown
|
|
|
892
894
|
@class_docs_by_name = @class_docs.to_h { |doc| [doc.fetch(:display_name), doc] }
|
|
893
895
|
@classes = @class_docs.map { |doc| doc.fetch(:klass) }
|
|
894
896
|
@pages = @store.all_files.select(&:text?).select(&:display?).sort_by(&:base_name)
|
|
895
|
-
@
|
|
896
|
-
|
|
897
|
-
@known_output_paths = Set.new
|
|
898
|
-
@class_docs.each do |doc|
|
|
899
|
-
@known_output_paths << doc.fetch(:output_path)
|
|
900
|
-
doc.fetch(:legacy_paths).each { |path| @known_output_paths << path }
|
|
901
|
-
end
|
|
897
|
+
@markdown_output_object_ids = (@classes + @pages).map(&:object_id)
|
|
898
|
+
@known_output_paths = @class_docs.map { |doc| doc.fetch(:output_path) }
|
|
902
899
|
@pages.each { |page| @known_output_paths << page_output_path(page) }
|
|
903
900
|
|
|
904
901
|
@root_path_segment = Pathname.new(@options.root || ".").basename
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
|
|
59
59
|
### <%= visibility.capitalize %> <%= type.capitalize %> Methods
|
|
60
60
|
<% methods.each do |method| -%>
|
|
61
|
-
|
|
62
61
|
#### `<%= method.name %><%= method_signature(method) %>`<%= anchor(method.aref) %>
|
|
63
62
|
<%= method_description(method, current_class: klass) %>
|
|
64
63
|
<% end -%>
|
data/mutant.yml
CHANGED
data/rdoc-markdown.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.summary = "RDoc plugin to generate markdown documentation "
|
|
13
13
|
spec.description = "RDoc plugin to generate markdown documentation and search index as sqlite database for entire content."
|
|
14
14
|
spec.homepage = "https://poshtui.com"
|
|
15
|
-
spec.required_ruby_version = ">=
|
|
15
|
+
spec.required_ruby_version = ">= 3.3.0"
|
|
16
16
|
|
|
17
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
|
18
18
|
|
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
|
33
33
|
|
|
34
34
|
spec.add_dependency "csv"
|
|
35
35
|
spec.add_dependency "erb"
|
|
36
|
-
spec.add_dependency "rdoc"
|
|
36
|
+
spec.add_dependency "rdoc", ">= 8.0"
|
|
37
37
|
spec.add_dependency "reverse_markdown"
|
|
38
38
|
|
|
39
39
|
spec.add_development_dependency "bundler", ">= 2.0"
|
|
@@ -41,7 +41,6 @@ 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"
|
|
45
44
|
spec.add_development_dependency "rdiscount", "~> 2.0"
|
|
46
45
|
spec.add_development_dependency "simplecov", "~> 0.22"
|
|
47
46
|
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.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stanislav (Stas) Katkov
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0'
|
|
46
|
+
version: '8.0'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0'
|
|
53
|
+
version: '8.0'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: reverse_markdown
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -135,20 +135,6 @@ 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'
|
|
152
138
|
- !ruby/object:Gem::Dependency
|
|
153
139
|
name: rdiscount
|
|
154
140
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -192,7 +178,6 @@ files:
|
|
|
192
178
|
- ".standard.yml"
|
|
193
179
|
- ".yard-lint.yml"
|
|
194
180
|
- AGENTS.md
|
|
195
|
-
- Appraisals
|
|
196
181
|
- CHANGELOG.md
|
|
197
182
|
- CODE_OF_CONDUCT.md
|
|
198
183
|
- Gemfile
|
|
@@ -217,14 +202,10 @@ files:
|
|
|
217
202
|
- example/jekyll-seo-tag/Liquid.md
|
|
218
203
|
- example/jekyll-seo-tag/Liquid/Tag.md
|
|
219
204
|
- example/jekyll-seo-tag/index.csv
|
|
220
|
-
- gemfiles/rdoc_7.gemfile
|
|
221
|
-
- gemfiles/rdoc_8.gemfile
|
|
222
|
-
- gemfiles/rdoc_head.gemfile
|
|
223
205
|
- lib/markdown.rb
|
|
224
206
|
- lib/rdoc/discover.rb
|
|
225
207
|
- lib/rdoc/generator/markdown.rb
|
|
226
|
-
- lib/rdoc/generator/markdown/
|
|
227
|
-
- lib/rdoc/generator/markdown/rdoc_markdown_pre.rb
|
|
208
|
+
- lib/rdoc/generator/markdown/crossref.rb
|
|
228
209
|
- lib/rdoc/markdown/version.rb
|
|
229
210
|
- lib/templates/classfile.md.erb
|
|
230
211
|
- mutant.yml
|
|
@@ -244,7 +225,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
244
225
|
requirements:
|
|
245
226
|
- - ">="
|
|
246
227
|
- !ruby/object:Gem::Version
|
|
247
|
-
version:
|
|
228
|
+
version: 3.3.0
|
|
248
229
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
230
|
requirements:
|
|
250
231
|
- - ">="
|
data/Appraisals
DELETED
data/gemfiles/rdoc_7.gemfile
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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: "../"
|
data/gemfiles/rdoc_8.gemfile
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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: "../"
|
data/gemfiles/rdoc_head.gemfile
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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", git: "https://github.com/ruby/rdoc.git", branch: "master"
|
|
19
|
-
|
|
20
|
-
gemspec path: "../"
|
|
@@ -1,187 +0,0 @@
|
|
|
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
|
-
# Creates an immutable signature index.
|
|
152
|
-
#
|
|
153
|
-
# @param signatures [Hash{Array => Array<String>}] Signature lookup.
|
|
154
|
-
#
|
|
155
|
-
# @return [void]
|
|
156
|
-
def initialize(signatures)
|
|
157
|
-
@signatures = signatures
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
# Looks up the RBS signature lines for an RDoc method.
|
|
161
|
-
#
|
|
162
|
-
# @param method [RDoc::AnyMethod] Method object to render.
|
|
163
|
-
#
|
|
164
|
-
# @return [Array<String>] RBS method type lines when available.
|
|
165
|
-
def signature_lines_for(method)
|
|
166
|
-
@signatures.fetch([method.parent.full_name, method.singleton, method.name], [])
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# Checks whether any RBS signatures were parsed.
|
|
170
|
-
#
|
|
171
|
-
# @return [Boolean] True when type signatures are available.
|
|
172
|
-
def any?
|
|
173
|
-
@signatures.any?
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
private_class_method \
|
|
177
|
-
:signatures_from,
|
|
178
|
-
:signatures_from_store,
|
|
179
|
-
:parsed_classes,
|
|
180
|
-
:rbs_file_path,
|
|
181
|
-
:add_method_signature_lines,
|
|
182
|
-
:rbs_signature_lines_from_method,
|
|
183
|
-
:store_signature_lines_from_method,
|
|
184
|
-
:method_type_signature_lines,
|
|
185
|
-
:store_type_signature_lines,
|
|
186
|
-
:nonblank_lines
|
|
187
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Preserves simple <pre class="ruby"> language metadata emitted by RDoc.
|
|
4
|
-
class ReverseMarkdown::Converters::RDocMarkdownPre < ReverseMarkdown::Converters::Pre
|
|
5
|
-
# Matches RDoc's plain language class names on pre blocks.
|
|
6
|
-
LANGUAGE_CLASS = /\A(?!highlight\z)[A-Za-z][A-Za-z0-9_+-]*\z/
|
|
7
|
-
|
|
8
|
-
# Converts an RDoc pre block into a GitHub-flavored Markdown fence.
|
|
9
|
-
#
|
|
10
|
-
# @param node [Nokogiri::XML::Node] RDoc pre node.
|
|
11
|
-
# @param _state [Hash] reverse_markdown converter state.
|
|
12
|
-
#
|
|
13
|
-
# @return [String] Markdown code fence.
|
|
14
|
-
def convert(node, _state)
|
|
15
|
-
content = treat_children(rdoc_pre_node(node), {})
|
|
16
|
-
"\n```#{language(node)}\n" << content << "\n```\n"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
# Rebuilds a plain pre node from RDoc-highlighted text.
|
|
22
|
-
#
|
|
23
|
-
# @param node [Nokogiri::XML::Node] RDoc pre node.
|
|
24
|
-
#
|
|
25
|
-
# @return [Nokogiri::XML::Node] Plain pre node.
|
|
26
|
-
def rdoc_pre_node(node)
|
|
27
|
-
Nokogiri::HTML.fragment("<pre>#{node.text}</pre>").at("pre")
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Extracts the Markdown fence language.
|
|
31
|
-
#
|
|
32
|
-
# @param node [Nokogiri::XML::Node] RDoc pre node.
|
|
33
|
-
#
|
|
34
|
-
# @return [String, nil] Language name, or nil when no language is known.
|
|
35
|
-
def language(node)
|
|
36
|
-
node["class"].to_s[LANGUAGE_CLASS] || super
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
ReverseMarkdown::Converters.register :pre, ReverseMarkdown::Converters::RDocMarkdownPre.new
|