[SUMMARY] Text Image (#50)

I just love it when a totally crazy idea of mine blossoms into a popular quiz.
Who would a thunk it?

As you've probably seen from the solutions, this quiz turns out to be fairly
easy, thanks to great tools like RMagick and GD. Those libraries can do the
heavy lifting of loading an image, resizing it, and dropping it to a smaller
color map. With that, you're code just needs to replace colors with some
symbols.

Here's some RMagick code from Mr. RMagick himself, Timothy Hunter:

  require 'RMagick'

  CHARS = [ 'W', 'M', '$', '@', '#', '%', '^', 'x', '*', 'o', '=', '+',
            ':', '~', '.', ' ' ]
  FONT_ROWS = 8
  FONT_COLS = 4

  img = Magick::Image.read(ARGV[0] || "Flower_Hat.jpg").first

  # Resize too-large images. The resulting image is going to be
  # about twice the size of the input, so if the original image is too
  # large we need to make it smaller so the ASCII version won't be too
  # big. The `change_geometry' method computes new dimensions for an
  # image based on the geometry argument. The '320x320>' argument says
  # "If the image is too big to fit in a 320x320 square, compute the
  # dimensions of an image that will fit, but retain the original aspect
  # ratio. If the image is already smaller than 320x320, keep the same
  # dimensions."
  img.change_geometry('320x320>') do |cols, rows|
    img.resize!(cols, rows) if cols != img.columns || rows != img.rows
  end

  # Compute the image size in ASCII "pixels" and resize the image to have
  # those dimensions. The resulting image does not have the same aspect
  # ratio as the original, but since our "pixels" are twice as tall as
  # they are wide we'll get our proportions back (roughly) when we render.
  pr = img.rows / FONT_ROWS
  pc = img.columns / FONT_COLS
  img.resize!(pc, pr)

  img = img.quantize(16, Magick::GRAYColorspace)
  img = img.normalize

  # Draw the image surrounded by a border. The `view' method is slow but
  # it makes it easy to address individual pixels. In grayscale images,
  # all three RGB channels have the same value so the red channel is as
  # good as any for choosing which character to represent the intensity of
  # this particular pixel.
  border = '+' + ('-' * pc) + '+'
  puts border
  img.view(0, 0, pc, pr) do |view|
      pr.times do |i|
          putc '|'
          pc.times { |j| putc CHARS[view[i][j].red/16] }
          puts '|'
      end
  end
  puts border

That is wonderfully commented code, of course, so I'm not going to repeat what
it does here.

I will mention a trick I found while playing with my own similar solution
though. I couldn't decide how many symbols to use, so I played with different
amounts. After about the third time of changing the Array and the argument to
quantize(), I realized that I could save myself a step. The same can be done
with the above code by changing two lines:

  # ...
  
  img = img.quantize(CHARS.size, Magick::GRAYColorspace)
  
  # ...
  
          pc.times { |j| putc CHARS[view[i][j].red/CHARS.size] }
  
  # ...

With that, you can add and remove CHARS to play around and the code will just do
the right thing.

Here's how our mascot looks, when hit with the above code:

···

+-------------------------------------------------------------------------+
  > .::+====+:: |
  > .:==o======ooo*oo+. |
  > +oo=====++++===oo***+ |
  > :oo==++++===++==ooooo*^*. |
  > :oo====++++====oooooooo*^* |
  > .oo=====++++========ooo**^^o |
  > .ooo=====++++++======ooo**^^%: |
  > :*oo*o==============oooo****^^^. |
  > :ooo$WW^===========oooo****^^^^^= |
  > ooo*WWW%=========oooo^^*^**^^^^^^ |
  > oooo=o::o=====oooo*%WWW$^^*^^^^*^: |
  > =ooo=:+====ooooo**o^WWW$***^****^: |
  > .*o*o*ooooo==ooo*^*+====o*^*****^. |
  > :o%$$$$$WW$$$%%^^^^**********^^= |
  > .oWWWWWWWWWWWWWW$%%^**o****^^= :::::: |
  > %$$$$$$$W$$W$WWWW$^****^^o. ...::::::::==: |
  > =WWWW$$$W$$$$WW$$%^^****+. .........:::::::::::::::::=o+ |
  > :$WWWWWWWWWWWW%^****^%%%%%^^**oo====++:::::::::::::::+=o+ |
  > :+oo*$$WWWWWWW$%^*^^^^^%$$$%%%^**o===+:::::::::::::::::++==o: |
  > .:====o*^%$$$$$%^^%%^^^^%%%%%%%^^**o===+::::::::::::::::::===oo |
  > .:+++++==o*^%%%%%%$%%%%^^^^%%%^^^**oo===++:::::::::::::::::+==ooo |
  > .:+::::+++=oo*^%%%$%%%%%^^^^^*****ooo===+++::::::::::::::::++===oo= |
  > :++::::::+++=oo*^%%%%%%^^****ooooo=====++:::::::::::::++:::++====o*. |
  > :+::::::::::+===o**^^^^**ooo=====+=+++++::::::::::::+::==++++===ooo+ |
  > :+::::::::::::+++==oooooo====+::::+:::::+::::+::++::+::+==++=====oo= |
  > .+::::::::::::::::++=+=====+::::::+:::::+::::+:::+:::+++========ooo= |
  > :+::::::::::::::::::+:++++::::::++::::::::::+:::++:++==========ooo+ |
  >.++++:::::::::::::::::::::::::::+:::::+::::+:::++++===========oooo: |
  >.++++::::::::::::::::::::::::::::::++:+::+=+++==============oooo=. |
  > +++++++::::::::::::::::::::::++::++::+==+=+===========o===ooo=: |
  > :==++++::::+:::::::::+:+:::::::::+++===++=============ooooo=: |
  > .===++++++++++::+++::+++:+++++::+===++====o==========o=o==:. |
  > :=======+++++++++++++++++:++===============oo====oo=o==:. |
  > :====================++++++==+=========o=====ooo====: |
  > .==================================ooooooo=oo===+: |
  > :+=============================oooo=o==oo==::. |
  > ::==========================o====oo===::. |
  > ::++==============+===========+::. |
  > ..:::++++==++=+++++++++::.. |
  > ....:.::::::... |
  +-------------------------------------------------------------------------+

For an interesting different approach, Simon Kroeger wrote some code to outline
the primary subject. That makes our duck look like this:

            .:'''''''.
           .: :.
          .: :.
          : :
         :' ':
        .: :
        : .':. ::
       :'.' : .. ':
       : :..' :' ': :
       :. ' : .: :
       ': '::'':.. ':' . :
        :: ''.. :' .:'':.
         :: . ': .: ..' . '.
         ': ''''' .: .:::::''' :.
         :: .:': :
       .: : .:' :
      .' '' '' :
     :' :
    : :
  .' :
  : ' :'
  : .:
  ' : .:
                     ' :
  : .:
  : .:
  : .'
  '. :'
    :. .'
     '. .:'
      ':. .:'
        ':. .:'
           ''..........''

I thought that was a surprising variation that got a great amount of detail
across. The bill is probably the easiest to make out here, compared with all
the solutions.

Let's see the code for that:

  require 'RMagick'
  require 'generator'
  require 'enumerator'

  puts "Usage: #{$0} <img> [size]" or exit if !ARGV[0]

  img, size = Magick::ImageList.new(ARGV[0]), (ARGV[1]||40).to_f
  factor = [size*1.5/img.rows, size/img.columns].min

  img.resize!(img.columns*factor, 2*(img.rows*factor*0.75).round)
  img = img.edge.despeckle.despeckle.normalize.threshold(50)

  pixels = img.get_pixels(0, 0, img.columns, img.rows).map{|c| c.red.zero?}

  pixels.to_enum(:each_slice, img.columns).each_slice(2) do |l|
    puts SyncEnumerator.new(*l).map{|p1, p2|
      [' ', "'", ".", ":"] [(p1 ? 0 : 1) + (p2 ? 0 : 2)]}.join('')
  end

Here we see RMagick used again to read in the picture and resize it to something
closer to terminal dimensions. Instead of dropping the color map here though,
we get an interesting chain of filters designed to draw out the edges of the
primary subject. (Obviously, this works better on some images than others.)

What's after that? I honestly had no clue. to_enum(), each_slice(),
SyncEnumerator? Did I switch languages and nobody told me? Obviously those two
harmless looking requires at the beginning of the program change some of the
rules and we're going to need to learn a little bit about "generator" and
"enumerator".

So, what's the first step? I tried http://www.ruby-doc.org/ because I'm a wimp.
Yep, there's "generator" but we're in trouble with "enumerator". No
documentation! I clicked the link anyway, to see what I could learn.

Seems each_slice() is added to Enumerable by the library and it expects one
argument. Well, that's something. It's a little hard to tell how it's being
used in Simon's code (complicated by to_enum()), so I figure, just put something
in an Array and try to call it. That should tell us something. irb to the
rescue!

  >> require "enumerator"
  => true
  >> pixels = (1..10).to_a
  => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  >> pixels.each_slice(2) { |slice| p slice }
  [1, 2]
  [3, 4]
  [5, 6]
  [7, 8]
  [9, 10]
  => nil

Perfect! That was all we need to see. It allows you to take off chunks of an
Array, it seems. Dang that's cool! Why didn't any of you tell me that was
there?!

Anybody see the Tic-Tac-Toe code posted to Ruby Talk on Tuesday? Look how
simple drawing the board can be:

  >> board = Array.new(9) { rand > 0.5 ? "X" : "O" }
  => ["X", "O", "O", "O", "O", "O", "O", "X", "O"]
  >> board.each_slice(3) { |row| puts row.join }
  XOO
  OOO
  OXO
  => nil

Okay, we've got each_slice() figured out. Let's do some more detective work.
Let's see if we can figure out to_enum(). When it is called in Simon's code it
seems to get passed a method name (the one we just learned!) and a number.
Well, we know each_slice() requires a number, so maybe that's the argument to
it? Again, let's just see if we can call it:

  >> pixels
  => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  >> enum = pixels.to_enum(:each_slice, 2)
  => #<Enumerable::Enumerator:0x342b58>

Well, we got... something. Hmm, I wonder what it can do?

  >> enum.methods
  => ["reject", "method", "send", "object_id", "enum_for", "singleton_methods",
  "member?", "__send__", "equal?", "taint", "find", "frozen?",
  "instance_variable_get", "each_with_index", "enum_cons", "kind_of?", "to_a",
  "instance_eval", "collect", "all?", "entries", "type", "enum_with_index",
  "protected_methods", "extend", "detect", "eql?", "display", "zip",
  "instance_variable_set", "hash", "is_a?", "map", "to_s", "any?", "sort",
  "class", "each_slice", "min", "tainted?", "private_methods", "find_all",
  "untaint", "each", "id", "inspect", "inject", "==", "===", "sort_by", "clone",
  "public_methods", "enum_slice", "max", "respond_to?", "select", "freeze",
  "__id__", "to_enum", "partition", "=~", "methods", "grep", "nil?", "dup",
  "each_cons", "instance_variables", "include?", "instance_of?"]

Okay, it seems to be Enumerable. Let's just see what each entry is:

  >> enum.each { |e| p e }
  [1, 2]
  [3, 4]
  [5, 6]
  [7, 8]
  [9, 10]
  => nil

Now I get it. We turned an each_slice(2) call into an each() call. That's
interesting.

It always bugs me that Strings iterate over lines instead of characters, by
default, and now I have the tool to fix it:

  >> char_str = "team".to_enum(:each_byte)
  => #<Enumerable::Enumerator:0x322d30>
  >> if char_str.any? { |c| c == ?i }
  >> puts "Huh?!"
  >> else
  ?> puts "There's no I in T-E-A-M!"
  >> end
  There's no I in T-E-A-M!
  => nil
  >> char_str.to_a
  => [116, 101, 97, 109]

Notice how I was able to use any?() and to_a() there, because we switched
each_byte() to each() and all other Enumerable methods use each().

One more mysterious piece of the puzzle, but this one is documented, which
almost takes all the fun out of it. Here's the example right out of the
documentation, minus some irb noise:

  >> require "generator"
  => true
  >> s = SyncEnumerator.new([1, 2, 3], %w{a b c})
  => #<SyncEnumerator:0x1b339c ...>
  >> s.each { |row| puts row.join(", ") }
  1, a
  2, b
  3, c
  => #<SyncEnumerator:0x1b339c ...>

Obviously, that just let's you traverse two Enumerable objects at once. First
you get the first entry of both, then the second, etc. Nothing too tricky
there.

Still remember the code that started all this?

  # ...
  
  pixels.to_enum(:each_slice, img.columns).each_slice(2) do |l|
    puts SyncEnumerator.new(*l).map{|p1, p2|
      [' ', "'", ".", ":"] [(p1 ? 0 : 1) + (p2 ? 0 : 2)]}.join('')
  end

This code iterates over rows of pixels (pixels.to_enum(:each_slice, img.columns)
...), two at-a-time (... .each_slice(2) ...). It then traverses those two rows
pixel-by-pixel in tandem (SyncEnumerator.new(*l).map{|p1, p2| ... }), averaging
the two on/off values (... [' ', "'", ".", ":"] [(p1 ? 0 : 1) + (p2 ? 0 : 2)]
...), and printing the results (puts ... .join('')). Work through that slowly,
until it sinks in. I know it took me a couple of tries.

I better wrap this up, since it's already quite lengthy, but don't forget to
take a peek at the other solutions. Harold Hausman rolled his own code for
analyzing bitmap images and others are now golfing that solution on Ruby Talk.
Rob Rypka and Brian Schroeder also did some sensational work mapping colors to
characters, producing some nice gradients.

A big thank you to all the enlightening solutions to this week's quiz. The
combined intelligence of the Ruby Quiz community is beyond measure.

Tomorrow, I have a new game for you. I figure it's The RubyConf Collective
verses the rest of us in the tournament, right?

Ruby Quiz wrote

So, what's the first step? I tried http://www.ruby-doc.org/ because I'm a wimp.
Yep, there's "generator" but we're in trouble with "enumerator". No
documentation! I clicked the link anyway, to see what I could learn.

http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/ext/enumerator/Attic/enumerator.txt?rev=1.2;content-type=text%2Fplain
http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/enumerator.c?content-type=text%2Fplain

Perfect! That was all we need to see. It allows you to take off chunks of an
Array, it seems. Dang that's cool! Why didn't any of you tell me that was
there?!

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/154552
(my source for the two links above)

daz

Attn: Gavin Sinclair

···

On Oct 13, 2005, at 8:31 AM, daz wrote:

Ruby Quiz wrote

So, what's the first step? I tried http://www.ruby-doc.org/ because I'm a wimp.
Yep, there's "generator" but we're in trouble with "enumerator". No
documentation! I clicked the link anyway, to see what I could learn.

http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/ext/enumerator/Attic/enumerator.txt?rev=1.2;content-type=text%2Fplain
http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/enumerator.c?content-type=text%2Fplain

Thank you for leading me to the docs!

Gavin, that second link looks like ready to put online RDoc. Any reason we don't have it on ruby-doc.org?

James Edward Gray II

James Edward Gray II wrote:

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Possibly because James Britt at ruby-doc.org doesn't
want to conflate 1.9 and 1.8.2 docs (?)

In 1.8.2, Enumerator is an extension;
in 1.9, it's a built-in class with (I think) added functionality.

It would be nice if 1.9 rdoc could be hosted somewhere, though.

daz

James Edward Gray II wrote:

>
> http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/ext/enumerator/
> Attic/enumerator.txt?rev=1.2;content-type=text%2Fplain
> http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/
> enumerator.c?content-type=text%2Fplain

Thank you for leading me to the docs!

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Wow! Them's some pretty long links! I take it there are some docs for
enumerator in CVS and they could do with some translation into RDoc.
OK, I'll make that my next target.

Thanks,
Gavin

Gavin, those are 1.9 docs. If that's a problem, just let me know and I'll build a patch to add them to Ruby 1.8 and see if I can get it committed.

James Edward Gray II

···

On Oct 13, 2005, at 9:51 AM, Gavin Sinclair wrote:

James Edward Gray II wrote:

http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/ext/enumerator/
Attic/enumerator.txt?rev=1.2;content-type=text%2Fplain
http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/
enumerator.c?content-type=text%2Fplain

Thank you for leading me to the docs!

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Wow! Them's some pretty long links! I take it there are some docs for
enumerator in CVS and they could do with some translation into RDoc.
OK, I'll make that my next target.

daz wrote:

James Edward Gray II wrote:

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Possibly because James Britt at ruby-doc.org doesn't
want to conflate 1.9 and 1.8.2 docs (?)

In 1.8.2, Enumerator is an extension;
in 1.9, it's a built-in class with (I think) added functionality.

It would be nice if 1.9 rdoc could be hosted somewhere, though.

There had been an older version on them on ruby-doc, though I think they got lost in the server shuffle.

I can add them again, if there is sufficient interest. But it seems that they're a bit avant garde for most people who wouldn't already have them locally anyway.

James

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

I see absolutely no reason not to make every last shred of documentation available to the users of Ruby. I say we document, document, document until there is no library left to cover.

Enumerator is a handy tool, soon to be a part of the core. Why would we *choose* not to educate people about it?!

If that line of thinking is wrong, I don't want to be right! Call me radical.

James Edward Gray II

···

On Oct 13, 2005, at 6:39 PM, James Britt wrote:

daz wrote:

James Edward Gray II wrote:

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Possibly because James Britt at ruby-doc.org doesn't
want to conflate 1.9 and 1.8.2 docs (?)
In 1.8.2, Enumerator is an extension;
in 1.9, it's a built-in class with (I think) added functionality.
It would be nice if 1.9 rdoc could be hosted somewhere, though.

There had been an older version on them on ruby-doc, though I think they got lost in the server shuffle.

I can add them again, if there is sufficient interest. But it seems that they're a bit avant garde for most people who wouldn't already have them locally anyway.

James Edward Gray II wrote:

>> Gavin, that second link looks like ready to put online RDoc. Any
>> reason we don't have it on ruby-doc.org?
>>
>
> Wow! Them's some pretty long links! I take it there are some docs
> for
> enumerator in CVS and they could do with some translation into RDoc.
> OK, I'll make that my next target.

Gavin, those are 1.9 docs. If that's a problem, just let me know and
I'll build a patch to add them to Ruby 1.8 and see if I can get it
committed.

The stuff on ruby-doc.org/{stdlib,core} is generated from 1.8 source
and library code, so 1.9 stuff won't appear there. There's no reason,
however, that other, arbitrary, documentation can't be hosted on
ruby-doc.org.

So if it's appropriate that it should appear in 1.8, I'd certainly
encourage you to make a patch and get it committed.

Cheers,
Gavin

James Edward Gray II wrote:

···

On Oct 13, 2005, at 6:39 PM, James Britt wrote:

daz wrote:

James Edward Gray II wrote:

Gavin, that second link looks like ready to put online RDoc. Any
reason we don't have it on ruby-doc.org?

Possibly because James Britt at ruby-doc.org doesn't
want to conflate 1.9 and 1.8.2 docs (?)
In 1.8.2, Enumerator is an extension;
in 1.9, it's a built-in class with (I think) added functionality.
It would be nice if 1.9 rdoc could be hosted somewhere, though.

There had been an older version on them on ruby-doc, though I think they got lost in the server shuffle.

I can add them again, if there is sufficient interest. But it seems that they're a bit avant garde for most people who wouldn't already have them locally anyway.

I see absolutely no reason not to make every last shred of documentation available to the users of Ruby. I say we document, document, document until there is no library left to cover.

Hosting documentation is trivial. Getting people to write documentation is not. At least not, it seems, without offering financial renumeration.

James

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Why write documentation when we don't put up what we have?

James Edward Gray II

···

On Oct 13, 2005, at 7:27 PM, James Britt wrote:

Hosting documentation is trivial. Getting people to write documentation is not. At least not, it seems, without offering financial renumeration.

I'm sorry, but the more I think about this, the more it bugs me...

Hosting documentation is trivial.

You do this part, right?

You run ads on the site and this (http://www.rubystuff.com/about.html\) also generates income for that service.

Getting people to write documentation is not.

I do this part. I've documented three standard libraries in the last year. ERb, Delegate, and Forwardable.

At least not, it seems, without offering financial renumeration.

I haven't seen my check yet?!

James Edward Gray II

···

On Oct 13, 2005, at 7:27 PM, James Britt wrote:

Getting people to write documentation is not.

I do this part. I've documented three standard libraries in the last year. ERb, Delegate, and Forwardable.

At least not, it seems, without offering financial renumeration.

If I could get paid to write docs I'd be all over it like something all over something else. But if someone could point to some area that needs documenting I'd be more than happy to help - I was a technical author a few years ago, and I have contributed code and docs to several open source projects (mainly Java), I just didn't realise that more hands were needed - please push links etc to me I'll help out with doco

Kev

James Edward Gray II wrote:

I'm sorry, but the more I think about this, the more it bugs me...

Why?

Hosting documentation is trivial.

You do this part, right?

Indeed.

You run ads on the site and this (http://www.rubystuff.com/ about.html) also generates income for that service.

Yes. Helps pay some of the bills.

Getting people to write documentation is not.

I do this part. I've documented three standard libraries in the last year. ERb, Delegate, and Forwardable.

There are a few people writing core and stdlib docs on a semi-regular basis, but by and large, there are large parts of Ruby insufficiently documented.

At least not, it seems, without offering financial renumeration.

I haven't seen my check yet?!

Maybe after the bills get paid.

:slight_smile:

James

···

On Oct 13, 2005, at 7:27 PM, James Britt wrote:

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Kev Jackson wrote:

Getting people to write documentation is not.

I do this part. I've documented three standard libraries in the last year. ERb, Delegate, and Forwardable.

At least not, it seems, without offering financial renumeration.

If I could get paid to write docs I'd be all over it like something all over something else. But if someone could point to some area that needs documenting I'd be more than happy to help - I was a technical author a few years ago, and I have contributed code and docs to several open source projects (mainly Java), I just didn't realise that more hands were needed - please push links etc to me I'll help out with doco

Perhaps the best place to start is here:

http://ruby-doc.org/stdlib/

Items listed to the left in italics do not have sufficient docs.

(That may be true as well of some of the other items, but I believe the italics are meant to indicate 'needs work.')

James

at RubyConf05

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Kev Jackson wrote:

If I could get paid to write docs I'd be all over it like something all
over something else. But if someone could point to some area that needs
documenting I'd be more than happy to help - I was a technical author a
few years ago, and I have contributed code and docs to several open
source projects (mainly Java), I just didn't realise that more hands
were needed - please push links etc to me I'll help out with doco

Hi Kev,

Documentation of core and library classs is written in the source code
(be it C or Ruby). Thus to contribute, you want to avail yourself of
(anonymous) CVS access (it's easy). Then you edit files, create a
patch, and get it committed. That last step has been the problem in
the past; mea culpa. Suggested process: email the patch to me and/or
James Gray (sorry, James!). Bug me mercilessly if nothing's being
done.

Anyway, then it ends up in Ruby itself and appears on ruby-doc.org
hopefully soon after.

Any questions, just email.

Cheers,
Gavin

Perhaps the best place to start is here:

RDoc Documentation

Items listed to the left in italics do not have sufficient docs.

Ok so I've looked at the site (and at the status report). I presume that to get working on them I'd need to get the actual ruby sources and start adding comments/doc/examples into the source files, but then how do I push changes in the original sources back so that the RDoc can be extracted/published? If the sources are part of the stdlib (which ships with ruby itself), is there a bugzilla/issu tracker or something to attach patches to?

Or is the preferred way to download a doc bundle and manually edit that?

I'll keep searching around myself (this afternoon I'm completely free which is nice) but any pointers in the preferred way of contributing would be appreciated

Kev

Gavin Sinclair wrote:

Kev Jackson wrote:

If I could get paid to write docs I'd be all over it like something all
over something else. But if someone could point to some area that needs
documenting I'd be more than happy to help - I was a technical author a
few years ago, and I have contributed code and docs to several open
source projects (mainly Java), I just didn't realise that more hands
were needed - please push links etc to me I'll help out with doco

Hi Kev,

Documentation of core and library classs is written in the source code
(be it C or Ruby). Thus to contribute, you want to avail yourself of
(anonymous) CVS access (it's easy). Then you edit files, create a
patch, and get it committed. That last step has been the problem in
the past; mea culpa. Suggested process: email the patch to me and/or
James Gray (sorry, James!). Bug me mercilessly if nothing's being
done.

BTW, what is the copyright on submitted docs, and is it made clear to those submitting documentation?

James Britt

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Ahh...I always wondered what was up with the italics. Good to know :slight_smile:

···

On Oct 14, 2005, at 12:09 AM, James Britt wrote:

RDoc Documentation

Items listed to the left in italics do not have sufficient docs.

Kev Jackson wrote:

Ok so I've looked at the site (and at the status report). I presume
that to get working on them I'd need to get the actual ruby sources and
start adding comments/doc/examples into the source files, but then how
do I push changes in the original sources back so that the RDoc can be
extracted/published? If the sources are part of the stdlib (which ships
with ruby itself), is there a bugzilla/issu tracker or something to
attach patches to?

Damn, thought I replied earlier but ... it hasn't appeared, so I guess
I didn't. Sorry if this is a duplicate.

You do need to get the Ruby sources (anonymous CVS is best) and work
with those. There's no bugzilla or similar for doc patches. This part
of the process has been a failure and I take responsibility for that.
If you have a patch, email it to me and/or James Gray. One of us will
massage it through ruby-core back into CVS, and James Britt and I will
regenerate the bits and pieces on ruby-doc.org/{core,stdlib}.

Thanks for any help, and feel free to ask any questions.

Cheers,
Gavin