Module: YARD::Templates::Helpers::HtmlHelper

Includes:
HtmlSyntaxHighlightHelper, MarkupHelper
Defined in:
lib/yard/templates/helpers/html_helper.rb

Constant Summary

SimpleMarkupHtml =
RDoc::Markup::ToHtml.new rescue SM::ToHtml.new

Constants included from MarkupHelper

MARKUP_PROVIDERS

Instance Method Summary

Methods included from HtmlSyntaxHighlightHelper

#html_syntax_highlight_ruby

Instance Method Details

- (Object) anchor_for(object)



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/yard/templates/helpers/html_helper.rb', line 202

def anchor_for(object)
  case object
  when CodeObjects::MethodObject
    "#{object.name}-#{object.scope}_#{object.type}"
  when CodeObjects::ClassVariableObject
    "#{object.name.to_s.gsub('@@', '')}-#{object.type}"
  when CodeObjects::Base
    "#{object.name}-#{object.type}"
  when CodeObjects::Proxy
    object.path
  else
    object.to_s
  end
end

- (Object) fix_dash_dash(text)

TODO: Refactor into own SimpleMarkup subclass

Don’t allow — to turn into — element. The chances of this being some --option is far more likely than the typographical meaning.



90
91
92
# File 'lib/yard/templates/helpers/html_helper.rb', line 90

def fix_dash_dash(text)
  text.gsub(/—(?=\S)/, '--')
end

- (Object) fix_typewriter(text)

TODO: Refactor into own SimpleMarkup subclass

Fixes RDoc behaviour with ++ only supporting alphanumeric text.



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/yard/templates/helpers/html_helper.rb', line 74

