summaryrefslogtreecommitdiff
path: root/lib/rdoc/text.rb
blob: 5280aa0fd2d9e6e420d137596790b0023fe0ac77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
##
# Methods for manipulating comment text

module RDoc::Text

  ##
  # Expands tab characters in +text+ to eight spaces

  def expand_tabs text
    expanded = []

    text.each_line do |line|
      line.gsub!(/^(.{8}*?)([^\t\r\n]{0,7})\t/) do
        "#{$1}#{$2}#{' ' * (8 - $2.size)}"
      end until line !~ /\t/

      expanded << line
    end

    expanded.join
  end

  ##
  # Flush +text+ left based on the shortest line

  def flush_left text
    indents = []

    text.each_line do |line|
      indents << (line =~ /[^\s]/ || 9999)
    end

    indent = indents.min

    flush = []

    text.each_line do |line|
      line[/^ {0,#{indent}}/] = ''
      flush << line
    end

    flush.join
  end

  ##
  # Convert a string in markup format into HTML.  Removes the first paragraph
  # tags if +remove_para+ is true.
  #
  # Requires the including class to implement #formatter

  def markup text
    document = parse text

    document.accept formatter
  end

  ##
  # Strips hashes, expands tabs then flushes +text+ to the left

  def normalize_comment text
    return text if text.empty?

    text = strip_hashes text
    text = expand_tabs text
    text = flush_left text
    strip_newlines text
  end

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

  def parse text
    return text if RDoc::Markup::Document === text

    text = normalize_comment text

    return RDoc::Markup::Document.new if text =~ /\A\n*\z/

    RDoc::Markup::Parser.parse text
  rescue RDoc::Markup::Parser::Error => e
    $stderr.puts <<-EOF
While parsing markup, RDoc encountered a #{e.class}:

#{e}
\tfrom #{e.backtrace.join "\n\tfrom "}

---8<---
#{text}
---8<---

RDoc #{RDoc::VERSION}

Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} #{RUBY_RELEASE_DATE}

Please file a bug report with the above information at:

http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse

    EOF
    raise
  end

  ##
  # Strips leading # characters from +text+

  def strip_hashes text
    return text if text =~ /^(?>\s*)[^\#]/
    text.gsub(/^\s*(#+)/) { $1.tr '#',' ' }
  end

  ##
  # Strips leading and trailing \n characters from +text+

  def strip_newlines text
    text.gsub(/\A\n*(.*?)\n*\z/m, '\1')
  end

  ##
  # Strips /* */ style comments

  def strip_stars text
    text = text.gsub %r%Document-method:\s+[\w:.#]+%, ''
    text.sub!  %r%/\*+%       do " " * $&.length end
    text.sub!  %r%\*+/%       do " " * $&.length end
    text.gsub! %r%^[ \t]*\*%m do " " * $&.length end
    text
  end

end