rspec-documentation 0.0.6 → 0.0.8

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.
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) %>