Including source in RDoc

Discussion in 'Ruby' started by Alex Gutteridge, Jan 11, 2007.

  1. 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
     
    Alex Gutteridge, Jan 11, 2007
    #1
    1. Advertising

  2. 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
     
    Stefano Crocco, Jan 11, 2007
    #2
    1. Advertising

  3. Alex Gutteridge

    matt Guest

    On Thu, 2007-01-11 at 19:04 +0900, Stefano Crocco wrote:

    > 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
     
    matt, Jan 11, 2007
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andreas Schwarz
    Replies:
    6
    Views:
    273
    Randy W. Sims
    Jan 1, 2004
  2. Brian Schröder
    Replies:
    5
    Views:
    157
    Dave Thomas
    Sep 18, 2004
  3. Tim Hunter
    Replies:
    1
    Views:
    108
    Dave Thomas
    Nov 1, 2004
  4. Daniel Berger
    Replies:
    1
    Views:
    154
    Dave Thomas
    Nov 2, 2004
  5. John Wilger
    Replies:
    3
    Views:
    191
    Dave Thomas
    Nov 13, 2004
Loading...

Share This Page