codeblock 1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []