slodown 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +61 -32
- data/lib/slodown.rb +0 -1
- data/lib/slodown/formatter.rb +40 -20
- data/lib/slodown/version.rb +1 -1
- data/slodown.gemspec +3 -4
- metadata +7 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69786a2c6984b3113df329ee878d76eb4de88655
|
4
|
+
data.tar.gz: 9daa0d51fa74d936cf5441d0aafd7013f88b2643
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37af9f2cf9371fac48f05e3301d916b5bf057980ff78b20f3b06848d9c7fbef5494e6604f658c69f89f063cd4cff11af9af53b941f78439bb3c163c6798abfaf
|
7
|
+
data.tar.gz: 70e96284fdb75a2d9ffa4025b5550c8c0f2f1bc8cfd53aef622b4bd1c2b511801123a32a9ed5a9a4529c1bf64a39465e79a66de4f3f86f1958c6f1b98cd28b4e
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,34 +1,34 @@
|
|
1
|
-
![
|
1
|
+
![Slodown](https://dl.dropbox.com/u/7288/hendrik.mans.de/slodown.png)
|
2
2
|
|
3
|
-
#
|
3
|
+
# Slodown is the ultimate user input rendering pipeline.
|
4
4
|
|
5
5
|
[![Build Status](https://travis-ci.org/hmans/slodown.png?branch=master)](https://travis-ci.org/hmans/slodown) [![Gem Version](https://badge.fury.io/rb/slodown.png)](http://badge.fury.io/rb/slodown)
|
6
6
|
|
7
|
-
**I love Markdown. I love syntax highlighting. I love oEmbed. And last but not least, I love whitelist-based HTML sanitizing.
|
7
|
+
**I love Markdown. I love syntax highlighting. I love oEmbed. And last but not least, I love whitelist-based HTML sanitizing. Slodown rolls all of these into one, and then some.**
|
8
8
|
|
9
|
-
Here's what
|
9
|
+
Here's what Slodown does by default:
|
10
10
|
|
11
11
|
- **render extended Markdown into HTML**. It uses the [kramdown](http://kramdown.rubyforge.org/) library, so yes, footnotes are supported!
|
12
|
-
- **add syntax highlighting to Markdown code blocks** through [CodeRay](http://coderay.rubychan.de/).
|
13
|
-
- **support super-easy rich media embeds
|
12
|
+
- **add syntax highlighting to Markdown code blocks** through [CodeRay](http://coderay.rubychan.de/), [Rouge](http://rouge.jneen.net/), or any other highlighter supported by kramdown.
|
13
|
+
- **support super-easy rich media embeds**. Just point the Markdown image syntax at, say, a Youtube video, and Slodown will fetch the complete embed code through the magic of [ruby-oembed](https://github.com/judofyr/ruby-oembed).
|
14
14
|
- **auto-link contained URLs** using [Rinku](https://github.com/vmg/rinku), which is smart enough to not auto-link URLs contained in, say, code blocks.
|
15
|
-
- **sanitize the generated HTML** using the white-list based [sanitize](https://github.com/rgrove/sanitize) gem.
|
15
|
+
- **sanitize the generated HTML** using the white-list based [sanitize](https://github.com/rgrove/sanitize) gem, with some really good default configuration.
|
16
16
|
|
17
|
-
|
17
|
+
Slodown is an extraction from [sloblog.io](http://sloblog.io). It is very easy to extend or modify, as it's just a plain old Ruby class you can inherit from.
|
18
18
|
|
19
|
-
##
|
19
|
+
## General Approach
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
gem 'slodown'
|
21
|
+
Slodown, out of the box, implements my preferred way of handling user input, which looks like this:
|
24
22
|
|
25
|
-
|
23
|
+
- Convert all Markdown to HTML.
|
24
|
+
- Don't strip HTML the user added themselves.
|
25
|
+
- Auto-link contained URLs and email addresses.
|
26
|
+
- Finally, and most importantly, run the entire HTML through a really, really good whitelist-based sanitizer.
|
26
27
|
|
27
|
-
|
28
|
+
This allows users to still add their own HTML, if required. In fact, I typically encourage users to make use of [kramdown's inline attributes], leaving it up the sanitizer to make sure they don't go crazy.
|
28
29
|
|
29
|
-
|
30
|
+
If this is not what you want, you will most likely be able to bend Slodown to your will -- it's pretty flexible.
|
30
31
|
|
31
|
-
$ gem install slodown
|
32
32
|
|
33
33
|
## Usage
|
34
34
|
|
@@ -62,6 +62,43 @@ formatter.extract_metadata.markdown.autolink.sanitize.to_s
|
|
62
62
|
formatter.complete.to_s
|
63
63
|
~~~
|
64
64
|
|
65
|
+
If you want to customize Slodown's default behavior, simply create a new class that inherits from `Slodown::Formatter` and override methods like `#kramdown_options`, or add your own behaviors.
|
66
|
+
|
67
|
+
|
68
|
+
## Syntax Highlighting
|
69
|
+
|
70
|
+
Just add [CodeRay](http://coderay.rubychan.de/) or [Rouge](http://rouge.jneen.net/) to your project to have code blocks in your Markdown syntax-highlighted. Slodown will try to detect which library you're using, but to be sure, change your `kramdown_options` accordingly. For example:
|
71
|
+
|
72
|
+
~~~ ruby
|
73
|
+
class Formatter < Slodown::Formatter
|
74
|
+
def kramdown_options
|
75
|
+
{
|
76
|
+
syntax_highlighter: 'coderay',
|
77
|
+
syntax_highlighter_opts: { css: :class }
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
~~~
|
82
|
+
|
83
|
+
|
84
|
+
## oEmbed support
|
85
|
+
|
86
|
+
> oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.
|
87
|
+
|
88
|
+
Slodown extends the Markdown image syntax to support oEmbed-based embeds.
|
89
|
+
Anything supported by the great [oEmbed gem](https://github.com/judofyr/ruby-oembed) will work. Just supply the URL:
|
90
|
+
|
91
|
+
~~~markdown
|
92
|
+
![youtube video](https://www.youtube.com/watch?v=oHg5SJYRHA0)
|
93
|
+
~~~
|
94
|
+
|
95
|
+
**Note on IFRAMEs:** Some oEmbed providers will return IFRAME-based embeds. If you want to control
|
96
|
+
which hosts are allowed to have IFRAMEs on your site, override the `Formatter#allowed_iframe_hosts` method to return a regular expression that will be matched against the IFRAME source URL's host. Please note that this will also apply to
|
97
|
+
IFRAME HTML tags added by the user directly.
|
98
|
+
|
99
|
+
**Note on Twitter:** Twitter's oEmbed endpoint will return a simple bit of markup that works okay out of the box, but can be expanded into a full tweet view client-side. For this to work, you'll want to add Twitter's [widget.js](http://platform.twitter.com/widgets.js) to your application. Please refer to the [Twitter documentation](https://dev.twitter.com/web/javascript) for full instructions.
|
100
|
+
|
101
|
+
|
65
102
|
### Metadata
|
66
103
|
|
67
104
|
Slodown allows metadata, such as the creation date, to be defined in the text to be processed:
|
@@ -84,33 +121,21 @@ Metadata can be accessed with `Slodown::Formatter#metadata`:
|
|
84
121
|
formatter.metadata[:title] # => "Slodown"
|
85
122
|
~~~
|
86
123
|
|
87
|
-
## OEmbed support
|
88
|
-
|
89
|
-
Slodown extends the Markdown image syntax to support OEmbed-based embeds.
|
90
|
-
Anything supported by the great [OEmbed gem](https://github.com/judofyr/ruby-oembed) will work. Just supply the URL:
|
91
|
-
|
92
|
-
~~~markdown
|
93
|
-
![youtube video](https://www.youtube.com/watch?v=oHg5SJYRHA0)
|
94
|
-
~~~
|
95
|
-
|
96
|
-
Some OEmbed providers will return IFRAME-based embeds. If you want to control
|
97
|
-
which hosts are allowed to have IFRAMEs on your site, override the `Formatter#allowed_iframe_hosts` method to return a regular expression that will be matched against the IFRAME source URL's host. Please note that this will also apply to
|
98
|
-
IFRAME HTML tags added by the user directly.
|
99
124
|
|
100
125
|
## Hints
|
101
126
|
|
102
127
|
* If you want to add more transformations or change the behavior of the `#complete` method, just subclass `Slodown::Formatter` and go wild. :-)
|
103
128
|
* Markdown transformations, HTML sanitizing, oEmbed handshakes and other operations are pretty expensive operations. For sake of performance (and stability), it is recommended that you cache the generated output in some manner.
|
104
|
-
* Eat more Schnitzel.
|
129
|
+
* Eat more Schnitzel. It's good for you.
|
105
130
|
|
106
131
|
## TODOs
|
107
132
|
|
108
|
-
- More/better specs.
|
133
|
+
- More/better specs. Slodown doesn't have a lot of functionality of its own, passing most of its duties over to the beautiful rendering gems it uses, but I'm sure there's still an opportunity or two for it to break, so, yeah, I should be adding _some_ specs.
|
109
134
|
- Better configuration for the HTML sanitizer. Right now, in order to change the sanitizing behavior, you'll need to inherit a new class from `Slodown::Formatter` and override its `#sanitize_config` method. Regarding the contents of the hash this method returns, please refer to the [sanitize documentation](https://github.com/rgrove/sanitize#custom-configuration).
|
110
135
|
|
111
136
|
## Contributing
|
112
137
|
|
113
|
-
Just like with my other gems, I am trying to keep
|
138
|
+
Just like with my other gems, I am trying to keep Slodown as sane (and small) as possible. If you
|
114
139
|
want to contribute code, **please talk to me before writing a patch or submitting
|
115
140
|
a pull request**! I'm serious about keeping things focused and would hate to cause
|
116
141
|
unnecessary disappointment. Thank you.
|
@@ -124,7 +149,11 @@ If you're still set on submitting a pull request, please consider the following:
|
|
124
149
|
|
125
150
|
## Version History
|
126
151
|
|
127
|
-
### 0.
|
152
|
+
### 0.3.0 (2016-02-22)
|
153
|
+
|
154
|
+
- Removed the dependency on CodeRay. If you want syntax highlighting in your Markdown parsing, simply add CodeRay (or Rouge, or any other highlighter supported by kramdown) to your project.
|
155
|
+
|
156
|
+
### 0.2.0 (2016-02-22)
|
128
157
|
|
129
158
|
- Slodown is now whitelisting all domains for possible iframe/embed-based media embeds by default. If you don't want this, you can override `Formatter#allowed_iframe_hosts` to return a regular expression that will match against the embed URL's host.
|
130
159
|
- Bumped minimum required version of kramdown to 1.5.0 for all the nice new syntax highlighter integrations it offers (and changes required due to deprecated/changed options.)
|
data/lib/slodown.rb
CHANGED
data/lib/slodown/formatter.rb
CHANGED
@@ -2,11 +2,15 @@ module Slodown
|
|
2
2
|
# This is the base Formatter class provided by Slodown. It works right
|
3
3
|
# out of the box if you want to use exactly the functionality provided by
|
4
4
|
# it, but in most projects, you'll probably want to create a new class
|
5
|
-
# inheriting from this one
|
5
|
+
# inheriting from this one, selectively overriding methods like
|
6
|
+
# +kramdown_options+ or adding your own.
|
6
7
|
#
|
7
8
|
class Formatter
|
9
|
+
attr_reader :metadata
|
10
|
+
|
8
11
|
def initialize(source)
|
9
12
|
@current = @source = source.to_s
|
13
|
+
@metadata = {}
|
10
14
|
end
|
11
15
|
|
12
16
|
# Run the entire pipeline in a sane order.
|
@@ -39,6 +43,8 @@ module Slodown
|
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
46
|
+
# Extract metadata from the document.
|
47
|
+
#
|
42
48
|
def extract_metadata
|
43
49
|
@metadata = {}
|
44
50
|
|
@@ -52,33 +58,27 @@ module Slodown
|
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
55
|
-
# Return a hash with the extracted metadata
|
56
|
-
#
|
57
|
-
def metadata
|
58
|
-
@metadata
|
59
|
-
end
|
60
|
-
|
61
61
|
def to_s
|
62
62
|
@current
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
#
|
65
|
+
# Return a hash of configuration values for kramdown. Please refer to
|
66
|
+
# the documentation of kramdown for details:
|
67
|
+
#
|
68
|
+
# http://kramdown.gettalong.org/options.html
|
68
69
|
#
|
69
|
-
def convert(&blk)
|
70
|
-
@current = blk.call(@current)
|
71
|
-
self
|
72
|
-
end
|
73
|
-
|
74
70
|
def kramdown_options
|
75
71
|
{
|
76
|
-
syntax_highlighter: 'coderay',
|
77
|
-
syntax_highlighter_opts: {
|
78
|
-
}
|
72
|
+
syntax_highlighter: defined?(Rouge) ? 'rouge' : 'coderay',
|
73
|
+
syntax_highlighter_opts: { }
|
79
74
|
}
|
80
75
|
end
|
81
76
|
|
77
|
+
# Return a hash of configuration values for the sanitize gem. Please refer
|
78
|
+
# to the documentation for sanitize for details:
|
79
|
+
#
|
80
|
+
# https://github.com/rgrove/sanitize#custom-configuration
|
81
|
+
#
|
82
82
|
def sanitize_config
|
83
83
|
{
|
84
84
|
elements: %w(
|
@@ -112,16 +112,27 @@ module Slodown
|
|
112
112
|
}
|
113
113
|
end
|
114
114
|
|
115
|
+
# Return a regular expression that will be matched against an embedded IFRAME's
|
116
|
+
# source URL's host. If the expression matches, the IFRAME tag will be whitelisted
|
117
|
+
# in its entirety; otherwise, it will be sanitized.
|
118
|
+
#
|
119
|
+
# By default, all hosts are allowed. Override this method if this is not what
|
120
|
+
# you want.
|
121
|
+
#
|
115
122
|
def allowed_iframe_hosts
|
116
|
-
# By default, allow everything. Override this to return a regular expression
|
117
|
-
# that will be matched against the iframe/embed's src URL's host.
|
118
123
|
/.*/
|
119
124
|
end
|
120
125
|
|
126
|
+
# A list of sanitize transformers to be applied to the markup that is to be
|
127
|
+
# sanitized. By default, we're only using +embed_transformer+.
|
128
|
+
#
|
121
129
|
def transformers
|
122
130
|
[embed_transformer]
|
123
131
|
end
|
124
132
|
|
133
|
+
# A sanitize transformer that will check the document for IFRAME tags and
|
134
|
+
# validate them against +allowed_iframe_hosts+.
|
135
|
+
#
|
125
136
|
def embed_transformer
|
126
137
|
lambda do |env|
|
127
138
|
node = env[:node]
|
@@ -146,5 +157,14 @@ module Slodown
|
|
146
157
|
{ node_whitelist: [node] }
|
147
158
|
end
|
148
159
|
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# Applies a conversion of the current text state.
|
164
|
+
#
|
165
|
+
def convert(&blk)
|
166
|
+
@current = blk.call(@current)
|
167
|
+
self
|
168
|
+
end
|
149
169
|
end
|
150
170
|
end
|
data/lib/slodown/version.rb
CHANGED
data/slodown.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Slodown::VERSION
|
9
9
|
gem.authors = ["Hendrik Mans"]
|
10
10
|
gem.email = ["hendrik@mans.de"]
|
11
|
-
gem.description = %q{Markdown + oEmbed + Sanitize +
|
12
|
-
gem.summary = %q{Markdown + oEmbed + Sanitize +
|
11
|
+
gem.description = %q{Markdown + oEmbed + Sanitize + Syntax Highlighting = the ultimate user input rendering pipeline.}
|
12
|
+
gem.summary = %q{Markdown + oEmbed + Sanitize + Syntax Highlighting = the ultimate user input rendering pipeline.}
|
13
13
|
gem.homepage = "https://github.com/hmans/slodown"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
@@ -18,10 +18,9 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_dependency 'kramdown', '>= 1.5.0'
|
21
|
-
gem.add_dependency 'coderay', '>= 1.0.0'
|
22
21
|
gem.add_dependency 'sanitize', '>= 2.0.0'
|
23
22
|
gem.add_dependency 'rinku', '>= 1.7.0'
|
24
|
-
gem.add_dependency 'ruby-oembed', '>= 0.
|
23
|
+
gem.add_dependency 'ruby-oembed', '>= 0.9.0'
|
25
24
|
|
26
25
|
gem.add_development_dependency 'rspec', '>= 2.12.0'
|
27
26
|
gem.add_development_dependency 'rspec-html-matchers'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slodown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hendrik Mans
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.5.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: coderay
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 1.0.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: sanitize
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +58,14 @@ dependencies:
|
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
61
|
+
version: 0.9.0
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
68
|
+
version: 0.9.0
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,8 +108,8 @@ dependencies:
|
|
122
108
|
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
125
|
-
description: Markdown + oEmbed + Sanitize +
|
126
|
-
pipeline.
|
111
|
+
description: Markdown + oEmbed + Sanitize + Syntax Highlighting = the ultimate user
|
112
|
+
input rendering pipeline.
|
127
113
|
email:
|
128
114
|
- hendrik@mans.de
|
129
115
|
executables: []
|
@@ -167,8 +153,8 @@ rubyforge_project:
|
|
167
153
|
rubygems_version: 2.5.1
|
168
154
|
signing_key:
|
169
155
|
specification_version: 4
|
170
|
-
summary: Markdown + oEmbed + Sanitize +
|
171
|
-
pipeline.
|
156
|
+
summary: Markdown + oEmbed + Sanitize + Syntax Highlighting = the ultimate user input
|
157
|
+
rendering pipeline.
|
172
158
|
test_files:
|
173
159
|
- spec/basic_formatting_spec.rb
|
174
160
|
- spec/metadata_extraction_spec.rb
|