Class: RDoc::Markup::ToRdoc

Inherits:
Formatter show all
Defined in:
lib/rdoc/markup/to_rdoc.rb

Overview

Outputs RDoc markup as RDoc markup! (mostly)

Direct Known Subclasses

ToAnsi, ToBs, ToMarkdown

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Formatter

#accept_document, #add_regexp_handling_RDOCLINK, #add_regexp_handling_TIDYLINK, #add_tag, #annotate, #convert, #convert_flow, #convert_regexp_handling, #convert_string, gen_relative_url, #ignore, #in_tt?, #off_tags, #on_tags, #parse_url, #tt?

Constructor Details

#initialize(markup = nil) ⇒ ToRdoc

Creates a new formatter that will output (mostly) RDoc markup



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rdoc/markup/to_rdoc.rb', line 45

def initialize markup = nil
  super nil, markup

  @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF)
  @width = 78
  init_tags

  @headings = {}
  @headings.default = []

  @headings[1] = ['= ',      '']
  @headings[2] = ['== ',     '']
  @headings[3] = ['=== ',    '']
  @headings[4] = ['==== ',   '']
  @headings[5] = ['===== ',  '']
  @headings[6] = ['====== ', '']

  @hard_break = "\n"
end

Instance Attribute Details

#indentObject

Current indent amount for output in characters



10
11
12
# File 'lib/rdoc/markup/to_rdoc.rb', line 10

def indent
  @indent
end

#list_indexObject (readonly)

Stack of current list indexes for alphabetic and numeric lists



20
21
22
# File 'lib/rdoc/markup/to_rdoc.rb', line 20

def list_index
  @list_index
end

#list_typeObject (readonly)

Stack of list types



25
26
27
# File 'lib/rdoc/markup/to_rdoc.rb', line 25

def list_type
  @list_type
end

#list_widthObject (readonly)

Stack of list widths for indentation



30
31
32
# File 'lib/rdoc/markup/to_rdoc.rb', line 30

def list_width
  @list_width
end

#prefixObject (readonly)

Prefix for the next list item. See #use_prefix



35
36
37
# File 'lib/rdoc/markup/to_rdoc.rb', line 35

def prefix
  @prefix
end

#resObject (readonly)

Output accumulator



40
41
42
# File 'lib/rdoc/markup/to_rdoc.rb', line 40

def res
  @res
end

#widthObject

Output width in characters



15
16
17
# File 'lib/rdoc/markup/to_rdoc.rb', line 15

def width
  @width
end

Instance Method Details

#accept_blank_line(blank_line) ⇒ Object

Adds blank_line to the output



77
78
79
# File 'lib/rdoc/markup/to_rdoc.rb', line 77

def accept_blank_line blank_line
  @res << "\n"
end

#accept_block_quote(block_quote) ⇒ Object

Adds paragraph to the output



84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rdoc/markup/to_rdoc.rb', line 84

def accept_block_quote block_quote
  @indent += 2

  block_quote.parts.each do |part|
    @prefix = '> '

    part.accept self
  end

  @indent -= 2
end

#accept_heading(heading) ⇒ Object

Adds heading to the output



99
100
101
102
103
104
105
# File 'lib/rdoc/markup/to_rdoc.rb', line 99

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

#accept_indented_paragraph(paragraph) ⇒ Object

Adds paragraph to the output



211
212
213
214
215
216
# File 'lib/rdoc/markup/to_rdoc.rb', line 211

def accept_indented_paragraph paragraph
  @indent += paragraph.indent
  text = paragraph.text @hard_break
  wrap attributes text
  @indent -= paragraph.indent
end

#accept_list_end(list) ⇒ Object

Finishes consumption of list



110
111
112
113
114
# File 'lib/rdoc/markup/to_rdoc.rb', line 110

def accept_list_end list
  @list_index.pop
  @list_type.pop
  @list_width.pop
end

#accept_list_item_end(list_item) ⇒ Object

Finishes consumption of list_item



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/rdoc/markup/to_rdoc.rb', line 119

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

#accept_list_item_start(list_item) ⇒ Object

Prepares the visitor for consuming list_item



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rdoc/markup/to_rdoc.rb', line 143

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

#accept_list_start(list) ⇒ Object

