rspec-documentation 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +15 -10
  5. data/README.md +1 -1
  6. data/exe/rspec-documentation +15 -0
  7. data/lib/rspec/documentation/version.rb +1 -1
  8. data/lib/rspec_documentation/configuration.rb +7 -0
  9. data/lib/rspec_documentation/document.rb +8 -1
  10. data/lib/rspec_documentation/documentation.rb +5 -6
  11. data/lib/rspec_documentation/formatters/html.rb +3 -1
  12. data/lib/rspec_documentation/kramdown_html_converter.rb +13 -0
  13. data/lib/rspec_documentation/page_collection.rb +3 -0
  14. data/lib/rspec_documentation/page_tree.rb +7 -3
  15. data/lib/rspec_documentation/page_tree_element.rb +1 -1
  16. data/lib/rspec_documentation/parsed_document.rb +38 -4
  17. data/lib/rspec_documentation/project_initialization.rb +8 -0
  18. data/lib/rspec_documentation/rspec/failure.rb +3 -3
  19. data/lib/rspec_documentation/util.rb +12 -2
  20. data/lib/templates/layout.css.erb +109 -5
  21. data/lib/templates/layout.html.erb +13 -4
  22. data/lib/templates/layout.js.erb +86 -4
  23. data/lib/templates/link.svg.erb +1 -0
  24. data/lib/templates/modal_spec.html.erb +5 -5
  25. data/lib/templates/spec_helper.rb.erb +25 -0
  26. data/lib/templates/tabbed_spec.html.erb +4 -4
  27. data/rspec-documentation/pages/001-Quickstart.md +9 -1
  28. data/rspec-documentation/pages/020-Running Tests.md +6 -21
  29. data/rspec-documentation/pages/030-Examples/012-Regular it Blocks.md +7 -7
  30. data/rspec-documentation/pages/030-Examples/020-HTML.md +14 -14
  31. data/rspec-documentation/pages/030-Examples/030-ANSI.md +3 -3
  32. data/rspec-documentation/pages/030-Examples/040-JSON.md +4 -4
  33. data/rspec-documentation/pages/030-Examples/050-YAML.md +4 -4
  34. data/rspec-documentation/pages/030-Examples/060-XML.md +4 -4
  35. data/rspec-documentation/pages/060-Configuration/Consistent Height.md +16 -0
  36. data/rspec-documentation/pages/060-Configuration/Index Search.md +13 -0
  37. data/rspec-documentation/pages/060-Configuration/Table of Contents.md +35 -0
  38. data/rspec-documentation/pages/080-Rubocop.md +36 -0
  39. data/rspec-documentation/spec_helper.rb +1 -0
  40. metadata +12 -6
  41. /data/rspec-documentation/pages/060-Configuration/{030-Attribution.md → Attribution.md} +0 -0
  42. /data/rspec-documentation/pages/060-Configuration/{020-Build Paths.md → Build Paths.md} +0 -0
  43. /data/rspec-documentation/pages/060-Configuration/{010-Context.md → Context.md} +0 -0
  44. /data/rspec-documentation/pages/060-Configuration/{040-Hooks.md → Hooks.md} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6eb4258635900a3617ddf6ab4cdfb7fe1d1cba62fbd8231f11437cf9b9734c6b
4
- data.tar.gz: f5db6165cfd08d759765d4e50a0398bfdb0ab99dee84567fd535bd97cd30f0a4
3
+ metadata.gz: 8ce43727fba18b77d655b8ba4dc96b66b730823d4c44603a17d3033f70092daa
4
+ data.tar.gz: a53de33b4779cca033dfaa87eea7e60f473af09db986117c9a3d98cd9417d874
5
5
  SHA512:
