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


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

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


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

def code_object
  @code_object
end

#from_pathObject

Path to this document for relative links


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

def from_path
  @from_path
end

#in_list_entryObject (readonly)

:nodoc:


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

def in_list_entry
  @in_list_entry
end

#listObject (readonly)

:nodoc:


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

def list
  @list
end

#resObject (readonly)

:nodoc:


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

def res
  @res
end

Instance Method Details

#accept_blank_line(blank_line) ⇒ Object

Adds blank_line to the output


268
269
270
# File 'lib/rdoc/markup/to_html.rb', line 268

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

#accept_block_quote(block_quote) ⇒ Object

Adds block_quote to the output


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

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.


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

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=\"#documentation\">&uarr;</a></span>"
  end
  @res << "</h#{level}>\n"
end

#accept_list_end(list) ⇒ Object

Finishes consumption of list


239
240
241
242
243
244
245
# File 'lib/rdoc/markup/to_html.rb', line 239

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


261
262
263
# File 'lib/rdoc/markup/to_html.rb', line 261

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


250
251
252
253
254
255
256
# File 'lib/rdoc/markup/to_html.rb', line 250

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


230
231
232
233
234
# File 'lib/rdoc/markup/to_html.rb', line 230

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


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

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


297
298
299
# File 'lib/rdoc/markup/to_html.rb', line 297

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

#accept_rule(rule) ⇒ Object

Adds rule to the output


223
224
225
# File 'lib/rdoc/markup/to_html.rb', line 223

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

#accept_verbatim(verbatim) ⇒ Object

Adds verbatim to the output


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

def accept_verbatim verbatim
  text = verbatim.text.rstrip

  klass = nil

  content = if verbatim.ruby? or parseable? text then
              begin
                tokens = RDoc::RubyLex.tokenize text, @options
                klass  = ' class="ruby"'

                RDoc::TokenStream.to_html tokens
              rescue RDoc::RubyLex::Error
                CGI.escapeHTML text
              end
            else
              CGI.escapeHTML text
            end

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

#convert_string(text) ⇒ Object

CGI-escapes text


306
307
308
# File 'lib/rdoc/markup/to_html.rb', line 306

def convert_string(text)
  CGI.escapeHTML text
end

#end_acceptingObject

Returns the generated output


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

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


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

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.


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

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


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

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.


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

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.


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

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]


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

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:


335
336
337
338
339
# File 'lib/rdoc/markup/to_html.rb', line 335

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


344
345
346
347
348
# File 'lib/rdoc/markup/to_html.rb', line 344

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


370
371
372
373
374
375
376
377
378
379
# File 'lib/rdoc/markup/to_html.rb', line 370

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


354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/rdoc/markup/to_html.rb', line 354

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 Ripper is available it can create a sexp from text


384
385
386
387
# File 'lib/rdoc/markup/to_html.rb', line 384

def parseable? text
  text =~ /\b(def|class|module|require) |=>|\{\s?\||do \|/ and
    text !~ /<%|%>/
end

#start_acceptingObject

Prepares the visitor for HTML generation


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

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

#to_html(item) ⇒ Object

Converts item to HTML using RDoc::Text#to_html


392
393
394
# File 'lib/rdoc/markup/to_html.rb', line 392

def to_html item
  super convert_flow @am.flow item
end