codeblock 1.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 (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +191 -0
  3. data/lib/codeblock.rb +606 -0
  4. metadata +59 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 583c7a3edfb276f54463bc3c9a04ff035d9c7597b8f353fdc18b1076cfdf1b33
4
+ data.tar.gz: b6d7010884b4fc6a0347896d9a6029ce6c8e01cbc11ef2f0c0e3e8dd4441d395
5
+ SHA512:
6
+ metadata.gz: b001b7883f3075a41638aa92f66935eb4b52ad3a7eb90b182d1b3ebc2950f11312787e4df387b63d69de4297fb4e472495093547781da1d8edaf5acaf5b551c4
7
+ data.tar.gz: 759e75ff240f9a12b4d06d67fd7af5ce536c0b0c896443ffbc30f7891d00d786147b180c7a914f7130494f82b3f44827fa61733a16283e92716e210716e5e7a1
@@ -0,0 +1,191 @@
1
+ # CodeBlock
2
+
3
+ CodeBlock assists in documenting code by importing working code for display in
4
+ documentation. CodeBlock allows you to write working examples of code, then
5
+ import that code into documentation without any copying or pasting. Features
6
+ include:
7
+
8
+ - import all of a file or just parts of it
9
+ - strip out lines that are not relevent to the documentation
10
+ - reference lines by name instead of line number
11
+
12
+ CodeBlock itself is not a documentation system. It is intended for use in other
13
+ documentation systems.
14
+
15
+ ## Basic usage
16
+
17
+ Consider an example of a code file that I have for development of a DBMS system
18
+ I'm developing called "Audrey". The code file looks like this:
19
+
20
+ #!/usr/bin/ruby -w
21
+ require 'audrey'
22
+
23
+ # connect to database, creating it if necessary
24
+ Audrey.connect('/tmp/my.db', 'rw') do |db|
25
+ db['hero'] = 'Thor'
26
+ db['antagonist'] = 'Loki'
27
+ end
28
+
29
+ # done
30
+ puts '[done]'
31
+
32
+ In its simplest use, a new CodeBlock object simply slurps in a code file. The
33
+ contents of the file are accessible in the object's to_s method. So, we might
34
+ use CodeBlock like this:
35
+
36
+ require 'codeblock'
37
+ src_path = 'samples/plain.rb'
38
+ block = CodeBlock.new(File.read src_path)
39
+ puts block.to_s # => outputs the exact contents of the file
40
+
41
+ So far that's not very useful. We could accomplish the same thing by simply
42
+ slurping in the file contents. Let's look at a more advanced usage.
43
+
44
+ Suppose you only want to display a certain block of code in your documentation.
45
+ Now, you could just copy and paste the relevent block into your documentation,
46
+ but that's redundant information. Your document doesn't get updated if you
47
+ change the working example. That's where CodeBlock gets useful. With CodeBlock,
48
+ you can name specific lines to import. Let's look at the same working code as
49
+ above, but with a few additions.
50
+
51
+ #!/usr/bin/ruby -w
52
+ require 'audrey'
53
+
54
+ # connect to database, creating it if necessary
55
+ Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=begin
56
+ db['hero'] = 'Thor'
57
+ db['antagonist'] = 'Loki'
58
+ end ## name=finish
59
+
60
+ # done
61
+ puts '[done]'
62
+
63
+ That's the same working code... all we've done is added some comments that
64
+ CodeBlock can interpret. Each line to which we want to add information has `##`
65
+ followed by name=value pairs. In the above example, the lines are givens the
66
+ names "begin" and "finish".
67
+
68
+ To extract the block of code that starts with "begin" and ends with "finish",
69
+ we set the CodeBlock#start and CodeBlock#end properties, like this:
70
+
71
+ src_path = 'samples/block.rb'
72
+ block = CodeBlock.new(File.read src_path)
73
+ block.start = 'begin'
74
+ block.end = 'finish'
75
+ block.to_s
76
+
77
+ That retrieves just the lines indicated. Notice that `##` and everything after
78
+ it is stripped from the lines:
79
+
80
+ Audrey.connect('/tmp/my.db', 'rw') do |db|
81
+ db['hero'] = 'Thor'
82
+ db['antagonist'] = 'Loki'
83
+ end
84
+
85
+ ## Skip lines
86
+
87
+ You might find that in some situations its helpful to have code in your working
88
+ file that isn't relevent to the documentation. In those case, you can indicate
89
+ that a line should be skipped with skip=true:
90
+
91
+ Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=start
92
+ db['hero'] = 'Thor'
93
+ puts db['hero'] ## skip=true
94
+ end ## name=end
95
+
96
+ That will results in a code sample that doesn't include that line
97
+
98
+ Audrey.connect('/tmp/my.db', 'rw') do |db|
99
+ db['hero'] = 'Thor'
100
+ end
101
+
102
+ ## Line numbers
103
+
104
+ You might want to include line numbers in your documentation. There are two ways
105
+ to do this.
106
+
107
+ First, you might want a string just of line numbers. Doing so would allow you to
108
+ put the line numbers into an HTML <pre> tag alongside the code itself. To get
109
+ line numbers simply call CodeBlock#line_nums_to_s. Doing so outputs something
110
+ like as follows. Notice that the numbers are right justified.
111
+
112
+ 1.
113
+ 2.
114
+ 3.
115
+ 4.
116
+ 5.
117
+ 6.
118
+ 7.
119
+ 8.
120
+ 9.
121
+ 10.
122
+ 11.
123
+ 12.
124
+
125
+ The line numbers match up with the lines that have been selected, not the line
126
+ numbers in the file. That allows you to display code lines and line numbers that
127
+ match up.
128
+
129
+ To output the entire code block with line numbers, set the block's `line_nums`
130
+ property to true:
131
+
132
+ block.line_nums = true
133
+ puts block.to_s
134
+
135
+ That will output something like this:
136
+
137
+ 1. # connect to database, creating it if necessary
138
+ 2. Audrey.connect('/tmp/my.db', 'rw') do |db|
139
+ 3. db['hero'] = 'Thor'
140
+ 4. db['antagonist'] = 'Loki'
141
+ 5. end
142
+ 6.
143
+ 7. # read
144
+ 8. Audrey.connect('/tmp/my.db', 'rw') do |db|
145
+ 9. puts db['hero']
146
+ 10. puts db['antagonist']
147
+ 11. end
148
+ 12.
149
+ 13. # done
150
+ 14. puts '[done]'
151
+
152
+ ## Named lines
153
+
154
+ Lines can be referenced by their names to get their line numbers. This allows
155
+ you to give the number of a line in a block without having to change the line
156
+ number when you modify the block. Access the line in the block's `named`
157
+ property.
158
+
159
+ In this example, we name one of the lines "Thor":
160
+
161
+ Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=start
162
+ db['hero'] = 'Thor' ## name=Thor
163
+ end ## name=end
164
+
165
+ Then, depending on how your documentation system works, you could reference the
166
+ line number like this:
167
+
168
+ src_path = 'samples/named-lines.rb'
169
+ block = CodeBlock.new(File.read(src_path), 'se'=>true)
170
+ puts "In line number #{block.named['Thor'].number} we set a value."
171
+
172
+ This will output as follows:
173
+
174
+ In line number 2 we set a value.
175
+
176
+ ## Install
177
+
178
+ ```
179
+ gem install codeblock
180
+ ```
181
+
182
+ ## Author
183
+
184
+ Mike O'Sullivan
185
+ mike@idocs.com
186
+
187
+ ## History
188
+
189
+ | version | date | notes |
190
+ |---------|---------------|-------------------------------------------------------|
191
+ | 1.0 | June 18, 2020 | Initial upload. |
@@ -0,0 +1,606 @@
1
+ require 'attparser'
2
+
3
+
4
+ #===============================================================================
5
+ # CodeBlock
6
+ #
7
+ class CodeBlock
8
+ # Version
9
+ VERSION = '1.0'
10
+
11
+ #---------------------------------------------------------------------------
12
+ # initialize
13
+ #
14
+
15
+ # First param should be the code that should be parsed. The remaining
16
+ # options follow the names of the various properties that can be set. So,
17
+ # for example, to create a block with named, starting and ending lines,
18
+ # you could do this:
19
+ #
20
+ # block = CodeBlock.new(src, 'start'=>'a', 'end'=>'b')
21
+ #
22
+ # You might find that you are often naming the starting line "start" and the
23
+ # ending line "end". To simplify setting those common names, you can use the
24
+ # se ("start/end") option:
25
+ #
26
+ # block = CodeBlock.new(src, 'se'=>true)
27
+ #
28
+ # That is exactly equivelant to:
29
+ #
30
+ # block = CodeBlock.new(src, 'start'=>'start', 'end'=>'end')
31
+
32
+ def initialize(raw, opts={})
33
+ @lines_org = raw.lines
34
+ @keep_meta = opts['keep_meta'] || false
35
+ @tab = opts['tab'] || ' '
36
+ @indent = opts['indent']
37
+ @line_nums = opts['line_nums']
38
+
39
+ # if 'se' param, set start and end to "start" and "end"
40
+ if opts['se']
41
+ @start = 'start'
42
+ @end = 'end'
43
+ else
44
+ @start = opts['start']
45
+ @end = opts['end']
46
+ end
47
+
48
+ # if collapse is defined
49
+ if opts.has_key?('collapse')
50
+ @collapse = opts['collapse']
51
+ else
52
+ @collapse = true
53
+ end
54
+
55
+ # if skip_skips is defined
56
+ if opts.has_key?('skip_skips')
57
+ @skip_skips = opts['skip_skips']
58
+ else
59
+ @skip_skips = true
60
+ end
61
+
62
+ # initialize block object
63
+ @block_ob = nil
64
+ end
65
+ #
66
+ # initialize
67
+ #---------------------------------------------------------------------------
68
+
69
+
70
+ #---------------------------------------------------------------------------
71
+ # attribute readers
72
+ #
73
+
74
+ # The name of the line that starts the block. Leave nil to start at the
75
+ # beginning of the file. If an ending line is given but that line is not
76
+ # found then an exception is raised.
77
+ attr_reader :start
78
+
79
+ # The name of the line that ends the block. Leave nil for no ending line.
80
+ # If an ending line is given but that line is not found then an exception is
81
+ # raised.
82
+ attr_reader :end
83
+
84
+ # The string to convert tab characters to. Defaults to four spaces.
85
+ attr_reader :tab
86
+
87
+ # If set, indicates a string to put at the beginning of each line. For
88
+ # Markdown, a value of four spaces is a good choice. Defaults to nil.
89
+ attr_reader :indent
90
+
91
+ # If true, then contiguous lines that contain just spaces are collapsed to a
92
+ # single space-only line.
93
+ attr_reader :collapse
94
+
95
+ # If true, the line meta information (i.e. the ## and everything after it)
96
+ # is not stripped from the output lines. Defaults to false.
97
+ attr_reader :keep_meta
98
+
99
+
100
+ # If true, then lines that are marked to be skipped are not skipped.
101
+ # Defaults to false.
102
+ attr_reader :skip_skips
103
+
104
+ # If true, line numbers are output with the block of code. Defaults to
105
+ # false.
106
+ attr_reader :line_nums
107
+
108
+ # The full array of lines in the code.
109
+ attr_reader :lines_full
110
+
111
+ #
112
+ # attribute readers
113
+ #---------------------------------------------------------------------------
114
+
115
+
116
+ #---------------------------------------------------------------------------
117
+ # start=, end=, tab=
118
+ #
119
+
120
+ # Sets the start property.
121
+ def start=(new_val)
122
+ @block_ob = nil
123
+ @start = new_val
124
+ end
125
+
126
+ # Sets the end property.
127
+ def end=(new_val)
128
+ @block_ob = nil
129
+ @end = new_val
130
+ end
131
+
132
+ # Sets the tab property.
133
+ def tab=(new_val)
134
+ @block_ob = nil
135
+ @tab = new_val
136
+ end
137
+
138
+ # Sets the indent property.
139
+ def indent=(new_val)
140
+ @block_ob = nil
141
+ @indent = new_val
142
+ end
143
+
144
+ # Sets the collapse property.
145
+ def collapse=(new_val)
146
+ @block_ob = nil
147
+ @collapse = new_val
148
+ end
149
+
150
+ # Sets the keep_meta property.
151
+ def keep_meta=(new_val)
152
+ @block_ob = nil
153
+ @keep_meta = new_val
154
+ end
155
+
156
+ # Sets the skip_skips property.
157
+ def skip_skips=(new_val)
158
+ @block_ob = nil
159
+ @skip_skips = new_val
160
+ end
161
+
162
+ # Sets the line_nums property.
163
+ def line_nums=(new_val)
164
+ @block_ob = nil
165
+ @line_nums = new_val
166
+ end
167
+
168
+ #
169
+ # start=, end=, tab=
170
+ #---------------------------------------------------------------------------
171
+
172
+
173
+ #---------------------------------------------------------------------------
174
+ # sort-of delegate some methods to block()
175
+ # NOTE: I can't get delegate() to work for delegating to a method. Not sure
176
+ # what I'm doing wrong. Feel free to fix it.
177
+ #
178
+
179
+ # Returns an array of the lines in the code block. Each element of the array
180
+ # is a CodeBlock::Line object.
181
+ def lines
182
+ return block.lines
183
+ end
184
+
185
+ # Returns a string of the code block.
186
+ def to_s
187
+ return block.to_s
188
+ end
189
+
190
+ # Returns a string of the line numbers, one number per line.
191
+ def line_nums_to_s
192
+ return block.line_nums_to_s
193
+ end
194
+
195
+ # Returns a string of the notes for each each line. Notes are set with the
196
+ # `notes` attribute in the meta section of the line, like this:
197
+ #
198
+ # db['hero'] = 'Thor' ## notes="Set the value in the database"
199
+ #
200
+ # There will be as many lines in the string as lines in the code block.
201
+ # Lines with no notes will be empty lines.
202
+ def notes_to_s
203
+ return block.notes_to_s
204
+ end
205
+
206
+ # A hash of named lines.
207
+ def named
208
+ return block.named
209
+ end
210
+
211
+ #
212
+ # sort-of delegate some methods to block()
213
+ #---------------------------------------------------------------------------
214
+
215
+
216
+ # private
217
+ private
218
+
219
+
220
+ #---------------------------------------------------------------------------
221
+ # block
222
+ #
223
+ def block()
224
+ # build block if necessary
225
+ if not @block_ob
226
+ @lines_full = @lines_org.map {|line| CodeBlock::Line.new(self, line)}
227
+ opts = {}
228
+ opts['start'] = @start
229
+ opts['end'] = @end
230
+ opts['tab'] = @tab
231
+ opts['collapse'] = @collapse
232
+ @block_ob = CodeBlock::Block.new(self, opts)
233
+ end
234
+
235
+ # return
236
+ return @block_ob
237
+ end
238
+ #
239
+ # block
240
+ #---------------------------------------------------------------------------
241
+ end
242
+ #
243
+ # CodeBlock
244
+ #===============================================================================
245
+
246
+
247
+ #===============================================================================
248
+ # CodeBlock::Line
249
+ #
250
+
251
+ # A CodeBlock::Line represents a single line in the block of code. Generally you
252
+ # will not need to instantiate a CodeBlock::Line object yourself.
253
+ class CodeBlock::Line
254
+ #---------------------------------------------------------------------------
255
+ # initialize
256
+ #
257
+
258
+ # Accepts a CodeBlock object and the raw string from the code.
259
+ def initialize(code, raw)
260
+ @code = code
261
+ @raw = raw
262
+ @number = nil
263
+ @display = @raw
264
+
265
+ # unless keep meta, else strip ## and everything after
266
+ if @code.keep_meta
267
+ @display = @raw
268
+ else
269
+ @display = @raw.sub(/\s*\#\#.*/mu, '')
270
+ end
271
+
272
+ # remove trailing spaces
273
+ @display = @display.rstrip
274
+
275
+ # attributes
276
+ if @raw.match(/\#\#/mu)
277
+ raw_atts = @raw.sub(/\A.*\#\#\s*/mu, '')
278
+ raw_atts = raw_atts.rstrip
279
+ @atts = AttParser.parse(raw_atts, 'infer'=>true)
280
+ else
281
+ @atts = {}
282
+ end
283
+ end
284
+ #
285
+ # initialize
286
+ #---------------------------------------------------------------------------
287
+
288
+
289
+ #---------------------------------------------------------------------------
290
+ # readers and accessors
291
+ #
292
+
293
+ # Returns a hash of the name=value pairs set in the line's meta section.
294
+ attr_reader :atts
295
+
296
+ # Returns the line's number in the code block.
297
+ attr_accessor :number
298
+
299
+ #
300
+ # readers and accessors
301
+ #---------------------------------------------------------------------------
302
+
303
+
304
+ #---------------------------------------------------------------------------
305
+ # convenience
306
+ #
307
+
308
+ # Returns the value of 'name' in the line's attributes. Returns nil if no
309
+ # name was set.
310
+ def name
311
+ return @atts['name']
312
+ end
313
+
314
+ # Returns the value of 'skip' in the line's attributes. Returns nil if no
315
+ # skip was set.
316
+ def skip
317
+ return @atts['skip']
318
+ end
319
+
320
+ # Returns the value of 'notes' in the line's attributes. Returns nil if no
321
+ # notes were set.
322
+ def notes
323
+ return @atts['notes']
324
+ end
325
+
326
+ #
327
+ # convenience
328
+ #---------------------------------------------------------------------------
329
+
330
+
331
+ #---------------------------------------------------------------------------
332
+ # to_s
333
+ #
334
+
335
+ # Returns the line as it should be displayed, taking into account tabs,
336
+ # indentation, line number, etc. If the line is to be skipped then nil is
337
+ # returned.
338
+ def to_s
339
+ if @atts['skip'] and (not @code.skip_skips)
340
+ return nil
341
+ else
342
+ return @display
343
+ end
344
+ end
345
+ #
346
+ # to_s
347
+ #---------------------------------------------------------------------------
348
+
349
+
350
+ #---------------------------------------------------------------------------
351
+ # has_content?
352
+ #
353
+
354
+ # Returns true if the line has any non-space characters.
355
+ def has_content?
356
+ return @display.match(/\S/mu)
357
+ end
358
+
359
+ # Returns false if the line has any non-space characters.
360
+ def no_content?
361
+ return !has_content?
362
+ end
363
+
364
+ #
365
+ # has_content?
366
+ #---------------------------------------------------------------------------
367
+ end
368
+ #
369
+ # CodeBlock::Line
370
+ #===============================================================================
371
+
372
+
373
+
374
+ #===============================================================================
375
+ # CodeBlock::Block
376
+ #
377
+
378
+ # This is the class that does the work of filtering which lines should be
379
+ # displayed and which shouldn't. Generally you won't have to work directly with
380
+ # this class.
381
+ class CodeBlock::Block
382
+ #---------------------------------------------------------------------------
383
+ # initialize
384
+ #
385
+ def initialize(p_code, opts={})
386
+ @code = p_code
387
+ @collapse = opts['collapse']
388
+ @tab = opts['tab'] || ' '
389
+ @start = opts['start']
390
+ @end = opts['end']
391
+
392
+ # build lines array
393
+ build_lines()
394
+ end
395
+ #
396
+ # initialize
397
+ #---------------------------------------------------------------------------
398
+
399
+
400
+ #---------------------------------------------------------------------------
401
+ # attribute readers
402
+ #
403
+
404
+ # The array of CodeBlock::Line objects.
405
+ attr_reader :lines
406
+
407
+ # A hash of named lines.
408
+ attr_reader :named
409
+
410
+ #
411
+ # attribute readers
412
+ #---------------------------------------------------------------------------
413
+
414
+
415
+
416
+ #---------------------------------------------------------------------------
417
+ # to_s
418
+ #
419
+
420
+ # Builds the string that is returned by CodeBlock#to_s.
421
+ def to_s()
422
+ # $tm.hrm
423
+ rv = []
424
+ indent = @code.indent || ''
425
+ line_nums = @code.line_nums
426
+
427
+ # get maximum width
428
+ if line_nums
429
+ max_width = @lines[-1].number.to_s.length
430
+ end
431
+
432
+ # build return array
433
+ @lines.each do |line|
434
+ # get string
435
+ v = line.to_s
436
+
437
+ # substitute tabs
438
+ if @tab
439
+ v = v.gsub(/\t/mu, @tab)
440
+ end
441
+
442
+ # line numbers
443
+ if line_nums
444
+ v = line.number.to_s.rjust(max_width) + '. ' + v
445
+ end
446
+
447
+ # indent
448
+ v = indent + v
449
+
450
+ # add to return array
451
+ rv.push v
452
+ end
453
+
454
+ # return
455
+ return rv.join("\n")
456
+ end
457
+ #
458
+ # to_s
459
+ #---------------------------------------------------------------------------
460
+
461
+
462
+ #---------------------------------------------------------------------------
463
+ # line_nums_to_s
464
+ #
465
+
466
+ # Builds the string that is returned by CodeBlock#line_nums_to_s.
467
+ def line_nums_to_s
468
+ # $tm.hrm
469
+ rv = []
470
+
471
+ # get maximum width
472
+ width = @lines[-1].number.to_s.length
473
+
474
+ # loop through lines
475
+ @lines.each do |line|
476
+ rv.push line.number.to_s.rjust(width) + '.'
477
+ end
478
+
479
+ # return
480
+ return rv.join("\n")
481
+ end
482
+ #
483
+ # line_nums_to_s
484
+ #---------------------------------------------------------------------------
485
+
486
+
487
+ #---------------------------------------------------------------------------
488
+ # notes_to_s
489
+ #
490
+
491
+ # Builds the string that is returned by CodeBlock#notes_to_s.
492
+ def notes_to_s
493
+ rv = []
494
+
495
+ # loop through lines
496
+ @lines.each do |line|
497
+ rv.push line.notes || ''
498
+ end
499
+
500
+ # return
501
+ return rv.join("\n")
502
+ end
503
+ #
504
+ # notes_to_s
505
+ #---------------------------------------------------------------------------
506
+
507
+
508
+ # private
509
+ private
510
+
511
+
512
+ #---------------------------------------------------------------------------
513
+ # build_lines
514
+ #
515
+ def build_lines
516
+ # $tm.hrm
517
+ @lines = []
518
+
519
+ # starting line name
520
+ started = @start ? false : true
521
+ ended = false
522
+
523
+ # get visible lines
524
+ @code.lines_full.each do |line|
525
+ # start if necessary
526
+ if (not started) and @start
527
+ started = line.atts['name'] == @start
528
+ end
529
+
530
+ # add line
531
+ if started and (not ended)
532
+ if line.to_s
533
+ @lines.push line.clone
534
+ end
535
+ end
536
+
537
+ # if ending line
538
+ if (not ended) and @end
539
+ ended = line.atts['name'] == @end
540
+ end
541
+ end
542
+
543
+ # strip leading empty lines
544
+ while @lines.any? and (not @lines[0].to_s.match(/\S/mu))
545
+ @lines.shift
546
+ end
547
+
548
+ # strip trailing empty lines
549
+ while @lines.any? and (not @lines[-1].to_s.match(/\S/mu))
550
+ @lines.pop
551
+ end
552
+
553
+ # collapse
554
+ if @collapse
555
+ while collapse_find()
556
+ end
557
+ end
558
+
559
+ # number lines
560
+ @lines.each_with_index() do |line, idx|
561
+ line.number = idx + 1
562
+ end
563
+
564
+ # build hash of named lines
565
+ @named = {}
566
+
567
+ # get named lines
568
+ @lines.each do |line|
569
+ if line.name
570
+ if @named[line.name]
571
+ raise 'https://motley.uno/messages/code/init/redundant-name: ' + line.name
572
+ end
573
+
574
+ @named[line.name] = line
575
+ end
576
+ end
577
+ end
578
+ #
579
+ # build_lines
580
+ #---------------------------------------------------------------------------
581
+
582
+
583
+ #---------------------------------------------------------------------------
584
+ # collapse_find
585
+ #
586
+ def collapse_find()
587
+ # loop through lines
588
+ @lines.each_with_index do|line, idx|
589
+ if idx > 0
590
+ if line.no_content? and @lines[idx-1].no_content?
591
+ @lines.delete_at(idx-1)
592
+ return true
593
+ end
594
+ end
595
+ end
596
+
597
+ # didn't find anymore lines to collapse
598
+ return false
599
+ end
600
+ #
601
+ # collapse_find
602
+ #---------------------------------------------------------------------------
603
+ end
604
+ #
605
+ # CodeBlock::Block
606
+ #===============================================================================
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codeblock
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Mike O'Sullivan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: attparser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description: Read a block of code from a working code file and format it.
28
+ email: mike@idocs.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/codeblock.rb
35
+ homepage: https://rubygems.org/gems/codeblock
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.7.6
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Document a block of code
59
+ test_files: []