6
- metadata.gz: e25685a33fb2cc2bace75aa20c72f2b33407f2edec5a14840163cced2662fd852d3c87f8e4b31741b15825311365348f22cf5754b1850ddec1196bba64181a02
7
- data.tar.gz: 3678422ca81bc09c5cd68db061b6a81746d21fb848824e229369721e727ac01f4fa4e517263ef9d47b8f1457f336d7dd6a0fdea0ee6ed63e498d62995f7c4102
6
+ metadata.gz: 7e44facb6a2ece7170e6111ced783f9e4a48780f478afbd257c6f30552816f6fcb22ab6733914f26c68168a71331f77c777f770e0e343c0301ad2be23855602e
7
+ data.tar.gz: ac708a5ee5336cb2c2aa9282704a94bb0d6d1f8120293af0cbc84e63d3914d88de25fdff7b942a1759f8f7a8d17e8252398ed3ba06d771c77023fa206bb42bc1
data/.rubocop.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  require:
2
+ - 'rubocop-rspec-documentation'
2
3
  - 'rubocop-rake'
3
4
  - 'rubocop-rspec'
4
5
 
data/Gemfile CHANGED
@@ -15,4 +15,5 @@ gem 'rspec-its', '~> 1.3'
15
15
  gem 'rubocop', '~> 1.52'
16
16
  gem 'rubocop-rake', '~> 0.6.0'
17
17
  gem 'rubocop-rspec', '~> 2.22'
18
+ gem 'rubocop-rspec-documentation', require: false
18
19
  gem 'strong_versions', '~> 0.4.5'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-documentation (0.0.6)
4
+ rspec-documentation (0.0.8)
5
5
  htmlbeautifier (~> 1.4)
6
6
  kramdown (~> 2.4)
7
7
  kramdown-parser-gfm (~> 1.1)
@@ -19,7 +19,7 @@ GEM
19
19
  devpack (0.4.1)
20
20
  diff-lcs (1.5.0)
21
21
  htmlbeautifier (1.4.2)
22
- i18n (1.13.0)
22
+ i18n (1.14.1)
23
23
  concurrent-ruby (~> 1.0)
24
24
  json (2.6.3)
25
25
  kramdown (2.4.0)
@@ -31,15 +31,16 @@ GEM
31
31
  paint (2.3.0)
32
32
  paintbrush (0.1.3)
33
33
  parallel (1.23.0)
34
- parser (3.2.2.1)
34
+ parser (3.2.2.3)
35
35
  ast (~> 2.4.1)
36
- racc (1.6.2)
36
+ racc
37
+ racc (1.7.0)
37
38
  rainbow (3.1.1)
38
39
  rake (13.0.6)
39
40
  redcarpet (3.6.0)
40
- regexp_parser (2.8.0)
41
+ regexp_parser (2.8.1)
41
42
  rexml (3.2.5)
42
- rouge (4.1.1)
43
+ rouge (4.1.2)
43
44
  rspec (3.12.0)
44
45
  rspec-core (~> 3.12.0)
45
46
  rspec-expectations (~> 3.12.0)
@@ -49,8 +50,8 @@ GEM
49
50
  rspec-expectations (3.12.3)
50
51
  diff-lcs (>= 1.2.0, < 2.0)
51
52
  rspec-support (~> 3.12.0)
52
- rspec-file_fixtures (0.1.6)
53
- rspec (~> 3.0)
53
+ rspec-file_fixtures (0.1.7)
54
+ rspec (~> 3.12)
54
55
  rspec-its (1.3.0)
55
56
  rspec-core (>= 3.0.0)
56
57
  rspec-expectations (>= 3.0.0)
@@ -58,10 +59,10 @@ GEM
58
59
  diff-lcs (>= 1.2.0, < 2.0)
59
60
  rspec-support (~> 3.12.0)
60
61
  rspec-support (3.12.0)
61
- rubocop (1.52.0)
62
+ rubocop (1.52.1)
62
63
  json (~> 2.3)
63
64
  parallel (~> 1.10)
64
- parser (>= 3.2.0.0)
65
+ parser (>= 3.2.2.3)
65
66
  rainbow (>= 2.2.2, < 4.0)
66
67
  regexp_parser (>= 1.8, < 3.0)
67
68
  rexml (>= 3.2.5, < 4.0)
@@ -80,6 +81,9 @@ GEM
80
81
  rubocop (~> 1.33)
81
82
  rubocop-capybara (~> 2.17)
82
83
  rubocop-factory_bot (~> 2.22)
84
+ rubocop-rspec-documentation (0.0.1)
85
+ rspec-documentation (~> 0.0.7)
86
+ rubocop (~> 1.52)
83
87
  ruby-progressbar (1.13.0)
