rdoc 7.1.0 → 7.2.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rdoc/code_object/attr.rb +2 -1
  3. data/lib/rdoc/code_object/context/section.rb +26 -8
  4. data/lib/rdoc/code_object/context.rb +15 -4
  5. data/lib/rdoc/code_object/mixin.rb +3 -0
  6. data/lib/rdoc/code_object/top_level.rb +2 -0
  7. data/lib/rdoc/comment.rb +1 -1
  8. data/lib/rdoc/cross_reference.rb +1 -3
  9. data/lib/rdoc/generator/template/aliki/_head.rhtml +5 -0
  10. data/lib/rdoc/generator/template/aliki/class.rhtml +5 -5
  11. data/lib/rdoc/generator/template/aliki/css/rdoc.css +28 -36
  12. data/lib/rdoc/generator/template/aliki/js/aliki.js +8 -2
  13. data/lib/rdoc/generator/template/aliki/js/bash_highlighter.js +167 -0
  14. data/lib/rdoc/generator/template/aliki/js/search_controller.js +1 -1
  15. data/lib/rdoc/markdown.kpeg +21 -7
  16. data/lib/rdoc/markdown.rb +35 -21
  17. data/lib/rdoc/markup/formatter.rb +129 -106
  18. data/lib/rdoc/markup/heading.rb +2 -2
  19. data/lib/rdoc/markup/inline_parser.rb +312 -0
  20. data/lib/rdoc/markup/parser.rb +1 -1
  21. data/lib/rdoc/markup/to_ansi.rb +51 -4
  22. data/lib/rdoc/markup/to_bs.rb +22 -42
  23. data/lib/rdoc/markup/to_html.rb +152 -177
  24. data/lib/rdoc/markup/to_html_crossref.rb +38 -78
  25. data/lib/rdoc/markup/to_html_snippet.rb +62 -62
  26. data/lib/rdoc/markup/to_label.rb +20 -21
  27. data/lib/rdoc/markup/to_markdown.rb +61 -37
  28. data/lib/rdoc/markup/to_rdoc.rb +86 -26
  29. data/lib/rdoc/markup/to_test.rb +9 -1
  30. data/lib/rdoc/markup/to_tt_only.rb +10 -16
  31. data/lib/rdoc/markup.rb +8 -30
  32. data/lib/rdoc/parser/changelog.rb +21 -0
  33. data/lib/rdoc/parser/prism_ruby.rb +44 -32
  34. data/lib/rdoc/parser/ruby.rb +1 -1
  35. data/lib/rdoc/text.rb +29 -5
  36. data/lib/rdoc/version.rb +1 -1
  37. metadata +4 -7
  38. data/lib/rdoc/markup/attr_changer.rb +0 -22
  39. data/lib/rdoc/markup/attr_span.rb +0 -35
  40. data/lib/rdoc/markup/attribute_manager.rb +0 -432
  41. data/lib/rdoc/markup/attributes.rb +0 -70
  42. data/lib/rdoc/markup/regexp_handling.rb +0 -40
