jazzy 0.13.2 → 0.13.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/Tests.yml +52 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +118 -0
  5. data/CONTRIBUTING.md +5 -5
  6. data/Gemfile.lock +68 -59
  7. data/README.md +65 -5
  8. data/Rakefile +30 -0
  9. data/bin/sourcekitten +0 -0
  10. data/js/package-lock.json +44 -0
  11. data/js/package.json +17 -0
  12. data/lib/jazzy/config.rb +29 -8
  13. data/lib/jazzy/doc_builder.rb +14 -2
  14. data/lib/jazzy/docset_builder.rb +2 -0
  15. data/lib/jazzy/docset_builder/info_plist.mustache +8 -0
  16. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.ttf +0 -0
  17. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.woff +0 -0
  18. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  19. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  20. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  21. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  22. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  23. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  24. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  25. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  26. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  27. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  28. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  29. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  30. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  31. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.ttf +0 -0
  32. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.woff +0 -0
  33. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.woff2 +0 -0
  34. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  35. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  36. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  37. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.ttf +0 -0
  38. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.woff +0 -0
  39. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.woff2 +0 -0
  40. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.ttf +0 -0
  41. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.woff +0 -0
  42. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.woff2 +0 -0
  43. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  44. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  45. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  46. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.ttf +0 -0
  47. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.woff +0 -0
  48. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.woff2 +0 -0
  49. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  50. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  51. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  52. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  53. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  54. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  55. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  56. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  57. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  58. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.ttf +0 -0
  59. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.woff +0 -0
  60. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.woff2 +0 -0
  61. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.ttf +0 -0
  62. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.woff +0 -0
  63. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  64. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.ttf +0 -0
  65. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.woff +0 -0
  66. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  67. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.ttf +0 -0
  68. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.woff +0 -0
  69. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  70. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.ttf +0 -0
  71. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.woff +0 -0
  72. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  73. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  74. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  75. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  76. data/lib/jazzy/extensions/katex/css/katex.min.css +1 -1
  77. data/lib/jazzy/extensions/katex/js/katex.min.js +1 -1
  78. data/lib/jazzy/gem_version.rb +1 -1
  79. data/lib/jazzy/jazzy_markdown.rb +38 -0
  80. data/lib/jazzy/podspec_documenter.rb +15 -3
  81. data/lib/jazzy/source_declaration.rb +15 -2
  82. data/lib/jazzy/source_declaration/type.rb +30 -0
  83. data/lib/jazzy/source_module.rb +2 -1
  84. data/lib/jazzy/sourcekitten.rb +11 -11
  85. data/lib/jazzy/symbol_graph.rb +95 -0
  86. data/lib/jazzy/symbol_graph/constraint.rb +94 -0
  87. data/lib/jazzy/symbol_graph/ext_node.rb +114 -0
  88. data/lib/jazzy/symbol_graph/graph.rb +193 -0
  89. data/lib/jazzy/symbol_graph/relationship.rb +39 -0
  90. data/lib/jazzy/symbol_graph/sym_node.rb +158 -0
  91. data/lib/jazzy/symbol_graph/symbol.rb +219 -0
  92. data/lib/jazzy/themes/apple/assets/css/jazzy.css.scss +96 -3
  93. data/lib/jazzy/themes/apple/assets/img/spinner.gif +0 -0
  94. data/lib/jazzy/themes/apple/assets/js/jazzy.search.js +70 -0
  95. data/lib/jazzy/themes/apple/assets/js/jquery.min.js +2 -2
  96. data/lib/jazzy/themes/apple/assets/js/lunr.min.js +6 -0
  97. data/lib/jazzy/themes/apple/assets/js/typeahead.jquery.js +1694 -0
  98. data/lib/jazzy/themes/apple/templates/doc.mustache +35 -0
  99. data/lib/jazzy/themes/apple/templates/header.mustache +7 -0
  100. data/lib/jazzy/themes/apple/templates/task.mustache +1 -1
  101. data/lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss +5 -0
  102. data/lib/jazzy/themes/fullwidth/assets/js/jquery.min.js +2 -2
  103. data/lib/jazzy/themes/fullwidth/assets/js/lunr.min.js +6 -1
  104. data/lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js +34 -14
  105. data/lib/jazzy/themes/fullwidth/templates/doc.mustache +30 -0
  106. data/lib/jazzy/themes/fullwidth/templates/task.mustache +1 -1
  107. data/lib/jazzy/themes/jony/assets/css/jazzy.css.scss +29 -1
  108. data/lib/jazzy/themes/jony/assets/js/jquery.min.js +2 -2
  109. data/lib/jazzy/themes/jony/templates/doc.mustache +30 -0
  110. data/lib/jazzy/themes/jony/templates/task.mustache +1 -1
  111. data/spec/integration_spec.rb +17 -8
  112. metadata +20 -8
  113. data/.circleci/config.yml +0 -83