84
88
  strong_versions (0.4.5)
85
89
  i18n (>= 0.5)
@@ -100,6 +104,7 @@ DEPENDENCIES
100
104
  rubocop (~> 1.52)
101
105
  rubocop-rake (~> 0.6.0)
102
106
  rubocop-rspec (~> 2.22)
107
+ rubocop-rspec-documentation
103
108
  strong_versions (~> 0.4.5)
104
109
 
105
110
  BUNDLED WITH
data/README.md CHANGED
@@ -13,7 +13,7 @@ There is no _DSL_ to learn and vanilla _RSpec_ examples are used to generate inp
13
13
 
14
14
  The following is an example _Markdown_ file.
15
15
 
16
- ````console
16
+ ````markdown
17
17
  # An example test
18
18
 
19
19
  This is a very simple test:
@@ -3,6 +3,21 @@
3
3
 
4
4
  require_relative '../lib/rspec/documentation'
5
5
 
6
+ require 'optparse'
7
+
8
+ options = {}
9
+
10
+ OptionParser.new do |opts|
11
+ opts.banner = 'Usage: rspec-documentation [options]'
12
+ opts.on('-F', '--fail-fast', 'Abort the run after the first failure.') { |val| options[:fail_fast] = val if val }
13
+ opts.on('-b', '--backtrace', 'Enable full backtrace.') { |val| options[:full_backtrace] = val if val }
14
+ end.parse!
15
+
16
+ RSpec::Documentation.configure do |config|
17
+ config.fail_fast = options[:fail_fast] if options.key?(:fail_fast)
18
+ config.full_backtrace = options[:full_backtrace] if options.key?(:full_backtrace)
19
+ end
20
+
6
21
  documentation = RSpec::Documentation.generate_documentation
7
22
 
8
23
  exit 1 if documentation.failed?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Documentation
5
- VERSION = '0.0.6'
5
+ VERSION = '0.0.8'
6
6
  end
7
7
  end
@@ -4,9 +4,16 @@ module RSpecDocumentation
4
4
  # Configures the rspec-documentation gem, allows setting a context that makes values available to each example.
5
5
  class Configuration
6
6
  attr_reader :hooks
7
+ attr_accessor :consistent_height, :max_height, :fail_fast, :full_backtrace, :table_of_contents, :index_search
7
8
 
8
9
  def initialize
9
10
  @context_defined = false
11
+ @consistent_height = false
12
+ @max_height = '30rem'
13
+ @fail_fast = false
14
+ @full_backtrace = false
15
+ @table_of_contents = true
16
+ @index_search = true
10
17
  @hooks = {}
11
18
  end
12
19
 
@@ -18,6 +18,7 @@ module RSpecDocumentation
18
18
 
19
19
  def render
20
20
  parsed_document.execute_and_substitute_examples!
21
+
21
22
  if parsed_document.failures.empty?
22
23
  RSpecDocumentation.template('layout').result(binding)
23
24
  else
@@ -63,11 +64,17 @@ module RSpecDocumentation
63
64
  attr_reader :document, :path
64
65
 
65
66
  def parsed_document
66
- @parsed_document ||= ParsedDocument.new(document, path: path)
67
+ @parsed_document ||= ParsedDocument.new(with_table_of_contents(document), path: path)
67
68
  end
68
69
 
69
70
  def gem_spec
70
71
  @gem_spec ||= Gem::Specification.load(Pathname.new(Dir.pwd).glob('*.gemspec').first.to_s)
71
72
  end
73
+
74
+ def with_table_of_contents(markdown)
75
+ return markdown unless RSpecDocumentation.configuration.table_of_contents
76
+
77
+ ['* TOC', '{:toc}', markdown].join("\n")
78
+ end
72
79
  end
73
80
  end
@@ -22,11 +22,14 @@ module RSpecDocumentation
22
22
  @failed || !page_collection.failures.empty?
23
23
  end
24
24
 
25
+ def page_collection
26
+ @page_collection ||= RSpecDocumentation::PageCollection.new(page_paths: page_paths)
27
+ end
28
+
25
29
  private
26
30
 
