diff options
author | dave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-16 05:44:25 +0000 |
---|---|---|
committer | dave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-16 05:44:25 +0000 |
commit | c5bbcadbe64477433a243be191c41010c7ae10dc (patch) | |
tree | 0d09db2cbe31c84eac3c29575e7008c9d7a6d57b /lib/rdoc/markup | |
parent | dcd30a1236cdb2e06b6dd1a74a4c0a0c29549be6 (diff) |
Initial load of support for ri/rdoc integration
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/markup')
-rw-r--r-- | lib/rdoc/markup/simple_markup/to_flow.rb | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/lib/rdoc/markup/simple_markup/to_flow.rb b/lib/rdoc/markup/simple_markup/to_flow.rb new file mode 100644 index 0000000000..b91bb12e1f --- /dev/null +++ b/lib/rdoc/markup/simple_markup/to_flow.rb @@ -0,0 +1,187 @@ +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/inline' + + +module SM + + module Flow + P = Struct.new(:body) + VERB = Struct.new(:body) + RULE = Struct.new(:width) + class LIST + attr_reader :type, :contents + def initialize(type) + @type = type + @contents = [] + end + def <<(stuff) + @contents << stuff + end + end + LI = Struct.new(:label, :body) + H = Struct.new(:level, :text) + end + + class ToFlow + + LIST_TYPE_TO_HTML = { + ListBase::BULLET => [ "<ul>", "</ul>" ], + ListBase::NUMBER => [ "<ol>", "</ol>" ], + ListBase::UPPERALPHA => [ "<ol>", "</ol>" ], + ListBase::LOWERALPHA => [ "<ol>", "</ol>" ], + ListBase::LABELED => [ "<dl>", "</dl>" ], + ListBase::NOTE => [ "<table>", "</table>" ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + init_tags + end + + ## + # Set up the standard mapping of attributes to HTML tags + # + def init_tags + @attr_tags = [ + InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"), + InlineTag.new(SM::Attribute.bitmap_for(:TT), "<tt>", "</tt>"), + InlineTag.new(SM::Attribute.bitmap_for(:EM), "<em>", "</em>"), + ] + end + + ## + # Add a new set of HTML tags for an attribute. We allow + # separate start and end tags for flexibility + # + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop) + end + + ## + # Given an HTML tag, decorate it with class information + # and the like if required. This is a no-op in the base + # class, but is overridden in HTML output classes that + # implement style sheets + + def annotate(tag) + tag + end + + ## + # Here's the client side of the visitor pattern + + def start_accepting + @res = [] + @list_stack = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << Flow::P.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_verbatim(am, fragment) + @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_rule(am, fragment) + @res << Rule.new(size) + end + + def accept_list_start(am, fragment) + @list_stack.push(@res) + list = Flow::LIST.new(fragment.type) + @res << list + @res = list + end + + def accept_list_end(am, fragment) + @res = @list_stack.pop + end + + def accept_list_item(am, fragment) + @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt))) + end + + def accept_blank_line(am, fragment) + # @res << annotate("<p />") << "\n" + end + + def accept_heading(am, fragment) + @res << Flow::H.new(fragment.head_level, am.flow(fragment.txt)) + end + + + ####################################################################### + + private + + ####################################################################### + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.on) + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.off) + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + # some of these patterns are taken from SmartyPants... + + def convert_string(item) + CGI.escapeHTML(item) + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + raise "Unhandled special: #{special}" unless handled + special.text + end + + + end + +end |