module RDoc::Text

Methods for manipulating comment text

Constants

MARKUP_FORMAT

Maps markup formats to classes that can parse them. If the format is unknown, "rdoc" format is used.

TO_HTML_CHARACTERS

Maps an encoding to a Hash of characters properly transcoded for that encoding.

See also encode_fallback.

Public Class Methods

encode_fallback(character, encoding, fallback) click to toggle source

Transcodes character to encoding with a fallback character.

# File lib/rdoc/text.rb, line 58
def self.encode_fallback character, encoding, fallback
 character.encode(encoding, :fallback => { character => fallback },
 :undef => :replace, :replace => fallback)
end

Public Instance Methods

expand_tabs(text) click to toggle source

Expands tab characters in text to eight spaces

# File lib/rdoc/text.rb, line 66
def expand_tabs text
 expanded = []
 text.each_line do |line|
 nil while line.gsub!(/(?:\G|\r)((?:.{8})*?)([^\t\r\n]{0,7})\t/) do
 r = "#{1ドル}#{2ドル}#{' ' * (8 - 2ドル.size)}"
 r.force_encoding text.encoding if Object.const_defined? :Encoding
 r
 end
 expanded << line
 end
 expanded.join
end
flush_left(text) click to toggle source

Flush text left based on the shortest line

# File lib/rdoc/text.rb, line 85
def flush_left text
 indent = 9999
 text.each_line do |line|
 line_indent = line =~ /\S/ || 9999
 indent = line_indent if indent > line_indent
 end
 empty = ''
 empty.force_encoding text.encoding if Object.const_defined? :Encoding
 text.gsub(/^ {0,#{indent}}/, empty)
end
markup(text) click to toggle source

Convert a string in markup format into HTML.

Requires the including class to implement formatter

# File lib/rdoc/text.rb, line 104
def markup text
 parse(text).accept formatter
end
normalize_comment(text) click to toggle source

Strips hashes, expands tabs then flushes text to the left

# File lib/rdoc/text.rb, line 111
def normalize_comment text
 return text if text.empty?
 text = strip_stars text
 text = strip_hashes text
 text = expand_tabs text
 text = flush_left text
 text = strip_newlines text
 text
end
parse(text, format = 'rdoc') click to toggle source

Normalizes text then builds a RDoc::Markup::Document from it

# File lib/rdoc/text.rb, line 125
def parse text, format = 'rdoc'
 return text if RDoc::Markup::Document === text
 return text.parse if RDoc::Comment === text
 text = normalize_comment text # TODO remove, should not be necessary
 return RDoc::Markup::Document.new if text =~ /\A\n*\z/
 MARKUP_FORMAT[format].parse text
end
snippet(text, limit = 100) click to toggle source

The first limit characters of text as HTML

# File lib/rdoc/text.rb, line 139
def snippet text, limit = 100
 document = parse text
 RDoc::Markup::ToHtmlSnippet.new(options, limit).convert document
end
strip_hashes(text) click to toggle source

Strips leading # characters from text

# File lib/rdoc/text.rb, line 148
def strip_hashes text
 return text if text =~ /^(?>\s*)[^\#]/
 empty = ''
 empty.force_encoding text.encoding if Object.const_defined? :Encoding
 text.gsub(/^\s*(#+)/) { 1ドル.tr '#', ' ' }.gsub(/^\s+$/, empty)
end
strip_newlines(text) click to toggle source

Strips leading and trailing n characters from text

# File lib/rdoc/text.rb, line 160
def strip_newlines text
 text.gsub(/\A\n*(.*?)\n*\z/m) do 1ドル end # block preserves String encoding
end
strip_stars(text) click to toggle source

Strips style comments

# File lib/rdoc/text.rb, line 167
def strip_stars text
 return text unless text =~ %r%/\*.*\*/%m
 encoding = text.encoding if Object.const_defined? :Encoding
 text = text.gsub %r%Document-method:\s+[\w:.#=!?]+%, ''
 space = ' '
 space.force_encoding encoding if encoding
 text.sub! %r%/\*+% do space * $&.length end
 text.sub! %r%\*+/% do space * $&.length end
 text.gsub! %r%^[ \t]*\*%m do space * $&.length end
 empty = ''
 empty.force_encoding encoding if encoding
 text.gsub(/^\s+$/, empty)
end
to_html(text) click to toggle source

Converts ampersand, dashes, ellipsis, quotes, copyright and registered trademark symbols in text to properly encoded characters.

# File lib/rdoc/text.rb, line 190
def to_html text
 if Object.const_defined? :Encoding then
 html = ''.encode text.encoding
 encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding]
 else
 html = ''
 encoded = {
 :close_dquote => '"',
 :close_squote => '’',
 :copyright => '©',
 :ellipsis => '...',
 :em_dash => '—',
 :en_dash => '–',
 :open_dquote => '"',
 :open_squote => '‘',
 :trademark => '®',
 }
 end
 s = StringScanner.new text
 insquotes = false
 indquotes = false
 after_word = nil
 until s.eos? do
 case
 when s.scan(/<(tt|code)>.*?<\/1円>/) then # skip contents of tt
 html << s.matched.gsub('\\', '\')
 when s.scan(/<(tt|code)>.*?/) then
 warn "mismatched <#{s[1]}> tag" # TODO signal file/line
 html << s.matched
 when s.scan(/<[^>]+\/?s*>/) then # skip HTML tags
 html << s.matched
 when s.scan(/\(\S)/) then # unhandled suppressed crossref
 html << s[1]
 after_word = nil
 when s.scan(/\.\.\.(\.?)/) then
 html << s[1] << encoded[:ellipsis]
 after_word = nil
 when s.scan(/\(c\)/) then
 html << encoded[:copyright]
 after_word = nil
 when s.scan(/\(r\)/) then
 html << encoded[:trademark]
 after_word = nil
 when s.scan(/---/) then
 html << encoded[:em_dash]
 after_word = nil
 when s.scan(/--/) then
 html << encoded[:en_dash]
 after_word = nil
 when s.scan(/&quot;|"/) then
 html << encoded[indquotes ? :close_dquote : :open_dquote]
 indquotes = !indquotes
 after_word = nil
 when s.scan(/``/) then # backtick double quote
 html << encoded[:open_dquote]
 after_word = nil
 when s.scan(/''/) then # tick double quote
 html << encoded[:close_dquote]
 after_word = nil
 when s.scan(/'/) then # single quote
 if insquotes
 html << encoded[:close_squote]
 insquotes = false
 elsif after_word
 # Mary's dog, my parents' house: do not start paired quotes
 html << encoded[:close_squote]
 else
 html << encoded[:open_squote]
 insquotes = true
 end
 after_word = nil
 else # advance to the next potentially significant character
 match = s.scan(/.+?(?=[<\.("'`&-])/) #"
 if match then
 html << match
 after_word = match =~ /\w$/
 else
 html << s.rest
 break
 end
 end
 end
 html
end
wrap(txt, line_len = 76) click to toggle source

Wraps txt to line_len

# File lib/rdoc/text.rb, line 284
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.join.strip
end