27
31
  def require_spec_helper
28
- path = pwd.join('rspec-documentation/spec_helper.rb')
29
- require path if path.file?
32
+ require Util.spec_helper_path if Util.spec_helper_path.file?
30
33
  end
31
34
 
32
35
  # Ensure `__rspec_documentation` shared context is always defined.
@@ -74,10 +77,6 @@ module RSpecDocumentation
74
77
  @page_paths ||= pwd.join('rspec-documentation/pages').glob('**/*.md')
75
78
  end
76
79
 
77
- def page_collection
78
- @page_collection ||= RSpecDocumentation::PageCollection.new(page_paths: page_paths)
79
- end
80
-
81
80
  def pwd
82
81
  @pwd ||= Pathname.new(Dir.pwd)
83
82
  end
@@ -5,6 +5,8 @@ module RSpecDocumentation
5
5
  # Beautifies HTML received from a `subject`, renders the raw subject to be inserted directly
6
6
  # into the output document.
7
7
  class Html
8
+ DOCTYPE_TAG = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" ' \
9
+ '"http://www.w3.org/TR/REC-html40/loose.dtd">'
8
10
  def initialize(subject:)
9
11
  @subject = subject
10
12
  end
@@ -16,7 +18,7 @@ module RSpecDocumentation
16
18
  end
17
19
 
18
20
  def rendered_output
19
- subject
21
+ subject&.to_s&.sub(DOCTYPE_TAG, '')
20
22
  end
21
23
 
22
24
  def render_raw?
@@ -9,6 +9,19 @@ module Kramdown
9
9
  element.attr['class'] ||= 'rspec-documentation-table table'
10
10
  super
11
11
  end
12
+
13
+ def convert_header(element, indent)
14
+ [
15
+ '<div class="heading">',
16
+ super,
17
+ "<a class='heading-anchor' href='##{element.attr['id']}'>#{link_icon}</a>",
18
+ '</div>'
19
+ ].join
20
+ end
21
+
22
+ def link_icon
23
+ @link_icon ||= RSpecDocumentation.template(:link, :svg).result
24
+ end
12
25
  end
13
26
  end
14
27
  end
@@ -6,6 +6,8 @@ module RSpecDocumentation
6
6
  class PageCollection
7
7
  attr_reader :failures, :page_paths
8
8
 
9
+ include Paintbrush
10
+
9
11
  def initialize(page_paths:)
10
12
  @page_paths = page_paths.sort_by(&:to_s)
11
13
  @buffer = {}
@@ -16,6 +18,7 @@ module RSpecDocumentation
16
18
  page_paths.zip(documents).each do |path, document|
17
19
  buffer[bundle_path_for(path)] = document.render
18
20
  failures.concat(document.failures)
21
+ break if RSpecDocumentation.configuration.fail_fast && !failures.empty?
19
22
  end
20
23
  end
21
24
 
@@ -48,15 +48,15 @@ module RSpecDocumentation
48
48
  nodes.last == '<ol>' ? nodes.pop : nodes.push('</ol>')
49
49
  end
50
50
 
51
- def build_tree(branch: structure, depth: 0)
52
- normalized_paths.each do |path|
51
+ def build_tree(paths: normalized_paths, branch: structure, depth: 0)
52
+ paths.each do |path|
53
53
  first, second, *rest = path_segments(path: path, depth: depth)
54
54
  next if second.nil?
55
55
 
56
56
  branch[first] ||= {}
57
57
  branch[first][:children] ||= Set.new
58
58
  branch[first][:children].add(second)
59
- build_tree(branch: branch[first], depth: depth + 1)
59
+ build_tree(paths: filtered_paths(path), branch: branch[first], depth: depth + 1)
60
60
  end
61
61
  end
62
62
 
@@ -74,6 +74,10 @@ module RSpecDocumentation
74
74
  end
75
75
  end
76
76
 
77
+ def filtered_paths(path)
78
+ normalized_paths.select { |normalized_path| normalized_path.to_s.start_with?(path.sub_ext('').to_s) }
79
+ end
80
+
77
81
  def page_tree_node(path:, child:)
78
82
  PageTreeElement.new(path: path, child: child, current_path: current_path).node
