Hi!
I think it is a good idea to illustrate how Ruby can be used as a
markup language. I therefore wrote an example document and a class
that generates HTML out of it. It is a quick hack but should give an
idea of how a more complex solution (including a couple of output
formats) could look like. For more take a look at the source of the
German comp.lang.ruby FAQ at
http://oss.erdfunkstelle.de/ruby/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Document in Ruby
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#!/usr/bin/env ruby
require "layout"
Fmt = HTML
d = Fmt.new("Documentation of Ruby in Ruby", "Josef 'Jupp' Schugt")
d.h1("Isn't that an absurd idea?")
d.p(
"At first sight it may seem absurd to use a " +
Fmt.i("programming") +
" language to write documents but it makes perfect sense. It requires
surprisingly little effort to write documentations in Ruby."
)
d.p(
"That simplicity results from Ruby's " + Fmt.i("object-oriented") +
" features."
)
d.p("Some of the advantages of using Ruby:")
d.ol([
"People who document Ruby can be assumed to be familiar with Ruby's
syntax.",
"The formatting capabilities can easily be restricted or expanded
according to the needs.",
"It is very simple to generated any output format you like by
simply instantiating the appropriate class.",
"Separation of structure and layout is very strict.",
"Output generation is incredibly fast.",
])
d.h1('What is needed?')
d.p(
"One needs very few means to typeset a book. As a rule of thumb one
can say that the typographic quality of a book " +
Fmt.i("decreases") + " with an " + Fmt.i("increasing") +
" number of typographic means used (unless you " + Fmt.b("really") +
" know what you are doing)."
)
d.p(
"If you think you need more than what is mentioned in the following
list you should consider reading a good book on typography."
)
d.ul([
"Headlines of several levels",
"Paragraphs",
"italics, bold, and typewriter font",
"Preformatted text",
"Itemization",
"Enumeration",
"Description lists",
"Tables",
"Graphics",
])
d.h1("Stuff not used above")
d.p("The stuff that hasn't been used above is:")
d.ul([
"Typewriter font",
"Preformatted text",
"Description lists",
"Tables",
"Graphics",
])
d.p("Let's demonstrate them now.")
d.h2("Preformatted text and Typewriter font")
d.p(
"The code given below extends the classes " + Fmt.tt("TrueClass") +
" and " + Fmt.tt("FalseClass") +
" so that they can be converted to an integer."
)
d.pre(
"
class TrueClass
def to_i
1
end
end
class FalseClass
def to_i
0
end
end
")
d.h2("Description List")
d.p(
"The description list below has some of the Ruby-related acronyms"
)
d.dl([
[ "DRY", "Don't repeat yourself" ],
[ "IANYM", "I am not Yukihiro Matsumoto" ],
[ "POLS", "Principle of least surprise" ],
[ "YAGNI / YANGI / YANGNI", "You ain't gonna need it" ],
[ "YWFWA", "Yes we freakin' well are" ],
])
d.h2("Table")
d.p(
"The table shows the same as the description list above"
)
d.table([
[ [ "Acronym", "th" ], ["Meaning", "th" ] ],
[ [ "DRY", "th" ], "Don't repeat yourself" ],
[ [ "IANYM", "th" ], "I am not Yukihiro Matsumoto" ],
[ [ "POLS", "th" ], "Principle of least surprise" ],
[ [ "YAGNI/YANGI/YANGNI", "th" ], "You ain't gonna need it" ],
[ [ "YWFWA", "th" ], "Yes we freakin' well are" ],
])
d.h2("Image")
d.p(
"Now it is time for the last element: A picture"
)
d.p(Fmt.img("./rubypower.gif"))
d.h1("Conclusion")
d.p(
"I hope to have shown that it is really easy to write documentations
in Ruby."
)
puts d
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Layout class for HTML
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#!/usr/bin/env ruby
class HTML
def initialize(title, author)
@date = Time.now.strftime("%Y-%m-%d, %H:%M:%S %Z")
@document = <<-EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>#{title} by #{author}</title>
<meta name="generator" content="Ruby HTML class"></meta>
</head>
<body>
<hr>
<h1>#{title}</h1>
<h2>#{author}</h2>
<h3>#{@date}</h3>
<hr>
EOF
end
def to_s
<<-EOF
#{@document}
<hr>
<p>
Generated by Ruby HTML class on #{@date}
</p>
</body>
</html>
EOF
end
def h1(text) @document << "<h1>#{text}</h1>\n" end
def h2(text) @document << "<h2>#{text}</h2>\n" end
def h3(text) @document << "<h3>#{text}</h3>\n" end
def h4(text) @document << "<h4>#{text}</h4>\n" end
def h5(text) @document << "<h5>#{text}</h5>\n" end
def h6(text) @document << "<h6>#{text}</h6>\n" end
def p(text) @document << "<p>\n#{text}\n</p>\n" end
def pre(text) @document << "<pre>#{text}</pre>\n" end
def ul(list)
@document << "<ul>\n<li>"
@document << list.join("</li>\n<li>")
@document << "</li>\n</ul>\n"
end
def ol(list)
@document << "<ol>\n<li>"
@document << list.join("</li>\n<li>")
@document << "</li>\n</ol>\n"
end
def dl(list)
@document << "<dl>\n"
list.each { |entry|
@document << "<dt><b>#{entry[0]}</b></dt>\n"
@document << "<dd>#{entry[1]}</dd>\n"
}
@document << "</dl>\n"
end
def table(list)
@document << "<table border>\n"
list.each { |row|
@document << "<tr>\n"
row.each { |cell|
if cell.class == String
@document << "<td>#{cell}</td>\n"
else
@document << "<th align=\"left\">"
@document << "<b>#{cell.first}</b>"
@document << "</th>\n"
end
}
@document << "</tr>\n"
}
@document << "</table>\n"
end
def HTML.i(text) "<i>#{text}</i>" end
def HTML.b(text) "<b>#{text}</b>" end
def HTML.tt(text) "<code>#{text}</code>\n" end
def HTML.img(url) "<img src=\"#{url}\" alt=\"#{url}\">" end
end
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
That's it for now.
Josef 'Jupp' SCHUGT