def fix_typewriter(text)
  text.gsub(/\+(?! )([^\n\+]{1,900})(?! )\+/) do
    type_text, pre_text, no_match = $1, $`, $&
    pre_match = pre_text.scan(%r(</?(?:pre|tt|code).*?>))
    if pre_match.last.nil? || pre_match.last.include?('/')
      '<tt>' + type_text.gsub(/(.)/, "\\1\004") + '</tt>'
    else
      no_match
    end
  end
end

- (Object) format_object_name_list(objects)



138
139
140
141
142
# File 'lib/yard/templates/helpers/html_helper.rb', line 138

def format_object_name_list(objects)
  objects.sort_by {|o| o.name.to_s.downcase }.map do |o| 
    "<span class='name'>" + linkify(o, o.name) + "</span>" 
  end.join(", ")
end

- (String) format_types(typelist, brackets = true)

Formats a list of types from a tag.

Parameters:

  • (Array<String>, FalseClass) typelist — the list of types to be formatted.
  • (Boolean) brackets (defaults to: true) — omits the surrounding brackets if brackets is set to false.

Returns:

  • (String) — the list of types formatted as [Type1, Type2, …] with the types linked to their respective descriptions.


156
157
158
159
160
161
162
163
164
# File 'lib/yard/templates/helpers/html_helper.rb', line 156

def format_types(typelist, brackets = true)
  return unless typelist.is_a?(Array)
  list = typelist.map do |type| 
    type = type.gsub(/([<>])/) { h($1) }
    type = type.gsub(/([\w:]+)/) { $1 == "lt" || $1 == "gt" ? $1 : linkify($1, $1) }
    "<tt>" + type + "</tt>"
  end
  list.empty? ? "" : (brackets ? "(#{list.join(", ")})" : list.join(", "))
end

- (String) h(text)

Escapes HTML entities

Parameters:

  • (String) text — the text to escape

Returns:

  • (String) — the HTML with escaped entities


15
16
17
# File 'lib/yard/templates/helpers/html_helper.rb', line 15

def h(text)
  CGI.escapeHTML(text.to_s)
end

- (Object) html_syntax_highlight(source, type = :ruby)



317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/yard/templates/helpers/html_helper.rb', line 317

def html_syntax_highlight(source, type = :ruby)
  return "" unless source
  return source if options[:no_highlight]
  
  # handle !!!LANG prefix to send to html_syntax_highlight_LANG
  if source =~ /\A[ \t]*!!!(\w+)[ \t]*\r?\n/
    type, source = $1, $'
    source = $'
  end
  
  meth = "html_syntax_highlight_#{type}"
  respond_to?(meth) ? send(meth, source) : h(source)
end

- (Object) html_syntax_highlight_plain(source)



331
332
333
# File 'lib/yard/templates/helpers/html_helper.rb', line 331

def html_syntax_highlight_plain(source)
  h(source)
end

- (String) htmlify(text, markup = options[:markup])

Turns text into HTML using markup style formatting.

Parameters:

  • (String) text — the text to format
  • (Symbol) markup (defaults to: options[:markup]) — examples are :markdown, :textile, :rdoc. To add a custom markup type, see MarkupHelper

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/yard/templates/helpers/html_helper.rb', line 33

def htmlify(text, markup = options[:markup])
  return "" unless text
  return text unless markup
  load_markup_provider(markup)

  # TODO: other libraries might be more complex
  case markup
  when :markdown
    html = markup_class(markup).new(text).to_html
  when :textile
    doc = markup_class(markup).new(text)
    doc.hard_breaks = false if doc.respond_to?(:hard_breaks=)
    html = doc.to_html
  when :rdoc

    begin
      SimpleMarkupHtml.instance_variable_set("@from_path", url_for(object))
      html = MarkupHelper::SimpleMarkup.convert(text, SimpleMarkupHtml)
    end

    html = fix_typewriter(html)
    html = fix_dash_dash(html)
  end

  html = resolve_links(html)
  html = html.gsub(/<pre>(?:\s*<code>)?(.+?)(?:<\/code>\s*)?<\/pre>/m) do
    str = $1
    str = html_syntax_highlight(CGI.unescapeHTML(str)) unless options[:no_highlight]
    %Q{<pre class="code">#{str}</pre>}
  end
  html
end

- (String) htmlify_line(*args)

HTMLified text as a single line (paragraphs removed)

Returns:

  • (String) — HTMLified text as a single line (paragraphs removed)


67
68
69
# File 'lib/yard/templates/helpers/html_helper.rb', line 67

def htmlify_line(*args)
  htmlify(*args).gsub(/<\/?p>/, '')
end


166
167
168
# File 'lib/yard/templates/helpers/html_helper.rb', line 166

def link_file(filename, title = nil, anchor = nil)
  link_url(url_for_file(filename, anchor), title)
end


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/yard/templates/helpers/html_helper.rb', line 170

def link_object(obj, otitle = nil, anchor = nil, relative = true)
  return otitle if obj.nil?
  obj = Registry.resolve(object, obj, true, true) if obj.is_a?(String)
  if !otitle && obj.root?
    title = "Top Level Namespace"
  elsif otitle
    title = otitle.to_s
  elsif object.is_a?(CodeObjects::Base)
    title = h(object.relative_path(obj))
  else
    title = h(obj.to_s)
  end
  return title unless serializer

  return title if obj.is_a?(CodeObjects::Proxy)

  link = url_for(obj, anchor, relative)
  link ? link_url(link, title, :title => "#{obj.path} (#{obj.type})") : title
end


190
191
192
193
194
195
196
# File 'lib/yard/templates/helpers/html_helper.rb', line 190

def link_url(url, title = nil, params = {})
  params = SymbolHash.new(false).update(
    :href => url,
    :title  => h(title || url)
  ).update(params)
  "<a #{tag_attrs(params)}>#{title}</a>"
end

Resolves any text in the form of {Name} to the object specified by Name. Also supports link titles in the form {Name title}.

Examples:

Linking to an instance method

  resolve_links("{MyClass#method}") # => "<a href='...'>MyClass#method</a>"

Linking to a class with a title

  resolve_links("{A::B::C the C class}") # => "<a href='...'>the c class</a>"

Parameters:

  • (String) text — the text to resolve links in

Returns:

  • (String) — HTML with linkified references


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/yard/templates/helpers/html_helper.rb', line 103

def resolve_links(text)
  code_tags = 0
  text.gsub(/<(\/)?(pre|code|tt)|\{(\S+?)(?:\s(.*?\S))?\}(?=[\W<]|.+<\/|$)/) do |str|
    tag = $2
    closed = $1
    if tag
      code_tags += (closed ? -1 : 1)
      next str
    end
    next str unless code_tags == 0
    
    name = $3
    title = $4 || name

    case name
    when %r{://}, /^mailto:/
      link_url(name, title, :target => '_parent')
    when /^file:(\S+?)(?:#(\S+))?$/
      link_file($1, title == name ? $1 : title, $2)
    else
      if object.is_a?(String)
        obj = name
      else
        obj = Registry.resolve(object, name, true, true)
        if obj.is_a?(CodeObjects::Proxy)
          match = text[/(.{0,20}\{.*?#{Regexp.quote name}.*?\}.{0,20})/, 1]
          log.warn "In file `#{object.file}':#{object.line}: Cannot resolve link to #{obj.path} from text" + (match ? ":" : ".")
          log.warn '...' + match.gsub(/\n/,"\n\t") + '...' if match
        end
        "<tt>" + linkify(obj, title) + "</tt>" 
      end
    end
  end
end