@@ -0,0 +1,39 @@
1
+ module Jazzy
2
+ module SymbolGraph
3
+ # A Relationship is a tidied-up SymbolGraph JSON object
4
+ class Relationship
5
+ attr_accessor :kind
6
+ attr_accessor :source_usr
7
+ attr_accessor :target_usr
8
+ attr_accessor :target_fallback # can be nil
9
+ attr_accessor :constraints # array, can be empty
10
+
11
+ KINDS = %w[memberOf conformsTo defaultImplementationOf
12
+ overrides inheritsFrom requirementOf
13
+ optionalRequirementOf].freeze
14
+
15
+ def protocol_requirement?
16
+ %i[requirementOf optionalRequirementOf].include? kind
17
+ end
18
+
19
+ def default_implementation?
20
+ kind == :defaultImplementationOf
21
+ end
22
+
23
+ def initialize(hash)
24
+ kind = hash[:kind]
25
+ unless KINDS.include?(kind)
26
+ raise "Unknown relationship kind '#{kind}'"
27
+ end
28
+ self.kind = kind.to_sym
29
+ self.source_usr = hash[:source]
30
+ self.target_usr = hash[:target]
31
+ if fallback = hash[:targetFallback]
32
+ # Strip the leading module name
33
+ self.target_fallback = fallback.sub(/^.*?\./, '')
34
+ end
35
+ self.constraints = Constraint.new_list(hash[:swiftConstraints] || [])
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,158 @@
1
+ module Jazzy
2
+ module SymbolGraph
3
+ # The rebuilt syntax tree is made of nodes that either match
4
+ # symbols or that we fabricate for extensions. This is the common
5
+ # treeishness.
6
+ class BaseNode
7
+ attr_accessor :children # array, can be empty
8
+ attr_accessor :parent # can be nil
9
+
10
+ def initialize
11
+ self.children = []
12
+ end
13
+
14
+ def add_child(child)
15
+ child.parent = self
16
+ children.append(child)
17
+ end
18
+
19
+ def children_to_sourcekit
20
+ children.sort.map(&:to_sourcekit)
21
+ end
22
+ end
23
+
24
+ # A SymNode is a node of the reconstructed syntax tree holding a symbol.
25
+ # It can turn itself into SourceKit and helps decode extensions.
26
+ class SymNode < BaseNode
27
+ attr_accessor :symbol
28
+ attr_writer :override
29
+ attr_writer :protocol_requirement
30
+ attr_writer :unlisted
31
+ attr_accessor :superclass_name
32
+
33
+ def override?
34
+ @override
35
+ end
36
+
37
+ def protocol_requirement?
38
+ @protocol_requirement
39
+ end
40
+
41
+ def top_level_decl?
42
+ !@unlisted && parent.nil?
43
+ end
44
+
45
+ def initialize(symbol)
46
+ self.symbol = symbol
47
+ super()
48
+ end
49
+
50
+ def qualified_name
51
+ symbol.path_components.join('.')
52
+ end
53
+
54
+ def parent_qualified_name
55
+ symbol.path_components[0...-1].join('.')
56
+ end
57
+
58
+ def protocol?
59
+ symbol.kind.end_with?('protocol')
60
+ end
61
+
62
+ def constraints
63
+ symbol.constraints
64
+ end
65
+
66
+ # Add another SymNode as a member if possible.
67
+ # It must go in an extension if either:
68
+ # - it has different generic constraints to us; or
69
+ # - we're a protocol and it's a default impl / ext method
70
+ def try_add_child(node, unique_context_constraints)
71
+ unless unique_context_constraints.empty? &&
72
+ (!protocol? || node.protocol_requirement?)
73
+ return false
74
+ end
75
+ add_child(node)
76
+ true
77
+ end
78
+
79
+ # The `Constraint`s on this decl that are both:
80
+ # 1. Unique, ie. not just inherited from its context; and
81
+ # 2. Constraining the *context's* gen params rather than our own.
82
+ def unique_context_constraints(context)
83
+ return symbol.constraints unless context
84
+
85
+ new_generic_type_params =
86
+ symbol.generic_type_params - context.symbol.generic_type_params
87
+
88
+ (symbol.constraints - context.symbol.constraints)
89
+ .select { |con| con.type_names.disjoint?(new_generic_type_params) }
90
+ end
91
+
92
+ # Messy check whether we need to fabricate an extension for a protocol
93
+ # conformance: don't bother if it's already in the type declaration.
94
+ def conformance?(protocol)
95
+ return false unless symbol.declaration =~ /(?<=:).*?(?=(where|$))/
96
+ Regexp.last_match[0] =~ /\b#{protocol}\b/
97
+ end
98
+
99
+ # Generate the 'where' clause for the declaration
100
+ def where_clause
101
+ parent_constraints = (parent && parent.constraints) || []
102
+ (constraints - parent_constraints).to_where_clause
103
+ end
104
+
105
+ def inherits_clause
106
+ return '' unless superclass_name
107
+ " : #{superclass_name}"
108
+ end
109
+
110
+ def full_declaration
111
+ symbol.availability
112
+ .append(symbol.declaration + inherits_clause + where_clause)
113
+ .join("\n")
114
+ end
115
+
116
+ # rubocop:disable Metrics/MethodLength
117
+ def to_sourcekit
118
+ declaration = full_declaration
119
+ xml_declaration = "<swift>#{CGI.escapeHTML(declaration)}</swift>"
120
+
121
+ hash = {
122
+ 'key.kind' => symbol.kind,
123
+ 'key.usr' => symbol.usr,
124
+ 'key.name' => symbol.name,
125
+ 'key.accessibility' => symbol.acl,
126
+ 'key.parsed_decl' => declaration,
127
+ 'key.annotated_decl' => xml_declaration,
128
+ }
129
+ if docs = symbol.doc_comments
130
+ hash['key.doc.comment'] = docs
131
+ hash['key.doc.full_as_xml'] = ''
132
+ end
133
+ if params = symbol.parameter_names
134
+ hash['key.doc.parameters'] =
135
+ params.map { |name| { 'name' => name } }
136
+ end
137
+ if location = symbol.location
138
+ hash['key.filepath'] = location[:filename]
139
+ hash['key.doc.line'] = location[:line]
140
+ hash['key.doc.column'] = location[:character]
141
+ end
142
+ unless children.empty?
143
+ hash['key.substructure'] = children_to_sourcekit
144
+ end
145
+
146
+ hash
147
+ end
148
+ # rubocop:enable Metrics/MethodLength
149
+
150
+ # Sort order - by symbol
151
+ include Comparable
152
+
153
+ def <=>(other)
154
+ symbol <=> other.symbol
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,219 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+ module Jazzy
3
+ module SymbolGraph
4
+ # A Symbol is a tidied-up SymbolGraph JSON object
5
+ class Symbol
6
+ attr_accessor :usr
7
+ attr_accessor :path_components
8
+ attr_accessor :declaration
9
+ attr_accessor :kind
10
+ attr_accessor :acl
11
+ attr_accessor :location # can be nil, keys :filename :line :character
12
+ attr_accessor :constraints # array, can be empty
13
+ attr_accessor :doc_comments # can be nil
14
+ attr_accessor :availability # array, can be empty
15
+ attr_accessor :generic_type_params # set, can be empty
16
+ attr_accessor :parameter_names # array, can be nil
17
+
18
+ def name
19
+ path_components[-1] || '??'
20
+ end
21
+
22
+ def initialize(hash)
23
+ self.usr = hash[:identifier][:precise]
24
+ self.path_components = hash[:pathComponents]
25
+ raw_decl = hash[:declarationFragments].map { |f| f[:spelling] }.join
26
+ init_kind(hash[:kind][:identifier])
27
+ init_declaration(raw_decl)
28
+ if func_signature = hash[:functionSignature]
29
+ init_func_signature(func_signature)
30
+ end
31
+ init_acl(hash[:accessLevel])
32
+ if location = hash[:location]
33
+ init_location(location)
34
+ end
35
+ init_constraints(hash, raw_decl)
36
+ if comments_hash = hash[:docComment]
37
+ init_doc_comments(comments_hash)
38
+ end
39
+ init_availability(hash[:availability] || [])
40
+ init_generic_type_params(hash)
41
+ end
42
+
43
+ # Repair problems with SymbolGraph's declprinter
44
+
45
+ def init_declaration(raw_decl)
46
+ # Too much 'Self.TypeName'; omitted arg labels look odd;
47
+ # duplicated constraints; swift 5.3 vs. master workaround
48
+ self.declaration =
49
+ raw_decl.gsub(/\bSelf\./, '')
50
+ .gsub(/(?<=\(|, )_: /, '_ arg: ')
51
+ .gsub(/ where.*$/, '')
52
+ if kind == 'source.lang.swift.decl.class'
53
+ declaration.sub!(/\s*:.*$/, '')
54
+ end
55
+ end
56
+
57
+ # Remember pieces of methods for later markdown parsing
58
+
59
+ def init_func_signature(func_signature)
60
+ self.parameter_names =
61
+ (func_signature[:parameters] || []).map { |h| h[:name] }
62
+ end
63
+
64
+ # Mapping SymbolGraph's declkinds to SourceKit
65
+
66
+ KIND_MAP = {
67
+ 'class' => 'class',
68
+ 'struct' => 'struct',
69
+ 'enum' => 'enum',
70
+ 'enum.case' => 'enumelement', # intentional
71
+ 'protocol' => 'protocol',
72
+ 'init' => 'function.constructor',
73
+ 'deinit' => 'function.destructor',
74
+ 'func.op' => 'function.operator',
75
+ 'type.method' => 'function.method.class',
76
+ 'static.method' => 'function.method.static',
77
+ 'method' => 'function.method.instance',
78
+ 'func' => 'function.free',
79
+ 'type.property' => 'var.class',
80
+ 'static.property' => 'var.static',
81
+ 'property' => 'var.instance',
82
+ 'var' => 'var.global',
83
+ 'subscript' => 'function.subscript',
84
+ 'type.subscript' => 'function.subscript',
85
+ 'static.subscript' => 'function.subscript',
86
+ 'typealias' => 'typealias',
87
+ 'associatedtype' => 'associatedtype',
88
+ }.freeze
89
+
90
+ # We treat 'static var' differently to 'class var'
91
+ def adjust_kind_for_declaration(kind)
92
+ return kind unless declaration =~ /\bstatic\b/
93
+ kind.gsub(/type/, 'static')
94
+ end
95
+
96
+ def init_kind(kind)
97
+ adjusted = adjust_kind_for_declaration(kind)
98
+ sourcekit_kind = KIND_MAP[adjusted.sub('swift.', '')]
99
+ raise "Unknown symbol kind '#{kind}'" unless sourcekit_kind
100
+ self.kind = 'source.lang.swift.decl.' + sourcekit_kind
101
+ end
102
+
103
+ # Mapping SymbolGraph's ACL to SourceKit
104
+
105
+ def init_acl(acl)
106
+ self.acl = 'source.lang.swift.accessibility.' + acl
107
+ end
108
+
109
+ # Symbol location - only available for public+ decls
110
+
111
+ def init_location(loc_hash)
112
+ self.location = {}
113
+ location[:filename] = loc_hash[:uri].sub(%r{^file://}, '')
114
+ location[:line] = loc_hash[:position][:line]
115
+ location[:character] = loc_hash[:position][:character]
116
+ end
117
+
118
+ # Generic constraints: in one or both of two places.
119
+ # There can be duplicates; these are removed by `Constraint`.
120
+ def init_constraints(hash, raw_decl)
121
+ raw_constraints = %i[swiftGenerics swiftExtension].flat_map do |key|
122
+ next [] unless container = hash[key]
123
+ container[:constraints] || []
124
+ end
125
+
126
+ constraints =
127
+ Constraint.new_list_for_symbol(raw_constraints, path_components)
128
+ if raw_decl =~ / where (.*)$/
129
+ constraints +=
130
+ Constraint.new_list_from_declaration(Regexp.last_match[1])
131
+ end
132
+
133
+ self.constraints = constraints.sort.uniq
134
+ end
135
+
136
+ # Generic type params
137
+ def init_generic_type_params(hash)
138
+ self.generic_type_params = Set.new(
139
+ if (generics = hash[:swiftGenerics]) &&
140
+ (parameters = generics[:parameters])
141
+ parameters.map { |p| p[:name] }
142
+ else
143
+ []
144
+ end,
145
+ )
146
+ end
147
+
148
+ def init_doc_comments(comments_hash)
149
+ self.doc_comments =
150
+ comments_hash[:lines].map { |l| l[:text] }
151
+ .join("\n")
152
+ end
153
+
154
+ # Availability
155
+ # Re-encode this as Swift. Should really teach Jazzy about these,
156
+ # could maybe then do something smarter here.
157
+ def init_availability(avail_hash_list)
158
+ self.availability = avail_hash_list.map do |avail|
159
+ str = '@available('
160
+ if avail[:isUnconditionallyDeprecated]
161
+ str += '*, deprecated'
162
+ elsif domain = avail[:domain]
163
+ str += domain
164
+ %i[introduced deprecated obsoleted].each do |event|
165
+ if version = avail[event]
166
+ str += ", #{event}: #{decode_version(version)}"
167
+ end
168
+ end
169
+ else
170
+ warn "Found confusing availability: #{avail}"
171
+ next nil
172
+ end
173
+
174
+ str += ', message: "' + avail[:message] + '"' if avail[:message]
175
+ str += ', renamed: "' + avail[:renamed] + '"' if avail[:renamed]
176
+
177
+ str + ')'
178
+ end.compact
179
+ end
180
+
181
+ def decode_version(hash)
182
+ str = hash[:major].to_s
183
+ str += ".#{hash[:minor]}" if hash[:minor]
184
+ str += ".#{hash[:patch]}" if hash[:patch]
185
+ str
186
+ end
187
+
188
+ # Sort order
189
+ include Comparable
190
+
191
+ # rubocop:disable Metrics/CyclomaticComplexity
192
+ # rubocop:disable Metrics/PerceivedComplexity
193
+ def <=>(other)
194
+ # Things with location: order by file/line/column
195
+ # (pls tell what wheel i am reinventing :/)
196
+ if location && other_loc = other.location
197
+ if location[:filename] == other_loc[:filename]
198
+ if location[:line] == other_loc[:line]
199
+ return location[:character] <=> other_loc[:character]
200
+ end
201
+ return location[:line] <=> other_loc[:line]
202
+ end
203
+ return location[:filename] <=> other_loc[:filename]
204
+ end
205
+
206
+ # Things with a location before things without a location
207
+ return +1 if location.nil? && other.location
208
+ return -1 if location && other.location.nil?
209
+
210
+ # Things without a location: by name and then USR
211
+ return usr <=> other.usr if name == other.name
212
+ name <=> other.name
213
+ end
214
+ # rubocop:enable Metrics/PerceivedComplexity
215
+ # rubocop:enable Metrics/CyclomaticComplexity
216
+ end
217
+ end
218
+ end
219
+ # rubocop:enable Metrics/ClassLength
@@ -18,12 +18,13 @@ $content_wrapper_width: 980px;
18
18
  $content_top_offset: 70px;
19
19
  $content_body_margin: 16px;
20
20
  $content_body_left_offset: $sidebar_width + $content_body_margin;
21
- $header_height: 26px;
21
+ $header_height: 32px;
22
22
  $breadcrumb_padding_top: 17px;
23
23
 
24
24
  $code_font: 0.95em Menlo, monospace;
25
25
 
26
- $gray_border: 1px solid #e2e2e2;
26
+ $gray_border_color: #e2e2e2;
27
+ $gray_border: 1px solid $gray_border_color;
27
28
  $declaration_language_border: 5px solid #cde9f4;
28
29
 
29
30
  $aside_color: #aaa;
@@ -104,12 +105,18 @@ p code, li code {
104
105
  padding: 2px 4px;
105
106
  border-radius: 4px;
106
107
  }
108
+ pre > code {
109
+ padding: 0;
110
+ }
107
111
 
108
112
  // Links
109
113
 
110
114
  a {
111
115
  color: $link_color;
112
116
  text-decoration: none;
117
+ code {
118
+ color: inherit;
119
+ }
113
120
  }
114
121
 
115
122
  // Lists
@@ -135,6 +142,25 @@ blockquote {
135
142
  border-left: 4px solid #ccc;
136
143
  }
137
144
 
145
+ // HRs
146
+
147
+ hr {
148
+ height: 1px;
149
+ border: none;
150
+ background-color: $gray_border_color;
151
+ }
152
+
153
+ // Footnotes
154
+
155
+ .footnote-ref {
156
+ display: inline-block;
157
+ scroll-margin-top: $content-top-offset;
158
+ }
159
+
160
+ .footnote-def {
161
+ scroll-margin-top: $content-top-offset;
162
+ }
163
+
138
164
  // General Content Wrapper
139
165
 
140
166
  .content-wrapper {
@@ -152,7 +178,7 @@ header {
152
178
  background-color: $bg_color;
153
179
  position: fixed;
154
180
  width: 100%;
155
- z-index: 2;
181
+ z-index: 3;
156
182
  img {
157
183
  padding-right: 6px;
158
184
  vertical-align: -4px;
@@ -309,6 +335,7 @@ header {
309
335
  }
310
336
 
311
337
  .task-group-section {
338
+ margin-top: 10px;
312
339
  padding-left: 6px;
313
340
  border-top: $gray_border;
314
341
  }
@@ -529,3 +556,69 @@ html.dash {
529
556
  position: static;
530
557
  }
531
558
  }
559
+
560
+ // ===========================================================================
561
+ //
562
+ // Search
563
+ //
564
+ // ===========================================================================
565
+ form[role=search] {
566
+ float: right;
567
+
568
+ input {
569
+ font: Helvetica, freesans, Arial, sans-serif;
570
+ margin-top: 6px;
571
+ font-size: 13px;
572
+ line-height: 20px;
573
+ padding: 0px 10px;
574
+ border: none;
575
+ border-radius: 1em;
576
+ .loading & {
577
+ background: white url(../img/spinner.gif) center right 4px no-repeat;
578
+ }
579
+ }
580
+
581
+ // Typeahead elements
582
+
583
+ .tt-menu {
584
+ margin: 0;
585
+ min-width: 300px;
586
+ background: $white_color;
587
+ color: #333;
588
+ border: $gray_border;
589
+ z-index: 4;
590
+ }
591
+
592
+ .tt-highlight {
593
+ font-weight: bold;
594
+ }
595
+
596
+ .tt-suggestion {
597
+ font: Helvetica, freesans, Arial, sans-serif;
598
+ font-size: 14px;
599
+ padding: 0 8px;
600
+ span {
601
+ display: table-cell;
602
+ white-space: nowrap;
603
+ }
604
+ .doc-parent-name {
605
+ width: 100%;
606
+ text-align: right;
607
+ font-weight: normal;
608
+ font-size: 0.9em;
609
+ padding-left: 16px;
610
+ }
611
+ }
612
+
613
+ .tt-suggestion:hover,
614
+ .tt-suggestion.tt-cursor {
615
+ cursor: pointer;
616
+ background-color: #4183c4;
617
+ color: #fff;
618
+ }
619
+
620
+ .tt-suggestion:hover .doc-parent-name,
621
+ .tt-suggestion.tt-cursor .doc-parent-name {
622
+ color: #fff;
623
+ }
624
+ }