79
83
  end
@@ -44,7 +44,7 @@ module RSpecDocumentation
44
44
 
45
45
  def li_open
46
46
  "<li id='#{Util.path_id(path.join(child))}' #{active_class} data-list-item-id='##{path_id}' " \
47
- "data-parent-id='##{parent_path_id}'>"
47
+ "data-search-tokens='#{Util.tokens(child).to_json}' data-parent-id='##{parent_path_id}'>"
48
48
  end
49
49
 
50
50
  def link
@@ -5,8 +5,16 @@ module RSpecDocumentation
5
5
  class ParsedDocument
6
6
  attr_reader :failures
7
7
 
8
+ include Paintbrush
9
+
8
10
  def initialize(document, path:)
9
- @document = Kramdown::Document.new(document, input: 'GFM', syntax_highlighter: 'rouge')
11
+ @document = Kramdown::Document.new(
12
+ document,
13
+ toc_levels: 2...6,
14
+ input: 'GFM',
15
+ syntax_highlighter: 'rouge',
16
+ auto_ids: true
17
+ )
10
18
  @path = path
11
19
  @failures = []
12
20
  end
@@ -16,11 +24,11 @@ module RSpecDocumentation
16
24
  end
17
25
 
18
26
  def execute_and_substitute_examples!
27
+ print_empty if specs.empty?
19
28
  specs.each do |spec|
20
29
  spec.run
21
- break failures << spec.failure unless spec.failure.nil?
22
-
23
- spec.parent.children[spec.index] = spec_element(spec)
30
+ process_outcome(spec)
31
+ break if RSpecDocumentation.configuration.fail_fast && !failures.empty?
24
32
  end
25
33
  end
26
34
 
@@ -65,8 +73,34 @@ module RSpecDocumentation
65
73
  end
66
74
  end
67
75
 
76
+ def process_outcome(spec)
77
+ if spec.failure.nil?
78
+ print_success(spec)
79
+ spec.parent.children[spec.index] = spec_element(spec)
80
+ else
81
+ print_failure(spec)
82
+ failures << spec.failure
83
+ end
84
+ end
85
+
86
+ def relative_path
87
+ path.relative_path_from(Util.base_dir)
88
+ end
89
+
68
90
  def report_error(spec)
69
91
  $stderr.write(spec.failure.message)
70
92
  end
93
+
94
+ def print_empty
95
+ warn(paintbrush { cyan " #{relative_path}" })
96
+ end
97
+
98
+ def print_success(spec)
99
+ warn(paintbrush { green " #{relative_path}:#{spec.location}" })
100
+ end
101
+
102
+ def print_failure(spec)
103
+ warn(paintbrush { red " #{relative_path}:#{spec.location}" })
104
+ end
71
105
  end
72
106
  end
@@ -9,6 +9,7 @@ module RSpecDocumentation
9
9
  print_welcome
10
10
  create_base_dir
11
11
  create_sample_files
12
+ create_spec_helper
12
13
  print_initialization_complete
13
14
  end
14
15
 
@@ -31,6 +32,13 @@ module RSpecDocumentation
31
32
  end
32
33
  end
33
34
 
35
+ def create_spec_helper
36
+ return if Util.spec_helper_path.exist?
37
+
38
+ Util.spec_helper_path.write(RSpecDocumentation.template(:spec_helper, :rb).result)
39
+ print_created(Util.spec_helper_path)
40
+ end
41
+
34
42
  def print_created(path)
35
43
  warn(paintbrush { " #{green_b 'create'} #{cyan path.relative_path_from(pwd)}" })
36
44
  end
@@ -39,9 +39,9 @@ module RSpecDocumentation
39
39
 
40
40
  def formatted_backtrace
41
41
  cause.backtrace
