rdoc 6.3.0 → 6.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

@@ -7,16 +7,22 @@ class RDoc::Markup::AttrSpan
7
7
  ##
8
8
  # Creates a new AttrSpan for +length+ characters
9
9
 
10
- def initialize(length)
10
+ def initialize(length, exclusive)
11
11
  @attrs = Array.new(length, 0)
12
+ @exclusive = exclusive
12
13
  end
13
14
 
14
15
  ##
15
16
  # Toggles +bits+ from +start+ to +length+
16
17
  def set_attrs(start, length, bits)
18
+ updated = false
17
19
  for i in start ... (start+length)
18
- @attrs[i] |= bits
20
+ if (@exclusive & @attrs[i]) == 0 || (@exclusive & bits) != 0
21
+ @attrs[i] |= bits
22
+ updated = true
23
+ end
19
24
  end
25
+ updated
20
26
  end
21
27
 
22
28
  ##
@@ -58,6 +58,10 @@ class RDoc::Markup::AttributeManager
58
58
 
59
59
  attr_reader :regexp_handlings
60
60
 
61
+ ##
62
+ # A bits of exclusive maps
63
+ attr_reader :exclusive_bitmap
64
+
61
65
  ##
62
66
  # Creates a new attribute manager that understands bold, emphasized and
63
67
  # teletype text.
@@ -68,17 +72,18 @@ class RDoc::Markup::AttributeManager
68
72
  @protectable = %w[<]
69
73
  @regexp_handlings = []
70
74
  @word_pair_map = {}
75
+ @exclusive_bitmap = 0
71
76
  @attributes = RDoc::Markup::Attributes.new
72
77
 
73
- add_word_pair "*", "*", :BOLD
74
- add_word_pair "_", "_", :EM
75
- add_word_pair "+", "+", :TT
78
+ add_word_pair "*", "*", :BOLD, true
79
+ add_word_pair "_", "_", :EM, true
80
+ add_word_pair "+", "+", :TT, true
76
81
 
77
- add_html "em", :EM
78
- add_html "i", :EM
79
- add_html "b", :BOLD
80
- add_html "tt", :TT
81
- add_html "code", :TT
82
+ add_html "em", :EM, true
83
+ add_html "i", :EM, true
84
+ add_html "b", :BOLD, true
85
+ add_html "tt", :TT, true
86
+ add_html "code", :TT, true
82
87
  end
83
88
 
84
89
  ##
@@ -122,29 +127,67 @@ class RDoc::Markup::AttributeManager
122
127
  res
123
128
  end
124
129
 
130
+ def exclusive?(attr)
131
+ (attr & @exclusive_bitmap) != 0
132
+ end
133
+
134
+ NON_PRINTING_START = "\1" # :nodoc:
135
+ NON_PRINTING_END = "\2" # :nodoc:
136
+
125
137
  ##
126
138
  # Map attributes like <b>text</b>to the sequence
127
139
  # \001\002<char>\001\003<char>, where <char> is a per-attribute specific
128
140
  # character
129
141
 
130
- def convert_attrs(str, attrs)
142
+ def convert_attrs(str, attrs, exclusive = false)
143
+ convert_attrs_matching_word_pairs(str, attrs, exclusive)
144
+ convert_attrs_word_pair_map(str, attrs, exclusive)
145
+ end
146
+
147
+ def convert_attrs_matching_word_pairs(str, attrs, exclusive)
131
148
  # first do matching ones
132
- tags = @matching_word_pairs.keys.join("")
149
+ tags = @matching_word_pairs.select { |start, bitmap|
150
+ if exclusive && exclusive?(bitmap)
151
+ true
152
+ elsif !exclusive && !exclusive?(bitmap)
153
+ true
154
+ else
155
+ false
156
+ end
157
+ }.keys
158
+ return if tags.empty?
159
+ all_tags = @matching_word_pairs.keys
133
160
 
