Including source in RDoc

A

Alex Gutteridge

Hi,

There was a Ruby Quiz on literate programming a little while back,
but I couldn't quite find an answer to my problem there, so I'm
coming to the group.

I'm writing some small example scripts to demo my library, and I'd
like a way of including the source of these scripts in the
documentation generated by RDoc. Trouble is, I can't see anyway of
telling RDoc to include the source in the generated HTML, so my
options seem to be:

1. Include a copy of the source in the comments of the same file
(simple, but seems a bit un-DRY-ish)
2. Comment the code (so RDoc sees it) and then post-process the file
when the script is run.

I've implemented the second option as shown in the foo.rb file below.
When run directly, it evals anything indented by two or more spaces
as Ruby code. Other comments are left alone. When RDoc sees it it
treats the code as pre-formatted text. It all feels a bit hacky
though. My questions is: 'Is there a better way?'.

[alexg@powerbook]/Users/alexg/Desktop(21): cat foo.rb
#RDoc documentation
#Here is the Foo class. It doesn't do much.
# class Foo
# def bar
# puts 'bar'
# end
# end
#All you can do is call bar on it as shown:
# Foo.new.bar

if __FILE__ == $0
eval(IO.read($0).gsub(/^\#\s\s/,''))
end
[alexg@powerbook]/Users/alexg/Desktop(22): ruby foo.rb
bar
[alexg@powerbook]/Users/alexg/Desktop(23): rdoc -f xml foo.rb

foo.rb:
Generating XML...
<?xml version="1.0" encoding="utf-8"?>
<rdoc>
<file-list>
<file name="foo.rb" id="foo.rb">
<file-info>
<path>foo.rb</path>
<dtm-modified>Thu Jan 11 17:27:34 +0900 2007</dtm-modified>
</file-info>

<description>
<p>
RDoc documentation Here is the Foo class. It doesn‘t do much.
</p>
<pre>
class Foo
def bar
puts 'bar'
end
end
</pre>
<p>
All you can do is call bar on it as shown:
</p>
<pre>
Foo.new.bar
</pre>

</description>
<contents>
</contents>

</file>
</file-list>
<class-module-list>
</class-module-list>
</rdoc>
Files: 1
Classes: 0
Modules: 0
Methods: 0
Elapsed: 0.214s

Alex Gutteridge

Bioinformatics Center
Kyoto University
 
S

Stefano Crocco

Alle 09:39, gioved=EC 11 gennaio 2007, Alex Gutteridge ha scritto:
Hi,

There was a Ruby Quiz on literate programming a little while back,
but I couldn't quite find an answer to my problem there, so I'm
coming to the group.

I'm writing some small example scripts to demo my library, and I'd
like a way of including the source of these scripts in the
documentation generated by RDoc. Trouble is, I can't see anyway of
telling RDoc to include the source in the generated HTML, so my
options seem to be:

1. Include a copy of the source in the comments of the same file
(simple, but seems a bit un-DRY-ish)
2. Comment the code (so RDoc sees it) and then post-process the file
when the script is run.

I've implemented the second option as shown in the foo.rb file below.
When run directly, it evals anything indented by two or more spaces
as Ruby code. Other comments are left alone. When RDoc sees it it
treats the code as pre-formatted text. It all feels a bit hacky
though. My questions is: 'Is there a better way?'.

[alexg@powerbook]/Users/alexg/Desktop(21): cat foo.rb
#RDoc documentation
#Here is the Foo class. It doesn't do much.
# class Foo
# def bar
# puts 'bar'
# end
# end
#All you can do is call bar on it as shown:
# Foo.new.bar

if __FILE__ =3D=3D $0
eval(IO.read($0).gsub(/^\#\s\s/,''))
end
[alexg@powerbook]/Users/alexg/Desktop(22): ruby foo.rb
bar
[alexg@powerbook]/Users/alexg/Desktop(23): rdoc -f xml foo.rb

foo.rb:
Generating XML...
<?xml version=3D"1.0" encoding=3D"utf-8"?>
<rdoc>
<file-list>
<file name=3D"foo.rb" id=3D"foo.rb">
<file-info>
<path>foo.rb</path>
<dtm-modified>Thu Jan 11 17:27:34 +0900 2007</dtm-modified>
</file-info>

<description>
<p>
RDoc documentation Here is the Foo class. It doesn‘t do much.
</p>
<pre>
class Foo
def bar
puts 'bar'
end
end
</pre>
<p>
All you can do is call bar on it as shown:
</p>
<pre>
Foo.new.bar
</pre>

</description>
<contents>
</contents>

</file>
</file-list>
<class-module-list>
</class-module-list>
</rdoc>
Files: 1
Classes: 0
Modules: 0
Methods: 0
Elapsed: 0.214s

Alex Gutteridge

Bioinformatics Center
Kyoto University

In my opinion, there's also a third option: instead of postprocessing the=20
script when it's run, preprocess the file when you generate the=20
documentation. Instead of generating the doc directly using rdoc, use a=20
script which turns the parts you want included into comments. This is a=20
simple attempt at doing it:
[file generate_rdoc.rb]

require 'tempfile'
require 'rdoc/rdoc'

def format_sources lines
to_format=3Dfalse
begin_regexp=3D/^#BEGIN_RDOC_SOURCE$/
end_regexp=3D/^#END_RDOC_SOURCE$/
formatted=3Dlines.map do |l|
if to_format and !l.match end_regexp then "##{l}"
elsif to_format and l.match end_regexp
to_format=3Dfalse
nil
elsif l.match begin_regexp
to_format=3Dtrue
nil
else l
end
end
formatted.compact
end

if $0=3D=3D__FILE__
lines=3DFile.readlines('demo.rb')
Tempfile.open('demo') do |f|
f.write format_sources(lines).join("#\n")
f.flush
RDoc::RDoc.new.document([f.path])
end
end

This script takes the demo.rb file, creates a temp file where the text=20
included between #BEGIN_RDOC_SOURCE and #END_RDOC_SOURCE commnents is=20
commented, then runs rdoc on it. For instance, the demo.rb file could look=
=20
like this

[file demo.rb]

# A class whose source you don't want to appear in the doc
class A
=2E..
end

#A class whose source you want in the doc
#BEGIN_RDOC_SOURCE
class B
=2E..
end
#END_RDOC_SOURCE

The temp file will be:

[temp file]
# A class whose source you don't want to appear in the doc
class A
=2E..
end

#A class whose source you want in the doc
#class B
#...
#end

If you want something more complex, you of course need a more advanced scri=
pt,=20
but, in my opinion, this is the best way to go, expecially taking into=20
account the fact that, being demo files, your users may want to look into=20
them to understand how to use the library, and they may be confused to find=
=20
the body of the script commented out.

I hope this helps

Stefano
 
M

matt

In my opinion, there's also a third option: instead of postprocessing the
script when it's run, preprocess the file when you generate the
documentation. Instead of generating the doc directly using rdoc, use a
script which turns the parts you want included into comments. This is a
simple attempt at doing it:

I suppose another (though not immediate) option would be to make a
request to modify RDoc to accomplish this, or do it yourself and submit
a patch.

I don't know much about the RDoc layout, but I would think that a change
so that you had a series of start/stop tags that don't interfere with
code, but allow for documentation processing:

def func1
...
end

# START DOC PROCESSING
def func 2
...
end
# END DOC PROCESSING

should allow for the code to remain unchanged, and a properly modified
RDoc could still process this into documentation.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top