Class: RDoc::Markup::ToHtml

Inherits:
Formatter show all
Includes:
Text
Defined in:
lib/rdoc/markup/to_html.rb

Overview

Outputs RDoc markup as HTML.

Direct Known Subclasses

ToHtmlCrossref, ToHtmlSnippet

Constant Summary collapse

LIST_TYPE_TO_HTML =

Maps RDoc::Markup::Parser::LIST_TOKENS types to HTML tags

{
  :BULLET => ['<ul>',                                      '</ul>'],
  :LABEL  => ['<dl class="rdoc-list label-list">',         '</dl>'],
  :LALPHA => ['<ol style="list-style-type: lower-alpha">', '</ol>'],
  :NOTE   => ['<dl class="rdoc-list note-list">',          '</dl>'],
  :NUMBER => ['<ol>',                                      '</ol>'],
  :UALPHA => ['<ol style="list-style-type: upper-alpha">', '</ol>'],
}

Constants included from Text

Text::MARKUP_FORMAT, Text::TO_HTML_CHARACTERS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Text

encode_fallback, #expand_tabs, #flush_left, #markup, #normalize_comment, #parse, #snippet, #strip_hashes, #strip_newlines, #strip_stars, #wrap

Methods inherited from Formatter

#accept_document, #add_special_RDOCLINK, #add_special_TIDYLINK, #add_tag, #annotate, #convert, #convert_flow, #convert_special, gen_relative_url, #ignore, #in_tt?, #off_tags, #on_tags, #parse_url, #tt?

Constructor Details

#initialize(options, markup = nil) ⇒ ToHtml

Creates a new formatter that will output HTML



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

def initialize options, markup = nil
  super

  @code_object = nil
  @from_path = ''
  @in_list_entry = nil
  @list = nil
  @th = nil
  @hard_break = "<br>\n"

  # external links
  @markup.add_special(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)\S+\w/,
                      :HYPERLINK)

  add_special_RDOCLINK
  add_special_TIDYLINK

  init_tags
end

Instance Attribute Details

#code_objectObject

The RDoc::CodeObject HTML is being generated for. This is used to generate namespaced URI fragments



33
34
35
# File 'lib/rdoc/markup/to_html.rb', line 33

def code_object
  @code_object
end

#from_pathObject

Path to this document for relative links



38
39
40
# File 'lib/rdoc/markup/to_html.rb', line 38

def from_path
  @from_path
end

#in_list_entryObject (readonly)

:nodoc:



26
27
28
# File 'lib/rdoc/markup/to_html.rb', line 26

def in_list_entry
  @in_list_entry
end

#listObject (readonly)

:nodoc:



27
28
29
# File 'lib/rdoc/markup/to_html.rb', line 27

def list
  @list
end

#resObject (readonly)

:nodoc:



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

def res
  @res
end

Instance Method Details

#accept_blank_line(blank_line) ⇒ Object

Adds blank_line to the output



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

def accept_blank_line(blank_line)
  # @res << annotate("<p />") << "\n"
end

#accept_block_quote(block_quote) ⇒ Object

Adds block_quote to the output



172
173
174
175
176
177
178
179
180
# File 'lib/rdoc/markup/to_html.rb', line 172

def accept_block_quote block_quote
  @res << "\n<blockquote>"

  block_quote.parts.each do |part|
    part.accept self
  end

  @res << "</blockquote>\n"
end

#accept_heading(heading) ⇒ Object

Adds heading to the output. The headings greater than 6 are trimmed to level 6.



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/rdoc/markup/to_html.rb', line 279

def accept_heading heading
  level = [6, heading.level].min

  label = heading.label @code_object

  @res << if @options.output_decoration
            "\n<h#{level} id=\"#{label}\">"
          else
            "\n<h#{level}>"
          end
  @res << to_html(heading.text)
  unless @options.pipe then
    @res << "<span><a href=\"##{label}\">&para;</a>"
    @res << " <a href=\"#top\">&uarr;</a></span>"
  end
  @res << "</h#{level}>\n"
end

#accept_list_end(list) ⇒ Object

Finishes consumption of list



242
243
244
245
246
247
248
# File 'lib/rdoc/markup/to_html.rb', line 242

