Class: Slodown::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/slodown/formatter.rb

Overview

This is the base Formatter class provided by Slodown. It works right out of the box if you want to use exactly the functionality provided by it, but in most projects, you'll probably want to create a new class inheriting from this one, selectively overriding methods like kramdown_options or adding your own.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ Formatter


11
12
13
14
# File 'lib/slodown/formatter.rb', line 11

def initialize(source)
  @current = @source = source.to_s
   = {}
end

Instance Attribute Details

#metadataObject (readonly)

Returns the value of attribute metadata


9
10
11
# File 'lib/slodown/formatter.rb', line 9

def 
  
end

Instance Method Details

#allowed_iframe_hostsObject

Return a regular expression that will be matched against an embedded IFRAME's source URL's host. If the expression matches, the IFRAME tag will be whitelisted in its entirety; otherwise, it will be sanitized.

By default, all hosts are allowed. Override this method if this is not what you want.


122
123
124
# File 'lib/slodown/formatter.rb', line 122

def allowed_iframe_hosts
  /.*/
end

Auto-link URLs through Rinku.


32
33
34
35
36
# File 'lib/slodown/formatter.rb', line 32

def autolink
  convert do |current|
    Rinku.auto_link(current)
  end
end

#completeObject

Run the entire pipeline in a sane order.


18
19
20
# File 'lib/slodown/formatter.rb', line 18

def complete
  .markdown.autolink.sanitize
end

#embed_transformerObject

A sanitize transformer that will check the document for IFRAME tags and validate them against allowed_iframe_hosts.


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/slodown/formatter.rb', line 136

def embed_transformer
  lambda do |env|
    node      = env[:node]
    node_name = env[:node_name]

    # We're fine with a bunch of stuff -- but not <iframe> and <embed> tags.
    return if env[:is_whitelisted] || !env[:node].element?
    return unless %w[iframe embed].include? env[:node_name]

    # We're dealing with an <iframe> or <embed> tag! Let's check its src attribute.
    # If its host name matches our regular expression, we can whitelist it.
    uri = URI(env[:node]['src'])
    return unless uri.host =~ allowed_iframe_hosts

    Sanitize.clean_node!(node, {
      elements: %w[iframe embed],
      attributes: {
        all: %w[allowfullscreen frameborder height src width]
      }
    })

    { node_whitelist: [node] }
  end
end

#extract_metadataObject

Extract metadata from the document.


48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/slodown/formatter.rb', line 48

def 
   = {}

  convert do |current|
    current.each_line.drop_while do |line|
      next false if line !~ /^#\+([a-z_]+): (.*)/

      key, value = $1, $2
      [key.to_sym] = value
    end.join('')
  end
end

#kramdown_optionsObject

Return a hash of configuration values for kramdown. Please refer to the documentation of kramdown for details:

kramdown.gettalong.org/options.html


70
71
72
73
74
75
# File 'lib/slodown/formatter.rb', line 70

def kramdown_options
  {
    syntax_highlighter: defined?(Rouge) ? 'rouge' : 'coderay',
    syntax_highlighter_opts: { }
  }
end

#markdownObject

Convert the current document state from Markdown into HTML.


24
25
26
27
28
# File 'lib/slodown/formatter.rb', line 24

def markdown
  convert do |current|
    Kramdown::Document.new(current, kramdown_options).to_slodown_html
  end
end

#sanitizeObject

Sanitize HTML tags.


40
41
42
43
44
# File 'lib/slodown/formatter.rb', line 40

def sanitize
  convert do |current|
    Sanitize.clean(current, sanitize_config)
  end
end

#sanitize_configObject

Return a hash of configuration values for the sanitize gem. Please refer to the documentation for sanitize for details:

github.com/rgrove/sanitize#custom-configuration


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/slodown/formatter.rb', line 82

def sanitize_config
  {
    elements: %w(
      p br a span sub sup strong em div hr abbr s
      ul ol li
      blockquote pre code kbd
      h1 h2 h3 h4 h5 h6
      img object param del
    ),
    attributes: {
      :all     => ['class', 'style', 'title', 'id'],
      'a'      => ['href', 'rel', 'name'],
      'li'     => ['id'],
      'sup'    => ['id'],
      'img'    => ['src', 'title', 'alt', 'width', 'height'],
      'object' => ['width', 'height'],
      'param'  => ['name', 'value'],
      'embed'  => ['allowscriptaccess', 'width', 'height', 'src'],
      'iframe' => ['width', 'height', 'src']
    },
    protocols: {
      'a' => { 'href' => ['ftp', 'http', 'https', 'mailto', '#fn', '#fnref', :relative] },
      'img' => {'src'  => ['http', 'https', :relative]},
      'iframe' => {'src'  => ['http', 'https']},
      'embed' => {'src'  => ['http', 'https']},
      'object' => {'src'  => ['http', 'https']},
      'li' => {'id' => ['fn']},
      'sup' => {'id' => ['fnref']}
    },
    transformers: transformers
  }
end

#to_sObject


61
62
63
# File 'lib/slodown/formatter.rb', line 61

def to_s
  @current
end

#transformersObject

A list of sanitize transformers to be applied to the markup that is to be sanitized. By default, we're only using embed_transformer.


129
130
131
# File 'lib/slodown/formatter.rb', line 129

def transformers
  [embed_transformer]
end