- (Object) signature(meth, link = true, show_extras = true, full_attr_name = true)



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/yard/templates/helpers/html_helper.rb', line 285

def signature(meth, link = true, show_extras = true, full_attr_name = true)
  meth = convert_method_to_overload(meth)
  
  type = signature_types(meth, link)
  scope = meth.scope == :class ? "+" : "-"
  name = full_attr_name ? meth.name : meth.name.to_s.gsub(/=$/, '')
  blk = format_block(meth)
  args = !full_attr_name && meth.writer? ? "" : format_args(meth)
  extras = []
  extras_text = ''
  if show_extras
    if rw = meth.attr_info
      attname = [rw[:read] ? 'read' : nil, rw[:write] ? 'write' : nil].compact
      attname = attname.size == 1 ? attname.join('') + 'only' : nil
      extras << attname if attname
    end
    extras << meth.visibility if meth.visibility != :public
    extras_text = ' <span class="extras">(' + extras.join(", ") + ')</span>' unless extras.empty?
  end
  title = "%s %s<strong>%s</strong>%s %s" % [scope, type, h(name), args, blk]
  if link
    if meth.is_a?(YARD::CodeObjects::MethodObject)
      link_title = "#{h meth.name(true)} (#{meth.scope} #{meth.type})"
    else
      link_title = "#{h name} (#{meth.type})"
    end
    link_url(url_for(meth), title, :title => link_title) + extras_text
  else
    title + extras_text
  end
end

- (Object) signature_types(meth, link = true)



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/yard/templates/helpers/html_helper.rb', line 260

def signature_types(meth, link = true)
  meth = convert_method_to_overload(meth)

  type = options[:default_return] || ""
  if meth.tag(:return) && meth.tag(:return).types
    types = meth.tags(:return).map {|t| t.types ? t.types : [] }.flatten
    first = link ? h(types.first) : format_types([types.first], false)
    if types.size == 2 && types.last == 'nil'
      type = first + '<sup>?</sup>'
    elsif types.size == 2 && types.last =~ /^(Array)?<#{Regexp.quote types.first}>$/
      type = first + '<sup>+</sup>'
    elsif types.size > 2
      type = [first, '...'].join(', ')
    elsif types == ['void'] && options[:hide_void_return]
      type = ""
    else
      type = link ? h(types.join(", ")) : format_types(types, false)
    end
  elsif !type.empty?
    type = link ? h(type) : format_types([type], false)
  end
  type = "(#{type}) " unless type.empty?
  type
end

- (Object) tag_attrs(opts = {})



198
199
200
# File 'lib/yard/templates/helpers/html_helper.rb', line 198

def tag_attrs(opts = {})
  opts.sort_by {|k, v| k.to_s }.map {|k,v| "#{k}=#{v.to_s.inspect}" if v }.join(" ")
end

- (Object) url_for(obj, anchor = nil, relative = true)



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/yard/templates/helpers/html_helper.rb', line 217

def url_for(obj, anchor = nil, relative = true)
  link = nil
  return link unless serializer
  
  if obj.is_a?(CodeObjects::Base) && !obj.is_a?(CodeObjects::NamespaceObject)
    # If the obj is not a namespace obj make it the anchor.
    anchor, obj = obj, obj.namespace
  end
  
  objpath = serializer.serialized_path(obj)
  return link unless objpath

  if relative
    fromobj = object
    if object.is_a?(CodeObjects::Base) && 
        !object.is_a?(CodeObjects::NamespaceObject)
      fromobj = fromobj.namespace
    end

    from = serializer.serialized_path(fromobj)
    link = File.relative_path(from, objpath)
  else
    link = objpath
  end

  link + (anchor ? '#' + urlencode(anchor_for(anchor)) : '')
end

- (Object) url_for_file(filename, anchor = nil)



245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/yard/templates/helpers/html_helper.rb', line 245

def url_for_file(filename, anchor = nil)
  fromobj = object
  if CodeObjects::Base === fromobj && !fromobj.is_a?(CodeObjects::NamespaceObject)
    fromobj = fromobj.namespace
  end
  from = serializer.serialized_path(fromobj)
  if filename == options[:readme]
    filename = 'index'
  else
    filename = 'file.' + File.basename(filename).gsub(/\.[^.]+$/, '')
  end
  link = File.relative_path(from, filename)
  link + '.html' + (anchor ? '#' + urlencode(anchor) : '')
end

- (String) urlencode(text)

Escapes a URL

Parameters:

Returns:

  • (String) — the escaped URL


23
24
25
# File 'lib/yard/templates/helpers/html_helper.rb', line 23

def urlencode(text)
  CGI.escape(text.to_s)
end