def accept_list_end(list)
  @list.pop
  if tag = @in_list_entry.pop
    @res << tag
  end
  @res << html_list_name(list.type, false) << "\n"
end

#accept_list_item_end(list_item) ⇒ Object

Finishes consumption of list_item



264
265
266
# File 'lib/rdoc/markup/to_html.rb', line 264

def accept_list_item_end(list_item)
  @in_list_entry[-1] = list_end_for(@list.last)
end

#accept_list_item_start(list_item) ⇒ Object

Prepares the visitor for consuming list_item



253
254
255
256
257
258
259
# File 'lib/rdoc/markup/to_html.rb', line 253

def accept_list_item_start(list_item)
  if tag = @in_list_entry.last
    @res << tag
  end

  @res << list_item_start(list_item, @list.last)
end

#accept_list_start(list) ⇒ Object

Prepares the visitor for consuming list



233
234
235
236
237
# File 'lib/rdoc/markup/to_html.rb', line 233

def accept_list_start(list)
  @list << list.type
  @res << html_list_name(list.type, true)
  @in_list_entry.push false
end

#accept_paragraph(paragraph) ⇒ Object

Adds paragraph to the output



185
186
187
188
189
190
191
# File 'lib/rdoc/markup/to_html.rb', line 185

def accept_paragraph paragraph
  @res << "\n<p>"
  text = paragraph.text @hard_break
  text = text.gsub(/\r?\n/, ' ')
  @res << wrap(to_html(text))
  @res << "</p>\n"
end

#accept_raw(raw) ⇒ Object

Adds raw to the output



300
301
302
# File 'lib/rdoc/markup/to_html.rb', line 300

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

#accept_rule(rule) ⇒ Object

Adds rule to the output



226
227
228
# File 'lib/rdoc/markup/to_html.rb', line 226

def accept_rule rule
  @res << "<hr>\n"
end

#accept_verbatim(verbatim) ⇒ Object

Adds verbatim to the output



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rdoc/markup/to_html.rb', line 196

def accept_verbatim verbatim
  text = verbatim.text.rstrip

  klass = nil

  content = if verbatim.ruby? or parseable? text then
              begin
                tokens = RDoc::RipperStateLex.parse text
                klass  = ' class="ruby"'

                result = RDoc::TokenStream.to_html tokens
                result = result + "\n" unless "\n" == result[-1]
                result
              rescue
                CGI.escapeHTML text
              end
            else
              CGI.escapeHTML text
            end

  if @options.pipe then
    @res << "\n<pre><code>#{CGI.escapeHTML text}\n</code></pre>\n"
  else
    @res << "\n<pre#{klass}>#{content}</pre>\n"
  end
end

#convert_string(text) ⇒ Object

CGI-escapes text



309
310
311
# File 'lib/rdoc/markup/to_html.rb', line 309

def convert_string(text)
  CGI.escapeHTML text
end

#end_acceptingObject

Returns the generated output



165
166
167
# File 'lib/rdoc/markup/to_html.rb', line 165

def end_accepting
  @res.join
end

#gen_url(url, text) ⇒ Object

Generate a link to url with content text. Handles the special cases for img: and link: described under handle_special_HYPERLINK



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/rdoc/markup/to_html.rb', line 317

def gen_url url, text
  scheme, url, id = parse_url url

  if %w[http https link].include?(scheme) and
     url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
    "<img src=\"#{url}\" />"
  else
    text = text.sub %r%^#{scheme}:/*%i, ''
    text = text.sub %r%^[*\^](\d+)$%,   '\1'

    link = "<a#{id} href=\"#{url}\">#{text}</a>"

    link = "<sup>#{link}</sup>" if /"foot/ =~ id

    link
  end
end

:section: Special Handling

These methods handle special markup added by RDoc::Markup#add_special.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rdoc/markup/to_html.rb', line 69

def handle_RDOCLINK url # :nodoc:
  case url
  when /^rdoc-ref:/
    $'
  when /^rdoc-label:/
    text = $'

    text = case text
           when /\Alabel-/    then $'
           when /\Afootmark-/ then $'
           when /\Afoottext-/ then $'
           else                    text
           end

    gen_url url, text
  when /^rdoc-image:/
    "<img src=\"#{$'}\">"
  else
    url =~ /\Ardoc-[a-z]+:/

    $'
  end
end

