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



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

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.



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

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



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

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



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

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



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

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



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

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



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

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

#accept_rule(rule) ⇒ Object

Adds rule to the output



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

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
# 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::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



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

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



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

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:



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

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



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

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



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

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



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

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)


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

def parseable? text
  eval("BEGIN {return true}\n#{text}")
rescue SyntaxError
  false
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



394
395
396
# File 'lib/rdoc/markup/to_html.rb', line 394

def to_html item
  super convert_flow @am.flow item
end