rtfdoc 0.1.0 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/README.md +2 -1
- data/lib/rtfdoc.rb +206 -29
- data/lib/rtfdoc/cli.rb +9 -0
- data/lib/rtfdoc/generators/bootstrap.rb +1 -8
- data/lib/rtfdoc/templates/{webpack.config.js.erb → webpack.config.js} +5 -2
- data/lib/rtfdoc/version.rb +1 -1
- data/rtfdoc.gemspec +2 -2
- data/src/attributes.erb +13 -7
- data/src/css/application.scss +193 -83
- data/src/index.html.erb +3 -3
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3536b8048b251df0869eb0bb16378eadc247d8cd4d46382ace2899a49cfc1f30
|
4
|
+
data.tar.gz: b659fd9034ca9183b442dd39e7e1eebe75644fc01d166bf37f84cd54d1de31df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0f64a36efec12b759cca63ef5f6c9dabea13e3f56a08061e9d2c08a34ea37eeaff96c35aacb30fd472e20bcb86414b3fe708d17c5ec96800107fc733e5fc700
|
7
|
+
data.tar.gz: 7b83e3baab95dcd2bbc0e6eaed000224ddc565b5b64b0553b765b8be88e27bac16c5c86514b0d58be4c178036a9430b4e13c2470a6c9831d2ccbb758107eea36
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rtfdoc (0.1.
|
4
|
+
rtfdoc (0.1.3)
|
5
5
|
erubi (~> 1.9.0)
|
6
6
|
redcarpet (~> 3.5.0)
|
7
|
-
rouge (~> 3.
|
7
|
+
rouge (~> 3.22.0)
|
8
8
|
thor (~> 1.0.1)
|
9
9
|
|
10
10
|
GEM
|
@@ -17,11 +17,11 @@ GEM
|
|
17
17
|
irb (1.2.4)
|
18
18
|
reline (>= 0.0.1)
|
19
19
|
minitest (5.14.1)
|
20
|
-
rake (
|
20
|
+
rake (13.0.1)
|
21
21
|
redcarpet (3.5.0)
|
22
22
|
reline (0.1.4)
|
23
23
|
io-console (~> 0.5)
|
24
|
-
rouge (3.
|
24
|
+
rouge (3.22.0)
|
25
25
|
thor (1.0.1)
|
26
26
|
|
27
27
|
PLATFORMS
|
@@ -33,7 +33,7 @@ DEPENDENCIES
|
|
33
33
|
byebug
|
34
34
|
irb
|
35
35
|
minitest (~> 5.0)
|
36
|
-
rake (~>
|
36
|
+
rake (~> 13.0)
|
37
37
|
rtfdoc!
|
38
38
|
|
39
39
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -14,7 +14,8 @@ $ gem install rtfdoc
|
|
14
14
|
|
15
15
|
You can scaffold a new project using `rtfdoc bootstrap <project_name>`. It will create a skeleton for your project, and generate needed configuration files.
|
16
16
|
|
17
|
-
Once in your project directory, you can install ruby dependencies using `bundle install` and javascript dependencies using `yarn install`.
|
17
|
+
Once in your project directory, you can install ruby dependencies using `bundle install` and javascript dependencies using `yarn install`. Then we want to stub the binary by running `bundle binstubs bundler rtfdoc`.
|
18
|
+
And finally, you'll copy the assets source by running `bin/rtfdoc install`.
|
18
19
|
|
19
20
|
By convention, you should put your documentation content under the `content/` directory. If you don't follow this convention, don't forget to modify the configuration file as well.
|
20
21
|
|
data/lib/rtfdoc.rb
CHANGED
@@ -3,8 +3,20 @@ require 'rouge'
|
|
3
3
|
require 'redcarpet'
|
4
4
|
require 'tmpdir'
|
5
5
|
|
6
|
+
require 'rtfdoc/version'
|
7
|
+
|
6
8
|
module RTFDoc
|
7
9
|
class AttributesComponent
|
10
|
+
# Needed because we can't call the same rendered within itself.
|
11
|
+
def self.private_renderer
|
12
|
+
@renderer ||= Redcarpet::Markdown.new(::RTFDoc::Renderer, {
|
13
|
+
underline: true,
|
14
|
+
space_after_headers: true,
|
15
|
+
fenced_code_blocks: true,
|
16
|
+
no_intra_emphasis: true
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
8
20
|
def initialize(raw_attrs, title)
|
9
21
|
@attributes = YAML.load(raw_attrs)
|
10
22
|
@title = title
|
@@ -14,6 +26,10 @@ module RTFDoc
|
|
14
26
|
class_eval <<-RUBY
|
15
27
|
define_method(:output) { #{template.src} }
|
16
28
|
RUBY
|
29
|
+
|
30
|
+
def to_html(text)
|
31
|
+
self.class.private_renderer.render(text) if text
|
32
|
+
end
|
17
33
|
end
|
18
34
|
|
19
35
|
class Renderer < Redcarpet::Render::Base
|
@@ -37,6 +53,10 @@ module RTFDoc
|
|
37
53
|
"<p>#{text}</p>"
|
38
54
|
end
|
39
55
|
|
56
|
+
def link(link, title, content)
|
57
|
+
%(<a title="#{title}" href="#{link}">#{content}</a>)
|
58
|
+
end
|
59
|
+
|
40
60
|
def header(text, level)
|
41
61
|
if level == 4
|
42
62
|
%(<div class="header-table">#{text}</div>)
|
@@ -89,26 +109,71 @@ module RTFDoc
|
|
89
109
|
if language == 'attributes' || language == 'parameters'
|
90
110
|
AttributesComponent.new(code, language).output
|
91
111
|
elsif language == 'response'
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
HTML
|
112
|
+
format_code('RESPONSE', code)
|
113
|
+
elsif language == 'title_and_code'
|
114
|
+
title, _code = code.split("\n", 2)
|
115
|
+
title ||= 'RESPONSE'
|
116
|
+
format_code(title, _code)
|
98
117
|
end
|
99
118
|
end
|
119
|
+
|
120
|
+
private def format_code(title, code)
|
121
|
+
<<-HTML
|
122
|
+
<div class="section-response">
|
123
|
+
<div class="response-topbar">#{title}</div>
|
124
|
+
<pre><code>#{rouge_formatter.format(rouge_lexer.lex(code.strip))}</code></pre>
|
125
|
+
</div>
|
126
|
+
HTML
|
127
|
+
end
|
128
|
+
|
100
129
|
end
|
101
130
|
|
102
131
|
class Template
|
103
|
-
|
104
|
-
|
105
|
-
|
132
|
+
attr_reader :app_name, :page_title
|
133
|
+
|
134
|
+
def initialize(nodes, config)
|
135
|
+
@content = nodes.flat_map(&:output).join
|
136
|
+
# @menu_content = nodes.map(&:menu_output).join
|
137
|
+
@app_name = config['app_name']
|
138
|
+
@page_title = config['title']
|
139
|
+
|
140
|
+
generate_grouped_menu_content(nodes)
|
106
141
|
end
|
107
142
|
|
108
143
|
def output
|
109
144
|
template = Erubi::Engine.new(File.read(File.expand_path('../src/index.html.erb', __dir__)))
|
110
145
|
eval(template.src)
|
111
146
|
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
# Transform a list of nodes into a list of groups. If all nodes already are groups, it will
|
151
|
+
# return the same list. Otherwise, it will build group from consecutives single resources.
|
152
|
+
def generate_grouped_menu_content(nodes)
|
153
|
+
i = 0
|
154
|
+
res = []
|
155
|
+
|
156
|
+
while i < nodes.length
|
157
|
+
node = nodes[i]
|
158
|
+
if node.is_a?(Group)
|
159
|
+
res << node
|
160
|
+
i += 1
|
161
|
+
else
|
162
|
+
inner = []
|
163
|
+
j = i
|
164
|
+
while node && !node.is_a?(Group)
|
165
|
+
inner << node
|
166
|
+
j += 1
|
167
|
+
node = nodes[j]
|
168
|
+
end
|
169
|
+
|
170
|
+
res << Group.new(nil, inner)
|
171
|
+
i = j
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
@menu_content = res.map(&:menu_output).join
|
176
|
+
end
|
112
177
|
end
|
113
178
|
|
114
179
|
module RenderAsSection
|
@@ -155,7 +220,7 @@ module RTFDoc
|
|
155
220
|
parse_metadata(YAML.load(raw_content.slice!(0, idx + 3)))
|
156
221
|
end
|
157
222
|
|
158
|
-
raise 'missing metadata' if resource && !@path && !@method
|
223
|
+
raise 'missing metadata' if resource && !meta_section? && !@path && !@method
|
159
224
|
|
160
225
|
@content, @example = raw_content.split('$$$')
|
161
226
|
end
|
@@ -177,17 +242,28 @@ module RTFDoc
|
|
177
242
|
end
|
178
243
|
|
179
244
|
def signature
|
180
|
-
sig
|
245
|
+
anchor(sig)
|
246
|
+
end
|
247
|
+
|
248
|
+
def example_to_html
|
249
|
+
res = super
|
250
|
+
@resource && res && !meta_section? ? res.sub('RESPONSE', sig) : res
|
251
|
+
end
|
252
|
+
|
253
|
+
private
|
254
|
+
|
255
|
+
def sig
|
256
|
+
@sig ||= <<-HTML.strip!
|
181
257
|
<div class="endpoint-def">
|
182
258
|
<div class="method method__#{method.downcase}">#{method.upcase}</div>
|
183
259
|
<div class="path">#{path}</div>
|
184
260
|
</div>
|
185
261
|
HTML
|
186
|
-
|
187
|
-
anchor(sig)
|
188
262
|
end
|
189
263
|
|
190
|
-
|
264
|
+
def meta_section?
|
265
|
+
name == 'desc' || name == 'object'
|
266
|
+
end
|
191
267
|
|
192
268
|
def menu_title
|
193
269
|
@menu_title || name.capitalize
|
@@ -221,16 +297,18 @@ module RTFDoc
|
|
221
297
|
end
|
222
298
|
|
223
299
|
def generate_example(sections)
|
224
|
-
endpoints = sections.reject { |s| s.name == 'desc' || s.name == 'object' }
|
300
|
+
endpoints = sections.reject { |s| s.is_a?(Scope) || s.name == 'desc' || s.name == 'object' }
|
225
301
|
signatures = endpoints.each_with_object("") do |e, res|
|
226
302
|
res << %(<div class="resource-sig">#{e.signature}</div>)
|
227
303
|
end
|
304
|
+
scopes = sections.select { |s| s.is_a?(Scope) }.map!(&:generate_example).join("\n")
|
228
305
|
|
229
306
|
@example = <<-HTML
|
230
307
|
<div class="section-response">
|
231
308
|
<div class="response-topbar">ENDPOINTS</div>
|
232
309
|
<div class="section-endpoints">#{signatures}</div>
|
233
310
|
</div>
|
311
|
+
#{scopes}
|
234
312
|
HTML
|
235
313
|
end
|
236
314
|
|
@@ -247,6 +325,25 @@ module RTFDoc
|
|
247
325
|
desc = nil
|
248
326
|
|
249
327
|
sections = endpoints.each_with_object([]) do |endpoint, res|
|
328
|
+
if endpoint.is_a?(Hash)
|
329
|
+
n, values = endpoint.each_pair.first
|
330
|
+
next unless n.start_with?('scope|')
|
331
|
+
dir_name = n.slice(6..-1)
|
332
|
+
|
333
|
+
scope_name = values['title'] || dir_name
|
334
|
+
scoped_endpoints = values['endpoints']
|
335
|
+
|
336
|
+
subsections = scoped_endpoints.each_with_object([]) do |e, r|
|
337
|
+
filename = paths.dig(dir_name, e)
|
338
|
+
next unless filename
|
339
|
+
content = File.read(filename)
|
340
|
+
r << Section.new(e, content, resource: name)
|
341
|
+
end
|
342
|
+
|
343
|
+
res << Scope.new(scope_name, subsections)
|
344
|
+
next res
|
345
|
+
end
|
346
|
+
|
250
347
|
filename = paths[endpoint]
|
251
348
|
next unless filename
|
252
349
|
|
@@ -274,7 +371,7 @@ module RTFDoc
|
|
274
371
|
head, *tail = sections
|
275
372
|
head.include_show_button = true
|
276
373
|
|
277
|
-
inner = sections.
|
374
|
+
inner = sections.flat_map(&:output).join("\n")
|
278
375
|
%(<section class="head-section">#{inner}</section>)
|
279
376
|
end
|
280
377
|
|
@@ -282,11 +379,80 @@ module RTFDoc
|
|
282
379
|
head, *tail = sections
|
283
380
|
<<-HTML
|
284
381
|
<li data-anchor="#{name}">
|
285
|
-
#{head.anchor(
|
382
|
+
#{head.anchor(human_name, class_list: 'expandable')}
|
286
383
|
<ul>#{tail.map(&:menu_output).join}</ul>
|
287
384
|
</li>
|
288
385
|
HTML
|
289
386
|
end
|
387
|
+
|
388
|
+
private
|
389
|
+
|
390
|
+
def human_name
|
391
|
+
name.tr('_', ' ').split.map!(&:capitalize).join(' ')
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
class Group
|
396
|
+
attr_reader :name, :resources
|
397
|
+
|
398
|
+
def initialize(name, resources, options = {})
|
399
|
+
@name = name
|
400
|
+
@resources = resources
|
401
|
+
|
402
|
+
sorted = true
|
403
|
+
sorted = options['sort'] if options.key?('sort')
|
404
|
+
@resources.sort! { |a, b| a.name <=> b.name } if sorted
|
405
|
+
end
|
406
|
+
|
407
|
+
def output
|
408
|
+
resources.map(&:output)
|
409
|
+
end
|
410
|
+
|
411
|
+
def menu_output
|
412
|
+
title = "<h5 class=\"nav-group-title\">#{name}</h5>" if name && name.length > 0
|
413
|
+
|
414
|
+
<<-HTML
|
415
|
+
<div class="sidebar-nav-group">
|
416
|
+
#{title}
|
417
|
+
<ul>#{resources.map(&:menu_output).join}</ul>
|
418
|
+
</div>
|
419
|
+
HTML
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
class Scope
|
424
|
+
attr_reader :name, :sections
|
425
|
+
|
426
|
+
def initialize(name, sections)
|
427
|
+
@name = name
|
428
|
+
@sections = sections
|
429
|
+
end
|
430
|
+
|
431
|
+
def output
|
432
|
+
sections.map(&:output)
|
433
|
+
end
|
434
|
+
|
435
|
+
def menu_output
|
436
|
+
<<-HTML
|
437
|
+
<li>
|
438
|
+
<div class="scope-title">#{name}</div>
|
439
|
+
<ul class="scoped">#{sections.map(&:menu_output).join}</ul>
|
440
|
+
</li>
|
441
|
+
HTML
|
442
|
+
end
|
443
|
+
|
444
|
+
def generate_example
|
445
|
+
signatures = sections.each_with_object("") do |s, res|
|
446
|
+
res << %(<div class="resource-sig">#{s.signature}</div>)
|
447
|
+
end
|
448
|
+
|
449
|
+
<<-HTML
|
450
|
+
<div class="section-response">
|
451
|
+
<div class="response-topbar">#{name} ENDPOINTS</div>
|
452
|
+
<div class="section-endpoints">#{signatures}</div>
|
453
|
+
</div>
|
454
|
+
HTML
|
455
|
+
end
|
290
456
|
end
|
291
457
|
|
292
458
|
class Generator
|
@@ -299,26 +465,37 @@ module RTFDoc
|
|
299
465
|
end
|
300
466
|
|
301
467
|
def run
|
302
|
-
tree = build_content_tree
|
468
|
+
@tree = build_content_tree
|
469
|
+
nodes = build_nodes(config['resources'])
|
303
470
|
|
304
|
-
|
471
|
+
out = File.new("#{Dir.tmpdir}/rtfdoc_output.html", 'w')
|
472
|
+
out.write(Template.new(nodes, config).output)
|
473
|
+
out.close
|
474
|
+
end
|
475
|
+
|
476
|
+
private
|
477
|
+
|
478
|
+
def build_nodes(ary, allow_groups: true)
|
479
|
+
ary.map do |rs|
|
305
480
|
if rs.is_a?(Hash)
|
306
|
-
name,
|
307
|
-
|
308
|
-
|
481
|
+
name, values = rs.each_pair.first
|
482
|
+
|
483
|
+
if name.start_with?('group|')
|
484
|
+
raise 'Nested groups are not yet supported' if !allow_groups
|
485
|
+
|
486
|
+
group_name = values.key?('title') ? values['title'] : name.slice(6..-1)
|
487
|
+
Group.new(group_name, build_nodes(values['resources'], allow_groups: false), values)
|
488
|
+
else
|
489
|
+
paths = @tree[name]
|
490
|
+
Resource.build(name, paths, endpoints: values)
|
491
|
+
end
|
309
492
|
else
|
310
|
-
paths = tree[rs]
|
493
|
+
paths = @tree[rs]
|
311
494
|
paths.is_a?(Hash) ? Resource.build(rs, paths) : Section.new(rs, File.read(paths))
|
312
495
|
end
|
313
496
|
end
|
314
|
-
|
315
|
-
out = File.new("#{Dir.tmpdir}/rtfdoc_output.html", 'w')
|
316
|
-
out.write(Template.new(nodes).output)
|
317
|
-
out.close
|
318
497
|
end
|
319
498
|
|
320
|
-
private
|
321
|
-
|
322
499
|
def build_content_tree
|
323
500
|
tree = {}
|
324
501
|
slicer = (@content_dir.length + 1)..-1
|
data/lib/rtfdoc/cli.rb
CHANGED
@@ -3,6 +3,8 @@ require 'rtfdoc/generators/bootstrap'
|
|
3
3
|
|
4
4
|
module RTFDoc
|
5
5
|
class CLI < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
|
6
8
|
def self.exit_on_failure?
|
7
9
|
true
|
8
10
|
end
|
@@ -14,5 +16,12 @@ module RTFDoc
|
|
14
16
|
def convert
|
15
17
|
::RTFDoc::Generator.new(options[:config]).run
|
16
18
|
end
|
19
|
+
|
20
|
+
source_root(File.expand_path('../../', __dir__))
|
21
|
+
|
22
|
+
desc 'install', 'Copy the latest version of the assets source in your project'
|
23
|
+
def install
|
24
|
+
directory 'src', 'src', exclude_pattern: /\.erb\Z/
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
@@ -25,18 +25,11 @@ module RTFDoc
|
|
25
25
|
|
26
26
|
def create_webpack_config
|
27
27
|
template('package.json.erb', "#{name}/package.json")
|
28
|
-
|
28
|
+
copy_file('webpack.config.js', "#{name}/webpack.config.js")
|
29
29
|
end
|
30
30
|
|
31
31
|
def create_config
|
32
32
|
template('config.yml.erb', "#{name}/config.yml")
|
33
33
|
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def gem_dir
|
38
|
-
File.expand_path('../../../', __dir__)
|
39
|
-
end
|
40
|
-
|
41
34
|
end
|
42
35
|
end
|
@@ -8,13 +8,13 @@ const devMode = process.env.NODE_ENV != 'production'
|
|
8
8
|
|
9
9
|
module.exports = {
|
10
10
|
mode: devMode ? "development" : "production",
|
11
|
-
entry:
|
11
|
+
entry: __dirname + "/src/js/index.js",
|
12
12
|
output: {
|
13
13
|
filename: devMode ? "main.js" : "main.[contenthash].js",
|
14
14
|
path: __dirname + "/dist",
|
15
15
|
},
|
16
16
|
plugins: [
|
17
|
-
new CleanWebpackPlugin(),
|
17
|
+
new CleanWebpackPlugin({ cleanStaleWebpackAssets: !devMode }),
|
18
18
|
new MiniCssExtractPlugin({
|
19
19
|
filename: devMode ? '[name].css' : '[name].[contenthash].css'
|
20
20
|
}),
|
@@ -23,6 +23,9 @@ module.exports = {
|
|
23
23
|
})
|
24
24
|
],
|
25
25
|
devtool: devMode ? "inline-source-map" : "source-map",
|
26
|
+
resolve: {
|
27
|
+
modules: [path.resolve(__dirname, 'node_modules')]
|
28
|
+
},
|
26
29
|
module: {
|
27
30
|
rules: [
|
28
31
|
{
|
data/lib/rtfdoc/version.rb
CHANGED
data/rtfdoc.gemspec
CHANGED
@@ -37,11 +37,11 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.require_paths = ["lib"]
|
38
38
|
|
39
39
|
spec.add_dependency "erubi", "~> 1.9.0"
|
40
|
-
spec.add_dependency "rouge", "~> 3.
|
40
|
+
spec.add_dependency "rouge", "~> 3.22.0"
|
41
41
|
spec.add_dependency "redcarpet", "~> 3.5.0"
|
42
42
|
spec.add_dependency "thor", "~> 1.0.1"
|
43
43
|
|
44
44
|
spec.add_development_dependency "bundler", "~> 1.17"
|
45
|
-
spec.add_development_dependency "rake", "~>
|
45
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
46
46
|
spec.add_development_dependency "minitest", "~> 5.0"
|
47
47
|
end
|
data/src/attributes.erb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
<div class="section-list">
|
2
|
-
<h5 class="section-list-title"><%= @title.capitalize %></h5>
|
3
2
|
<ul>
|
4
3
|
<% @attributes.each do |name, hash| %>
|
5
4
|
<li class="list-item">
|
@@ -11,9 +10,9 @@
|
|
11
10
|
<% end %>
|
12
11
|
</div>
|
13
12
|
<div class="list-item-description">
|
14
|
-
|
13
|
+
<%= to_html(hash['desc']) %>
|
15
14
|
</div>
|
16
|
-
<% if hash
|
15
|
+
<% if hash.key?('children') || hash.key?('after_children') %>
|
17
16
|
<div class="section-list section-list-child">
|
18
17
|
<h5
|
19
18
|
class="section-list-title section-list-title-child"
|
@@ -27,17 +26,24 @@
|
|
27
26
|
<span>Show child attributes</span>
|
28
27
|
</h5>
|
29
28
|
<ul class="child-list hidden">
|
30
|
-
<% hash['children'].each do |child_name, child_hash| %>
|
29
|
+
<% Array(hash['children']).each do |child_name, child_hash| %>
|
31
30
|
<li class="list-item">
|
32
31
|
<div class="list-item-label">
|
33
|
-
<div class="list-item-name"><%=
|
34
|
-
<div class="list-item-type"><%=
|
32
|
+
<div class="list-item-name"><%= child_name %></div>
|
33
|
+
<div class="list-item-type"><%= child_hash['type'] %> </div>
|
35
34
|
</div>
|
36
35
|
<div class="list-item-description">
|
37
|
-
|
36
|
+
<%= to_html(child_hash['desc']) %>
|
38
37
|
</div>
|
39
38
|
</li>
|
40
39
|
<% end %>
|
40
|
+
<% if (str = hash['after_children']) %>
|
41
|
+
<li class="list-item">
|
42
|
+
<div class="list-item-description">
|
43
|
+
<%= to_html(str) %>
|
44
|
+
</div>
|
45
|
+
</li>
|
46
|
+
<% end %>
|
41
47
|
</ul>
|
42
48
|
</div>
|
43
49
|
<% end %>
|
data/src/css/application.scss
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
--content-width: calc(100vw - var(--sidebar-width));
|
18
18
|
--section-padding: 5vw;
|
19
19
|
--example-width: 40vw;
|
20
|
+
--max-example-width: 33vw;
|
20
21
|
--sp20: 20px;
|
21
22
|
--sp24: 24px;
|
22
23
|
--monospace-font: "SFMono-Regular", "Consolas", "Menlo", monospace;
|
@@ -29,14 +30,20 @@
|
|
29
30
|
--endpoints-line-height: 22px;
|
30
31
|
--table-font-size: 14px;
|
31
32
|
--table-line-height: 18px;
|
32
|
-
--code-font-size: 14px;
|
33
|
+
--code-font-size: 14px;
|
34
|
+
--code-block-font-size: 13px;
|
35
|
+
}
|
33
36
|
|
34
37
|
* {
|
35
38
|
box-sizing: border-box;
|
36
|
-
word-wrap: break-word;
|
39
|
+
word-wrap: break-word;
|
40
|
+
-moz-osx-font-smoothing: grayscale;
|
41
|
+
-webkit-font-smoothing: antialiased;
|
42
|
+
}
|
37
43
|
|
38
44
|
html {
|
39
|
-
overflow: auto;
|
45
|
+
overflow: auto;
|
46
|
+
}
|
40
47
|
|
41
48
|
body {
|
42
49
|
margin: 0;
|
@@ -46,7 +53,9 @@ body {
|
|
46
53
|
overflow-y: scroll;
|
47
54
|
max-width: 100%;
|
48
55
|
-moz-osx-font-smoothing: grayscale;
|
49
|
-
|
56
|
+
-webkit-font-smoothing: antialiased;
|
57
|
+
background-color: var(--background-color);
|
58
|
+
}
|
50
59
|
|
51
60
|
body[data-theme="dark"] {
|
52
61
|
--background-color: var(--sail-gray900);
|
@@ -73,13 +82,16 @@ body[data-theme="dark"] {
|
|
73
82
|
--nav-color: var(--sail-gray300);
|
74
83
|
--nav-hover-color: var(--sail-gray50);
|
75
84
|
--nav-header-color: var(--sail-gray50);
|
76
|
-
--brand-color:
|
77
|
-
--switch-background-color: #
|
85
|
+
--brand-color: #4db7e8;
|
86
|
+
--switch-background-color: #3d4eac;
|
78
87
|
--code-strings: #98c379;
|
79
88
|
--code-numbers: #56b6c2;
|
80
89
|
--code-booleans: #d19a66;
|
81
90
|
--child-list-title-color: var(--sail-gray500);
|
82
|
-
--child-list-title-hover-color: var(--sail-gray100);
|
91
|
+
--child-list-title-hover-color: var(--sail-gray100);
|
92
|
+
--scoped-endpoints-title-color: var(--sail-gray50);
|
93
|
+
--link-color: #4db7e8;
|
94
|
+
}
|
83
95
|
|
84
96
|
body[data-theme="light"] {
|
85
97
|
--background-color: #fff;
|
@@ -112,7 +124,20 @@ body[data-theme="light"] {
|
|
112
124
|
--code-numbers: #005cc5;
|
113
125
|
--code--booleans: #e36209;
|
114
126
|
--child-list-title-color: #586069;
|
115
|
-
--child-list-title-hover-color: #24292e;
|
127
|
+
--child-list-title-hover-color: #24292e;
|
128
|
+
--scoped-endpoints-title-color: var(--sail-cyan500);
|
129
|
+
--link-color: var(--sail-cyan500);
|
130
|
+
}
|
131
|
+
|
132
|
+
a, a:visited {
|
133
|
+
color: var(--link-color);
|
134
|
+
text-decoration: none;
|
135
|
+
}
|
136
|
+
|
137
|
+
a:hover {
|
138
|
+
color: var(--nav-hover-color);
|
139
|
+
text-decoration: none;
|
140
|
+
}
|
116
141
|
|
117
142
|
#sidebar {
|
118
143
|
width: var(--sidebar-width);
|
@@ -122,42 +147,89 @@ body[data-theme="light"] {
|
|
122
147
|
left: 0;
|
123
148
|
bottom: 0;
|
124
149
|
z-index: 10;
|
125
|
-
box-shadow: -1px 0 0 0 var(--divider-color) inset;
|
150
|
+
box-shadow: -1px 0 0 0 var(--divider-color) inset;
|
151
|
+
}
|
126
152
|
|
127
153
|
.sidebar-header {
|
128
154
|
color: var(--nav-header-color);
|
129
155
|
padding: 16px;
|
130
156
|
display: flex;
|
131
157
|
flex-direction: row;
|
132
|
-
justify-content: space-between;
|
133
|
-
.sidebar-
|
158
|
+
justify-content: space-between;
|
159
|
+
.sidebar-title {
|
134
160
|
font-size: 15px;
|
135
|
-
line-height: 20px;
|
136
|
-
|
161
|
+
line-height: 20px;
|
162
|
+
}
|
163
|
+
.api {
|
137
164
|
text-transform: uppercase;
|
138
|
-
color: var(--brand-color);
|
165
|
+
color: var(--brand-color);
|
166
|
+
}
|
167
|
+
}
|
139
168
|
|
140
169
|
.sidebar-nav {
|
141
|
-
margin-top: 16px;
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
170
|
+
margin-top: 16px;
|
171
|
+
width: 100%;
|
172
|
+
max-height: 570px;
|
173
|
+
overflow-y: scroll;
|
174
|
+
}
|
175
|
+
|
176
|
+
.sidebar-nav-group {
|
177
|
+
padding-bottom: 12px;
|
178
|
+
|
179
|
+
h5 {
|
180
|
+
text-transform: uppercase;
|
181
|
+
margin: 0;
|
182
|
+
padding: 16px 16px 8px 16px;
|
183
|
+
color: var(--title-color);
|
184
|
+
font-size: 13px;
|
185
|
+
font-weight: 600;
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
.sidebar-nav a {
|
190
|
+
text-decoration: none;
|
191
|
+
color: var(--nav-color);
|
192
|
+
transition: color .2s ease;
|
193
|
+
font-size: var(--nav-font-size);
|
194
|
+
font-weight: 500;
|
195
|
+
display: block;
|
196
|
+
padding: 5px 16px;
|
197
|
+
}
|
198
|
+
|
199
|
+
.sidebar-nav a:hover {
|
200
|
+
color: var(--nav-hover-color);
|
201
|
+
}
|
202
|
+
|
203
|
+
.sidebar-nav a.current span {
|
204
|
+
border-bottom: 2px solid var(--brand-color);
|
205
|
+
}
|
206
|
+
|
207
|
+
.sidebar-nav li > ul {
|
208
|
+
display: none;
|
209
|
+
padding-left: 16px;
|
210
|
+
transition: all 2s ease;
|
211
|
+
}
|
212
|
+
|
213
|
+
.sidebar-nav li.expanded {
|
214
|
+
margin-bottom: 10px;
|
215
|
+
}
|
216
|
+
|
217
|
+
.sidebar-nav li.expanded > ul,
|
218
|
+
.sidebar-nav li.current > ul {
|
219
|
+
display: block;
|
220
|
+
}
|
221
|
+
|
222
|
+
.sidebar-nav li > ul.scoped {
|
223
|
+
display: block;
|
224
|
+
}
|
225
|
+
|
226
|
+
.sidebar-nav .scope-title {
|
227
|
+
font-size: 13px;
|
228
|
+
color: var(--scoped-endpoints-title-color);
|
229
|
+
text-transform: uppercase;
|
230
|
+
font-weight: 400;
|
231
|
+
padding: 8px 0 3px 16px;
|
232
|
+
}
|
161
233
|
|
162
234
|
/*Simple css to style it like a toggle switch*/
|
163
235
|
.theme-switch-wrapper {
|
@@ -289,18 +361,21 @@ section > section .section-divider {
|
|
289
361
|
.section-body {
|
290
362
|
flex-shrink: 0;
|
291
363
|
width: calc(var(--example-width) - var(--section-padding));
|
292
|
-
margin-right: var(--section-padding);
|
364
|
+
margin-right: var(--section-padding);
|
365
|
+
|
366
|
+
a { font-weight: 500; }
|
367
|
+
}
|
293
368
|
|
294
369
|
.section-example {
|
295
370
|
position: sticky;
|
296
371
|
align-self: flex-start;
|
297
372
|
top: 0;
|
298
373
|
flex-grow: 1;
|
299
|
-
max-width:
|
374
|
+
max-width: var(--max-example-width);
|
300
375
|
padding-top: calc(40px + var(--sp20)); }
|
301
376
|
|
302
377
|
p {
|
303
|
-
margin-top:
|
378
|
+
margin-top: 16px;
|
304
379
|
font-size: var(--main-font-size);
|
305
380
|
line-height: var(--main-line-height);
|
306
381
|
font-weight: 400;
|
@@ -330,75 +405,103 @@ ul {
|
|
330
405
|
.section-response {
|
331
406
|
background: var(--response-background-color);
|
332
407
|
border-radius: 8px;
|
333
|
-
box-shadow: 0 0 0 1px var(--response-shadow-color);
|
334
|
-
|
408
|
+
box-shadow: 0 0 0 1px var(--response-shadow-color);
|
409
|
+
max-height: 83vh;
|
410
|
+
overflow: hidden;
|
411
|
+
margin-bottom: 24px;
|
412
|
+
|
413
|
+
&:last-child { margin-bottom: 0 }
|
414
|
+
|
415
|
+
.response-topbar {
|
335
416
|
background: var(--block-header-background-color);
|
336
417
|
padding: 10px 12px;
|
337
418
|
font-weight: 500;
|
338
419
|
font-size: 12px;
|
339
420
|
color: var(--response-header-color);
|
340
|
-
border-radius: 8px 8px 0 0;
|
341
|
-
|
421
|
+
border-radius: 8px 8px 0 0;
|
422
|
+
text-transform: uppercase;
|
423
|
+
|
424
|
+
.endpoint-def { overflow-y: auto; }
|
425
|
+
}
|
426
|
+
|
427
|
+
p {
|
342
428
|
margin: 0;
|
343
|
-
padding: 12px var(--sp20);
|
344
|
-
|
429
|
+
padding: 12px var(--sp20);
|
430
|
+
}
|
431
|
+
|
432
|
+
pre {
|
345
433
|
margin: 0;
|
346
434
|
padding: 12px;
|
347
435
|
color: var(--code-color);
|
348
436
|
font-family: var(--monospace-font);
|
349
437
|
font-size: var(--code-font-size);
|
350
438
|
font-weight: 400;
|
351
|
-
line-height: 18px;
|
439
|
+
line-height: 18px;
|
440
|
+
max-height: 75vh;
|
441
|
+
overflow: auto;
|
442
|
+
}
|
443
|
+
}
|
352
444
|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
445
|
+
|
446
|
+
|
447
|
+
.endpoint-def {
|
448
|
+
display: flex;
|
449
|
+
flex-direction: row;
|
450
|
+
font-family: var(--monospace-font);
|
451
|
+
font-size: var(--code-font-size);
|
452
|
+
font-weight: 500;
|
453
|
+
line-height: 22px;
|
454
|
+
color: var(--endpoints-def-color);
|
455
|
+
|
456
|
+
.method {
|
364
457
|
text-align: right;
|
458
|
+
margin-right: 7px;
|
459
|
+
text-transform: uppercase;
|
460
|
+
}
|
461
|
+
|
462
|
+
.path { text-transform: none }
|
463
|
+
|
464
|
+
.method__get { color: var(--sail-blue400); }
|
465
|
+
.method__post { color: #50b573; }
|
466
|
+
.method__patch,
|
467
|
+
.method__put {
|
468
|
+
color: #50b573;
|
469
|
+
}
|
470
|
+
.method__delete { color: var(--redish); }
|
471
|
+
}
|
472
|
+
|
473
|
+
.section-endpoints {
|
474
|
+
padding: 12px 22px;
|
475
|
+
overflow-y: auto;
|
476
|
+
|
477
|
+
a { text-decoration: none; }
|
478
|
+
a:hover .method {
|
479
|
+
filter: brightness(calc(100% + var(--filter-ratio)));
|
480
|
+
}
|
481
|
+
a:hover .path {
|
482
|
+
color: var(--endpoints-def-hover-color);
|
483
|
+
}
|
484
|
+
|
485
|
+
.resource-sig .method {
|
365
486
|
width: 55px;
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
.section-endpoints .method__post {
|
370
|
-
color: #50b573; }
|
371
|
-
.section-endpoints .method__patch,
|
372
|
-
.section-endpoints .method__put {
|
373
|
-
color: #50b573; }
|
374
|
-
.section-endpoints .method__delete {
|
375
|
-
color: var(--redish); }
|
376
|
-
.section-endpoints a {
|
377
|
-
text-decoration: none; }
|
378
|
-
.section-endpoints a:hover .method {
|
379
|
-
filter: brightness(calc(100% + var(--filter-ratio))); }
|
380
|
-
.section-endpoints a:hover .path {
|
381
|
-
color: var(--endpoints-def-hover-color); }
|
487
|
+
min-width: 55px;
|
488
|
+
}
|
489
|
+
}
|
382
490
|
|
383
|
-
h3 {
|
384
|
-
margin-top: 20px;
|
385
|
-
padding-top: 16px; }
|
386
491
|
|
387
|
-
h3
|
388
|
-
.section-list .section-list-title {
|
492
|
+
h3 {
|
389
493
|
font-size: 16px;
|
390
494
|
font-weight: 500;
|
391
|
-
padding
|
495
|
+
padding: 24px 0 10px;
|
392
496
|
border-bottom: 1px solid var(--divider-color);
|
393
497
|
display: flex;
|
394
498
|
align-items: baseline;
|
395
499
|
color: var(--title-color);
|
396
500
|
margin: 0;
|
397
|
-
margin-top:
|
398
|
-
width: 100%;
|
501
|
+
margin-top: 16px;
|
502
|
+
width: 100%;
|
503
|
+
}
|
399
504
|
|
400
|
-
.section-list {
|
401
|
-
margin-top: 32px; }
|
402
505
|
.section-list .list-item {
|
403
506
|
padding-top: 16px;
|
404
507
|
padding-bottom: 15px;
|
@@ -453,7 +556,9 @@ h3,
|
|
453
556
|
cursor: pointer;
|
454
557
|
color: var(--child-list-title-hover-color); }
|
455
558
|
.section-list .section-list-title-child.child-revealed {
|
456
|
-
border-bottom: 1px solid var(--divider-color);
|
559
|
+
border-bottom: 1px solid var(--divider-color);
|
560
|
+
width: 100%;
|
561
|
+
}
|
457
562
|
.section-list .section-list-title-child.child-revealed .svg-plus {
|
458
563
|
transform: rotate(45deg); }
|
459
564
|
.section-list .section-list-title-child .svg-plus {
|
@@ -509,12 +614,17 @@ p code {
|
|
509
614
|
border: 1px solid var(--inline-code-border);
|
510
615
|
padding: 2px 3px 0;
|
511
616
|
margin: 0 1px;
|
512
|
-
font-size:
|
617
|
+
font-size: .9em;
|
513
618
|
font-family: var(--monospace-font);
|
514
619
|
font-weight: 500;
|
515
620
|
background: var(--inline-code-background); }
|
516
621
|
|
517
622
|
/** Code highlighting **/
|
623
|
+
pre code {
|
624
|
+
font-family: var(--monospace-font);
|
625
|
+
font-size: var(--code-block-font-size);
|
626
|
+
}
|
627
|
+
|
518
628
|
pre code,
|
519
629
|
pre code .w {
|
520
630
|
color: var(--code-color); }
|
data/src/index.html.erb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
<head>
|
5
5
|
<meta charset="utf-8">
|
6
|
-
<title
|
6
|
+
<title><%= page_title %></title>
|
7
7
|
<meta name="description" content="">
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
9
9
|
</head>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<div id="sidebar" class="sidebar">
|
12
12
|
<div class="sidebar-header">
|
13
13
|
<div class="sidebar-title">
|
14
|
-
|
14
|
+
<%= app_name %> <span class="api">api</span>
|
15
15
|
</div>
|
16
16
|
<div class="theme-switch-wrapper">
|
17
17
|
<div class="theme-switch">
|
@@ -23,7 +23,7 @@
|
|
23
23
|
</div>
|
24
24
|
</div>
|
25
25
|
<nav class="sidebar-nav" role="navigation">
|
26
|
-
|
26
|
+
<%= @menu_content %>
|
27
27
|
</nav>
|
28
28
|
</div>
|
29
29
|
<div id="content" class="content-area">
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtfdoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ccocchi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubi
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
33
|
+
version: 3.22.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: 3.22.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: redcarpet
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '13.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '13.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: minitest
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,7 +132,7 @@ files:
|
|
132
132
|
- lib/rtfdoc/templates/config.yml.erb
|
133
133
|
- lib/rtfdoc/templates/gitignore
|
134
134
|
- lib/rtfdoc/templates/package.json.erb
|
135
|
-
- lib/rtfdoc/templates/webpack.config.js
|
135
|
+
- lib/rtfdoc/templates/webpack.config.js
|
136
136
|
- lib/rtfdoc/version.rb
|
137
137
|
- rtfdoc.gemspec
|
138
138
|
- src/attributes.erb
|