From d464704f111d211c1f1ff9ef23ef1d755054be00 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Wed, 15 Aug 2007 19:08:43 +0000 Subject: add tag v1_8_5_54 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_5_54@12952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- .../lib/rdoc/markup/simple_markup/to_html.rb | 289 +++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 ruby_1_8_5/lib/rdoc/markup/simple_markup/to_html.rb (limited to 'ruby_1_8_5/lib/rdoc/markup/simple_markup/to_html.rb') diff --git a/ruby_1_8_5/lib/rdoc/markup/simple_markup/to_html.rb b/ruby_1_8_5/lib/rdoc/markup/simple_markup/to_html.rb new file mode 100644 index 0000000000..26b5f4ce70 --- /dev/null +++ b/ruby_1_8_5/lib/rdoc/markup/simple_markup/to_html.rb @@ -0,0 +1,289 @@ +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/inline' + +require 'cgi' + +module SM + + class ToHtml + + LIST_TYPE_TO_HTML = { + ListBase::BULLET => [ "" ], + ListBase::NUMBER => [ "
    ", "
" ], + ListBase::UPPERALPHA => [ "
    ", "
" ], + ListBase::LOWERALPHA => [ "
    ", "
" ], + ListBase::LABELED => [ "
", "
" ], + ListBase::NOTE => [ "", "
" ], + } + + 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), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(:TT), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(: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 = "" + @in_list_entry = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << annotate("

") + "\n" + @res << wrap(convert_flow(am.flow(fragment.txt))) + @res << annotate("

") + "\n" + end + + def accept_verbatim(am, fragment) + @res << annotate("
") + "\n"
+      @res << CGI.escapeHTML(fragment.txt)
+      @res << annotate("
") << "\n" + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << "
" + end + + def accept_list_start(am, fragment) + @res << html_list_name(fragment.type, true) <<"\n" + @in_list_entry.push false + end + + def accept_list_end(am, fragment) + if tag = @in_list_entry.pop + @res << annotate(tag) << "\n" + end + @res << html_list_name(fragment.type, false) <<"\n" + end + + def accept_list_item(am, fragment) + if tag = @in_list_entry.last + @res << annotate(tag) << "\n" + end + @res << list_item_start(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n" + @in_list_entry[-1] = list_end_for(fragment.type) + end + + def accept_blank_line(am, fragment) + # @res << annotate("

") << "\n" + end + + def accept_heading(am, fragment) + @res << convert_heading(fragment.head_level, am.flow(fragment.txt)) + end + + # This is a higher speed (if messier) version of wrap + + def wrap(txt, line_len = 76) + res = "" + sp = 0 + ep = txt.length + while sp < ep + # scan back for a space + p = sp + line_len - 1 + if p >= ep + p = ep + else + while p > sp and txt[p] != ?\s + p -= 1 + end + if p <= sp + p = sp + line_len + while p < ep and txt[p] != ?\s + p += 1 + end + end + end + res << txt[sp...p] << "\n" + sp = p + sp += 1 while sp < ep and txt[sp] == ?\s + end + res + 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). + + + # convert -- to em-dash, (-- to en-dash) + gsub(/---?/, '—'). #gsub(/--/, '–'). + + # convert ... to elipsis (and make sure .... becomes .) + gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…'). + + # convert single closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1’" }. + gsub(%r{\'(?=\W|s\b)}) { "’" }. + + # convert single opening quote + gsub(/'/, '‘'). + + # convert double closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1”" }. + + # convert double opening quote + gsub(/'/, '“'). + + # convert copyright + gsub(/\(c\)/, '©'). + + # convert and registered trademark + gsub(/\(r\)/, '®') + + 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 + + def convert_heading(level, flow) + res = + annotate("") + + convert_flow(flow) + + annotate("\n") + end + + def html_list_name(list_type, is_open_tag) + tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}") + annotate(tags[ is_open_tag ? 0 : 1]) + end + + def list_item_start(am, fragment) + case fragment.type + when ListBase::BULLET, ListBase::NUMBER + annotate("

  • ") + + when ListBase::UPPERALPHA + annotate("
  • ") + + when ListBase::LOWERALPHA + annotate("
  • ") + + when ListBase::LABELED + annotate("
    ") + + convert_flow(am.flow(fragment.param)) + + annotate("
    ") + + annotate("
    ") + + when ListBase::NOTE + annotate("") + + annotate("") + + convert_flow(am.flow(fragment.param)) + + annotate("") + + annotate("") + else + raise "Invalid list type" + end + end + + def list_end_for(fragment_type) + case fragment_type + when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA + "
  • " + when ListBase::LABELED + "" + when ListBase::NOTE + "" + else + raise "Invalid list type" + end + end + + end + +end -- cgit v1.2.3