Prepares the visitor for consuming list



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/rdoc/markup/to_rdoc.rb', line 176

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

#accept_paragraph(paragraph) ⇒ Object

Adds paragraph to the output



203
204
205
206
# File 'lib/rdoc/markup/to_rdoc.rb', line 203

def accept_paragraph paragraph
  text = paragraph.text @hard_break
  wrap attributes text
end

#accept_raw(raw) ⇒ Object

Adds raw to the output



221
222
223
# File 'lib/rdoc/markup/to_rdoc.rb', line 221

def accept_raw raw
  @res << raw.parts.join("\n")
end

#accept_rule(rule) ⇒ Object

Adds rule to the output



228
229
230
231
232
# File 'lib/rdoc/markup/to_rdoc.rb', line 228

def accept_rule rule
  use_prefix or @res << ' ' * @indent
  @res << '-' * (@width - @indent)
  @res << "\n"
end

#accept_table(header, body, aligns) ⇒ Object

Adds table to the output



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/rdoc/markup/to_rdoc.rb', line 251

def accept_table header, body, aligns
  widths = header.zip(body) do |h, b|
    [h.size, b.size].max
  end
  aligns = aligns.map do |a|
    case a
    when nil
      :center
    when :left
      :ljust
    when :right
      :rjust
    end
  end
  @res << header.zip(widths, aligns) do |h, w, a|
    h.__send__(a, w)
  end.join("|").rstrip << "\n"
  @res << widths.map {|w| "-" * w }.join("|") << "\n"
  body.each do |row|
    @res << row.zip(widths, aligns) do |t, w, a|
      t.__send__(a, w)
    end.join("|").rstrip << "\n"
  end
end

#accept_verbatim(verbatim) ⇒ Object

Outputs verbatim indented 2 columns



237
238
239
240
241
242
243
244
245
246
# File 'lib/rdoc/markup/to_rdoc.rb', line 237

def accept_verbatim verbatim
  indent = ' ' * (@indent + 2)

  verbatim.parts.each do |part|
    @res << indent unless part == "\n"
    @res << part
  end

  @res << "\n"
end

#attributes(text) ⇒ Object

Applies attribute-specific markup to text using RDoc::AttributeManager



279
280
281
282
# File 'lib/rdoc/markup/to_rdoc.rb', line 279

def attributes text
  flow = @am.flow text.dup
  convert_flow flow
end

#end_acceptingObject

Returns the generated output



287
288
289
# File 'lib/rdoc/markup/to_rdoc.rb', line 287

def end_accepting
  @res.join
end

#handle_regexp_HARD_BREAK(target) ⇒ Object

Adds a newline to the output



303
304
305
# File 'lib/rdoc/markup/to_rdoc.rb', line 303

def handle_regexp_HARD_BREAK target
  "\n"
end

#handle_regexp_SUPPRESSED_CROSSREF(target) ⇒ Object

Removes preceding \ from the suppressed crossref target



294
295
296
297
298
# File 'lib/rdoc/markup/to_rdoc.rb', line 294

def handle_regexp_SUPPRESSED_CROSSREF target
  text = target.text
  text = text.sub('\\', '') unless in_tt?
  text
end

#init_tagsObject

Maps attributes to HTML sequences



68
69
70
71
72
# File 'lib/rdoc/markup/to_rdoc.rb', line 68

def init_tags
  add_tag :BOLD, "<b>", "</b>"
  add_tag :TT,   "<tt>", "</tt>"
  add_tag :EM,   "<em>", "</em>"
end

#start_acceptingObject

Prepares the visitor for text generation



310
311
312
313
314
315
316
317
318
# File 'lib/rdoc/markup/to_rdoc.rb', line 310

def start_accepting
  @res = [""]
  @indent = 0
  @prefix = nil

  @list_index = []
  @list_type  = []
  @list_width = []
end

#use_prefixObject

Adds the stored #prefix to the output and clears it. Lists generate a prefix for later consumption.



324
325
326
327
328
329
# File 'lib/rdoc/markup/to_rdoc.rb', line 324

def use_prefix
  prefix, @prefix = @prefix, nil
  @res << prefix if prefix

  prefix
end

#wrap(text) ⇒ Object

Wraps text to #width



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/rdoc/markup/to_rdoc.rb', line 334

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