Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

James Robertson http://www.r0bertson.co.uk

« Newer Snippets
Older Snippets »
Showing 1-3 of 3 total  RSS 

Creating a simple Ruby Class documenter

This Ruby code stores the class name, method names, and method parameters from a ruby file in an XML file. I have a habit of forgetting what methods I use in my classes, with this code I should at least be able to build up a quick class browser.

#!/usr/bin/ruby

# file: ruby2xml.rb

require 'rexml/document'
include REXML

class Ruby2XML

  attr :doc
  
  def initialize(buffer)

    @outline = buffer.scan(/^class\s+(\w+)(\s+)?|def\s+(\w+)(\s+)?\(?(.*(?=\)))?/)
    @doc = Document.new
    @doc.add_element('ruby')
    o_class = Element.new('class')
    o_class.add_attribute('name', get_class_name)
    o_methods = Element.new('methods')
    
    #get the methods
    1.upto(get_method_count) {|i| o_methods.add_element(add_method(@outline[i])) }
    o_class.add_element(o_methods)
    @doc.root.add_element o_class

  end
  
  private # everything below this point is private
  
  def get_class_name()
    @outline[0][0]
  end
  
  def get_method_count
    mc = -1
    @outline.each {|m| mc += 1}
    mc 
  end
  
  def add_method(amethod)
    o_method = Element.new('method')
    o_method.add_attribute('name',amethod[2]) #get the method name
    o_params = Element.new('params')

    if amethod[4] then # get the parameter names
      amethod[4].split(',').each {|a| o_params.add_element(add_param(a.strip))}
    end
    
    o_method.add_element(o_params)    
    o_method
  end
  
  def add_param(param)
    o_param = Element.new('param')
    o_param.text = param
    o_param
  end
      
end

if __FILE__ == $0

  buffer = File.new('ruby2xml.rb').read
  rx2 = Ruby2XML.new(buffer)
  
  file = File.new('ruby2xml.xml','w')
  file.puts rx2.doc
  file.close

end


Note: This is just my first attempt at building some kind of Ruby code documenter, but it should be good enough for my needs at the moment.

output
<ruby>
  <class name='Ruby2XML'>
    <methods>
      <method name='initialize'><params><param>buffer</param></params></method>
      <method name='get_class_name'><params/></method>
      <method name='get_method_count'><params/></method>
      <method name='add_method'><params><param>amethod</param></params></method>
      <method name='add_param'><params><param>param</param></params></method>
    </methods>
  </class>
</ruby>

Generate Ruby code using XML and XSL

This XSL code transforms an XML file into a basic Ruby file. See the previous post ('Transforming an XML file into an XSL file' http://snipr.com/1usrh [dzone.com]) for an example of the XML used.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>

  <xsl:template match="recordx">
  <xsl:variable name="project" select="summary/project" />
  <xsl:variable name="parent_element" select="summary/parent_element" />
  <xsl:text>#!/usr/bin/ruby
#file: </xsl:text><xsl:value-of select="$project"/><xsl:text>.rb

require 'recordx'

class </xsl:text><xsl:value-of select="$project"/><xsl:text> &lt; RecordX

  def initialize()
    @project = "</xsl:text><xsl:value-of select="$project"/><xsl:text>"
    @parent_element = '</xsl:text><xsl:value-of select="$parent_element"/><xsl:text>fields'
    @proj = Projxml.new
    @doc_vrecord = initialize_xml_class(SERVER_URL + '/' + @project + '/class_template.xml')
    @doc_file = get_doc()
  end
  
end

if __FILE__ == $0
    r = </xsl:text><xsl:value-of select="$project"/><xsl:text>.new()
end
  </xsl:text>
  </xsl:template>
  
</xsl:stylesheet>

Transforming an XML file into an XSL file

This XSL uses the XML for creating another XSL file which renders a web page containing records for a specific project, but I have found the projects I am working on use similar page layouts (ie. menu, body(articles), inputs, and buttons), so it makes sense to re-use a generic template.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="recordx">
    <xsl:variable name="colon"><xsl:text>:</xsl:text></xsl:variable>
    <xsl:element name="xsl:stylesheet">
      <xsl:attribute name="xmlns{$colon}xsl">
        <xsl:text>http://www.w3.org/1999/XSL/Transform</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="version">
        <xsl:text>1.0</xsl:text>
      </xsl:attribute>
      <xsl:element name="xsl:template">
      <xsl:attribute name="match">
        <xsl:value-of select="summary/project"/><xsl:text>page</xsl:text>
      </xsl:attribute>
      <xsl:copy-of select="menu/*"/>
      <xsl:copy-of select="articles/*"/>
      </xsl:element>
      <xsl:element name="xsl:template">
        <xsl:attribute name="match">
          <xsl:value-of select="summary/project"/><xsl:text>page/inputs</xsl:text>
      </xsl:attribute>
      <xsl:element name="div">
        <xsl:element name="dl"> 
          <xsl:for-each select="records/fields">
            <xsl:if test="c='true'">
              <xsl:element name="xsl:apply-templates">
                <xsl:attribute name="select"><xsl:copy-of select="field"/></xsl:attribute>
              </xsl:element>
            </xsl:if>
          </xsl:for-each>
        </xsl:element>
      </xsl:element>
      </xsl:element>      
      <xsl:call-template name="inputx" />      
    </xsl:element>
  </xsl:template>
  
  <xsl:template name="inputx">
    <xsl:apply-templates select="records/fields"/>
  </xsl:template>
  
  <xsl:template match="records/fields">
    <xsl:if test="c='true'">
    <xsl:element name="xsl:template">
      <xsl:attribute name="match"><xsl:value-of select="field"/></xsl:attribute>
        <dt>
          <xsl:element name="label">
            <xsl:attribute name="for"><xsl:text>title</xsl:text></xsl:attribute>
            <xsl:element name="xsl:value-of">
              <xsl:attribute name="select"><xsl:text>@title</xsl:text></xsl:attribute>
            </xsl:element>
          </xsl:element>
        </dt>
        <dd>
          <xsl:element name="input">
            <xsl:attribute name="type"><xsl:text>text</xsl:text></xsl:attribute>
            <xsl:attribute name="id"><xsl:text>title</xsl:text></xsl:attribute>
            <xsl:attribute name="size"><xsl:text>{@size}</xsl:text></xsl:attribute>            
          </xsl:element>
        </dd>
    </xsl:element>
    </xsl:if>
  </xsl:template>
  
</xsl:stylesheet>


... and here's the XML which is used by the XSL above.

<recordx>
<summary><project>books</project><parent_element>book_entry</parent_element></summary>
<menu>
  <div id="gboxes">
    <ul>
      <li><a href="/empsearch/devsearch.xml?id=all">home</a></li> 
      <li><a href="/main/development_blog.xml">development</a></li>
    </ul>
  </div>
</menu>
<articles>
  <div id="articles">
    <h1>www<xsl:value-of select="@title" /></h1>
    <div>
      <xsl:apply-templates select="inputs"></xsl:apply-templates>
    </div>
    <div>
      <xsl:apply-templates select="buttons"></xsl:apply-templates>
    </div>
    <span id="in1"></span>
  </div> 
</articles>
<records>
<fields id='17647'><field>author</field><c>true</c><r>true</r><u>true</u></fields>
<fields id='17675'><field>subject</field><c>true</c><r>true</r><u>false</u></fields>
<fields id='17699'><field>rating</field><c/><r/><u/></fields>
<fields id='17700'><field>last_modified</field><c/><r/><u/></fields>
</records>
</recordx>


« Newer Snippets
Older Snippets »
Showing 1-3 of 3 total  RSS