class RDoc::Markup::ToRdoc
Outputs RDoc markup as RDoc markup! (mostly)
Constants
- DEFAULT_HEADINGS
Attributes
Current indent amount for output in characters
Stack of current list indexes for alphabetic and numeric lists
Stack of list types
Stack of list widths for indentation
Prefix for the next list item. See use_prefix
Output accumulator
Output width in characters
Public Class Methods
Creates a new formatter that will output (mostly) RDoc markup
RDoc::Markup::Formatter::new
# File lib/rdoc/markup/to_rdoc.rb, line 55 def initialize(markup = nil) super nil, markup @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF) @width = 78 @headings = DEFAULT_HEADINGS.dup @hard_break = "\n" end
Public Instance Methods
Adds blank_line to the output
# File lib/rdoc/markup/to_rdoc.rb, line 68 def accept_blank_line(blank_line) @res << "\n" end
Adds paragraph to the output
# File lib/rdoc/markup/to_rdoc.rb, line 75 def accept_block_quote(block_quote) @indent += 2 block_quote.parts.each do |part| @prefix = '> ' part.accept self end @indent -= 2 end
Adds heading to the output
# File lib/rdoc/markup/to_rdoc.rb, line 90 def accept_heading(heading) use_prefix or @res << ' ' * @indent @res << @headings[heading.level][0] @res << attributes(heading.text) @res << @headings[heading.level][1] @res << "\n" end
Adds paragraph to the output
# File lib/rdoc/markup/to_rdoc.rb, line 202 def accept_indented_paragraph(paragraph) @indent += paragraph.indent text = paragraph.text @hard_break wrap attributes text @indent -= paragraph.indent end
Finishes consumption of list
# File lib/rdoc/markup/to_rdoc.rb, line 101 def accept_list_end(list) @list_index.pop @list_type.pop @list_width.pop end
Finishes consumption of list_item
# File lib/rdoc/markup/to_rdoc.rb, line 110 def accept_list_item_end(list_item) width = case @list_type.last when :BULLET then 2 when :NOTE, :LABEL then if @prefix then @res << @prefix.strip @prefix = nil end @res << "\n" 2 else bullet = @list_index.last.to_s @list_index[-1] = @list_index.last.succ bullet.length + 2 end @indent -= width end
Prepares the visitor for consuming list_item
# File lib/rdoc/markup/to_rdoc.rb, line 134 def accept_list_item_start(list_item) type = @list_type.last case type when :NOTE, :LABEL then stripped_labels = Array(list_item.label).map do |label| attributes(label).strip end bullets = case type when :NOTE stripped_labels.map { |b| "#{b}::" } when :LABEL stripped_labels.map { |b| "[#{b}]" } end bullets = bullets.join("\n") bullets << "\n" unless stripped_labels.empty? @prefix = ' ' * @indent @indent += 2 @prefix << bullets + (' ' * @indent) else bullet = type == :BULLET ? '*' : @list_index.last.to_s + '.' @prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1) width = bullet.length + 1 @indent += width end end
Prepares the visitor for consuming list
# File lib/rdoc/markup/to_rdoc.rb, line 167 def accept_list_start(list) case list.type when :BULLET then @list_index << nil @list_width << 1 when :LABEL, :NOTE then @list_index << nil @list_width << 2 when :LALPHA then @list_index << 'a' @list_width << list.items.length.to_s.length when :NUMBER then @list_index << 1 @list_width << list.items.length.to_s.length when :UALPHA then @list_index << 'A' @list_width << list.items.length.to_s.length else raise RDoc::Error, "invalid list type #{list.type}" end @list_type << list.type end
Adds paragraph to the output
# File lib/rdoc/markup/to_rdoc.rb, line 194 def accept_paragraph(paragraph) text = paragraph.text @hard_break wrap attributes text end
Adds raw to the output
# File lib/rdoc/markup/to_rdoc.rb, line 212 def accept_raw(raw) @res << raw.parts.join("\n") end
Adds rule to the output
# File lib/rdoc/markup/to_rdoc.rb, line 219 def accept_rule(rule) use_prefix or @res << ' ' * @indent @res << '-' * (@width - @indent) @res << "\n" end
Adds table to the output
# File lib/rdoc/markup/to_rdoc.rb, line 242 def accept_table(header, body, aligns) header = header.map { |h| attributes h } body = body.map { |row| row.map { |t| attributes t } } widths = header.zip(*body).map do |cols| cols.compact.map { |col| calculate_text_width(col) }.max end aligns = aligns.map do |a| case a when nil, :center :center when :left :ljust when :right :rjust end end @res << header.zip(widths, aligns).map do |h, w, a| extra_width = h.size - calculate_text_width(h) h.__send__(a, w + extra_width) end.join("|").rstrip << "\n" @res << widths.map {|w| "-" * w }.join("|") << "\n" body.each do |row| @res << widths.zip(aligns).each_with_index.map do |(w, a), i| t = row[i] || "" extra_width = t.size - calculate_text_width(t) t.__send__(a, w + extra_width) end.join("|").rstrip << "\n" end end
Outputs verbatim indented 2 columns
# File lib/rdoc/markup/to_rdoc.rb, line 228 def accept_verbatim(verbatim) indent = ' ' * (@indent + 2) verbatim.parts.each do |part| @res << indent unless part == "\n" @res << part end @res << "\n" end
# File lib/rdoc/markup/to_rdoc.rb, line 347 def add_text(text) emit_inline(text) end
Applies attribute-specific markup to text using RDoc::Markup::InlineParser
# File lib/rdoc/markup/to_rdoc.rb, line 358 def attributes(text) handle_inline(text) end
# File lib/rdoc/markup/to_rdoc.rb, line 272 def calculate_text_width(text) text.size end
# File lib/rdoc/markup/to_rdoc.rb, line 351 def emit_inline(text) @inline_output << text end
Returns the generated output
# File lib/rdoc/markup/to_rdoc.rb, line 365 def end_accepting @res.join end
RDoc::Markup::Formatter#handle_BOLD
# File lib/rdoc/markup/to_rdoc.rb, line 284 def handle_BOLD(target) on(:BOLD) super off(:BOLD) end
RDoc::Markup::Formatter#handle_BOLD_WORD
# File lib/rdoc/markup/to_rdoc.rb, line 296 def handle_BOLD_WORD(word) on(:BOLD) super off(:BOLD) end
RDoc::Markup::Formatter#handle_EM
# File lib/rdoc/markup/to_rdoc.rb, line 290 def handle_EM(target) on(:EM) super off(:EM) end
RDoc::Markup::Formatter#handle_EM_WORD
# File lib/rdoc/markup/to_rdoc.rb, line 302 def handle_EM_WORD(word) on(:EM) super off(:EM) end
# File lib/rdoc/markup/to_rdoc.rb, line 320 def handle_HARD_BREAK add_text("\n") end
# File lib/rdoc/markup/to_rdoc.rb, line 276 def handle_PLAIN_TEXT(text) add_text(text) end
# File lib/rdoc/markup/to_rdoc.rb, line 280 def handle_REGEXP_HANDLING_TEXT(text) add_text(text) end
RDoc::Markup::Formatter#handle_STRIKE
# File lib/rdoc/markup/to_rdoc.rb, line 314 def handle_STRIKE(target) on(:STRIKE) super off(:STRIKE) end
RDoc::Markup::Formatter#handle_TIDYLINK
# File lib/rdoc/markup/to_rdoc.rb, line 324 def handle_TIDYLINK(label_part, url) super add_text("( #{url} )") end
RDoc::Markup::Formatter#handle_TT
# File lib/rdoc/markup/to_rdoc.rb, line 308 def handle_TT(code) on(:TT) super off(:TT) end
RDoc::Markup::Formatter#handle_inline
# File lib/rdoc/markup/to_rdoc.rb, line 329 def handle_inline(text, initial_attributes = []) @attributes = Hash.new(0) initial_attributes.each { |attr| on(attr) } out = @inline_output = +'' super(text) @inline_output = nil out end
Removes preceding \ from the suppressed crossref target
# File lib/rdoc/markup/to_rdoc.rb, line 372 def handle_regexp_SUPPRESSED_CROSSREF(text) text.sub('\\', '') end
# File lib/rdoc/markup/to_rdoc.rb, line 342 def off(attr) @attributes[attr] -= 1 @attributes.delete(attr) if @attributes[attr] == 0 end
# File lib/rdoc/markup/to_rdoc.rb, line 338 def on(attr) @attributes[attr] += 1 end
Prepares the visitor for text generation
# File lib/rdoc/markup/to_rdoc.rb, line 379 def start_accepting @res = [""] @indent = 0 @prefix = nil @list_index = [] @list_type = [] @list_width = [] end
Adds the stored prefix to the output and clears it. Lists generate a prefix for later consumption.
# File lib/rdoc/markup/to_rdoc.rb, line 393 def use_prefix prefix, @prefix = @prefix, nil @res << prefix if prefix prefix end
Wraps text to width
# File lib/rdoc/markup/to_rdoc.rb, line 403 def wrap(text) return unless text && !text.empty? text_len = @width - @indent text_len = 20 if text_len < 20 next_prefix = ' ' * @indent prefix = @prefix || next_prefix @prefix = nil text.scan(/\G(?:([^ \n]{#{text_len}})(?=[^ \n])|(.{1,#{text_len}})(?:[ \n]|\z))/) do @res << prefix << ($1 || $2) << "\n" prefix = next_prefix end end