#handle_special_HARD_BREAK(special) ⇒ Object

special is a <br>



96
97
98
# File 'lib/rdoc/markup/to_html.rb', line 96

def handle_special_HARD_BREAK special
  '<br>'
end

special is a potential link. The following schemes are handled:

mailto:

Inserted as-is.

http:

Links are checked to see if they reference an image. If so, that image gets inserted using an <img> tag. Otherwise a conventional <a href> is used.

link:

Reference to a local file relative to the output directory.



112
113
114
115
116
# File 'lib/rdoc/markup/to_html.rb', line 112

def handle_special_HYPERLINK(special)
  url = special.text

  gen_url url, url
end

special is an rdoc-schemed link that will be converted into a hyperlink.

For the rdoc-ref scheme the named reference will be returned without creating a link.

For the rdoc-label scheme the footnote and label prefixes are stripped when creating a link. All other contents will be linked verbatim.



127
128
129
# File 'lib/rdoc/markup/to_html.rb', line 127

def handle_special_RDOCLINK special
  handle_RDOCLINK special.text
end

This special is a link where the label is different from the URL label[url] or {long label}[url]



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rdoc/markup/to_html.rb', line 135

def handle_special_TIDYLINK(special)
  text = special.text

  return text unless
    text =~ /^\{(.*)\}\[(.*?)\]$/ or text =~ /^(\S+)\[(.*?)\]$/

  label = $1
  url   = $2

  label = handle_RDOCLINK label if /^rdoc-image:/ =~ label

  gen_url url, label
end

#html_list_name(list_type, open_tag) ⇒ Object

Determines the HTML list element for list_type and open_tag

Raises:



338
339
340
341
342
# File 'lib/rdoc/markup/to_html.rb', line 338

def html_list_name(list_type, open_tag)
  tags = LIST_TYPE_TO_HTML[list_type]
  raise RDoc::Error, "Invalid list type: #{list_type.inspect}" unless tags
  tags[open_tag ? 0 : 1]
end

#init_tagsObject

Maps attributes to HTML tags



347
348
349
350
351
# File 'lib/rdoc/markup/to_html.rb', line 347

def init_tags
  add_tag :BOLD, "<strong>", "</strong>"
  add_tag :TT,   "<code>",   "</code>"
  add_tag :EM,   "<em>",     "</em>"
end

#list_end_for(list_type) ⇒ Object

Returns the HTML end-tag for list_type



373
374
375
376
377
378
379
380
381
382
# File 'lib/rdoc/markup/to_html.rb', line 373

def list_end_for(list_type)
  case list_type
  when :BULLET, :LALPHA, :NUMBER, :UALPHA then
    "</li>"
  when :LABEL, :NOTE then
    "</dd>"
  else
    raise RDoc::Error, "Invalid list type: #{list_type.inspect}"
  end
end

#list_item_start(list_item, list_type) ⇒ Object

Returns the HTML tag for list_type, possible using a label from list_item



357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/rdoc/markup/to_html.rb', line 357

def list_item_start(list_item, list_type)
  case list_type
  when :BULLET, :LALPHA, :NUMBER, :UALPHA then
    "<li>"
  when :LABEL, :NOTE then
    Array(list_item.label).map do |label|
      "<dt>#{to_html label}\n"
    end.join << "<dd>"
  else
    raise RDoc::Error, "Invalid list type: #{list_type.inspect}"
  end
end

#parseable?(text) ⇒ Boolean

Returns true if text is valid ruby syntax

Returns:

  • (Boolean)


387
388
389
390
391
392
393
394
# File 'lib/rdoc/markup/to_html.rb', line 387

def parseable? text
  verbose, $VERBOSE = $VERBOSE, nil
  eval("BEGIN {return true}\n#{text}")
rescue SyntaxError
  false
ensure
  $VERBOSE = verbose
end

#start_acceptingObject

Prepares the visitor for HTML generation



156
157
158
159
160
# File 'lib/rdoc/markup/to_html.rb', line 156

def start_accepting
  @res = []
  @in_list_entry = []
  @list = []
end

#to_html(item) ⇒ Object

Converts item to HTML using RDoc::Text#to_html



399
400
401
# File 'lib/rdoc/markup/to_html.rb', line 399

def to_html item
  super convert_flow @am.flow item
end