yard 0.9.36 → 0.9.43
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/CHANGELOG.md +82 -1
- data/README.md +29 -25
- data/docs/GettingStarted.md +41 -15
- data/docs/Parser.md +17 -42
- data/docs/Tags.md +5 -5
- data/docs/Templates.md +5 -4
- data/docs/WhatsNew.md +59 -7
- data/docs/templates/default/yard_tags/html/setup.rb +1 -1
- data/lib/yard/autoload.rb +18 -0
- data/lib/yard/cli/diff.rb +7 -2
- data/lib/yard/code_objects/base.rb +1 -1
- data/lib/yard/code_objects/extra_file_object.rb +1 -0
- data/lib/yard/code_objects/macro_object.rb +0 -1
- data/lib/yard/code_objects/proxy.rb +1 -1
- data/lib/yard/docstring_parser.rb +0 -1
- data/lib/yard/handlers/base.rb +23 -1
- data/lib/yard/handlers/processor.rb +1 -1
- data/lib/yard/handlers/rbs/attribute_handler.rb +79 -0
- data/lib/yard/handlers/rbs/base.rb +38 -0
- data/lib/yard/handlers/rbs/constant_handler.rb +18 -0
- data/lib/yard/handlers/rbs/method_handler.rb +327 -0
- data/lib/yard/handlers/rbs/mixin_handler.rb +20 -0
- data/lib/yard/handlers/rbs/namespace_handler.rb +26 -0
- data/lib/yard/handlers/ruby/attribute_handler.rb +7 -4
- data/lib/yard/handlers/ruby/constant_handler.rb +24 -6
- data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
- data/lib/yard/handlers/ruby/visibility_handler.rb +14 -1
- data/lib/yard/i18n/locale.rb +1 -1
- data/lib/yard/i18n/pot_generator.rb +1 -1
- data/lib/yard/logging.rb +116 -61
- data/lib/yard/open_struct.rb +67 -0
- data/lib/yard/parser/rbs/rbs_parser.rb +325 -0
- data/lib/yard/parser/rbs/statement.rb +75 -0
- data/lib/yard/parser/ruby/ast_node.rb +5 -4
- data/lib/yard/parser/ruby/legacy/irb/slex.rb +19 -1
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +20 -5
- data/lib/yard/parser/ruby/ruby_parser.rb +109 -24
- data/lib/yard/parser/source_parser.rb +5 -4
- data/lib/yard/registry_resolver.rb +7 -0
- data/lib/yard/rubygems/specification.rb +1 -1
- data/lib/yard/server/commands/base.rb +1 -1
- data/lib/yard/server/library_version.rb +1 -1
- data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +168 -88
- data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +203 -12
- data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +1 -17
- data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -2
- data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +3 -3
- data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +2 -3
- data/lib/yard/server/templates/doc_server/processing/html/processing.erb +22 -16
- data/lib/yard/tags/default_factory.rb +1 -0
- data/lib/yard/tags/directives.rb +7 -1
- data/lib/yard/tags/library.rb +3 -3
- data/lib/yard/tags/overload_tag.rb +2 -1
- data/lib/yard/tags/tag.rb +2 -1
- data/lib/yard/tags/types_explainer.rb +5 -4
- data/lib/yard/templates/engine.rb +0 -1
- data/lib/yard/templates/helpers/base_helper.rb +1 -1
- data/lib/yard/templates/helpers/html_helper.rb +21 -6
- data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +6 -1
- data/lib/yard/templates/helpers/markup/hybrid_markdown.rb +2147 -0
- data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
- data/lib/yard/templates/helpers/markup_helper.rb +4 -2
- data/lib/yard/templates/template_options.rb +0 -1
- data/lib/yard/version.rb +1 -1
- data/po/ja.po +82 -82
- data/templates/default/fulldoc/html/css/common.css +1 -1
- data/templates/default/fulldoc/html/css/full_list.css +201 -53
- data/templates/default/fulldoc/html/css/style.css +991 -399
- data/templates/default/fulldoc/html/full_list.erb +8 -5
- data/templates/default/fulldoc/html/js/app.js +799 -312
- data/templates/default/fulldoc/html/js/full_list.js +332 -214
- data/templates/default/fulldoc/html/setup.rb +10 -2
- data/templates/default/layout/html/headers.erb +1 -1
- data/templates/default/layout/html/layout.erb +3 -1
- data/templates/default/method/html/header.erb +3 -3
- data/templates/default/module/html/defines.erb +3 -3
- data/templates/default/module/html/inherited_methods.erb +1 -0
- data/templates/default/module/html/method_summary.erb +8 -0
- data/templates/default/module/setup.rb +20 -0
- data/templates/default/onefile/html/headers.erb +2 -0
- data/templates/default/onefile/html/layout.erb +3 -4
- data/templates/default/tags/html/example.erb +2 -2
- data/templates/guide/fulldoc/html/css/style.css +347 -97
- data/templates/guide/fulldoc/html/js/app.js +61 -33
- data/templates/guide/layout/html/layout.erb +69 -72
- metadata +19 -8
|
@@ -1,12 +1,203 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
(() => {
|
|
2
|
+
function query(selector, root) {
|
|
3
|
+
return (root || document).querySelector(selector);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function ready(callback) {
|
|
7
|
+
if (document.readyState === "loading") {
|
|
8
|
+
document.addEventListener("DOMContentLoaded", callback, { once: true });
|
|
9
|
+
} else {
|
|
10
|
+
callback();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function createAutocomplete(input) {
|
|
15
|
+
const form = input.form;
|
|
16
|
+
const results = document.createElement("div");
|
|
17
|
+
const list = document.createElement("ul");
|
|
18
|
+
let requestTimer = null;
|
|
19
|
+
let controller = null;
|
|
20
|
+
let items = [];
|
|
21
|
+
let activeIndex = -1;
|
|
22
|
+
let blurTimer = null;
|
|
23
|
+
|
|
24
|
+
if (!form) return;
|
|
25
|
+
|
|
26
|
+
results.className = "ac_results";
|
|
27
|
+
results.hidden = true;
|
|
28
|
+
results.setAttribute("role", "listbox");
|
|
29
|
+
results.id = `${input.id}_results`;
|
|
30
|
+
list.setAttribute("role", "presentation");
|
|
31
|
+
results.appendChild(list);
|
|
32
|
+
input.setAttribute("autocomplete", "off");
|
|
33
|
+
input.setAttribute("aria-autocomplete", "list");
|
|
34
|
+
input.setAttribute("aria-controls", results.id);
|
|
35
|
+
input.setAttribute("aria-expanded", "false");
|
|
36
|
+
form.appendChild(results);
|
|
37
|
+
|
|
38
|
+
function syncResultsWidth() {
|
|
39
|
+
results.style.width = `${input.offsetWidth}px`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function hideResults() {
|
|
43
|
+
results.hidden = true;
|
|
44
|
+
input.setAttribute("aria-expanded", "false");
|
|
45
|
+
input.removeAttribute("aria-activedescendant");
|
|
46
|
+
activeIndex = -1;
|
|
47
|
+
items = [];
|
|
48
|
+
list.innerHTML = "";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function setActive(index) {
|
|
52
|
+
if (!items.length) return;
|
|
53
|
+
activeIndex = (index + items.length) % items.length;
|
|
54
|
+
items.forEach((item, itemIndex) => {
|
|
55
|
+
item.element.classList.toggle("ac_over", itemIndex === activeIndex);
|
|
56
|
+
});
|
|
57
|
+
input.setAttribute(
|
|
58
|
+
"aria-activedescendant",
|
|
59
|
+
items[activeIndex].element.id,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function selectItem(item) {
|
|
64
|
+
input.value = item.values[1];
|
|
65
|
+
window.location.href = item.values[3];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function renderItems(lines) {
|
|
69
|
+
syncResultsWidth();
|
|
70
|
+
list.innerHTML = "";
|
|
71
|
+
items = lines.map((line, index) => {
|
|
72
|
+
const values = line.split(",");
|
|
73
|
+
const element = document.createElement("li");
|
|
74
|
+
const label = document.createElement("span");
|
|
75
|
+
const namespace = document.createElement("small");
|
|
76
|
+
|
|
77
|
+
element.id = `${results.id}_item_${index}`;
|
|
78
|
+
element.setAttribute("role", "option");
|
|
79
|
+
element.className = index % 2 === 0 ? "ac_even" : "ac_odd";
|
|
80
|
+
label.textContent = values[0];
|
|
81
|
+
element.appendChild(label);
|
|
82
|
+
|
|
83
|
+
if (values[1] !== "") {
|
|
84
|
+
namespace.textContent = `(${values[1]})`;
|
|
85
|
+
element.appendChild(document.createTextNode(" "));
|
|
86
|
+
element.appendChild(namespace);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
element.addEventListener("mouseenter", () => {
|
|
90
|
+
setActive(index);
|
|
91
|
+
});
|
|
92
|
+
element.addEventListener("mousedown", (event) => {
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
selectItem(items[index]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
list.appendChild(element);
|
|
98
|
+
|
|
99
|
+
return { element: element, values: values };
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (items.length) {
|
|
103
|
+
results.hidden = false;
|
|
104
|
+
input.setAttribute("aria-expanded", "true");
|
|
105
|
+
setActive(0);
|
|
106
|
+
} else {
|
|
107
|
+
hideResults();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function fetchResults(term) {
|
|
112
|
+
if (controller) controller.abort();
|
|
113
|
+
controller = new AbortController();
|
|
114
|
+
input.classList.add("ac_loading");
|
|
115
|
+
|
|
116
|
+
fetch(`${form.action}?q=${encodeURIComponent(term)}&_=${Date.now()}`, {
|
|
117
|
+
headers: {
|
|
118
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
119
|
+
},
|
|
120
|
+
signal: controller.signal,
|
|
121
|
+
})
|
|
122
|
+
.then((response) => response.text())
|
|
123
|
+
.then((text) => {
|
|
124
|
+
const lines = text
|
|
125
|
+
.split("\n")
|
|
126
|
+
.map((line) => line.trim())
|
|
127
|
+
.filter(Boolean);
|
|
128
|
+
|
|
129
|
+
renderItems(lines);
|
|
130
|
+
})
|
|
131
|
+
.catch((error) => {
|
|
132
|
+
if (error.name !== "AbortError") hideResults();
|
|
133
|
+
})
|
|
134
|
+
.finally(() => {
|
|
135
|
+
input.classList.remove("ac_loading");
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
input.addEventListener("input", () => {
|
|
140
|
+
clearTimeout(requestTimer);
|
|
141
|
+
if (blurTimer) clearTimeout(blurTimer);
|
|
142
|
+
|
|
143
|
+
if (!input.value.trim()) {
|
|
144
|
+
hideResults();
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
requestTimer = setTimeout(() => {
|
|
149
|
+
fetchResults(input.value.trim());
|
|
150
|
+
}, 200);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
input.addEventListener("keydown", (event) => {
|
|
154
|
+
if (
|
|
155
|
+
results.hidden &&
|
|
156
|
+
(event.key === "ArrowDown" || event.key === "ArrowUp")
|
|
157
|
+
) {
|
|
158
|
+
if (!input.value.trim()) return;
|
|
159
|
+
fetchResults(input.value.trim());
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (event.key === "ArrowDown") {
|
|
164
|
+
event.preventDefault();
|
|
165
|
+
setActive(activeIndex + 1);
|
|
166
|
+
} else if (event.key === "ArrowUp") {
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
setActive(activeIndex - 1);
|
|
169
|
+
} else if (event.key === "Enter") {
|
|
170
|
+
if (activeIndex >= 0 && items[activeIndex]) {
|
|
171
|
+
event.preventDefault();
|
|
172
|
+
selectItem(items[activeIndex]);
|
|
173
|
+
}
|
|
174
|
+
} else if (event.key === "Escape") {
|
|
175
|
+
hideResults();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
input.addEventListener("blur", () => {
|
|
180
|
+
blurTimer = setTimeout(hideResults, 150);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
input.addEventListener("focus", () => {
|
|
184
|
+
syncResultsWidth();
|
|
185
|
+
if (items.length) {
|
|
186
|
+
results.hidden = false;
|
|
187
|
+
input.setAttribute("aria-expanded", "true");
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
document.addEventListener("click", (event) => {
|
|
192
|
+
if (!form.contains(event.target)) hideResults();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
window.addEventListener("resize", syncResultsWidth);
|
|
196
|
+
syncResultsWidth();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
ready(() => {
|
|
200
|
+
const input = query("#search_box");
|
|
201
|
+
if (input) createAutocomplete(input);
|
|
202
|
+
});
|
|
203
|
+
})();
|
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
<form class="search" method="get" action="<%= abs_url base_path(router.search_prefix) %>">
|
|
2
|
-
<input name="q" type="search" placeholder="Search" id="search_box" size="30" value="<%= h @query %>"
|
|
2
|
+
<input name="q" type="search" placeholder="Search" id="search_box" size="30" value="<%= h @query %>">
|
|
3
3
|
</form>
|
|
4
|
-
<script type="text/javascript" charset="utf-8">
|
|
5
|
-
$(function() {
|
|
6
|
-
$('#search_box').autocomplete($('#search_box').parent().attr('action'), {
|
|
7
|
-
width: 200,
|
|
8
|
-
formatItem: function(item) {
|
|
9
|
-
var values = item[0].split(",");
|
|
10
|
-
return values[0] + (values[1] == '' ? "" : " <small>(" + values[1] + ")</small>");
|
|
11
|
-
}
|
|
12
|
-
}).result(function(event, item) {
|
|
13
|
-
var values = item[0].split(",")
|
|
14
|
-
$('#search_box').val(values[1]);
|
|
15
|
-
location.href = values[3];
|
|
16
|
-
return false;
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
</script>
|
|
20
4
|
|
|
21
5
|
<div id="menu">
|
|
22
6
|
<% unless @single_library %>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
document.getElementById("<%= anchor_for(object) %>").insertAdjacentHTML(
|
|
3
|
+
"afterbegin",
|
|
4
|
+
'<a class="permalink" href="<%= abs_url base_path(router.docs_prefix) %>/<%= urlencode serializer.serialized_path(object) %>">permalink</a>'
|
|
5
|
+
);
|
|
4
6
|
</script>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<meta
|
|
1
|
+
<meta charset="UTF-8">
|
|
2
2
|
<title>YARD Documentation Server <%= YARD::VERSION %> - Library Listing</title>
|
|
3
|
-
<link rel="stylesheet" href="<%= abs_url('css', 'style.css') %>?<%= mtime('css/style.css') %>" type="text/css" media="screen" charset="utf-8"
|
|
4
|
-
<link rel="stylesheet" href="<%= abs_url('css', 'custom.css') %>?<%= mtime('css/custom.css') %>" type="text/css" media="screen" charset="utf-8"
|
|
3
|
+
<link rel="stylesheet" href="<%= abs_url('css', 'style.css') %>?<%= mtime('css/style.css') %>" type="text/css" media="screen" charset="utf-8">
|
|
4
|
+
<link rel="stylesheet" href="<%= abs_url('css', 'custom.css') %>?<%= mtime('css/custom.css') %>" type="text/css" media="screen" charset="utf-8">
|
|
5
5
|
<style type="text/css" media="screen">
|
|
6
6
|
ul { list-style: circle inside none; padding: 0; }
|
|
7
7
|
li { font-size: 1.2em; line-height: 1.4em; padding: 3px 5px; }
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
<!DOCTYPE html
|
|
2
|
-
|
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
4
3
|
<head>
|
|
5
4
|
<%= erb(:headers) %>
|
|
6
5
|
</head>
|
|
@@ -2,29 +2,35 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<link rel="stylesheet" href="<%= abs_url('css', 'style.css') %>?<%= mtime('css/style.css') %>" type="text/css" media="screen" charset="utf-8"
|
|
6
|
-
<link rel="stylesheet" href="<%= abs_url('css', 'custom.css') %>?<%= mtime('css/custom.css') %>" type="text/css" media="screen" charset="utf-8"
|
|
7
|
-
<script type="text/javascript" charset="utf-8" src="<%= abs_url('js', 'jquery.js') %>?<%= mtime('js/jquery.js') %>"></script>
|
|
5
|
+
<link rel="stylesheet" href="<%= abs_url('css', 'style.css') %>?<%= mtime('css/style.css') %>" type="text/css" media="screen" charset="utf-8">
|
|
6
|
+
<link rel="stylesheet" href="<%= abs_url('css', 'custom.css') %>?<%= mtime('css/custom.css') %>" type="text/css" media="screen" charset="utf-8">
|
|
8
7
|
<script type="text/javascript" charset="utf-8">
|
|
9
8
|
function checkPage(process) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
fetch("<%= router.request.path %>" + (process ? "?process=true" : ""), { cache: "no-store" })
|
|
10
|
+
.then(function(response) {
|
|
11
|
+
if (response.status === 200) window.location.reload();
|
|
12
|
+
});
|
|
13
|
+
setTimeout(checkPage, 2000);
|
|
13
14
|
}
|
|
14
15
|
function setFade() {
|
|
15
16
|
centerMessage();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
window.addEventListener("resize", centerMessage);
|
|
18
|
+
document.getElementById('fade').style.display = 'block';
|
|
19
|
+
document.getElementById('processing').style.display = 'block';
|
|
19
20
|
}
|
|
20
21
|
function centerMessage() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
var fade = document.getElementById('fade');
|
|
23
|
+
var processing = document.getElementById('processing');
|
|
24
|
+
var fadeTop = parseInt(window.getComputedStyle(fade).top, 10) || 0;
|
|
25
|
+
fade.style.width = window.innerWidth + 'px';
|
|
26
|
+
fade.style.height = (window.innerHeight - fadeTop) + 'px';
|
|
27
|
+
processing.style.left = (window.innerWidth / 2 - processing.offsetWidth / 2) + 'px';
|
|
28
|
+
processing.style.top = (window.innerHeight / 2 - processing.offsetHeight / 2) + 'px';
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
document.addEventListener("DOMContentLoaded", function() {
|
|
31
|
+
checkPage(true);
|
|
32
|
+
setFade();
|
|
33
|
+
});
|
|
28
34
|
</script>
|
|
29
35
|
<style type="text/css" media="screen">
|
|
30
36
|
body { overflow: hidden; margin: 12px; display: block; }
|
|
@@ -46,7 +52,7 @@
|
|
|
46
52
|
<strong><%= @library.name %></strong> <% if @library.version %>(<%= @library.version %>)<% end %> is being processed.
|
|
47
53
|
You'll be redirected when the pages are built, it shouldn't take much longer.
|
|
48
54
|
</p>
|
|
49
|
-
<img src="<%= abs_url('images', 'processing.gif') %>?<%= mtime('images/processing.gif') %>" align="center"
|
|
55
|
+
<img src="<%= abs_url('images', 'processing.gif') %>?<%= mtime('images/processing.gif') %>" align="center">
|
|
50
56
|
</div>
|
|
51
57
|
</body>
|
|
52
58
|
</html>
|
data/lib/yard/tags/directives.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require 'ostruct'
|
|
3
2
|
|
|
4
3
|
module YARD
|
|
5
4
|
module Tags
|
|
@@ -544,6 +543,7 @@ module YARD
|
|
|
544
543
|
# @since 0.8.0
|
|
545
544
|
class ParseDirective < Directive
|
|
546
545
|
def call
|
|
546
|
+
existing = YARD::Registry.all.lazy.map(&:path).to_set if handler
|
|
547
547
|
lang = tag.types ? tag.types.first.to_sym :
|
|
548
548
|
(handler ? handler.parser.parser_type : :ruby)
|
|
549
549
|
if handler && lang == handler.parser.parser_type
|
|
@@ -556,6 +556,12 @@ module YARD
|
|
|
556
556
|
src_parser.file = handler.parser.file if handler
|
|
557
557
|
src_parser.parse(StringIO.new(tag.text))
|
|
558
558
|
end
|
|
559
|
+
return unless handler
|
|
560
|
+
YARD::Registry.all.each do |obj|
|
|
561
|
+
next if existing.include? obj.path
|
|
562
|
+
obj.files.each { |entry| entry[1] = handler.statement.line if entry[0] == handler.parser.file.to_s }
|
|
563
|
+
obj.source = handler.statement.source
|
|
564
|
+
end
|
|
559
565
|
end
|
|
560
566
|
end
|
|
561
567
|
|
data/lib/yard/tags/library.rb
CHANGED
|
@@ -507,7 +507,7 @@ module YARD
|
|
|
507
507
|
#
|
|
508
508
|
# @example
|
|
509
509
|
# # Synchronizes system time using NTP.
|
|
510
|
-
# # @see
|
|
510
|
+
# # @see https://ntp.org/documentation.html NTP Documentation
|
|
511
511
|
# # @see NTPHelperMethods
|
|
512
512
|
# class NTPUpdater; end
|
|
513
513
|
define_tag "See Also", :see, :with_name
|
|
@@ -541,7 +541,7 @@ module YARD
|
|
|
541
541
|
# @example
|
|
542
542
|
# # @todo Add support for Jabberwocky service.
|
|
543
543
|
# # There is an open source Jabberwocky library available
|
|
544
|
-
# # at
|
|
544
|
+
# # at https://jbrwcky.org that can be easily integrated.
|
|
545
545
|
# class Wonderlander; end
|
|
546
546
|
# @see tag:note
|
|
547
547
|
define_tag "Todo Item", :todo
|
|
@@ -554,7 +554,7 @@ module YARD
|
|
|
554
554
|
# of a specific object.
|
|
555
555
|
#
|
|
556
556
|
# @example
|
|
557
|
-
# # The public REST API for
|
|
557
|
+
# # The public REST API for https://jbrwcky.org
|
|
558
558
|
# # @version 2.0
|
|
559
559
|
# class JabberwockyAPI; end
|
|
560
560
|
define_tag "Version", :version
|
|
@@ -60,7 +60,8 @@ module YARD
|
|
|
60
60
|
args = YARD::Handlers::Ruby::Legacy::Base.new(nil, nil).send(:tokval_list, toks, :all)
|
|
61
61
|
args = args.map do |a|
|
|
62
62
|
k, v = *a.split(/:|=/, 2)
|
|
63
|
-
|
|
63
|
+
v.strip! if v
|
|
64
|
+
[k.strip.to_s + (a[k.size, 1] == ':' ? ':' : ''), (v && v.empty? ? nil : v)]
|
|
64
65
|
end if args
|
|
65
66
|
@name = meth.to_sym
|
|
66
67
|
@parameters = args
|
data/lib/yard/tags/tag.rb
CHANGED
|
@@ -23,6 +23,7 @@ module YARD
|
|
|
23
23
|
attr_accessor :types
|
|
24
24
|
|
|
25
25
|
# @return [String] a name associated with the tag
|
|
26
|
+
# @return [nil] if no tag name is supplied
|
|
26
27
|
attr_accessor :name
|
|
27
28
|
|
|
28
29
|
# @return [CodeObjects::Base] the associated object
|
|
@@ -37,7 +38,7 @@ module YARD
|
|
|
37
38
|
# +raise+, etc.
|
|
38
39
|
#
|
|
39
40
|
# @param [#to_s] tag_name the tag name to create the tag for
|
|
40
|
-
# @param [String] text
|
|
41
|
+
# @param [String, nil] text the descriptive text for this tag, or nil if none provided
|
|
41
42
|
# @param [Array<String>] types optional type list of formally declared types
|
|
42
43
|
# for the tag
|
|
43
44
|
# @param [String] name optional key name which the tag refers to
|
|
@@ -32,7 +32,7 @@ module YARD
|
|
|
32
32
|
|
|
33
33
|
def to_s(singular = true)
|
|
34
34
|
if name[0, 1] == "#"
|
|
35
|
-
singular ? "an object that responds to
|
|
35
|
+
(singular ? "an object that responds to " : "objects that respond to ") + list_join(name.split(/ *& */), with: "and")
|
|
36
36
|
elsif name[0, 1] =~ /[A-Z]/
|
|
37
37
|
singular ? "a#{name[0, 1] =~ /[aeiou]/i ? 'n' : ''} " + name : "#{name}#{name[-1, 1] =~ /[A-Z]/ ? "'" : ''}s"
|
|
38
38
|
else
|
|
@@ -42,12 +42,12 @@ module YARD
|
|
|
42
42
|
|
|
43
43
|
private
|
|
44
44
|
|
|
45
|
-
def list_join(list)
|
|
45
|
+
def list_join(list, with: "or")
|
|
46
46
|
index = 0
|
|
47
47
|
list.inject(String.new) do |acc, el|
|
|
48
48
|
acc << el.to_s
|
|
49
49
|
acc << ", " if index < list.size - 2
|
|
50
|
-
acc << "
|
|
50
|
+
acc << " #{with} " if index == list.size - 2
|
|
51
51
|
index += 1
|
|
52
52
|
acc
|
|
53
53
|
end
|
|
@@ -102,6 +102,7 @@ module YARD
|
|
|
102
102
|
:fixed_collection_start => /\(/,
|
|
103
103
|
:fixed_collection_end => /\)/,
|
|
104
104
|
:type_name => /#{ISEP}#{METHODNAMEMATCH}|#{NAMESPACEMATCH}|\w+/,
|
|
105
|
+
:symbol => /:#{METHODNAMEMATCH}/,
|
|
105
106
|
:type_next => /[,;]/,
|
|
106
107
|
:whitespace => /\s+/,
|
|
107
108
|
:hash_collection_start => /\{/,
|
|
@@ -130,7 +131,7 @@ module YARD
|
|
|
130
131
|
next unless (match.nil? && @scanner.eos?) || (match && token = @scanner.scan(match))
|
|
131
132
|
found = true
|
|
132
133
|
case token_type
|
|
133
|
-
when :type_name
|
|
134
|
+
when :type_name, :symbol
|
|
134
135
|
raise SyntaxError, "expecting END, got name '#{token}'" if name
|
|
135
136
|
name = token
|
|
136
137
|
when :type_next
|
|
@@ -45,7 +45,7 @@ module YARD::Templates::Helpers
|
|
|
45
45
|
# method depending on the arguments passed in.
|
|
46
46
|
#
|
|
47
47
|
# @example Linking a URL
|
|
48
|
-
# linkify('
|
|
48
|
+
# linkify('https://example.com')
|
|
49
49
|
# @example Including docstring contents of an object
|
|
50
50
|
# linkify('include:YARD::Docstring')
|
|
51
51
|
# @example Linking to an extra file
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
2
|
+
if RUBY_VERSION < '3.5'
|
|
3
|
+
require 'cgi/util'
|
|
4
|
+
else
|
|
5
|
+
require 'cgi/escape'
|
|
6
|
+
end
|
|
3
7
|
|
|
4
8
|
module YARD
|
|
5
9
|
module Templates::Helpers
|
|
@@ -89,10 +93,16 @@ module YARD
|
|
|
89
93
|
:tables,
|
|
90
94
|
:with_toc_data,
|
|
91
95
|
:no_intraemphasis).to_html
|
|
96
|
+
when 'Commonmarker'
|
|
97
|
+
provider.to_html(text, :options => { }, :plugins => { :syntax_highlighter => nil })
|
|
92
98
|
when 'CommonMarker'
|
|
93
|
-
|
|
99
|
+
provider.render_html(text, %i[DEFAULT GITHUB_PRE_LANG], %i[autolink table])
|
|
94
100
|
else
|
|
95
|
-
provider.
|
|
101
|
+
if provider.respond_to?(:to_html)
|
|
102
|
+
provider.to_html(text)
|
|
103
|
+
else
|
|
104
|
+
provider.new(text).to_html
|
|
105
|
+
end
|
|
96
106
|
end
|
|
97
107
|
end
|
|
98
108
|
|
|
@@ -152,7 +162,7 @@ module YARD
|
|
|
152
162
|
# @return [String] the output HTML
|
|
153
163
|
# @since 0.6.0
|
|
154
164
|
def html_markup_text(text)
|
|
155
|
-
h(text).gsub(/\r?\n/, '<br
|
|
165
|
+
h(text).gsub(/\r?\n/, '<br>')
|
|
156
166
|
end
|
|
157
167
|
|
|
158
168
|
# @return [String] the same text with no markup
|
|
@@ -224,7 +234,7 @@ module YARD
|
|
|
224
234
|
# @return [String] HTML with linkified references
|
|
225
235
|
def resolve_links(text)
|
|
226
236
|
code_tags = 0
|
|
227
|
-
text.gsub(%r{<(/)?(pre|code|tt)|(\\|!)?\{(?!\})(\S+?)(?:\s([^\}]*?\S))?\}(
|
|
237
|
+
text.gsub(%r{<(/)?(pre|code|tt)|(\\|!)?\{(?!\})(\S+?)(?:\s([^\}]*?\S))?\}(?=\W|.+</|$)}m) do |str|
|
|
228
238
|
closed = $1
|
|
229
239
|
tag = $2
|
|
230
240
|
escape = $3
|
|
@@ -646,7 +656,12 @@ module YARD
|
|
|
646
656
|
language ||= detect_lang_in_codeblock_attributes($1, $2)
|
|
647
657
|
language ||= object.source_type
|
|
648
658
|
|
|
649
|
-
if
|
|
659
|
+
# Skip re-highlighting if the block is already highlighted (e.g. from a recursive
|
|
660
|
+
# htmlify call via {include:} or {yard:include_tags}). Passing pre-highlighted HTML
|
|
661
|
+
# through CGI.unescapeHTML would corrupt deliberately-escaped entities inside spans.
|
|
662
|
+
# Note: this heuristic suppresses highlighting for code blocks in :html markup that
|
|
663
|
+
# contain a literal <span> tag in the source being documented (an uncommon edge case).
|
|
664
|
+
if options.highlight && string !~ HtmlSyntaxHighlightHelper::ALREADY_HIGHLIGHTED_RE
|
|
650
665
|
string = html_syntax_highlight(CGI.unescapeHTML(string), language)
|
|
651
666
|
end
|
|
652
667
|
classes = ['code', language].compact.join(' ')
|
|
@@ -6,6 +6,11 @@ module YARD
|
|
|
6
6
|
module HtmlSyntaxHighlightHelper
|
|
7
7
|
include ModuleHelper
|
|
8
8
|
|
|
9
|
+
# Matches source that has already been highlighted (i.e. contains a span tag).
|
|
10
|
+
# Used to avoid double-processing pre-highlighted HTML in the rescue clause of
|
|
11
|
+
# {#html_syntax_highlight_ruby_ripper} and in the {HtmlHelper#parse_codeblocks} guard.
|
|
12
|
+
ALREADY_HIGHLIGHTED_RE = /<span[\s>]/
|
|
13
|
+
|
|
9
14
|
# Highlights Ruby source
|
|
10
15
|
# @param [String] source the Ruby source code
|
|
11
16
|
# @return [String] the highlighted Ruby source
|
|
@@ -39,7 +44,7 @@ module YARD
|
|
|
39
44
|
end
|
|
40
45
|
output
|
|
41
46
|
rescue Parser::ParserSyntaxError
|
|
42
|
-
source =~
|
|
47
|
+
source =~ ALREADY_HIGHLIGHTED_RE ? source : h(source)
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
def html_syntax_highlight_ruby_legacy(source)
|