42
- .take_while { |line| line.start_with?(Dir.pwd) }
43
- .map { |line| paintbrush { red " #{line.sub("#{Dir.pwd}/", '')}" } }
44
- .join("\n")
42
+ &.take_while { |line| RSpecDocumentation.configuration.full_backtrace || line.start_with?(Dir.pwd) }
43
+ &.map { |line| paintbrush { red " #{line.sub("#{Dir.pwd}/", '')}" } }
44
+ &.join("\n")
45
45
  end
46
46
 
47
47
  def indented(text)
@@ -14,6 +14,10 @@ module RSpecDocumentation
14
14
  bundle_dir.join('index.html')
15
15
  end
16
16
 
17
+ def self.spec_helper_path
18
+ root_dir.join('rspec-documentation/spec_helper.rb')
19
+ end
20
+
17
21
  def self.base_dir
18
22
  root_dir.join('rspec-documentation', 'pages')
19
23
  end
@@ -29,7 +33,11 @@ module RSpecDocumentation
29
33
  end
30
34
 
31
35
  def self.label(path)
32
- Pathname.new(path).basename.sub_ext('').sub(ORDERING_PREFIX_REGEXP, '')
36
+ Pathname.new(path).basename.sub_ext('').sub(ORDERING_PREFIX_REGEXP, '').to_s
37
+ end
38
+
39
+ def self.tokens(path)
40
+ label(path).downcase.split
33
41
  end
34
42
 
35
43
  def self.path_id(path)
@@ -52,7 +60,9 @@ module RSpecDocumentation
52
60
  end
53
61
 
54
62
  def self.normalized_filename(path)
55
- path.to_s.gsub(' ', '-').downcase.sub(ORDERING_PREFIX_REGEXP, '')
63
+ path.split.map do |segment|
64
+ segment.to_s.gsub(' ', '-').downcase.sub(ORDERING_PREFIX_REGEXP, '')
65
+ end.join('/')
56
66
  end
57
67
  end
58
68
  end
@@ -7,6 +7,7 @@
7
7
  MonokaiSublime, Pastie, ThankfulEyes, Tulip */
8
8
  <%= Rouge::Theme.find('molokai').render(scope: '.highlight') %>
9
9
 
10
+ <% if RSpecDocumentation.configuration.consistent_height %>
10
11
  /* https://stackoverflow.com/a/61587938 */
11
12
  .consistent-height .tab-content {
12
13
  display: flex;
@@ -22,6 +23,7 @@
22
23
  .consistent-height .tab-content > .active {
23
24
  visibility: visible;
24
25
  }
26
+ <% end %>
25
27
 
26
28
  @keyframes fade-in {
27
29
  from {
@@ -33,6 +35,35 @@
33
35
  }
34
36
  }
35
37
 
38
+ [data-bs-theme="dark"] .table-of-contents-wrapper {
39
+ border-color: #444242;
40
+ background-color: #4e4e4e55;
41
+ }
42
+
43
+ [data-bs-theme="dark"] .table-of-contents-wrapper .title {
44
+ border-color: #444242;
45
+ }
46
+
47
+ [data-bs-theme="dark"] table.rspec-documentation-table td, [data-bs-theme="dark"] table.rspec-documentation-table th {
48
+ border: 1px solid #4e4e4e;
49
+ }
50
+
51
+ [data-bs-theme="dark"] table.rspec-documentation-table tr:hover td {
52
+ background-color: #325d8833;
53
+ }
54
+
55
+ [data-bs-theme="dark"] .header-wrapper {
56
+ background-color: #212121;
57
+ }
58
+
59
+ [data-bs-theme="dark"] .form-control {
60
+ color: #b2b2b2;
61
+ }
62
+
63
+ [data-bs-theme="dark"] input.form-control::placeholder {
64
+ color: #999;
65
+ }
66
+
36
67
  body {
37
68
  opacity: 0;
38
69
  animation: fade-in ease-in 1;
@@ -43,6 +74,11 @@ body {
43
74
 
44
75
  .header-wrapper {
45
76
  background-color: #fff;
77
+ z-index: 100000;
78
+ }
79
+
80
+ table.rspec-documentation-table tr:hover td {
81
+ background-color: #8a8d9124;
46
82
  }
47
83
 
48
84
  table.rspec-documentation-table td, table.rspec-documentation-table th {
@@ -50,12 +86,68 @@ table.rspec-documentation-table td, table.rspec-documentation-table th {
50
86
  padding: 0.5rem 1rem;
51
87
  }
52
88
 
53
- [data-bs-theme="dark"] table.rspec-documentation-table td, [data-bs-theme="dark"] table.rspec-documentation-table th {
54
- border: 1px solid #4e4e4e;
89
+ .index-search {
90
+ margin-bottom: 1rem;
55
91
  }
56
92
 
57
- [data-bs-theme="dark"] .header-wrapper {
58
- background-color: #212121;
93
+ .page-tree li.search-active {
94
+ list-style: circle;
95
+ list-style-color: green;
96
+ }
97
+
98
+ .table-of-contents-wrapper {
99
+ position: relative;
100
+ padding: 0.4rem 0.8rem;
101
+ background-color: #c7c7c729;
102
+ display: inline-block;
103
+ float: right;
104
+ margin-left: 1rem;
105
+ margin-bottom: 0.4rem;
106
+ border-style: solid;
107
+ border-width: 1px;
108
+ border-radius: 10px;
109
+ border-color: #cfcfcf;
110
+ }
111
+
112
+ .table-of-contents-wrapper .title {
113
+ text-align: center;
114
+ border-bottom: 1px solid #cfcfcf;
115
+ margin-bottom: 0.2rem;
116
+ padding-bottom: 0.2rem;
117
+ font-weight: bold;
118
+ }
119
+
120
+ #markdown-toc {
121
+ list-style: disc;
122
+ line-height: 1.8rem;
123
+ padding: 0;
124
+ margin-bottom: 0;
125
+ padding-left: 1rem;
126
+ }
127
+
128
+ #markdown-toc ul {
129
+ padding-left: 1rem;
130
+ }
131
+
132
+ .heading-anchor {
133
+ padding: 0.2rem;
134
+ vertical-align: middle;
135
+ display: inline-block;
136
+ padding-bottom: 0.4rem;
137
+ scroll-padding-top: 5rem;
138
+ }
139
+
140
+ .heading-anchor svg {
141
+ width: 1rem;
142
+ height: 1rem;
143
+ }
144
+
145
+ .heading-anchor svg path {
146
+ fill: #7ac0f8;
147
+ }
148
+
149
+ #markdown-toc li a {
150
+ text-decoration: none;
59
151
  }
60
152
 
61
153
  .theme-switcher {
@@ -86,9 +178,21 @@ h1.title a {
86
178
  text-decoration: none;
87
179
  }
88
180
 
181
+ .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 {
182
+ display: inline-block;
183
+ scroll-margin-top: 6rem;
184
+ }
185
+
186
+ .heading-anchor {
187
+ font-size: 0.8rem;
188
+ text-decoration: none;
189
+ color: rgb(122,192,248);
190
+ }
191
+
89
192
  .code {
90
193
  font-family: monospace;
91
- max-height: 30rem;
194
+ font-size: 0.9rem;
195
+ max-height: <%= RSpecDocumentation.configuration.max_height %>;
92
196
  overflow-y: auto;
93
197
  }
94
198
 
@@ -1,6 +1,7 @@
1
1
  <html>
2
2
  <head>
3
3
  <meta charset="utf-8" />
4
+ <title><%= title %></title>
4
5
  <%= RSpecDocumentation.template(:stylesheet_links).result(binding) %>
5
6
  <%= RSpecDocumentation.hook(:after_head) %>
6
7
  </head>
@@ -15,11 +16,19 @@
15
16
 
16
17
  <div class="row flex-nowrap">
17
18
  <div class="col-sm-2 fs-6 mt-1 ms-3 me-3">
18
- <ol class="page-tree hidden position-fixed">
19
- <% page_tree.elements.each do |element| %>
20
- <%= element %>
19
+ <div class="position-fixed">
20
+ <% if RSpecDocumentation.configuration.index_search %>
21
+ <div class="index-search">
22
+ <input type="text" class="index-search-field form-control" placeholder="Search (Ctrl+/)" />
23
+ </div>
21
24
  <% end %>
22
- </ol>
25
+
26
+ <ol class="page-tree hidden">
27
+ <% page_tree.elements.each do |element| %>
28
+ <%= element %>
29
+ <% end %>
30
+ </ol>
31
+ </div>
23
32
  </div>
24
33
 
25
34
  <%= RSpecDocumentation.hook(:before_content) %>