@@ -1,432 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ##
4
- # Manages changes of attributes in a block of text
5
-
6
- class RDoc::Markup::AttributeManager
7
- unless ::MatchData.method_defined?(:match_length)
8
- using ::Module.new {
9
- refine(::MatchData) {
10
- def match_length(nth) # :nodoc:
11
- b, e = offset(nth)
12
- e - b if b
13
- end
14
- }
15
- }
16
- end
17
-
18
- ##
19
- # The NUL character
20
-
21
- NULL = "\000".freeze
22
-
23
- #--
24
- # We work by substituting non-printing characters in to the text. For now
25
- # I'm assuming that I can substitute a character in the range 0..8 for a 7
26
- # bit character without damaging the encoded string, but this might be
27
- # optimistic
28
- #++
29
-
30
- A_PROTECT = 004 # :nodoc:
31
-
32
- ##
33
- # Special mask character to prevent inline markup handling
34
-
35
- PROTECT_ATTR = A_PROTECT.chr # :nodoc:
36
-
37
- ##
38
- # The attributes enabled for this markup object.
39
-
40
- attr_reader :attributes
41
-
42
- ##
43
- # This maps delimiters that occur around words (such as *bold* or +tt+)
44
- # where the start and end delimiters and the same. This lets us optimize
45
- # the regexp
46
-
47
- attr_reader :matching_word_pairs
48
-
49
- ##
50
- # And this is used when the delimiters aren't the same. In this case the
51
- # hash maps a pattern to the attribute character
52
-
53
- attr_reader :word_pair_map
54
-
55
- ##
56
- # This maps HTML tags to the corresponding attribute char
57
-
58
- attr_reader :html_tags
59
-
60
- ##
61
- # A \ in front of a character that would normally be processed turns off
62
- # processing. We do this by turning \< into <#{PROTECT}
63
-
64
- attr_reader :protectable
65
-
66
- ##
67
- # And this maps _regexp handling_ sequences to a name. A regexp handling
68
- # sequence is something like a WikiWord
69
-
70
- attr_reader :regexp_handlings
71
-
72
- ##
73
- # A bits of exclusive maps
74
- attr_reader :exclusive_bitmap
75
-
76
- ##
77
- # Creates a new attribute manager that understands bold, emphasized and
78
- # teletype text.
79
-
80
- def initialize
81
- @html_tags = {}
82
- @matching_word_pairs = {}
83
- @protectable = %w[<]
84
- @regexp_handlings = []
85
- @word_pair_map = {}
86
- @exclusive_bitmap = 0
87
- @attributes = RDoc::Markup::Attributes.new
88
-
89
- add_word_pair "*", "*", :BOLD, true
90
- add_word_pair "_", "_", :EM, true
91
- add_word_pair "+", "+", :TT, true
92
- add_word_pair "`", "`", :TT, true
93
-
94
- add_html "em", :EM, true
95
- add_html "i", :EM, true
96
- add_html "b", :BOLD, true
97
- add_html "tt", :TT, true
98
- add_html "code", :TT, true
99
- add_html "s", :STRIKE, true
100
- add_html "del", :STRIKE, true
101
-
102
- @word_pair_chars = @matching_word_pairs.keys.join
103
-
104
- # Matches a word pair delimiter (*, _, +, `) that is NOT already protected.
105
- # Used by #protect_code_markup to escape delimiters inside <code>/<tt> tags.
106
- @unprotected_word_pair_regexp = /([#{@word_pair_chars}])(?!#{PROTECT_ATTR})/
107
- end
108
-
109
- ##
110
- # Return an attribute object with the given turn_on and turn_off bits set
111
-
112
- def attribute(turn_on, turn_off)
113
- RDoc::Markup::AttrChanger.new turn_on, turn_off
114
- end
115
-
116
- ##
117
- # Changes the current attribute from +current+ to +new+
118
-
119
- def change_attribute(current, new)
120
- diff = current ^ new
121
- attribute(new & diff, current & diff)
122
- end
123
-
124
- ##
125
- # Used by the tests to change attributes by name from +current_set+ to
126
- # +new_set+
127
-
128
- def changed_attribute_by_name(current_set, new_set)
129
- current = new = 0
130
- current_set.each do |name|
131
- current |= @attributes.bitmap_for(name)
132
- end
133
-
134
- new_set.each do |name|
135
- new |= @attributes.bitmap_for(name)
136
- end
137
-
138
- change_attribute(current, new)
139
- end
140
-
141
- ##
142
- # Copies +start_pos+ to +end_pos+ from the current string
143
-
144
- def copy_string(start_pos, end_pos)
145
- res = @str[start_pos...end_pos]
146
- res.gsub!(/\000/, '')
147
- res
148
- end
149
-
150
- # :nodoc:
151
- def exclusive?(attr)
152
- (attr & @exclusive_bitmap) != 0
153
- end
154
-
155
- NON_PRINTING_START = "\1" # :nodoc:
156
- NON_PRINTING_END = "\2" # :nodoc:
157
-
158
- ##
159
- # Map attributes like <b>text</b>to the sequence
160
- # \001\002<char>\001\003<char>, where <char> is a per-attribute specific
161
- # character
162
-
163
- def convert_attrs(str, attrs, exclusive = false)
164
- convert_attrs_matching_word_pairs(str, attrs, exclusive)
165
- convert_attrs_word_pair_map(str, attrs, exclusive)
166
- end
167
-
168
- # :nodoc:
169
- def convert_attrs_matching_word_pairs(str, attrs, exclusive)
170
- # first do matching ones
171
- tags = @matching_word_pairs.select { |start, bitmap|
172
- exclusive == exclusive?(bitmap)
173
- }.keys
174
- return if tags.empty?
175
- tags = "[#{tags.join("")}](?!#{PROTECT_ATTR})"
176
- all_tags = "[#{@word_pair_chars}](?!#{PROTECT_ATTR})"
177
-
178
- re = /(?:^|\W|#{all_tags})\K(#{tags})(\1*[#\\]?[\w:#{PROTECT_ATTR}.\/\[\]-]+?\S?)\1(?!\1)(?=#{all_tags}|\W|$)/
179
-
180
- 1 while str.gsub!(re) { |orig|
181
- a, w = (m = $~).values_at(1, 2)
182
- attr = @matching_word_pairs[a]
183
- if attrs.set_attrs(m.begin(2), w.length, attr)
184
- a = NULL * a.length
185
- else
186
- a = NON_PRINTING_START + a + NON_PRINTING_END
187
- end
188
- a + w + a
189
- }
190
- str.delete!(NON_PRINTING_START + NON_PRINTING_END)
191
- end
192
-
193
- # :nodoc:
194
- def convert_attrs_word_pair_map(str, attrs, exclusive)
195
- # then non-matching
196
- unless @word_pair_map.empty? then
197
- @word_pair_map.each do |regexp, attr|
198
- next unless exclusive == exclusive?(attr)
199
- 1 while str.gsub!(regexp) { |orig|
200
- w = (m = ($~))[2]
201
- updated = attrs.set_attrs(m.begin(2), w.length, attr)
202
- if updated
203
- NULL * m.match_length(1) + w + NULL * m.match_length(3)
204
- else
205
- orig
206
- end
207
- }
208
- end
209
- end
210
- end
211
-
212
- ##
213
- # Converts HTML tags to RDoc attributes
214
-
215
- def convert_html(str, attrs, exclusive = false)
216
- tags = @html_tags.select { |start, bitmap|
217
- exclusive == exclusive?(bitmap)
218
- }.keys.join '|'
219
-
220
- 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { |orig|
221
- attr = @html_tags[$1.downcase]
222
- html_length = $~.match_length(1) + 2 # "<>".length
223
- seq = NULL * html_length
224
- attrs.set_attrs($~.begin(2), $~.match_length(2), attr)
225
- seq + $2 + seq + NULL
226
- }
227
- end
228
-
229
- ##
230
- # Converts regexp handling sequences to RDoc attributes
231
-
232
- def convert_regexp_handlings(str, attrs, exclusive = false)
233
- @regexp_handlings.each do |regexp, attribute|
234
- next unless exclusive == exclusive?(attribute)
235
- str.scan(regexp) do
236
- capture = $~.size == 1 ? 0 : 1
237
-
238
- s, e = $~.offset capture
239
-
240
- attrs.set_attrs s, e - s, attribute | @attributes.regexp_handling
241
- end
242
- end
243
- end
244
-
245
- ##
246
- # Escapes regexp handling sequences of text to prevent conversion to RDoc
247
-
248
- def mask_protected_sequences
249
- # protect __send__, __FILE__, etc.
250
- @str.gsub!(/__([a-z]+)__/i,
251
- "_#{PROTECT_ATTR}_#{PROTECT_ATTR}\\1_#{PROTECT_ATTR}_#{PROTECT_ATTR}")
252
- @str.gsub!(/(\A|[^\\])\\([#{Regexp.escape @protectable.join}])/m,
253
- "\\1\\2#{PROTECT_ATTR}")
254
- @str.gsub!(/\\(\\[#{Regexp.escape @protectable.join}])/m, "\\1")
255
- end
256
-
257
- ##
258
- # Protects word pair delimiters (*, _, +) inside
259
- # <code> and <tt> tags from being processed as inline formatting.
260
- # For example, *bold* in +*bold*+ will NOT be rendered as bold.
261
-
262
- def protect_code_markup
263
- @str.gsub!(/<(code|tt)>(.*?)<\/\1>/im) do
264
- tag = $1
265
- content = $2
266
- # Protect word pair delimiters (*, _, +) from being processed
267
- escaped = content.gsub(@unprotected_word_pair_regexp, "\\1#{PROTECT_ATTR}")
268
- # Protect HTML-like tags from being processed (e.g., <del> inside code)
269
- escaped = escaped.gsub(/<(?!#{PROTECT_ATTR})/, "<#{PROTECT_ATTR}")
270
- "<#{tag}>#{escaped}</#{tag}>"
271
- end
272
- end
273
-
274
- ##
275
- # Unescapes regexp handling sequences of text
276
-
277
- def unmask_protected_sequences
278
- @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000")
279
- end
280
-
281
- ##
282
- # Adds a markup class with +name+ for words wrapped in the +start+ and
283
- # +stop+ character. To make words wrapped with "*" bold:
284
- #
285
- # am.add_word_pair '*', '*', :BOLD
286
-
287
- def add_word_pair(start, stop, name, exclusive = false)
288
- raise ArgumentError, "Word flags may not start with '<'" if
289
- start[0, 1] == '<'
290
-
291
- bitmap = @attributes.bitmap_for name
292
-
293
- if start == stop then
294
- @matching_word_pairs[start] = bitmap
295
- else
296
- pattern = /(#{Regexp.escape start})(\S+)(#{Regexp.escape stop})/
297
- @word_pair_map[pattern] = bitmap
298
- end
299
-
300
- @protectable << start[0, 1]
301
- @protectable.uniq!
302
-
303
- @exclusive_bitmap |= bitmap if exclusive
304
- end
305
-
306
- ##
307
- # Adds a markup class with +name+ for words surrounded by HTML tag +tag+.
308
- # To process emphasis tags:
309
- #
310
- # am.add_html 'em', :EM
311
-
312
- def add_html(tag, name, exclusive = false)
313
- bitmap = @attributes.bitmap_for name
314
- @html_tags[tag.downcase] = bitmap
315
- @exclusive_bitmap |= bitmap if exclusive
316
- end
317
-
318
- ##
319
- # Adds a regexp handling for +pattern+ with +name+. A simple URL handler
320
- # would be:
321
- #
322
- # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK)
323
-
324
- def add_regexp_handling(pattern, name, exclusive = false)
325
- bitmap = @attributes.bitmap_for(name)
326
- @regexp_handlings << [pattern, bitmap]
327
- @exclusive_bitmap |= bitmap if exclusive
328
- end
329
-
330
- ##
331
- # Processes +str+ converting attributes, HTML and regexp handlings
332
-
333
- def flow(str)
334
- @str = str.dup
335
-
336
- mask_protected_sequences
337
- protect_code_markup
338
-
339
- @attrs = RDoc::Markup::AttrSpan.new @str.length, @exclusive_bitmap
340
-
341
- convert_attrs @str, @attrs, true
342
- convert_html @str, @attrs, true
343
- convert_regexp_handlings @str, @attrs, true
344
- convert_attrs @str, @attrs
345
- convert_html @str, @attrs
346
- convert_regexp_handlings @str, @attrs
347
-
348
- unmask_protected_sequences
349
-
350
- split_into_flow
351
- end
352
-
353
- ##
354
- # Debug method that prints a string along with its attributes
355
-
356
- def display_attributes
357
- puts
358
- puts @str.tr(NULL, "!")
359
- bit = 1
360
- 16.times do |bno|
361
- line = ""
362
- @str.length.times do |i|
363
- if (@attrs[i] & bit) == 0
364
- line << " "
365
- else
366
- if bno.zero?
367
- line << "S"
368
- else
369
- line << ("%d" % (bno+1))
370
- end
371
- end
372
- end
373
- puts(line) unless line =~ /^ *$/
374
- bit <<= 1
375
- end
376
- end
377
-
378
- ##
379
- # Splits the string into chunks by attribute change
380
-
381
- def split_into_flow
382
- res = []
383
- current_attr = 0
384
-
385
- str_len = @str.length
386
-
387
- # skip leading invisible text
388
- i = 0
389
- i += 1 while i < str_len and @str[i].chr == "\0"
390
- start_pos = i
391
-
392
- # then scan the string, chunking it on attribute changes
393
- while i < str_len
394
- new_attr = @attrs[i]
395
- if new_attr != current_attr
396
- if i > start_pos
397
- res << copy_string(start_pos, i)
398
- start_pos = i
399
- end
400
-
401
- res << change_attribute(current_attr, new_attr)
402
- current_attr = new_attr
403
-
404
- if (current_attr & @attributes.regexp_handling) != 0 then
405
- i += 1 while
406
- i < str_len and (@attrs[i] & @attributes.regexp_handling) != 0
407
-
408
- res << RDoc::Markup::RegexpHandling.new(current_attr,
409
- copy_string(start_pos, i))
410
- start_pos = i
411
- next
412
- end
413
- end
414
-
415
- # move on, skipping any invisible characters
416
- begin
417
- i += 1
418
- end while i < str_len and @str[i].chr == "\0"
419
- end
420
-
421
- # tidy up trailing text
422
- if start_pos < str_len
423
- res << copy_string(start_pos, str_len)
424
- end
425
-
426
- # and reset to all attributes off
427
- res << change_attribute(current_attr, 0) if current_attr != 0
428
-
429
- res
430
- end
431
-
432
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
- ##
3
- # We manage a set of attributes. Each attribute has a symbol name and a bit
4
- # value.
5
-
6
- class RDoc::Markup::Attributes
7
-
8
- ##
9
- # The regexp handling attribute type. See RDoc::Markup#add_regexp_handling
10
-
11
- attr_reader :regexp_handling
12
-
13
- ##
14
- # Creates a new attributes set.
15
-
16
- def initialize
17
- @regexp_handling = 1
18
-
19
- @name_to_bitmap = [
20
- [:_REGEXP_HANDLING_, @regexp_handling],
21
- ]
22
-
23
- @next_bitmap = @regexp_handling << 1
24
- end
25
-
26
- ##
27
- # Returns a unique bit for +name+
28
-
29
- def bitmap_for(name)
30
- bitmap = @name_to_bitmap.assoc name
31
-
32
- unless bitmap then
33
- bitmap = @next_bitmap
34
- @next_bitmap <<= 1
35
- @name_to_bitmap << [name, bitmap]
36
- else
37
- bitmap = bitmap.last
38
- end
39
-
40
- bitmap
41
- end
42
-
43
- ##
44
- # Returns a string representation of +bitmap+
45
-
46
- def as_string(bitmap)
47
- return 'none' if bitmap.zero?
48
- res = []
49
-
50
- @name_to_bitmap.each do |name, bit|
51
- res << name if (bitmap & bit) != 0
52
- end
53
-
54
- res.join ','
55
- end
56
-
57
- ##
58
- # yields each attribute name in +bitmap+
59
-
60
- def each_name_of(bitmap)
61
- return enum_for __method__, bitmap unless block_given?
62
-
63
- @name_to_bitmap.each do |name, bit|
64
- next if bit == @regexp_handling
65
-
66
- yield name.to_s if (bitmap & bit) != 0
67
- end
68
- end
69
-
70
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
- ##
3
- # Hold details of a regexp handling sequence
4
-
5
- class RDoc::Markup::RegexpHandling
6
-
7
- ##
8
- # Regexp handling type
9
-
10
- attr_reader :type
11
-
12
- ##
13
- # Regexp handling text
14
-
15
- attr_accessor :text
16
-
17
- ##
18
- # Creates a new regexp handling sequence of +type+ with +text+
19
-
20
- def initialize(type, text)
21
- @type, @text = type, text
22
- end
23
-
24
- ##
25
- # Regexp handlings are equal when the have the same text and type
26
-
27
- def ==(o)
28
- self.text == o.text && self.type == o.type
29
- end
30
-
31
- def inspect # :nodoc:
32
- "#<RDoc::Markup::RegexpHandling:0x%x @type=%p, @text=%p>" % [
33
- object_id, @type, text.dump]
34
- end
35
-
36
- def to_s # :nodoc:
37
- "RegexpHandling: type=#{type} text=#{text.dump}"
38
- end
39
-
40
- end