SNIPPET: YamlToHtml.rb (Or; Yet Another YAML Addict prowls the night..)

=begin

Rubistas:

This be a mostly harmless way to convert YAML lists into cute HTML tables.
The goals of the "project" are:

- comments and lists convert into fragmentary XHTML
  - comments get small and emphatic
  - lists become tables
- low-level details pass thru safely but un-cutened
- we can't do vertical lists of lists, or keys of keys, yet

Note that last "goal" implies I can't usefully convert most of the YAML
appearing on my drive...

Any help - especially preening or obscuring the regular expressions -
moderately appreciated.

The goal of the goals is to allow a Wiki-style web site convert YAML into
simple tables, essentially the way some Wikis convert

nebulous>specifications> into tables. YAML, naturally, avoids the "yet

another markup language" syndrome.

If you color and border the tables cutely, then "- [...]\n- [...] # comment"
transforms into this HTML:

···

+-----+-----+
  > Foo | Bar |
  +-----+-----+
  > You | Two | # comment
  +-----+-----+

So comments that decorate rows appear to hang off their right ends. That
feature is not implemented here, but you could do something with CSS.

Another long-term goal is Jamis Buck's Syntax modules support this kind of
output, possibly as a "pretty-html" back-end.

But is the world ready for "YASTL Ain't a Structured Transformation
Language" yet?

--
  Phlip
  http://www.c2.com/cgi/wiki?TestFirstUserInterfacesPrinciples
  "Be brave, little Piglet", said Pooh as he started the chain saw

=end

require('test/unit')

def _yamlToRow(line, gotTable)
    q = line

    if line =~ /\s*\[(.*)\]\s*/ then
        q = $1
        q = q.split(', ').join('</td><td>')
    end

    comment = ''

    if line =~ /\s*\#\s*(.*)/ then
        comment = '<td><em><small>' + $1 + '</small></em></td>'
    end

    tab = ''
    tab = '<table>' if not gotTable
    return tab + '<tr><td>' + q + '</td>' + comment + '</tr>'
end

def yamlToHtml(yaml)

    xhtml = yaml

    xhtml.gsub!(/\&|\<|\>/) do |q|
        if q == '&' then q = '&amp;' end
        if q == '<' then q = '&lt;' end
        if q == '>' then q = '&gt;' end
        q
    end

    xhtml.gsub!(/^(\s*-\s*\[.*,\s*)\n(.*)/) do |q|
        $1+$2
    end

    nu = ''
    gotTable = false

    xhtml.each_line do |line|
        if line =~/^-(.*)/ then
            q = _yamlToRow($1, gotTable)
            gotTable = true
            nu += q
        elsif line =~/^(\s*)\#\s*(.*)/ then
            nu += '</table>' if gotTable
            nu += $1 + '<em><small>' + $2 + "</small></em><br/>"
            gotTable = false
        else
            nu += line + '<p/>'
        end
    end

    nu += '</table>' if gotTable
    return nu

end

if __FILE__ == $0 then
  if ARGV.size == 0 then
    class TestYaml2Html < Test::Unit::TestCase

      def test_rawHTML()
        yaml = '& the devil\'s <dark> voice'
        xhtml = yamlToHtml(yaml)
        assert_equal '&amp; the devil\'s &lt;dark&gt; voice<p/>', xhtml
      end

      def test_brokeLine()
        yaml = "- [ format, froo,\n groo ]"
        xhtml = yamlToHtml(yaml)

        assert_equal '<table><tr><td> format</td><td>froo</td>'+
                                                "<td> groo
</td></tr></table>", xhtml
      end

      def test_comment_after_table_closes_table_and_reopens_another()
        yaml = "- [ format ]\n # comment \n- [ frobmat ]"
        xhtml = yamlToHtml(yaml)

        assert_equal '<table><tr><td> format </td></tr></table>' +
                     ' <em><small>comment </small></em><br/>'+
                     '<table><tr><td> frobmat </td></tr></table>', xhtml
      end

      def test_list()
        yaml = '- list'
        xhtml = yamlToHtml(yaml)
        assert_equal '<table><tr><td> list</td></tr></table>', xhtml
        yaml = "- [ node1, node2 ]"
        xhtml = yamlToHtml(yaml)
        assert_equal '<table><tr><td> node1</td><td>node2
</td></tr></table>', xhtml
        yaml = "- [ node1, node2 ]\n- [ node3, node4 ]"
        xhtml = yamlToHtml(yaml)

        assert_equal '<table>' +
                     "<tr><td> node1</td><td>node2 </td></tr>" +
                     '<tr><td> node3</td><td>node4 </td></tr>' +
                     '</table>', xhtml
      end

      def test_list_with_comment()

        yaml = "- [ node1, node2 ]\n- [ node3, node4 ] # I be comment"
        xhtml = yamlToHtml(yaml)

        assert_equal '<table>' +
                     "<tr><td> node1</td><td>node2 </td></tr>" +
                     '<tr><td> node3</td><td>node4 </td><td>' +
                     '<em><small>I be comment</small></em></td></tr>' +
                     '</table>', xhtml
      end

      def test_comment()
        yaml = '# I\'m a little comment short and stout'
        xhtml = yamlToHtml(yaml)
        assert_equal '<em><small>I\'m a little comment short and
stout</small></em><br/>', xhtml

        yaml = ' # nother comment'
        xhtml = yamlToHtml(yaml)
        assert_equal ' <em><small>nother comment</small></em><br/>', xhtml

        yaml = "#comment one\n # comment two"
        xhtml = yamlToHtml(yaml)
        assert_equal "<em><small>comment one</small></em><br/>"+
                         " <em><small>comment two</small></em><br/>", xhtml
      end

    end
  elsif ARGV.size = 1 then
    title = ARGV[0]
    print '<html><head><title>' + title + '</title></head><body>'
    print yamlToHtml(File.read(ARGV[0]))
    print '</body></html>'
  end
end