annotaterb 4.0.0 → 4.1.1
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.
- checksums.yaml +4 -4
- data/README.md +4 -5
- data/VERSION +1 -1
- data/lib/annotate_rb/model_annotator/annotation_decider.rb +62 -0
- data/lib/annotate_rb/model_annotator/annotation_diff.rb +19 -0
- data/lib/annotate_rb/model_annotator/annotation_diff_generator.rb +44 -0
- data/lib/annotate_rb/model_annotator/annotation_generator.rb +94 -0
- data/lib/annotate_rb/model_annotator/annotator.rb +27 -31
- data/lib/annotate_rb/model_annotator/column_annotation_builder.rb +92 -0
- data/lib/annotate_rb/model_annotator/column_attributes_builder.rb +102 -0
- data/lib/annotate_rb/model_annotator/column_type_builder.rb +51 -0
- data/lib/annotate_rb/model_annotator/column_wrapper.rb +84 -0
- data/lib/annotate_rb/model_annotator/constants.rb +2 -2
- data/lib/annotate_rb/model_annotator/file_annotator.rb +9 -11
- data/lib/annotate_rb/model_annotator/file_annotator_instruction.rb +17 -0
- data/lib/annotate_rb/model_annotator/foreign_key_annotation_builder.rb +55 -0
- data/lib/annotate_rb/model_annotator/helper.rb +75 -22
- data/lib/annotate_rb/model_annotator/index_annotation_builder.rb +74 -0
- data/lib/annotate_rb/model_annotator/model_file_annotator.rb +21 -84
- data/lib/annotate_rb/model_annotator/model_files_getter.rb +4 -2
- data/lib/annotate_rb/model_annotator/model_wrapper.rb +155 -0
- data/lib/annotate_rb/model_annotator/related_files_list_builder.rb +137 -0
- data/lib/annotate_rb/model_annotator.rb +13 -1
- data/lib/annotate_rb/options.rb +16 -9
- data/lib/annotate_rb/parser.rb +0 -14
- data/lib/annotate_rb.rb +0 -1
- metadata +15 -4
- data/lib/annotate_rb/env.rb +0 -30
- data/lib/annotate_rb/model_annotator/schema_info.rb +0 -480
@@ -1,480 +0,0 @@
|
|
1
|
-
module AnnotateRb
|
2
|
-
module ModelAnnotator
|
3
|
-
module SchemaInfo # rubocop:disable Metrics/ModuleLength
|
4
|
-
# Don't show default value for these column types
|
5
|
-
NO_DEFAULT_COL_TYPES = %w[json jsonb hstore].freeze
|
6
|
-
|
7
|
-
# Don't show limit (#) on these column types
|
8
|
-
# Example: show "integer" instead of "integer(4)"
|
9
|
-
NO_LIMIT_COL_TYPES = %w[integer bigint boolean].freeze
|
10
|
-
|
11
|
-
INDEX_CLAUSES = {
|
12
|
-
unique: {
|
13
|
-
default: 'UNIQUE',
|
14
|
-
markdown: '_unique_'
|
15
|
-
},
|
16
|
-
where: {
|
17
|
-
default: 'WHERE',
|
18
|
-
markdown: '_where_'
|
19
|
-
},
|
20
|
-
using: {
|
21
|
-
default: 'USING',
|
22
|
-
markdown: '_using_'
|
23
|
-
}
|
24
|
-
}.freeze
|
25
|
-
|
26
|
-
END_MARK = '== Schema Information End'.freeze
|
27
|
-
|
28
|
-
class << self
|
29
|
-
# Use the column information in an ActiveRecord class
|
30
|
-
# to create a comment block containing a line for
|
31
|
-
# each column. The line contains the column name,
|
32
|
-
# the type (and length), and any optional attributes
|
33
|
-
def generate(klass, header, options = {}) # rubocop:disable Metrics/MethodLength
|
34
|
-
info = "# #{header}\n"
|
35
|
-
info << get_schema_header_text(klass, options)
|
36
|
-
|
37
|
-
max_size = max_schema_info_width(klass, options)
|
38
|
-
md_names_overhead = 6
|
39
|
-
md_type_allowance = 18
|
40
|
-
bare_type_allowance = 16
|
41
|
-
|
42
|
-
if options[:format_markdown]
|
43
|
-
info << format("# %-#{max_size + md_names_overhead}.#{max_size + md_names_overhead}s | %-#{md_type_allowance}.#{md_type_allowance}s | %s\n",
|
44
|
-
'Name',
|
45
|
-
'Type',
|
46
|
-
'Attributes')
|
47
|
-
info << "# #{'-' * (max_size + md_names_overhead)} | #{'-' * md_type_allowance} | #{'-' * 27}\n"
|
48
|
-
end
|
49
|
-
|
50
|
-
cols = columns(klass, options)
|
51
|
-
cols.each do |col|
|
52
|
-
col_type = get_col_type(col)
|
53
|
-
attrs = get_attributes(col, col_type, klass, options)
|
54
|
-
col_name = if with_comments?(klass, options) && col.comment
|
55
|
-
"#{col.name}(#{col.comment.gsub(/\n/, '\\n')})"
|
56
|
-
else
|
57
|
-
col.name
|
58
|
-
end
|
59
|
-
|
60
|
-
if options[:format_rdoc]
|
61
|
-
info << format("# %-#{max_size}.#{max_size}s<tt>%s</tt>",
|
62
|
-
"*#{col_name}*::",
|
63
|
-
attrs.unshift(col_type).join(', ')).rstrip + "\n"
|
64
|
-
elsif options[:format_yard]
|
65
|
-
info << sprintf("# @!attribute #{col_name}") + "\n"
|
66
|
-
ruby_class = col.respond_to?(:array) && col.array ? "Array<#{map_col_type_to_ruby_classes(col_type)}>" : map_col_type_to_ruby_classes(col_type)
|
67
|
-
info << sprintf("# @return [#{ruby_class}]") + "\n"
|
68
|
-
elsif options[:format_markdown]
|
69
|
-
name_remainder = max_size - col_name.length - non_ascii_length(col_name)
|
70
|
-
type_remainder = (md_type_allowance - 2) - col_type.length
|
71
|
-
info << format("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`",
|
72
|
-
col_name,
|
73
|
-
' ',
|
74
|
-
col_type,
|
75
|
-
' ',
|
76
|
-
attrs.join(', ').rstrip).gsub('``', ' ').rstrip + "\n"
|
77
|
-
else
|
78
|
-
info << format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
info << get_index_info(klass, options) if options[:show_indexes] && klass.table_exists?
|
83
|
-
|
84
|
-
info << get_foreign_key_info(klass, options) if options[:show_foreign_keys] && klass.table_exists?
|
85
|
-
|
86
|
-
info << get_schema_footer_text(klass, options)
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def get_schema_header_text(klass, options = {})
|
92
|
-
info = "#\n"
|
93
|
-
if options[:format_markdown]
|
94
|
-
info << "# Table name: `#{klass.table_name}`\n"
|
95
|
-
info << "#\n"
|
96
|
-
info << "# ### Columns\n"
|
97
|
-
else
|
98
|
-
info << "# Table name: #{klass.table_name}\n"
|
99
|
-
end
|
100
|
-
info << "#\n"
|
101
|
-
end
|
102
|
-
|
103
|
-
def max_schema_info_width(klass, options)
|
104
|
-
cols = columns(klass, options)
|
105
|
-
|
106
|
-
if with_comments?(klass, options)
|
107
|
-
max_size = cols.map do |column|
|
108
|
-
column.name.size + (column.comment ? width(column.comment) : 0)
|
109
|
-
end.max || 0
|
110
|
-
max_size += 2
|
111
|
-
else
|
112
|
-
max_size = cols.map(&:name).map(&:size).max
|
113
|
-
end
|
114
|
-
max_size += options[:format_rdoc] ? 5 : 1
|
115
|
-
|
116
|
-
max_size
|
117
|
-
end
|
118
|
-
|
119
|
-
def with_comments?(klass, options)
|
120
|
-
options[:with_comment] &&
|
121
|
-
klass.columns.first.respond_to?(:comment) &&
|
122
|
-
klass.columns.map(&:comment).any? { |comment| !comment.nil? }
|
123
|
-
end
|
124
|
-
|
125
|
-
def width(string)
|
126
|
-
string.chars.inject(0) { |acc, elem| acc + (elem.bytesize == 3 ? 2 : 1) }
|
127
|
-
end
|
128
|
-
|
129
|
-
# TODO: Memoize this since it's called multiple times with the same args
|
130
|
-
def columns(klass, options)
|
131
|
-
cols = klass.columns
|
132
|
-
cols += translated_columns(klass)
|
133
|
-
|
134
|
-
ignore_columns = options[:ignore_columns]
|
135
|
-
if ignore_columns
|
136
|
-
cols = cols.reject do |col|
|
137
|
-
col.name.match(/#{ignore_columns}/)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
cols = cols.sort_by(&:name) if options[:sort]
|
142
|
-
cols = classified_sort(cols) if options[:classified_sort]
|
143
|
-
|
144
|
-
cols
|
145
|
-
end
|
146
|
-
|
147
|
-
# Add columns managed by the globalize gem if this gem is being used.
|
148
|
-
def translated_columns(klass)
|
149
|
-
return [] unless klass.respond_to? :translation_class
|
150
|
-
|
151
|
-
ignored_cols = ignored_translation_table_colums(klass)
|
152
|
-
klass.translation_class.columns.reject do |col|
|
153
|
-
ignored_cols.include? col.name.to_sym
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# These are the columns that the globalize gem needs to work but
|
158
|
-
# are not necessary for the models to be displayed as annotations.
|
159
|
-
def ignored_translation_table_colums(klass)
|
160
|
-
# Construct the foreign column name in the translations table
|
161
|
-
# eg. Model: Car, foreign column name: car_id
|
162
|
-
foreign_column_name = [
|
163
|
-
klass.translation_class.to_s
|
164
|
-
.gsub('::Translation', '').gsub('::', '_')
|
165
|
-
.downcase,
|
166
|
-
'_id'
|
167
|
-
].join.to_sym
|
168
|
-
|
169
|
-
[
|
170
|
-
:id,
|
171
|
-
:created_at,
|
172
|
-
:updated_at,
|
173
|
-
:locale,
|
174
|
-
foreign_column_name
|
175
|
-
]
|
176
|
-
end
|
177
|
-
|
178
|
-
def classified_sort(cols)
|
179
|
-
rest_cols = []
|
180
|
-
timestamps = []
|
181
|
-
associations = []
|
182
|
-
id = nil
|
183
|
-
|
184
|
-
cols.each do |c|
|
185
|
-
if c.name.eql?('id')
|
186
|
-
id = c
|
187
|
-
elsif c.name.eql?('created_at') || c.name.eql?('updated_at')
|
188
|
-
timestamps << c
|
189
|
-
elsif c.name[-3, 3].eql?('_id')
|
190
|
-
associations << c
|
191
|
-
else
|
192
|
-
rest_cols << c
|
193
|
-
end
|
194
|
-
end
|
195
|
-
[rest_cols, timestamps, associations].each { |a| a.sort_by!(&:name) }
|
196
|
-
|
197
|
-
([id] << rest_cols << timestamps << associations).flatten.compact
|
198
|
-
end
|
199
|
-
|
200
|
-
def get_col_type(col)
|
201
|
-
if (col.respond_to?(:bigint?) && col.bigint?) || /\Abigint\b/ =~ col.sql_type
|
202
|
-
'bigint'
|
203
|
-
else
|
204
|
-
(col.type || col.sql_type).to_s
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
# Get the list of attributes that should be included in the annotation for
|
209
|
-
# a given column.
|
210
|
-
def get_attributes(column, column_type, klass, options)
|
211
|
-
attrs = []
|
212
|
-
attrs << "default(#{schema_default(klass, column)})" unless column.default.nil? || hide_default?(column_type, options)
|
213
|
-
attrs << 'unsigned' if column.respond_to?(:unsigned?) && column.unsigned?
|
214
|
-
attrs << 'not null' unless column.null
|
215
|
-
attrs << 'primary key' if klass.primary_key && (klass.primary_key.is_a?(Array) ? klass.primary_key.collect(&:to_sym).include?(column.name.to_sym) : column.name.to_sym == klass.primary_key.to_sym)
|
216
|
-
|
217
|
-
if column_type == 'decimal'
|
218
|
-
column_type << "(#{column.precision}, #{column.scale})"
|
219
|
-
elsif !%w[spatial geometry geography].include?(column_type)
|
220
|
-
if column.limit && !options[:format_yard]
|
221
|
-
if column.limit.is_a? Array
|
222
|
-
attrs << "(#{column.limit.join(', ')})"
|
223
|
-
else
|
224
|
-
column_type << "(#{column.limit})" unless hide_limit?(column_type, options)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
# Check out if we got an array column
|
230
|
-
attrs << 'is an Array' if column.respond_to?(:array) && column.array
|
231
|
-
|
232
|
-
# Check out if we got a geometric column
|
233
|
-
# and print the type and SRID
|
234
|
-
if column.respond_to?(:geometry_type)
|
235
|
-
attrs << "#{column.geometry_type}, #{column.srid}"
|
236
|
-
elsif column.respond_to?(:geometric_type) && column.geometric_type.present?
|
237
|
-
attrs << "#{column.geometric_type.to_s.downcase}, #{column.srid}"
|
238
|
-
end
|
239
|
-
|
240
|
-
# Check if the column has indices and print "indexed" if true
|
241
|
-
# If the index includes another column, print it too.
|
242
|
-
if options[:simple_indexes] && klass.table_exists? # Check out if this column is indexed
|
243
|
-
indices = retrieve_indexes_from_table(klass).select { |ind| ind.columns.include? column.name }
|
244
|
-
indices&.sort_by(&:name)&.each do |ind|
|
245
|
-
next if ind.columns.is_a?(String)
|
246
|
-
|
247
|
-
ind = ind.columns.reject! { |i| i == column.name }
|
248
|
-
attrs << (ind.empty? ? 'indexed' : "indexed => [#{ind.join(', ')}]")
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
attrs
|
253
|
-
end
|
254
|
-
|
255
|
-
def schema_default(klass, column)
|
256
|
-
quote(klass.column_defaults[column.name])
|
257
|
-
end
|
258
|
-
|
259
|
-
# Simple quoting for the default column value
|
260
|
-
def quote(value)
|
261
|
-
case value
|
262
|
-
when NilClass then 'NULL'
|
263
|
-
when TrueClass then 'TRUE'
|
264
|
-
when FalseClass then 'FALSE'
|
265
|
-
when Float, Integer then value.to_s
|
266
|
-
# BigDecimals need to be output in a non-normalized form and quoted.
|
267
|
-
when BigDecimal then value.to_s('F')
|
268
|
-
when Array then value.map { |v| quote(v) }
|
269
|
-
else
|
270
|
-
value.inspect
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def hide_default?(col_type, options)
|
275
|
-
excludes =
|
276
|
-
if options[:hide_default_column_types].blank?
|
277
|
-
NO_DEFAULT_COL_TYPES
|
278
|
-
else
|
279
|
-
options[:hide_default_column_types].split(',')
|
280
|
-
end
|
281
|
-
|
282
|
-
excludes.include?(col_type)
|
283
|
-
end
|
284
|
-
|
285
|
-
def hide_limit?(col_type, options)
|
286
|
-
excludes =
|
287
|
-
if options[:hide_limit_column_types].blank?
|
288
|
-
NO_LIMIT_COL_TYPES
|
289
|
-
else
|
290
|
-
options[:hide_limit_column_types].split(',')
|
291
|
-
end
|
292
|
-
|
293
|
-
excludes.include?(col_type)
|
294
|
-
end
|
295
|
-
|
296
|
-
def retrieve_indexes_from_table(klass)
|
297
|
-
table_name = klass.table_name
|
298
|
-
return [] unless table_name
|
299
|
-
|
300
|
-
indexes = klass.connection.indexes(table_name)
|
301
|
-
return indexes if indexes.any? || !klass.table_name_prefix
|
302
|
-
|
303
|
-
# Try to search the table without prefix
|
304
|
-
table_name_without_prefix = table_name.to_s.sub(klass.table_name_prefix, '')
|
305
|
-
klass.connection.indexes(table_name_without_prefix)
|
306
|
-
end
|
307
|
-
|
308
|
-
def map_col_type_to_ruby_classes(col_type)
|
309
|
-
case col_type
|
310
|
-
when 'integer' then Integer.to_s
|
311
|
-
when 'float' then Float.to_s
|
312
|
-
when 'decimal' then BigDecimal.to_s
|
313
|
-
when 'datetime', 'timestamp', 'time' then Time.to_s
|
314
|
-
when 'date' then Date.to_s
|
315
|
-
when 'text', 'string', 'binary', 'inet', 'uuid' then String.to_s
|
316
|
-
when 'json', 'jsonb' then Hash.to_s
|
317
|
-
when 'boolean' then 'Boolean'
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
def non_ascii_length(string)
|
322
|
-
string.to_s.chars.reject(&:ascii_only?).length
|
323
|
-
end
|
324
|
-
|
325
|
-
def format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
|
326
|
-
format('# %s:%s %s',
|
327
|
-
mb_chars_ljust(col_name, max_size),
|
328
|
-
mb_chars_ljust(col_type, bare_type_allowance),
|
329
|
-
attrs.join(', ')).rstrip + "\n"
|
330
|
-
end
|
331
|
-
|
332
|
-
def mb_chars_ljust(string, length)
|
333
|
-
string = string.to_s
|
334
|
-
padding = length - width(string)
|
335
|
-
if padding.positive?
|
336
|
-
string + (' ' * padding)
|
337
|
-
else
|
338
|
-
string[0..(length - 1)]
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
def get_index_info(klass, options = {})
|
343
|
-
index_info = if options[:format_markdown]
|
344
|
-
"#\n# ### Indexes\n#\n"
|
345
|
-
else
|
346
|
-
"#\n# Indexes\n#\n"
|
347
|
-
end
|
348
|
-
|
349
|
-
indexes = retrieve_indexes_from_table(klass)
|
350
|
-
return '' if indexes.empty?
|
351
|
-
|
352
|
-
max_size = indexes.collect { |index| index.name.size }.max + 1
|
353
|
-
indexes.sort_by(&:name).each do |index|
|
354
|
-
index_info << if options[:format_markdown]
|
355
|
-
final_index_string_in_markdown(index)
|
356
|
-
else
|
357
|
-
final_index_string(index, max_size)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
index_info
|
362
|
-
end
|
363
|
-
|
364
|
-
def final_index_string_in_markdown(index)
|
365
|
-
details = format(
|
366
|
-
'%s%s%s',
|
367
|
-
index_unique_info(index, :markdown),
|
368
|
-
index_where_info(index, :markdown),
|
369
|
-
index_using_info(index, :markdown)
|
370
|
-
).strip
|
371
|
-
details = " (#{details})" unless details.blank?
|
372
|
-
|
373
|
-
format(
|
374
|
-
"# * `%s`%s:\n# * **`%s`**\n",
|
375
|
-
index.name,
|
376
|
-
details,
|
377
|
-
index_columns_info(index).join("`**\n# * **`")
|
378
|
-
)
|
379
|
-
end
|
380
|
-
|
381
|
-
def final_index_string(index, max_size)
|
382
|
-
format(
|
383
|
-
"# %-#{max_size}.#{max_size}s %s%s%s%s",
|
384
|
-
index.name,
|
385
|
-
"(#{index_columns_info(index).join(',')})",
|
386
|
-
index_unique_info(index),
|
387
|
-
index_where_info(index),
|
388
|
-
index_using_info(index)
|
389
|
-
).rstrip + "\n"
|
390
|
-
end
|
391
|
-
|
392
|
-
def index_columns_info(index)
|
393
|
-
Array(index.columns).map do |col|
|
394
|
-
if index.try(:orders) && index.orders[col.to_s]
|
395
|
-
"#{col} #{index.orders[col.to_s].upcase}"
|
396
|
-
else
|
397
|
-
col.to_s.gsub("\r", '\r').gsub("\n", '\n')
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
def index_where_info(index, format = :default)
|
403
|
-
value = index.try(:where).try(:to_s)
|
404
|
-
if value.blank?
|
405
|
-
''
|
406
|
-
else
|
407
|
-
" #{INDEX_CLAUSES[:where][format]} #{value}"
|
408
|
-
end
|
409
|
-
end
|
410
|
-
|
411
|
-
def index_unique_info(index, format = :default)
|
412
|
-
index.unique ? " #{INDEX_CLAUSES[:unique][format]}" : ''
|
413
|
-
end
|
414
|
-
|
415
|
-
def index_using_info(index, format = :default)
|
416
|
-
value = index.try(:using) && index.using.try(:to_sym)
|
417
|
-
if !value.blank? && value != :btree
|
418
|
-
" #{INDEX_CLAUSES[:using][format]} #{value}"
|
419
|
-
else
|
420
|
-
''
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
def get_foreign_key_info(klass, options = {})
|
425
|
-
fk_info = if options[:format_markdown]
|
426
|
-
"#\n# ### Foreign Keys\n#\n"
|
427
|
-
else
|
428
|
-
"#\n# Foreign Keys\n#\n"
|
429
|
-
end
|
430
|
-
|
431
|
-
return '' unless klass.connection.respond_to?(:supports_foreign_keys?) &&
|
432
|
-
klass.connection.supports_foreign_keys? && klass.connection.respond_to?(:foreign_keys)
|
433
|
-
|
434
|
-
foreign_keys = klass.connection.foreign_keys(klass.table_name)
|
435
|
-
return '' if foreign_keys.empty?
|
436
|
-
|
437
|
-
format_name = lambda do |fk|
|
438
|
-
return fk.options[:column] if fk.name.blank?
|
439
|
-
|
440
|
-
options[:show_complete_foreign_keys] ? fk.name : fk.name.gsub(/(?<=^fk_rails_)[0-9a-f]{10}$/, '...')
|
441
|
-
end
|
442
|
-
|
443
|
-
max_size = foreign_keys.map(&format_name).map(&:size).max + 1
|
444
|
-
foreign_keys.sort_by { |fk| [format_name.call(fk), fk.column] }.each do |fk|
|
445
|
-
ref_info = "#{fk.column} => #{fk.to_table}.#{fk.primary_key}"
|
446
|
-
constraints_info = ''
|
447
|
-
constraints_info += "ON DELETE => #{fk.on_delete} " if fk.on_delete
|
448
|
-
constraints_info += "ON UPDATE => #{fk.on_update} " if fk.on_update
|
449
|
-
constraints_info.strip!
|
450
|
-
|
451
|
-
fk_info << if options[:format_markdown]
|
452
|
-
format("# * `%s`%s:\n# * **`%s`**\n",
|
453
|
-
format_name.call(fk),
|
454
|
-
constraints_info.blank? ? '' : " (_#{constraints_info}_)",
|
455
|
-
ref_info)
|
456
|
-
else
|
457
|
-
format("# %-#{max_size}.#{max_size}s %s %s",
|
458
|
-
format_name.call(fk),
|
459
|
-
"(#{ref_info})",
|
460
|
-
constraints_info).rstrip + "\n"
|
461
|
-
end
|
462
|
-
end
|
463
|
-
|
464
|
-
fk_info
|
465
|
-
end
|
466
|
-
|
467
|
-
def get_schema_footer_text(_klass, options = {})
|
468
|
-
info = ''
|
469
|
-
if options[:format_rdoc]
|
470
|
-
info << "#--\n"
|
471
|
-
info << "# #{END_MARK}\n"
|
472
|
-
info << "#++\n"
|
473
|
-
else
|
474
|
-
info << "#\n"
|
475
|
-
end
|
476
|
-
end
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
480
|
-
end
|