yard-markdown-relative-links 0.2.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 +7 -0
- data/CHANGELOG.md +27 -0
- data/MIT-LICENSE +20 -0
- data/README.md +134 -0
- data/lib/yard/relative_markdown_links/version.rb +7 -0
- data/lib/yard/relative_markdown_links.rb +259 -0
- data/lib/yard-markdown-relative-links.rb +3 -0
- metadata +74 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fbcb5b063125d5b23b85d928be3f180acc9c225504b93cf2ed75eb536e5e3971
|
|
4
|
+
data.tar.gz: fe4b93bcd506fae09bb4975aa0313729e1c64654b3f599e4da49e061d6264674
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2e403985e27ffc84edc382582b47530428cca504b38668a1410d7777d6c04b4be42482321a72af1ab174473d2f44a2cb91433b909b8aa0fa1923bb26d3a6ab0e
|
|
7
|
+
data.tar.gz: 13ad0ea218d206df70ca047eb183212e6c627587aacb63da22861a211034aff20f61411283329e9619208ae387cd371ab0ba781fe2e2b8565bf4322371b365f2
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-03-03
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Replaced `Nokogiri` with a stdlib-only anchor rewriter for link conversion
|
|
13
|
+
- Refactored file lookup caching to rebuild indexes when YARD file lists change
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Test coverage for uppercase/single-quoted anchors and malformed HTML fragments
|
|
18
|
+
|
|
19
|
+
## [0.1.0] - 2026-03-03
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Initial release
|
|
24
|
+
- Convert relative Markdown links to YARD file references
|
|
25
|
+
- Support for files in subdirectories by resolving links relative to the current file's directory
|
|
26
|
+
- Preserve anchor/fragment links (e.g., `file.md#section`)
|
|
27
|
+
- Basename fallback matching when there's exactly one file with the matching name
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2026 Daniel Harrington
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# yard-markdown-relative-links
|
|
2
|
+
|
|
3
|
+
[](https://github.com/rubiii/yard-markdown-relative-links/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
A YARD plugin to convert relative links between Markdown files.
|
|
6
|
+
|
|
7
|
+
GitHub and YARD render Markdown files differently. In particular, relative links in Markdown files that work in GitHub don't work in YARD. For example, if you have `[hello](FOO.md)` in your README, YARD renders it as `<a href="FOO.md">hello</a>`, creating a broken link in your docs.
|
|
8
|
+
|
|
9
|
+
With this plugin enabled, you'll get `<a href="file.FOO.html">hello</a>` instead, which correctly links through to the rendered HTML file.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Converts relative Markdown links to YARD file references
|
|
14
|
+
- **Supports files in subdirectories** — links from `docs/index.md` to `getting-started.md` correctly resolve to `docs/getting-started.md`
|
|
15
|
+
- Preserves anchor/fragment links (e.g., `file.md#section`)
|
|
16
|
+
- Falls back to basename matching for simple cases
|
|
17
|
+
- No `Nokogiri` runtime dependency (stdlib-only link rewriting)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Add this line to your application's `Gemfile`:
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
gem 'yard-markdown-relative-links'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
And then execute:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
bundle install
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or install it yourself as:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
gem install yard-markdown-relative-links
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
Add this line to your application's `.yardopts`:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
--plugin relative_markdown_links
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
You'll also need to make sure your Markdown files are processed by YARD. To include all Markdown files in your project, add the following lines to the end of your application's `.yardopts`:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
-
|
|
51
|
+
**/*.md
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Example `.yardopts`
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
--markup markdown
|
|
58
|
+
--plugin relative_markdown_links
|
|
59
|
+
--readme README.md
|
|
60
|
+
-
|
|
61
|
+
docs/*.md
|
|
62
|
+
lib/**/*.rb
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## How It Works
|
|
66
|
+
|
|
67
|
+
When YARD processes your Markdown files, this plugin intercepts the HTML output and converts relative links to YARD's `{file:}` syntax.
|
|
68
|
+
|
|
69
|
+
The plugin resolves links in three ways:
|
|
70
|
+
|
|
71
|
+
1. **Exact match** — If the link path exactly matches a file in YARD's file list (e.g., `docs/index.md`), it's used directly.
|
|
72
|
+
|
|
73
|
+
2. **Relative to current file** — If processing `docs/index.md` and it contains a link to `getting-started.md`, the plugin resolves this relative to the current file's directory, finding `docs/getting-started.md`.
|
|
74
|
+
|
|
75
|
+
3. **Basename fallback** — If there's exactly one file with the matching basename, it's used (e.g., `getting-started.md` matches `docs/getting-started.md` if that's the only file with that name).
|
|
76
|
+
|
|
77
|
+
## Background
|
|
78
|
+
|
|
79
|
+
### Origins
|
|
80
|
+
|
|
81
|
+
This gem is a replacement for the original [`yard-relative_markdown_links`](https://github.com/haines/yard-relative_markdown_links) gem created by Andrew Haines. The original gem was archived in February 2026.
|
|
82
|
+
|
|
83
|
+
The original gem solved an important problem: relative links between Markdown files that work on GitHub don't work in YARD-generated documentation. However, it had a limitation — it only matched links against exact file paths in YARD's file list, which meant links between files in subdirectories didn't work properly.
|
|
84
|
+
|
|
85
|
+
For example, if you had documentation in a `docs/` folder:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
docs/
|
|
89
|
+
├── index.md # contains [Getting Started](getting-started.md)
|
|
90
|
+
└── getting-started.md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The link in `index.md` would work on GitHub but not in YARD, because the original gem looked for `getting-started.md` in the file list, but YARD registered it as `docs/getting-started.md`.
|
|
94
|
+
|
|
95
|
+
### Comparison with the Original Gem
|
|
96
|
+
|
|
97
|
+
| Feature | Original | This Gem |
|
|
98
|
+
|---------|----------|----------|
|
|
99
|
+
| Convert exact path matches | ✅ | ✅ |
|
|
100
|
+
| Preserve fragment/anchors (`#section`) | ✅ | ✅ |
|
|
101
|
+
| Skip absolute URLs | ✅ | ✅ |
|
|
102
|
+
| RDoc filename mapping | ✅ | ✅ |
|
|
103
|
+
| **Subdirectory support** | ❌ | ✅ |
|
|
104
|
+
| **Parent directory (`..`) resolution** | ❌ | ✅ |
|
|
105
|
+
| **Basename fallback matching** | ❌ | ✅ |
|
|
106
|
+
| **Malformed URI handling** | ❌ | ✅ |
|
|
107
|
+
|
|
108
|
+
### Key Improvements
|
|
109
|
+
|
|
110
|
+
1. **Subdirectory support** — When processing `docs/index.md`, a link to `getting-started.md` is resolved relative to the current file's directory, correctly finding `docs/getting-started.md`.
|
|
111
|
+
|
|
112
|
+
2. **Parent directory resolution** — Links like `../other-file.md` are normalized and resolved correctly.
|
|
113
|
+
|
|
114
|
+
3. **Basename fallback** — If there's exactly one file with a matching basename, it's used even without the full path.
|
|
115
|
+
|
|
116
|
+
4. **Error handling** — Malformed URIs are gracefully skipped instead of raising exceptions.
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
Run tests:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
bundle exec rake test
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Run linting:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bundle exec rake lint
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
Released under the [MIT License](LICENSE.txt).
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
require_relative 'relative_markdown_links/version'
|
|
6
|
+
|
|
7
|
+
module YARD
|
|
8
|
+
# A YARD plugin to convert relative links between Markdown files.
|
|
9
|
+
#
|
|
10
|
+
# GitHub and YARD render Markdown files differently. In particular, relative
|
|
11
|
+
# links in Markdown files that work in GitHub don't work in YARD. For example,
|
|
12
|
+
# if you have `[hello](docs/FOO.md)` in your README, YARD renders it as
|
|
13
|
+
# `<a href="docs/FOO.md">hello</a>`, creating a broken link in your docs.
|
|
14
|
+
#
|
|
15
|
+
# With this plugin enabled, you'll get `<a href="file.FOO.html">hello</a>`
|
|
16
|
+
# instead, which correctly links through to the rendered HTML file.
|
|
17
|
+
#
|
|
18
|
+
# This plugin also properly handles files in subdirectories. For example,
|
|
19
|
+
# if `docs/index.md` links to `getting-started.md`, the plugin resolves
|
|
20
|
+
# the link relative to the current file's directory, finding
|
|
21
|
+
# `docs/getting-started.md` in YARD's file list.
|
|
22
|
+
module RelativeMarkdownLinks
|
|
23
|
+
ANCHOR_TAG_PATTERN = %r{<a\b(?<attributes>[^>]*)>(?<content>.*?)</a>}im
|
|
24
|
+
HREF_ATTRIBUTE_PATTERN = /
|
|
25
|
+
\bhref
|
|
26
|
+
\s*=\s*
|
|
27
|
+
(?:
|
|
28
|
+
"(?<double>[^"]*)"
|
|
29
|
+
|
|
|
30
|
+
'(?<single>[^']*)'
|
|
31
|
+
|
|
|
32
|
+
(?<bare>[^\s"'=<>`]+)
|
|
33
|
+
)
|
|
34
|
+
/imx
|
|
35
|
+
RDOC_FILENAME_PATTERN = %r{\A(?<dirname>(?:[^/#]*/)*+)(?<basename>[^/#]+)\.(?<ext>rb|rdoc|md)\z}i
|
|
36
|
+
|
|
37
|
+
# Resolves relative links from Markdown files.
|
|
38
|
+
#
|
|
39
|
+
# @param text [String] the HTML fragment in which to resolve links
|
|
40
|
+
# @return [String] HTML with relative links to extra files converted to `{file:}` links
|
|
41
|
+
def resolve_links(text)
|
|
42
|
+
return super unless options.files
|
|
43
|
+
|
|
44
|
+
super(rewrite_anchor_links(text))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Replace supported HTML anchors with YARD {file:} references when they resolve to known files.
|
|
50
|
+
#
|
|
51
|
+
# @param text [String] HTML fragment to rewrite
|
|
52
|
+
# @return [String]
|
|
53
|
+
def rewrite_anchor_links(text)
|
|
54
|
+
text.gsub(ANCHOR_TAG_PATTERN) do |anchor_tag|
|
|
55
|
+
attributes = Regexp.last_match[:attributes]
|
|
56
|
+
content = Regexp.last_match[:content]
|
|
57
|
+
href = extract_href(attributes)
|
|
58
|
+
file_ref = href && resolve_href(href)
|
|
59
|
+
|
|
60
|
+
file_ref ? "{file:#{file_ref} #{content}}" : anchor_tag
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Extract the href attribute value from an <a ...> attribute string.
|
|
65
|
+
#
|
|
66
|
+
# @param attributes [String]
|
|
67
|
+
# @return [String, nil]
|
|
68
|
+
def extract_href(attributes)
|
|
69
|
+
match = HREF_ATTRIBUTE_PATTERN.match(attributes)
|
|
70
|
+
return nil unless match
|
|
71
|
+
|
|
72
|
+
match[:double] || match[:single] || match[:bare]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Resolve a raw href string into a YARD file reference target.
|
|
76
|
+
#
|
|
77
|
+
# @param raw_href [String]
|
|
78
|
+
# @return [String, nil]
|
|
79
|
+
def resolve_href(raw_href)
|
|
80
|
+
href = URI(raw_href)
|
|
81
|
+
return nil unless href.relative?
|
|
82
|
+
return nil if href.query
|
|
83
|
+
|
|
84
|
+
path = href.path
|
|
85
|
+
return nil if path.nil? || path.empty?
|
|
86
|
+
|
|
87
|
+
resolved_path = resolve_file_path(path)
|
|
88
|
+
return nil unless resolved_path
|
|
89
|
+
|
|
90
|
+
href.fragment ? "#{resolved_path}##{href.fragment}" : resolved_path
|
|
91
|
+
rescue URI::InvalidURIError
|
|
92
|
+
# Skip malformed URIs
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Resolve a relative file path to a known file in the YARD file list.
|
|
97
|
+
#
|
|
98
|
+
# @param path [String] the relative path from the link
|
|
99
|
+
# @return [String, nil] the resolved path if found, nil otherwise
|
|
100
|
+
def resolve_file_path(path)
|
|
101
|
+
indexes = file_indexes
|
|
102
|
+
|
|
103
|
+
# First, try exact match (works for root-level files like docs/index.md from README)
|
|
104
|
+
return path if indexes[:filenames].include?(path)
|
|
105
|
+
|
|
106
|
+
# Try RDoc-style filename mapping (e.g., foo_bar_md.html -> foo_bar.md)
|
|
107
|
+
rdoc_resolved = indexes[:rdoc_filenames][path]
|
|
108
|
+
return rdoc_resolved if rdoc_resolved
|
|
109
|
+
|
|
110
|
+
# Try RDoc-style basename-only matching
|
|
111
|
+
rdoc_basename_resolved = resolve_rdoc_by_basename(path, indexes[:rdoc_basename_to_paths])
|
|
112
|
+
return rdoc_basename_resolved if rdoc_basename_resolved
|
|
113
|
+
|
|
114
|
+
# Try resolving relative to current file's directory
|
|
115
|
+
resolved = resolve_relative_to_current_file(path, indexes[:filenames])
|
|
116
|
+
return resolved if resolved
|
|
117
|
+
|
|
118
|
+
# Fallback: try to find by basename alone (for simple cases)
|
|
119
|
+
resolve_by_basename(path, indexes[:basename_to_paths])
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Build and memoize lookup structures for the current options.files list.
|
|
123
|
+
#
|
|
124
|
+
# @return [Hash]
|
|
125
|
+
def file_indexes
|
|
126
|
+
filenames = options.files.map(&:filename)
|
|
127
|
+
return @file_indexes if @file_indexes && @file_indexes_filenames == filenames
|
|
128
|
+
|
|
129
|
+
@file_indexes_filenames = filenames
|
|
130
|
+
@file_indexes = {
|
|
131
|
+
filenames: filenames.to_set,
|
|
132
|
+
basename_to_paths: build_basename_mapping(filenames),
|
|
133
|
+
rdoc_filenames: build_rdoc_filename_mapping(filenames),
|
|
134
|
+
rdoc_basename_to_paths: build_rdoc_basename_mapping(filenames)
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Resolve a path relative to the current file being processed.
|
|
139
|
+
#
|
|
140
|
+
# @param path [String] the relative path from the link
|
|
141
|
+
# @param filenames [Set<String>] known filenames
|
|
142
|
+
# @return [String, nil] the resolved path if found, nil otherwise
|
|
143
|
+
def resolve_relative_to_current_file(path, filenames)
|
|
144
|
+
current_dir = current_file_directory
|
|
145
|
+
return nil unless current_dir
|
|
146
|
+
|
|
147
|
+
resolved = File.join(current_dir, path)
|
|
148
|
+
resolved = normalize_path(resolved)
|
|
149
|
+
resolved if filenames.include?(resolved)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Resolve a path by matching its basename against known files.
|
|
153
|
+
#
|
|
154
|
+
# @param path [String] the relative path from the link
|
|
155
|
+
# @param basename_to_paths [Hash{String => Array<String>}]
|
|
156
|
+
# @return [String, nil] the resolved path if exactly one match, nil otherwise
|
|
157
|
+
def resolve_by_basename(path, basename_to_paths)
|
|
158
|
+
basename = File.basename(path)
|
|
159
|
+
candidates = basename_to_paths[basename]
|
|
160
|
+
candidates.first if candidates&.size == 1
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Get the directory of the current file being processed.
|
|
164
|
+
#
|
|
165
|
+
# @return [String, nil] the directory path, or nil if not available
|
|
166
|
+
def current_file_directory
|
|
167
|
+
# Try @file first (set in layout template)
|
|
168
|
+
return File.dirname(@file.filename) if defined?(@file) && @file.respond_to?(:filename)
|
|
169
|
+
|
|
170
|
+
# Try options.file (set during serialization)
|
|
171
|
+
return File.dirname(options.file.filename) if options.respond_to?(:file) && options.file.respond_to?(:filename)
|
|
172
|
+
|
|
173
|
+
nil
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Build a mapping from basename to full paths for fallback resolution.
|
|
177
|
+
#
|
|
178
|
+
# @param filenames [Array<String>] known filenames
|
|
179
|
+
# @return [Hash{String => Array<String>}] mapping of basenames to full paths
|
|
180
|
+
def build_basename_mapping(filenames)
|
|
181
|
+
mapping = Hash.new { |h, k| h[k] = [] }
|
|
182
|
+
filenames.each do |filename|
|
|
183
|
+
mapping[File.basename(filename)] << filename
|
|
184
|
+
end
|
|
185
|
+
mapping
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Build a mapping from RDoc-style HTML filenames to original filenames.
|
|
189
|
+
#
|
|
190
|
+
# RDoc generates filenames like `foo_bar_md.html` for `foo_bar.md`.
|
|
191
|
+
# This mapping allows resolving such links back to the original files.
|
|
192
|
+
#
|
|
193
|
+
# @param filenames [Array<String>] known filenames
|
|
194
|
+
# @return [Hash{String => String}] mapping of RDoc HTML names to original filenames
|
|
195
|
+
# @see https://github.com/ruby/rdoc/blob/0e060c69f51ec4a877e5cde69b31d47eaeb2a2b9/lib/rdoc/markup/to_html.rb#L364-L366
|
|
196
|
+
def build_rdoc_filename_mapping(filenames)
|
|
197
|
+
filenames.filter_map do |filename|
|
|
198
|
+
match = RDOC_FILENAME_PATTERN.match(filename)
|
|
199
|
+
next unless match
|
|
200
|
+
|
|
201
|
+
rdoc_name = "#{match[:dirname]}#{match[:basename].tr('.', '_')}_#{match[:ext]}.html"
|
|
202
|
+
[rdoc_name, filename]
|
|
203
|
+
end.to_h
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Build a mapping from RDoc-style basenames to original filenames.
|
|
207
|
+
#
|
|
208
|
+
# @param filenames [Array<String>] known filenames
|
|
209
|
+
# @return [Hash{String => Array<String>}] mapping of RDoc basenames to original filenames
|
|
210
|
+
def build_rdoc_basename_mapping(filenames)
|
|
211
|
+
mapping = Hash.new { |h, k| h[k] = [] }
|
|
212
|
+
filenames.each do |filename|
|
|
213
|
+
match = RDOC_FILENAME_PATTERN.match(filename)
|
|
214
|
+
next unless match
|
|
215
|
+
|
|
216
|
+
rdoc_basename = "#{match[:basename].tr('.', '_')}_#{match[:ext]}.html"
|
|
217
|
+
mapping[rdoc_basename] << filename
|
|
218
|
+
end
|
|
219
|
+
mapping
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Resolve RDoc-style filename by basename alone.
|
|
223
|
+
#
|
|
224
|
+
# @param path [String] the RDoc-style HTML filename (e.g., getting-started_md.html)
|
|
225
|
+
# @param rdoc_basename_to_paths [Hash{String => Array<String>}]
|
|
226
|
+
# @return [String, nil] the resolved path if exactly one match, nil otherwise
|
|
227
|
+
def resolve_rdoc_by_basename(path, rdoc_basename_to_paths)
|
|
228
|
+
basename = File.basename(path)
|
|
229
|
+
candidates = rdoc_basename_to_paths[basename]
|
|
230
|
+
candidates.first if candidates&.size == 1
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Normalize a file path, resolving . and .. components.
|
|
234
|
+
#
|
|
235
|
+
# @param path [String] the path to normalize
|
|
236
|
+
# @return [String] the normalized path
|
|
237
|
+
def normalize_path(path)
|
|
238
|
+
parts = path.split('/')
|
|
239
|
+
result = []
|
|
240
|
+
|
|
241
|
+
parts.each do |part|
|
|
242
|
+
case part
|
|
243
|
+
when '.', ''
|
|
244
|
+
# Skip current directory markers and empty parts
|
|
245
|
+
next
|
|
246
|
+
when '..'
|
|
247
|
+
# Go up one directory
|
|
248
|
+
result.pop
|
|
249
|
+
else
|
|
250
|
+
result << part
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
result.join('/')
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
Templates::Template.extra_includes << RelativeMarkdownLinks
|
|
259
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yard-markdown-relative-links
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Daniel Harrington
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: yard
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.9'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '0.9'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '1'
|
|
32
|
+
description: |
|
|
33
|
+
A YARD plugin that converts relative Markdown links to work in generated documentation.
|
|
34
|
+
Supports files in subdirectories by resolving links relative to the current file's location.
|
|
35
|
+
Works seamlessly with GitHub-style relative links while generating correct YARD file references.
|
|
36
|
+
email:
|
|
37
|
+
- me@rubiii.com
|
|
38
|
+
executables: []
|
|
39
|
+
extensions: []
|
|
40
|
+
extra_rdoc_files: []
|
|
41
|
+
files:
|
|
42
|
+
- CHANGELOG.md
|
|
43
|
+
- MIT-LICENSE
|
|
44
|
+
- README.md
|
|
45
|
+
- lib/yard-markdown-relative-links.rb
|
|
46
|
+
- lib/yard/relative_markdown_links.rb
|
|
47
|
+
- lib/yard/relative_markdown_links/version.rb
|
|
48
|
+
homepage: https://github.com/rubiii/yard-markdown-relative-links
|
|
49
|
+
licenses:
|
|
50
|
+
- MIT
|
|
51
|
+
metadata:
|
|
52
|
+
homepage_uri: https://github.com/rubiii/yard-markdown-relative-links
|
|
53
|
+
source_code_uri: https://github.com/rubiii/yard-markdown-relative-links
|
|
54
|
+
changelog_uri: https://github.com/rubiii/yard-markdown-relative-links/blob/main/CHANGELOG.md
|
|
55
|
+
bug_tracker_uri: https://github.com/rubiii/yard-markdown-relative-links/issues
|
|
56
|
+
rubygems_mfa_required: 'true'
|
|
57
|
+
rdoc_options: []
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '3.3'
|
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
requirements: []
|
|
71
|
+
rubygems_version: 4.0.3
|
|
72
|
+
specification_version: 4
|
|
73
|
+
summary: A YARD plugin to convert relative links between Markdown files
|
|
74
|
+
test_files: []
|