2008-02-09 22:59:08 -05:00
|
|
|
require 'rdoc/markup'
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
##
|
|
|
|
# Base class for RDoc markup formatters
|
|
|
|
#
|
|
|
|
# Formatters use a visitor pattern to convert content into output.
|
2011-07-30 20:19:00 -04:00
|
|
|
#
|
|
|
|
# If you'd like to write your own Formatter use
|
|
|
|
# RDoc::Markup::FormatterTestCase. If you're writing a text-output formatter
|
|
|
|
# use RDoc::Markup::TextFormatterTestCase which provides extra test cases.
|
2010-04-01 03:45:16 -04:00
|
|
|
|
2008-02-09 22:59:08 -05:00
|
|
|
class RDoc::Markup::Formatter
|
|
|
|
|
2010-12-19 22:22:49 -05:00
|
|
|
##
|
|
|
|
# Tag for inline markup containing a +bit+ for the bitmask and the +on+ and
|
|
|
|
# +off+ triggers.
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
InlineTag = Struct.new(:bit, :on, :off)
|
|
|
|
|
|
|
|
##
|
|
|
|
# Creates a new Formatter
|
|
|
|
|
2011-06-16 00:59:24 -04:00
|
|
|
def initialize markup = nil
|
|
|
|
@markup = markup || RDoc::Markup.new
|
|
|
|
@am = @markup.attribute_manager
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
@attr_tags = []
|
|
|
|
|
|
|
|
@in_tt = 0
|
|
|
|
@tt_bit = RDoc::Markup::Attribute.bitmap_for :TT
|
|
|
|
end
|
|
|
|
|
2011-06-16 00:59:24 -04:00
|
|
|
##
|
|
|
|
# Adds +document+ to the output
|
|
|
|
|
|
|
|
def accept_document document
|
|
|
|
document.parts.each do |item|
|
|
|
|
item.accept self
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
##
|
|
|
|
# Add a new set of tags for an attribute. We allow separate start and end
|
|
|
|
# tags for flexibility
|
|
|
|
|
|
|
|
def add_tag(name, start, stop)
|
|
|
|
attr = RDoc::Markup::Attribute.bitmap_for name
|
|
|
|
@attr_tags << InlineTag.new(attr, start, stop)
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Allows +tag+ to be decorated with additional information.
|
|
|
|
|
|
|
|
def annotate(tag)
|
|
|
|
tag
|
2008-02-09 22:59:08 -05:00
|
|
|
end
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
##
|
|
|
|
# Marks up +content+
|
|
|
|
|
2008-02-09 22:59:08 -05:00
|
|
|
def convert(content)
|
|
|
|
@markup.convert content, self
|
|
|
|
end
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
##
|
|
|
|
# Converts flow items +flow+
|
|
|
|
|
|
|
|
def convert_flow(flow)
|
|
|
|
res = []
|
|
|
|
|
|
|
|
flow.each do |item|
|
|
|
|
case item
|
|
|
|
when String then
|
|
|
|
res << convert_string(item)
|
|
|
|
when RDoc::Markup::AttrChanger then
|
|
|
|
off_tags res, item
|
|
|
|
on_tags res, item
|
|
|
|
when RDoc::Markup::Special then
|
|
|
|
res << convert_special(item)
|
|
|
|
else
|
|
|
|
raise "Unknown flow element: #{item.inspect}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
res.join
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Converts added specials. See RDoc::Markup#add_special
|
|
|
|
|
2011-08-23 19:53:49 -04:00
|
|
|
def convert_special special
|
|
|
|
return special.text if in_tt?
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
handled = false
|
|
|
|
|
|
|
|
RDoc::Markup::Attribute.each_name_of special.type do |name|
|
|
|
|
method_name = "handle_special_#{name}"
|
|
|
|
|
|
|
|
if respond_to? method_name then
|
|
|
|
special.text = send method_name, special
|
|
|
|
handled = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
raise "Unhandled special: #{special}" unless handled
|
|
|
|
|
|
|
|
special.text
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Converts a string to be fancier if desired
|
|
|
|
|
|
|
|
def convert_string string
|
|
|
|
string
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Are we currently inside tt tags?
|
|
|
|
|
|
|
|
def in_tt?
|
|
|
|
@in_tt > 0
|
|
|
|
end
|
|
|
|
|
2010-12-19 22:22:49 -05:00
|
|
|
##
|
|
|
|
# Turns on tags for +item+ on +res+
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
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 then
|
|
|
|
res << annotate(tag.on)
|
|
|
|
@in_tt += 1 if tt? tag
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-12-19 22:22:49 -05:00
|
|
|
##
|
|
|
|
# Turns off tags for +item+ on +res+
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
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 then
|
|
|
|
@in_tt -= 1 if tt? tag
|
|
|
|
res << annotate(tag.off)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Is +tag+ a tt tag?
|
|
|
|
|
|
|
|
def tt? tag
|
|
|
|
tag.bit == @tt_bit
|
|
|
|
end
|
|
|
|
|
2008-02-09 22:59:08 -05:00
|
|
|
end
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
class RDoc::Markup
|
|
|
|
autoload :ToAnsi, 'rdoc/markup/to_ansi'
|
|
|
|
autoload :ToBs, 'rdoc/markup/to_bs'
|
|
|
|
autoload :ToHtml, 'rdoc/markup/to_html'
|
|
|
|
autoload :ToHtmlCrossref, 'rdoc/markup/to_html_crossref'
|
|
|
|
autoload :ToRdoc, 'rdoc/markup/to_rdoc'
|
|
|
|
end
|