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



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

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
# 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
    bullets = Array(list_item.label).map do |label|
      attributes(label).strip
    end.join "\n"

    bullets << ":\n" unless bullets.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



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/rdoc/markup/to_rdoc.rb', line 168

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



195
196
197
198
# File 'lib/rdoc/markup/to_rdoc.rb', line 195

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

#accept_raw(raw) ⇒ Object

Adds raw to the output



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

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

#accept_rule(rule) ⇒ Object

Adds rule to the output



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

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



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/rdoc/markup/to_rdoc.rb', line 243

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



229
230
231
232
233
234
235
236
237
238
# File 'lib/rdoc/markup/to_rdoc.rb', line 229

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



271
272
273
274
# File 'lib/rdoc/markup/to_rdoc.rb', line 271

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

#end_acceptingObject

Returns the generated output



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

def end_accepting
  @res.join
end

#handle_regexp_HARD_BREAK(target) ⇒ Object

Adds a newline to the output



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

def handle_regexp_HARD_BREAK target
  "\n"
end

#handle_regexp_SUPPRESSED_CROSSREF(target) ⇒ Object

Removes preceding \ from the suppressed crossref target



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

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



302
303
304
305
306
307
308
309
310
# File 'lib/rdoc/markup/to_rdoc.rb', line 302

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.



316
317
318
319
320
321
# File 'lib/rdoc/markup/to_rdoc.rb', line 316

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

  prefix
end

#wrap(text) ⇒ Object

Wraps text to #width



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/rdoc/markup/to_rdoc.rb', line 326

def wrap text
  return unless text && !text.empty?

  text_len = @width - @indent

  text_len = 20 if text_len < 20

  re = /^(.{0,#{text_len}})[ \n]/
  next_prefix = ' ' * @indent

  prefix = @prefix || next_prefix
  @prefix = nil

  @res << prefix

  while text.length > text_len
    if text =~ re then
      @res << $1
      text.slice!(0, $&.length)
    else
      @res << text.slice!(0, text_len)
    end

    @res << "\n" << next_prefix
  end

  if text.empty? then
    @res.pop
    @res.pop
  else
    @res << text
    @res << "\n"
  end
end