134
- re = /(^|\W)([#{tags}])([#\\]?[\w:.\/-]+?\S?)\2(\W|$)/
161
+ re = /(^|\W|[#{all_tags.join("")}])([#{tags.join("")}])(\2*[#\\]?[\w:.\/\[\]-]+?\S?)\2(?!\2)([#{all_tags.join("")}]|\W|$)/
135
162
 
136
- 1 while str.gsub!(re) do
163
+ 1 while str.gsub!(re) { |orig|
137
164
  attr = @matching_word_pairs[$2]
138
- attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
139
- $1 + NULL * $2.length + $3 + NULL * $2.length + $4
140
- end
165
+ attr_updated = attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
166
+ if attr_updated
167
+ $1 + NULL * $2.length + $3 + NULL * $2.length + $4
168
+ else
169
+ $1 + NON_PRINTING_START + $2 + NON_PRINTING_END + $3 + NON_PRINTING_START + $2 + NON_PRINTING_END + $4
170
+ end
171
+ }
172
+ str.delete!(NON_PRINTING_START + NON_PRINTING_END)
173
+ end
141
174
 
175
+ def convert_attrs_word_pair_map(str, attrs, exclusive)
142
176
  # then non-matching
143
177
  unless @word_pair_map.empty? then
144
178
  @word_pair_map.each do |regexp, attr|
145
- str.gsub!(regexp) {
146
- attrs.set_attrs($`.length + $1.length, $2.length, attr)
147
- NULL * $1.length + $2 + NULL * $3.length
179
+ if !exclusive
180
+ next if exclusive?(attr)
181
+ else
182
+ next if !exclusive?(attr)
183
+ end
184
+ 1 while str.gsub!(regexp) { |orig|
185
+ updated = attrs.set_attrs($`.length + $1.length, $2.length, attr)
186
+ if updated
187
+ NULL * $1.length + $2 + NULL * $3.length
188
+ else
189
+ orig
190
+ end
148
191
  }
149
192
  end
150
193
  end
@@ -153,10 +196,18 @@ class RDoc::Markup::AttributeManager
153
196
  ##
154
197
  # Converts HTML tags to RDoc attributes
155
198
 
156
- def convert_html(str, attrs)
157
- tags = @html_tags.keys.join '|'
199
+ def convert_html(str, attrs, exclusive = false)
200
+ tags = @html_tags.select { |start, bitmap|
201
+ if exclusive && exclusive?(bitmap)
202
+ true
203
+ elsif !exclusive && !exclusive?(bitmap)
204
+ true
205
+ else
206
+ false
207
+ end
208
+ }.keys.join '|'
158
209
 
159
- 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) {
210
+ 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { |orig|
160
211
  attr = @html_tags[$1.downcase]
161
212
  html_length = $1.length + 2
162
213
  seq = NULL * html_length
@@ -168,8 +219,13 @@ class RDoc::Markup::AttributeManager
168
219
  ##
169
220
  # Converts regexp handling sequences to RDoc attributes
170
221
 
171
- def convert_regexp_handlings str, attrs
222
+ def convert_regexp_handlings str, attrs, exclusive = false
172
223
  @regexp_handlings.each do |regexp, attribute|
224
+ if exclusive
225
+ next if !exclusive?(attribute)
226
+ else
227
+ next if exclusive?(attribute)
228
+ end
173
229
  str.scan(regexp) do
174
230
  capture = $~.size == 1 ? 0 : 1
175
231
 
@@ -205,7 +261,7 @@ class RDoc::Markup::AttributeManager
205
261
  #
206
262
  # am.add_word_pair '*', '*', :BOLD
207
263
 
208
- def add_word_pair(start, stop, name)
264
+ def add_word_pair(start, stop, name, exclusive = false)
209
265
  raise ArgumentError, "Word flags may not start with '<'" if
210
266
  start[0,1] == '<'
211
267
 
@@ -220,6 +276,8 @@ class RDoc::Markup::AttributeManager
220
276
 
221
277
  @protectable << start[0,1]
222
278
  @protectable.uniq!
279
+
280
+ @exclusive_bitmap |= bitmap if exclusive
223
281
  end
224
282
 
225
283
  ##
@@ -228,8 +286,10 @@ class RDoc::Markup::AttributeManager
228
286
  #
229
287
  # am.add_html 'em', :EM
230
288
 
231
- def add_html(tag, name)
232
- @html_tags[tag.downcase] = @attributes.bitmap_for name
289
+ def add_html(tag, name, exclusive = false)
290
+ bitmap = @attributes.bitmap_for name
291
+ @html_tags[tag.downcase] = bitmap
292
+ @exclusive_bitmap |= bitmap if exclusive
233
293
  end
234
294
 
235
295
  ##
@@ -238,8 +298,10 @@ class RDoc::Markup::AttributeManager
238
298
  #
239
299
  # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK)
240
300
 
241
- def add_regexp_handling pattern, name
242
- @regexp_handlings << [pattern, @attributes.bitmap_for(name)]
301
+ def add_regexp_handling pattern, name, exclusive = false
302
+ bitmap = @attributes.bitmap_for(name)
303
+ @regexp_handlings << [pattern, bitmap]
304
+ @exclusive_bitmap |= bitmap if exclusive
243
305
  end
244
306
 
245
307
  ##
@@ -250,8 +312,11 @@ class RDoc::Markup::AttributeManager
250
312
 
251
313
  mask_protected_sequences
252
314
 
253
- @attrs = RDoc::Markup::AttrSpan.new @str.length
315
+ @attrs = RDoc::Markup::AttrSpan.new @str.length, @exclusive_bitmap
254
316
 
317
+ convert_attrs @str, @attrs, true
318
+ convert_html @str, @attrs, true
319
+ convert_regexp_handlings @str, @attrs, true
255
320
  convert_attrs @str, @attrs
256
321
  convert_html @str, @attrs
257
322
  convert_regexp_handlings @str, @attrs
@@ -163,6 +163,8 @@ class RDoc::Markup::PreProcess
163
163
  if RDoc::Context === code_object then
164
164
  section = code_object.add_section param
165
165
  code_object.temporary_section = section
166
+ elsif RDoc::AnyMethod === code_object then
167
+ code_object.section_title = param
166
168
  end
167
169
 
168
170
  blankline # ignore category if we're not on an RDoc::Context
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ ##
3
+ # A section of table
4
+
5
+ class RDoc::Markup::Table
6
+ attr_accessor :header, :align, :body
7
+
8
+ def initialize header, align, body
9
+ @header, @align, @body = header, align, body
10
+ end
11
+
12
+ def == other
13
+ self.class == other.class and
14
+ @header == other.header and
15
+ @align == other.align and
16
+ @body == other.body
17
+ end
18
+
19
+ def accept visitor
20
+ visitor.accept_table @header, @body, @align
21
+ end
22
+
23
+ def pretty_print q # :nodoc:
24
+ q.group 2, '[Table: ', ']' do
25
+ q.group 2, '[Head: ', ']' do
26
+ q.seplist @header.zip(@align) do |text, align|
27
+ q.pp text
28
+ if align
29
+ q.text ":"
30
+ q.breakable
31
+ q.text align.to_s
32
+ end
33
+ end
34
+ end
35
+ q.breakable
36
+ q.group 2, '[Body: ', ']' do
37
+ q.seplist @body do |body|
38
+ q.group 2, '[', ']' do
39
+ q.seplist body do |text|
40
+ q.pp text
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -314,6 +314,29 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
314
314
  @res << raw.parts.join("\n")
315
315
  end
316
316
 
317
+ ##
318
+ # Adds +table+ to the output
319
+
320
+ def accept_table header, body, aligns
321
+ @res << "\n<table role=\"table\">\n<thead>\n<tr>\n"
322
+ header.zip(aligns) do |text, align|
323
+ @res << '<th'
324
+ @res << ' align="' << align << '"' if align
325
+ @res << '>' << CGI.escapeHTML(text) << "</th>\n"
326
+ end
327
+ @res << "</tr>\n</thead>\n<tbody>\n"
328
+ body.each do |row|
329
+ @res << "<tr>\n"
330
+ row.zip(aligns) do |text, align|
331
+ @res << '<td'
332
+ @res << ' align="' << align << '"' if align
333
+ @res << '>' << CGI.escapeHTML(text) << "</td>\n"
334
+ end
335
+ @res << "</tr>\n"
336
+ end
337
+ @res << "</tbody>\n</table>\n"
338
+ end
339
+
317
340
  # :section: Utilities
318
341
 
319
342
  ##
@@ -334,6 +357,10 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
334
357
  url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
335
358
  "<img src=\"#{url}\" />"
336
359
  else
360
+ if scheme != 'link' and %r%\A((?!https?:)(?:[^/#]*/)*+)([^/#]+)\.(rb|rdoc|md)(?=\z|#)%i =~ url
361
+ url = "#$1#{$2.tr('.', '_')}_#$3.html#$'"
362
+ end
363
+
337
364
  text = text.sub %r%^#{scheme}:/*%i, ''
338
365
  text = text.sub %r%^[*\^](\d+)$%, '\1'
339
366
 
@@ -41,6 +41,7 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
41
41
  alias accept_raw ignore
42
42
  alias accept_rule ignore
43
43
  alias accept_verbatim ignore
44
+ alias accept_table ignore
44
45
 
45
46
  end
46
47
 
@@ -237,6 +237,34 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
237
237
  @res << "\n"
238
238
  end
239
239
 
240
+ ##
241
+ # Adds +table+ to the output
242
+
243
+ def accept_table header, body, aligns
244
+ widths = header.zip(body) do |h, b|
245
+ [h.size, b.size].max
246
+ end
247
+ aligns = aligns.map do |a|
248
+ case a
249
+ when nil
250
+ :center
251
+ when :left
252
+ :ljust
253
+ when :right
254
+ :rjust
255
+ end
256
+ end
257
+ @res << header.zip(widths, aligns) do |h, w, a|
258
+ h.__send__(a, w)
259
+ end.join("|").rstrip << "\n"
260
+ @res << widths.map {|w| "-" * w }.join("|") << "\n"
261
+ body.each do |row|
262
+ @res << row.zip(widths, aligns) do |t, w, a|
263
+ t.__send__(a, w)
264
+ end.join("|").rstrip << "\n"
265
+ end
266
+ end
267
+
240
268
  ##
241
269
  # Applies attribute-specific markup to +text+ using RDoc::AttributeManager
242
270
 
@@ -82,6 +82,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
82
82
  alias accept_list_item_end ignore
83
83
  alias accept_list_end_bullet ignore
84
84
  alias accept_list_start ignore
85
+ alias accept_table ignore
85
86
  # :startdoc:
86
87
 
87
88
  end
data/lib/rdoc/markup.rb CHANGED
@@ -843,6 +843,7 @@ https://github.com/ruby/rdoc/issues
843
843
  autoload :List, 'rdoc/markup/list'
844
844
  autoload :ListItem, 'rdoc/markup/list_item'
845
845
  autoload :Paragraph, 'rdoc/markup/paragraph'
846
+ autoload :Table, 'rdoc/markup/table'
846
847
  autoload :Raw, 'rdoc/markup/raw'
847
848
  autoload :Rule, 'rdoc/markup/rule'
848
849
  autoload :Verbatim, 'rdoc/markup/verbatim'
data/lib/rdoc/options.rb CHANGED
@@ -338,8 +338,9 @@ class RDoc::Options
338
338
 
339
339
  attr_reader :visibility
340
340
 
341
- def initialize # :nodoc:
341
+ def initialize loaded_options = nil # :nodoc:
342
342
  init_ivars
343
+ override loaded_options if loaded_options
343
344
  end
344
345
 
345
346
  def init_ivars # :nodoc:
@@ -417,6 +418,37 @@ class RDoc::Options
417
418
  init_with map
418
419
  end
419
420
 
421
+ def override map # :nodoc:
422
+ if map.has_key?('encoding')
423
+ encoding = map['encoding']
424
+ @encoding = encoding ? Encoding.find(encoding) : encoding
425
+ end
426
+
427
+ @charset = map['charset'] if map.has_key?('charset')
428
+ @exclude = map['exclude'] if map.has_key?('exclude')
429
+ @generator_name = map['generator_name'] if map.has_key?('generator_name')
430
+ @hyperlink_all = map['hyperlink_all'] if map.has_key?('hyperlink_all')
431
+ @line_numbers = map['line_numbers'] if map.has_key?('line_numbers')
432
+ @locale_name = map['locale_name'] if map.has_key?('locale_name')
433
+ @locale_dir = map['locale_dir'] if map.has_key?('locale_dir')
434
+ @main_page = map['main_page'] if map.has_key?('main_page')
435
+ @markup = map['markup'] if map.has_key?('markup')
436
+ @op_dir = map['op_dir'] if map.has_key?('op_dir')
437
+ @show_hash = map['show_hash'] if map.has_key?('show_hash')
438
+ @tab_width = map['tab_width'] if map.has_key?('tab_width')
439
+ @template_dir = map['template_dir'] if map.has_key?('template_dir')
440
+ @title = map['title'] if map.has_key?('title')
441
+ @visibility = map['visibility'] if map.has_key?('visibility')
442
+ @webcvs = map['webcvs'] if map.has_key?('webcvs')
443
+
444
+ if map.has_key?('rdoc_include')
445
+ @rdoc_include = sanitize_path map['rdoc_include']
446
+ end
447
+ if map.has_key?('static_path')
448
+ @static_path = sanitize_path map['static_path']
449
+ end
450
+ end
451
+
420
452
  def == other # :nodoc:
421
453
  self.class === other and
422
454
  @encoding == other.encoding and
@@ -939,7 +971,7 @@ Usage: #{opt.program_name} [options] [names...]
939
971
  opt.on("--template-stylesheets=FILES", PathArray,
940
972
  "Set (or add to) the list of files to",
941
973
  "include with the html template.") do |value|
942
- @template_stylesheets << value
974
+ @template_stylesheets.concat value
943
975
  end
944
976
 
945
977
  opt.separator nil
@@ -1250,4 +1282,33 @@ Usage: #{opt.program_name} [options] [names...]
1250
1282
  end
1251
1283
  end
1252
1284
 
1285
+ ##
1286
+ # Loads options from .rdoc_options if the file exists, otherwise creates a
1287
+ # new RDoc::Options instance.
1288
+
1289
+ def self.load_options
1290
+ options_file = File.expand_path '.rdoc_options'
1291
+ return RDoc::Options.new unless File.exist? options_file
1292
+
1293
+ RDoc.load_yaml
1294
+
1295
+ begin
1296
+ options = YAML.safe_load File.read('.rdoc_options'), permitted_classes: [RDoc::Options, Symbol]
1297
+ rescue Psych::SyntaxError
1298
+ raise RDoc::Error, "#{options_file} is not a valid rdoc options file"
1299
+ end
1300
+
1301
+ return RDoc::Options.new unless options # Allow empty file.
1302
+
1303
+ raise RDoc::Error, "#{options_file} is not a valid rdoc options file" unless
1304
+ RDoc::Options === options or Hash === options
1305
+
1306
+ if Hash === options
1307
+ # Override the default values with the contents of YAML file.
1308
+ options = RDoc::Options.new options
1309
+ end
1310
+
1311
+ options
1312
+ end
1313
+
1253
1314
  end
data/lib/rdoc/parser/c.rb CHANGED
@@ -173,6 +173,8 @@ class RDoc::Parser::C < RDoc::Parser
173
173
  @classes = load_variable_map :c_class_variables
174
174
  @singleton_classes = load_variable_map :c_singleton_class_variables
175
175
 
176
+ @markup = @options.markup
177
+
176
178
  # class_variable => { function => [method, ...] }
177
179
  @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
178
180
 
@@ -439,7 +441,7 @@ class RDoc::Parser::C < RDoc::Parser
439
441
  next unless cls = @classes[c]
440
442
  m = @known_classes[m] || m
441
443
 
442
- comment = RDoc::Comment.new '', @top_level, :c
444
+ comment = new_comment '', @top_level, :c
443
445
  incl = cls.add_include RDoc::Include.new(m, comment)
444
446
  incl.record_location @top_level
445
447
  end
@@ -521,7 +523,7 @@ class RDoc::Parser::C < RDoc::Parser
521
523
  \s*"#{Regexp.escape new_name}"\s*,
522
524
  \s*"#{Regexp.escape old_name}"\s*\);%xm
523
525
 
524
- RDoc::Comment.new($1 || '', @top_level, :c)
526
+ new_comment($1 || '', @top_level, :c)
525
527
  end
526
528
 
527
529
  ##
@@ -560,7 +562,7 @@ class RDoc::Parser::C < RDoc::Parser
560
562
  ''
561
563
  end
562
564
 
563
- RDoc::Comment.new comment, @top_level, :c
565
+ new_comment comment, @top_level, :c
564
566
  end
565
567
 
566
568
  ##
@@ -600,7 +602,7 @@ class RDoc::Parser::C < RDoc::Parser
600
602
 
601
603
  case type
602
604
  when :func_def
603
- comment = RDoc::Comment.new args[0], @top_level, :c
605
+ comment = new_comment args[0], @top_level, :c
604
606
  body = args[1]
605
607
  offset, = args[2]
606
608
 
@@ -630,7 +632,7 @@ class RDoc::Parser::C < RDoc::Parser
630
632
 
631
633
  body
632
634
  when :macro_def
633
- comment = RDoc::Comment.new args[0], @top_level, :c
635
+ comment = new_comment args[0], @top_level, :c
634
636
  body = args[1]
635
637
  offset, = args[2]
636
638
 
@@ -737,7 +739,7 @@ class RDoc::Parser::C < RDoc::Parser
737
739
  comment = ''
738
740
  end
739
741
 
740
- comment = RDoc::Comment.new comment, @top_level, :c
742
+ comment = new_comment comment, @top_level, :c
741
743
  comment.normalize
742
744
 
743
745
  look_for_directives_in class_mod, comment
@@ -782,7 +784,7 @@ class RDoc::Parser::C < RDoc::Parser
782
784
  table[const_name] ||
783
785
  ''
784
786
 
785
- RDoc::Comment.new comment, @top_level, :c
787
+ new_comment comment, @top_level, :c
786
788
  end
787
789
 
788
790
  ##
@@ -813,7 +815,7 @@ class RDoc::Parser::C < RDoc::Parser
813
815
 
814
816
  return unless comment
815
817
 
816
- RDoc::Comment.new comment, @top_level, :c
818
+ new_comment comment, @top_level, :c
817
819
  end
818
820
 
819
821
  ##
@@ -947,7 +949,7 @@ class RDoc::Parser::C < RDoc::Parser
947
949
 
948
950
  new_comment = "#{$1}#{new_comment.lstrip}"
949
951
 
950
- new_comment = RDoc::Comment.new new_comment, @top_level, :c
952
+ new_comment = self.new_comment(new_comment, @top_level, :c)
951
953
 
952
954
  con = RDoc::Constant.new const_name, new_definition, new_comment
953
955
  else
@@ -1028,7 +1030,12 @@ class RDoc::Parser::C < RDoc::Parser
1028
1030
 
1029
1031
 
1030
1032
  meth_obj.record_location @top_level
1033
+
1034
+ if meth_obj.section_title
1035
+ class_obj.temporary_section = class_obj.add_section(meth_obj.section_title)
1036
+ end
1031
1037
  class_obj.add_method meth_obj
1038
+
1032
1039
  @stats.add_method meth_obj
1033
1040
  meth_obj.visibility = :private if 'private_method' == type
1034
1041
  end
@@ -1222,4 +1229,9 @@ class RDoc::Parser::C < RDoc::Parser
1222
1229
  @top_level
1223
1230
  end
1224
1231
 
1232
+ def new_comment text = nil, location = nil, language = nil
1233
+ RDoc::Comment.new(text, location, language).tap do |comment|
1234
+ comment.format = @markup
1235
+ end
1236
+ end
1225
1237
  end