CodeBlock
CodeBlock assists in documenting code by importing working code for display in documentation. CodeBlock allows you to write working examples of code, then import that code into documentation without any copying or pasting. Features include:
- import all of a file or just parts of it
- strip out lines that are not relevent to the documentation
- reference lines by name instead of line number
CodeBlock itself is not a documentation system. It is intended for use in other documentation systems.
Basic usage
Consider an example of a code file that I have for development of a DBMS system I'm developing called "Audrey". The code file looks like this:
#!/usr/bin/ruby -w
require 'audrey'
# connect to database, creating it if necessary
Audrey.connect('/tmp/my.db', 'rw') do |db|
db['hero'] = 'Thor'
db['antagonist'] = 'Loki'
end
# done
puts '[done]'
In its simplest use, a new CodeBlock object simply slurps in a code file. The contents of the file are accessible in the object's to_s method. So, we might use CodeBlock like this:
require 'codeblock'
src_path = 'samples/plain.rb'
block = CodeBlock.new(File.read src_path)
puts block.to_s # => outputs the exact contents of the file
So far that's not very useful. We could accomplish the same thing by simply slurping in the file contents. Let's look at a more advanced usage.
Suppose you only want to display a certain block of code in your documentation. Now, you could just copy and paste the relevent block into your documentation, but that's redundant information. Your document doesn't get updated if you change the working example. That's where CodeBlock gets useful. With CodeBlock, you can name specific lines to import. Let's look at the same working code as above, but with a few additions.
#!/usr/bin/ruby -w
require 'audrey'
# connect to database, creating it if necessary
Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=begin
db['hero'] = 'Thor'
db['antagonist'] = 'Loki'
end ## name=finish
# done
puts '[done]'
That's the same working code... all we've done is added some comments that
CodeBlock can interpret. Each line to which we want to add information has ##
followed by name=value pairs. In the above example, the lines are givens the
names "begin" and "finish".
To extract the block of code that starts with "begin" and ends with "finish", we set the CodeBlock#start and CodeBlock#end properties, like this:
src_path = 'samples/block.rb'
block = CodeBlock.new(File.read src_path)
block.start = 'begin'
block.end = 'finish'
block.to_s
That retrieves just the lines indicated. Notice that ## and everything after
it is stripped from the lines:
Audrey.connect('/tmp/my.db', 'rw') do |db|
db['hero'] = 'Thor'
db['antagonist'] = 'Loki'
end
Skip lines
You might find that in some situations its helpful to have code in your working file that isn't relevent to the documentation. In those case, you can indicate that a line should be skipped with skip=true:
Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=start
db['hero'] = 'Thor'
puts db['hero'] ## skip=true
end ## name=end
That will results in a code sample that doesn't include that line
Audrey.connect('/tmp/my.db', 'rw') do |db|
db['hero'] = 'Thor'
end
Line numbers
You might want to include line numbers in your documentation. There are two ways to do this.
First, you might want a string just of line numbers. Doing so would allow you to put the line numbers into an HTML
tag alongside the code itself. To get
line numbers simply call CodeBlock#line_nums_to_s. Doing so outputs something
like as follows. Notice that the numbers are right justified.</p>
<pre><code> 1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
The line numbers match up with the lines that have been selected, not the line numbers in the file. That allows you to display code lines and line numbers that match up.
To output the entire code block with line numbers, set the block's line_nums
property to true:
block.line_nums = true
puts block.to_s
That will output something like this:
1. # connect to database, creating it if necessary
2. Audrey.connect('/tmp/my.db', 'rw') do |db|
3. db['hero'] = 'Thor'
4. db['antagonist'] = 'Loki'
5. end
6.
7. # read
8. Audrey.connect('/tmp/my.db', 'rw') do |db|
9. puts db['hero']
10. puts db['antagonist']
11. end
12.
13. # done
14. puts '[done]'
Named lines
Lines can be referenced by their names to get their line numbers. This allows
you to give the number of a line in a block without having to change the line
number when you modify the block. Access the line in the block's named
property.
In this example, we name one of the lines "Thor":
Audrey.connect('/tmp/my.db', 'rw') do |db| ## name=start
db['hero'] = 'Thor' ## name=Thor
end ## name=end
Then, depending on how your documentation system works, you could reference the line number like this:
src_path = 'samples/named-lines.rb'
block = CodeBlock.new(File.read(src_path), 'se'=>true)
puts "In line number #{block.named['Thor'].number} we set a value."
This will output as follows:
In line number 2 we set a value.
Install
gem install codeblock
Author
Mike O'Sullivan [email protected]
History
| version | date | notes |
|---|---|---|
| 1.0 | June 18, 2020 | Initial upload. |
| 1.1 | June 19, 2020 | Fixed bug with skip_skips. |