content-pipeline 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/License +7 -8
- data/Readme.md +35 -6
- data/lib/content/pipeline/core_extensions/hash_ext.rb +0 -10
- data/lib/content/pipeline/core_extensions/object_ext.rb +2 -10
- data/lib/content/pipeline/filters/code_highlight.rb +47 -13
- data/lib/content/pipeline/filters/gemoji.rb +67 -0
- data/lib/content/pipeline/filters/markdown.rb +45 -20
- data/lib/content/pipeline/filters.rb +55 -12
- data/lib/content/pipeline/jekyll/convertor.rb +27 -0
- data/lib/content/pipeline/version.rb +1 -1
- data/lib/content/pipeline.rb +43 -7
- metadata +15 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b05e4ba2c18469028c3062e838dfe6ce04085599
|
4
|
+
data.tar.gz: 0154fe65c6601b4ad3b7539a5986c3a58391000d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f552817247cd9e852c5b935705d63cd065ccba52cfd2c6f960ec2fcc94955059f3bd2926c4039fe63dd8bda0c26d3db5d195e156fe360fa6799dde4c9aa254e5
|
7
|
+
data.tar.gz: c405bdbd8f9488567a8afb3bc82346812305a6eea1ddbebd3a7609ab0815cd177a2450dacb6aec9fca19c29a0e04dfb4934056a06dbaf8c650ae3dd71ffa9348
|
data/Gemfile
CHANGED
data/License
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
Copyright 2013-2014 Jordon Bedwell
|
2
2
|
|
3
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you
|
4
|
-
|
5
|
-
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you maynot use
|
4
|
+
this file except in compliance with the License. You may obtain a copy of the
|
5
|
+
License at: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
|
7
|
-
Unless required by applicable law or agreed to in writing, software
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
permissions and limitations under the License.
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
8
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
9
|
+
CONDITIONS OF ANY KIND, either express orimplied. See the License for the
|
10
|
+
specific language governing permissions and limitations under the License.
|
data/Readme.md
CHANGED
@@ -20,6 +20,11 @@ gem 'content-pipeline', '~> <VERSION>'
|
|
20
20
|
Content Pipeline is extremely simple to use out of the box:
|
21
21
|
|
22
22
|
```ruby
|
23
|
+
|
24
|
+
# ---------------------------------------------------------------------
|
25
|
+
# With custom filters and global-filter options + per-filter options.
|
26
|
+
# ---------------------------------------------------------------------
|
27
|
+
|
23
28
|
pipeline = Content::Pipeline.new([ MyFilter ], {
|
24
29
|
:my_filter => {
|
25
30
|
:o1 => true
|
@@ -31,15 +36,31 @@ pipeline.filter('# Markdown', {
|
|
31
36
|
:o1 => false
|
32
37
|
}
|
33
38
|
})
|
39
|
+
|
40
|
+
# ---------------------------------------------------------------------
|
41
|
+
# With only global-filter options + per-filter options.
|
42
|
+
# ---------------------------------------------------------------------
|
43
|
+
|
44
|
+
pipeline = Content::Pipeline.new({
|
45
|
+
:my_filter => {
|
46
|
+
:o1 => true
|
47
|
+
}
|
48
|
+
})
|
49
|
+
|
50
|
+
pipeline.filter("# Markdown", {
|
51
|
+
:my_filter => {
|
52
|
+
:o1 => false
|
53
|
+
}
|
54
|
+
})
|
34
55
|
```
|
35
56
|
|
36
57
|
```ruby
|
37
58
|
Content::Pipeline.new.filter('# Markdown')
|
38
59
|
```
|
39
60
|
|
40
|
-
* Supports multiple Markdowns.
|
41
61
|
* Supports global options with overrides.
|
42
|
-
* By default uses
|
62
|
+
* By default uses `CodeHighlight`, `Markdown`, `Gemoji`.
|
63
|
+
* Supports multiple Markdowns.
|
43
64
|
|
44
65
|
*It should be noted that if you send a list of filters you wish to use, it will not use the default filters at all. So where you see `[ MyFilter ]` that will be the only filter that is ran, since it automatically assumes this is the pipeline you wish to use.*
|
45
66
|
|
@@ -47,15 +68,15 @@ Content::Pipeline.new.filter('# Markdown')
|
|
47
68
|
|
48
69
|
Filter options are set globally and can be overriden each time the filter is ran, this allows for you to setup a single pipeline and then adjust it on the fly on a per-content basis, for example if you wish to run `Markdown` `:safe` on user comments but not on posts, then you would simply setup the global pipeline and then each time you parse a user comment send the content with the hash `{ :markdown => { :safe => true }}`.
|
49
70
|
|
50
|
-
*All options are keyed based on their class name, so `MyFilter` would have the option key `:my_filter`*
|
71
|
+
*All options are keyed based on their class name, so `MyFilter` would have the option key `:my_filter` but it also supports `:myfilter`*
|
51
72
|
|
52
73
|
### Content::Pipeline::Filters::Markdown
|
53
74
|
|
54
75
|
The Markdown filter allows you to choose between `github-markdown` and `kramdown`, and by default will use `kramdown` on jRuby and `github-markdown` on any other Ruby that supports it. **These dependencies are loose, which means you must install the one you wish to use.**
|
55
76
|
|
56
77
|
Options:
|
57
|
-
* `:type` => [`:gfm`, `:markdown`, `:kramdown`]
|
58
|
-
* `:safe` => [`true`, `false`]
|
78
|
+
* `:type` => [`:gfm`, `:markdown`, `md`, `:kramdown`]
|
79
|
+
* `:safe` => [`true`, `false`]
|
59
80
|
|
60
81
|
*You should not need to adjust any of your "\`\`\`" because the `Markdown` filter will automatically convert those to `~~~` if you choose Kramdown. This is not done because one way is
|
61
82
|
better than the other, it's done so that people can remain agnostic.*
|
@@ -65,4 +86,12 @@ better than the other, it's done so that people can remain agnostic.*
|
|
65
86
|
The code highlight filter allows you to highlight code, with or without Pygments. If Pygments is supported it will require it and syntax highlight, otherwise it will simply wrap your code in the normal code style and not syntax highlight it. You will still have the line numbers, just not the fancy syntax highlight.
|
66
87
|
|
67
88
|
Options:
|
68
|
-
* `:default` -
|
89
|
+
* `:default` - `:ruby`
|
90
|
+
|
91
|
+
### Content::Pipeline::Filters::Gemoji
|
92
|
+
|
93
|
+
The Gemoji filter allows you to convert `:gemoji:` into image tags, liquid asset tags and if you really really need it, a custom tag by sending a proc. By default it will use the path `/asset` which can be overriden.
|
94
|
+
|
95
|
+
* `:as_liquid_asset` - `nil`
|
96
|
+
* `:tag` - `Proc` - 2args - path, name.
|
97
|
+
* `:asset_path` - `/assets`
|
@@ -1,15 +1,5 @@
|
|
1
1
|
module CoreExtensions
|
2
|
-
|
3
|
-
# -------------------------------------------------------------------
|
4
|
-
# Hash Extensions.
|
5
|
-
# -------------------------------------------------------------------
|
6
|
-
|
7
2
|
module HashExt
|
8
|
-
|
9
|
-
# -----------------------------------------------------------------
|
10
|
-
# Merge a hash, merging hashes in hashes with hashes in hashes.
|
11
|
-
# -----------------------------------------------------------------
|
12
|
-
|
13
3
|
unless method_defined?(:deep_merge)
|
14
4
|
def deep_merge(new_hash)
|
15
5
|
merge(new_hash) do |k, o, n|
|
@@ -1,26 +1,18 @@
|
|
1
1
|
require "nokogiri"
|
2
2
|
|
3
3
|
module CoreExtensions
|
4
|
-
|
5
|
-
# -------------------------------------------------------------------
|
6
|
-
# Object Extensions.
|
7
|
-
# -------------------------------------------------------------------
|
8
|
-
|
9
4
|
module ObjectExt
|
10
5
|
def jruby?
|
11
6
|
RbConfig::CONFIG["ruby_install_name"] == "jruby"
|
12
7
|
end
|
13
8
|
|
14
|
-
#
|
15
|
-
# Convert an element to a Nokogiri document fragment.
|
16
|
-
# -----------------------------------------------------------------
|
9
|
+
# -------------------------------------------------------------------------
|
17
10
|
|
18
11
|
def to_nokogiri_fragment
|
12
|
+
return self if self.is_a?(Nokogiri::HTML::DocumentFragment)
|
19
13
|
Nokogiri::HTML.fragment(self.to_s)
|
20
14
|
end
|
21
15
|
end
|
22
16
|
end
|
23
17
|
|
24
|
-
# ---------------------------------------------------------------------
|
25
|
-
|
26
18
|
Object.send(:include, CoreExtensions::ObjectExt)
|
@@ -1,21 +1,23 @@
|
|
1
1
|
require "pygments" unless jruby?
|
2
2
|
|
3
3
|
class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
|
4
|
-
add_filter
|
4
|
+
add_filter({
|
5
|
+
:highlight => :nokogiri
|
6
|
+
})
|
7
|
+
|
8
|
+
# ---------------------------------------------------------------------------
|
5
9
|
|
6
10
|
Matcher = /<pre>(.+)<\/pre>/m
|
7
11
|
Templates = {
|
8
12
|
:numb => %Q{<span class="line-number">%s</span>\n},
|
9
13
|
:line => '<span class="line">%s</span>',
|
10
|
-
:wrap => <<-HTML
|
14
|
+
:wrap => <<-HTML,
|
11
15
|
<figure class="code">
|
12
16
|
<div class="highlight">
|
13
17
|
<table>
|
14
18
|
<tbody>
|
15
19
|
<tr>
|
16
|
-
|
17
|
-
<pre>%s</pre>
|
18
|
-
</td>
|
20
|
+
%s
|
19
21
|
<td class="code">
|
20
22
|
<pre><code class="%s">%s</code></pre>
|
21
23
|
</td>
|
@@ -25,9 +27,22 @@ class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
|
|
25
27
|
</div>
|
26
28
|
</figure>
|
27
29
|
HTML
|
30
|
+
|
31
|
+
:gutter => <<-HTML
|
32
|
+
<td class="gutter">
|
33
|
+
<pre>%s</pre>
|
34
|
+
</td>
|
35
|
+
HTML
|
28
36
|
}
|
29
37
|
|
30
|
-
#
|
38
|
+
# ---------------------------------------------------------------------------
|
39
|
+
|
40
|
+
def initialize(*args)
|
41
|
+
super(*args)
|
42
|
+
@opts[:gutter] = true if @opts[:gutter].nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
# ---------------------------------------------------------------------------
|
31
46
|
|
32
47
|
private
|
33
48
|
def highlight
|
@@ -38,23 +53,42 @@ class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
|
|
38
53
|
end
|
39
54
|
end
|
40
55
|
|
41
|
-
#
|
56
|
+
# ---------------------------------------------------------------------------
|
57
|
+
# @arg String: The "multi-line" string you wish to parse.
|
58
|
+
# @arg String: The "programming language" you wish to highlight as.
|
59
|
+
# ---------------------------------------------------------------------------
|
42
60
|
|
43
61
|
private
|
44
62
|
def wrap(str, lang)
|
45
|
-
lines, numbs = "", ""
|
46
|
-
|
47
|
-
|
63
|
+
lines, numbs = "", ""
|
64
|
+
|
65
|
+
str.each_line.with_index(1) do |l, n|
|
66
|
+
lines+= Templates[:line] % l
|
67
|
+
|
68
|
+
if @opts[:gutter]
|
69
|
+
numbs+= Templates[:numb] % n
|
70
|
+
end
|
48
71
|
end
|
49
72
|
|
50
|
-
|
73
|
+
if ! @opts[:gutter]
|
74
|
+
[
|
75
|
+
numbs, lang, lines
|
76
|
+
]
|
77
|
+
else
|
78
|
+
[
|
79
|
+
Templates[:gutter] % numbs, lang, lines
|
80
|
+
]
|
81
|
+
end
|
51
82
|
end
|
52
83
|
|
53
|
-
#
|
84
|
+
# ---------------------------------------------------------------------------
|
85
|
+
# @arg String: The "multi-line" string you wish to highlight.
|
86
|
+
# @arg String: The lang you wish to use when highlighting the string.
|
87
|
+
# ---------------------------------------------------------------------------
|
54
88
|
|
55
89
|
private
|
56
90
|
def pygments(str, lang)
|
57
|
-
return str if jruby? || !Pygments::Lexer[lang]
|
91
|
+
return str if jruby? || ! Pygments::Lexer[lang]
|
58
92
|
Pygments::Lexer[lang].highlight(str) =~ Matcher ? $1 : str
|
59
93
|
end
|
60
94
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "gemoji"
|
2
|
+
|
3
|
+
class Content::Pipeline::Filters::Gemoji < Content::Pipeline::Filter
|
4
|
+
EmojiPattern = /(?:^\s*|\s+):(#{Emoji.names.map { |n| Regexp.escape(n) }.join("|")}):(?:\s+|\s*$)/m
|
5
|
+
EmojiTag = %Q{<img class="emoji" src="%s" alt=":%s:" height="20" width="20">}
|
6
|
+
EmojiLiquidTag = %Q{{%%img "%s" ":%s:" %%}}
|
7
|
+
|
8
|
+
add_filter({
|
9
|
+
:gemoji => :nokogiri
|
10
|
+
})
|
11
|
+
|
12
|
+
# ---------------------------------------------------------------------------
|
13
|
+
# This is a simple wrapper method around the default initialize.
|
14
|
+
# ---------------------------------------------------------------------------
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
super(*args)
|
18
|
+
# I should make this an addon.
|
19
|
+
@opts[:asset_path] ||= "/assets"
|
20
|
+
end
|
21
|
+
|
22
|
+
# ---------------------------------------------------------------------------
|
23
|
+
# Because of the way that Nokogiri behaves we need to go out of our
|
24
|
+
# way and ensure that we capture both text nodes in the root and
|
25
|
+
# text nodes in elements (such as paragraphs and shit like that...)
|
26
|
+
# ---------------------------------------------------------------------------
|
27
|
+
|
28
|
+
private
|
29
|
+
def gemoji
|
30
|
+
@str = @str.to_nokogiri_fragment
|
31
|
+
[:xpath, :search].each do |t|
|
32
|
+
@str.send(t, "text()").each do |n|
|
33
|
+
parse_node(n)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# ---------------------------------------------------------------------------
|
39
|
+
# @arg Nokogiri::XML::Text: The Text node you wish to parse.
|
40
|
+
# ---------------------------------------------------------------------------
|
41
|
+
|
42
|
+
def parse_node(node)
|
43
|
+
return node if node.ancestors.any? do |n|
|
44
|
+
n.node_name == "code" || n.node_name == "pre"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Because it's no more performant than 40 objs.
|
48
|
+
node.replace(node.to_html.gsub(EmojiPattern) do
|
49
|
+
ep = "#{@opts[:asset_path].chomp("/")}/#{$1}.png"
|
50
|
+
en = $1
|
51
|
+
|
52
|
+
if ! @opts[:tag] && ! @opts[:tag].is_a?(Proc)
|
53
|
+
if @opts[:as_liquid_asset]
|
54
|
+
EmojiLiquidTag % [
|
55
|
+
ep, en
|
56
|
+
]
|
57
|
+
else
|
58
|
+
EmojiTag % [
|
59
|
+
ep, en
|
60
|
+
]
|
61
|
+
end
|
62
|
+
else
|
63
|
+
@opts[:tag].call(ep, en)
|
64
|
+
end
|
65
|
+
end)
|
66
|
+
end
|
67
|
+
end
|
@@ -1,35 +1,56 @@
|
|
1
1
|
class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
|
2
|
-
add_filter
|
2
|
+
add_filter({
|
3
|
+
:markdown => :str,
|
4
|
+
:strip_html => :nokogiri
|
5
|
+
})
|
6
|
+
|
7
|
+
# ---------------------------------------------------------------------------
|
3
8
|
|
4
9
|
private
|
5
|
-
def
|
6
|
-
|
10
|
+
def default
|
11
|
+
jruby? ? :kramdown : :gfm
|
7
12
|
end
|
8
13
|
|
9
|
-
#
|
14
|
+
# ---------------------------------------------------------------------------
|
10
15
|
|
11
16
|
private
|
12
17
|
def markdown
|
13
|
-
type = @opts.fetch(:type,
|
14
|
-
@str =
|
15
|
-
|
18
|
+
@type = @opts.fetch(:type, default)
|
19
|
+
@str = backtick(@str)
|
16
20
|
@str = case
|
17
|
-
|
18
|
-
require "github/markdown"
|
19
|
-
GitHub::Markdown.to_html(@str, type).strip
|
21
|
+
when @type =~ /\Amd|markdown|gfm\Z/ then parse_github
|
20
22
|
else
|
21
|
-
|
22
|
-
str = Kramdown::Document.new(@str, :enable_coderay => false)
|
23
|
-
normalize_kramdown(str.to_html).strip
|
23
|
+
parse_kramdown
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
27
|
+
# ---------------------------------------------------------------------------
|
28
|
+
|
29
|
+
private
|
30
|
+
def parse_github
|
31
|
+
require "github/markdown"
|
32
|
+
GitHub::Markdown.to_html(@str, @type).strip
|
33
|
+
end
|
34
|
+
|
35
|
+
# ---------------------------------------------------------------------------
|
36
|
+
|
37
|
+
private
|
38
|
+
def parse_kramdown
|
39
|
+
require "kramdown"
|
40
|
+
str = Kramdown::Document.new(@str, {
|
41
|
+
:enable_coderay => false
|
42
|
+
})
|
43
|
+
|
44
|
+
# For consistent output, like it ok?!
|
45
|
+
normalize_kramdown(str.to_html).strip
|
46
|
+
end
|
47
|
+
|
48
|
+
# ---------------------------------------------------------------------------
|
28
49
|
|
29
50
|
private
|
30
51
|
def strip_html
|
31
|
-
@str = @str.to_nokogiri_fragment
|
32
52
|
if @opts[:safe]
|
53
|
+
@str = @str.to_nokogiri_fragment
|
33
54
|
private_methods(false).keep_if { |m| m =~ /\Astrip_/ }.each do |m|
|
34
55
|
unless m == :strip_html
|
35
56
|
send(m)
|
@@ -38,7 +59,7 @@ class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
|
|
38
59
|
end
|
39
60
|
end
|
40
61
|
|
41
|
-
#
|
62
|
+
# ---------------------------------------------------------------------------
|
42
63
|
|
43
64
|
private
|
44
65
|
def strip_links
|
@@ -47,7 +68,7 @@ class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
|
|
47
68
|
end
|
48
69
|
end
|
49
70
|
|
50
|
-
#
|
71
|
+
# ---------------------------------------------------------------------------
|
51
72
|
|
52
73
|
private
|
53
74
|
def strip_image
|
@@ -56,14 +77,18 @@ class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
|
|
56
77
|
end
|
57
78
|
end
|
58
79
|
|
59
|
-
#
|
80
|
+
# ---------------------------------------------------------------------------
|
81
|
+
# @arg String: The Markdown string, convert `` to ~~~.
|
82
|
+
# ---------------------------------------------------------------------------
|
60
83
|
|
61
84
|
private
|
62
|
-
def
|
85
|
+
def backtick(str)
|
63
86
|
str.gsub(/^`{3}(\s?[a-zA-Z0-9]+)?$/, "~~~\\1")
|
64
87
|
end
|
65
88
|
|
66
|
-
#
|
89
|
+
# ---------------------------------------------------------------------------
|
90
|
+
# @arg String: The converted Markdown string, from Kramdown.
|
91
|
+
# ---------------------------------------------------------------------------
|
67
92
|
|
68
93
|
private
|
69
94
|
def normalize_kramdown(str)
|
@@ -1,38 +1,81 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
1
3
|
class Content::Pipeline
|
2
4
|
class Filter
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegator "self.class.filters", :each_with_index
|
8
|
+
def_delegator "self.class.filters", :each
|
9
|
+
def_delegator "self.class.filters", :size
|
10
|
+
def_delegator "self.class.filters", :[]
|
11
|
+
def_delegator "self.class", :filters
|
12
|
+
|
13
|
+
# -------------------------------------------------------------------------
|
14
|
+
|
3
15
|
def initialize(str, opts = nil)
|
4
16
|
@opts, @str = (opts || {}), str
|
5
17
|
end
|
6
18
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
19
|
+
# -------------------------------------------------------------------------
|
20
|
+
# @arg Array: The next filter in the chain, to check the types.
|
21
|
+
# -------------------------------------------------------------------------
|
22
|
+
|
23
|
+
def run(next_filter = nil)
|
24
|
+
return @str unless size > 0
|
25
|
+
|
26
|
+
each_with_index do |f, i|
|
27
|
+
send(f.first)
|
10
28
|
|
11
|
-
|
12
|
-
|
13
|
-
|
29
|
+
unless size == i + 1 || @str.is_a?(String) || \
|
30
|
+
self[i + 1].last == :nokogiri
|
31
|
+
|
32
|
+
@str = @str.to_s
|
33
|
+
end
|
14
34
|
end
|
15
35
|
|
16
|
-
|
17
|
-
|
36
|
+
next_filter = next_filter.filters.first if next_filter
|
37
|
+
if ! next_filter || next_filter.last != :nokogiri
|
38
|
+
return @str.to_s
|
39
|
+
end
|
18
40
|
|
19
|
-
|
41
|
+
@str
|
42
|
+
end
|
20
43
|
|
21
44
|
class << self
|
22
45
|
attr_reader :filters
|
23
46
|
|
47
|
+
# -----------------------------------------------------------------------
|
48
|
+
# @arg Hash: The filters and the type of input they prefer.
|
49
|
+
# -----------------------------------------------------------------------
|
50
|
+
|
24
51
|
def add_filter(*filters)
|
25
52
|
@filters ||= []
|
26
|
-
|
53
|
+
|
54
|
+
filters.each do |f|
|
55
|
+
if f.is_a?(Hash)
|
56
|
+
f.each do |k, v|
|
57
|
+
@filters.push([
|
58
|
+
k, v
|
59
|
+
])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
@filters.push([
|
63
|
+
f,
|
64
|
+
:str
|
65
|
+
])
|
66
|
+
end
|
67
|
+
end
|
27
68
|
end
|
28
69
|
end
|
29
70
|
end
|
30
71
|
|
31
|
-
#
|
72
|
+
# ---------------------------------------------------------------------------
|
32
73
|
|
33
74
|
module Filters
|
34
75
|
require_relative "filters/code_highlight"
|
35
76
|
require_relative "filters/markdown"
|
36
|
-
|
77
|
+
require_relative "filters/gemoji"
|
78
|
+
# The filters I prefer to use by default are here.
|
79
|
+
DEFAULT_FILTERS = [ Markdown, CodeHighlight, Gemoji ].freeze
|
37
80
|
end
|
38
81
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "content/pipeline"
|
2
|
+
|
3
|
+
module Content::Pipeline::Jekyll
|
4
|
+
class Convertor < Jekyll::Convertor
|
5
|
+
CONTENT_PIPELINE = Content::Pipeline.new
|
6
|
+
|
7
|
+
def matches(ext)
|
8
|
+
ext =~ /\.(md|markdown)\Z/
|
9
|
+
end
|
10
|
+
|
11
|
+
# -------------------------------------------------------------------------
|
12
|
+
|
13
|
+
def output_ext(ext)
|
14
|
+
".html"
|
15
|
+
end
|
16
|
+
|
17
|
+
# -------------------------------------------------------------------------
|
18
|
+
# It should be noted that MARKDOWN_CONVERTOR uses the default options
|
19
|
+
# provided by Content::Pipeline at:
|
20
|
+
# https://github.com/envygeeks/content-pipeline
|
21
|
+
# -------------------------------------------------------------------------
|
22
|
+
|
23
|
+
def convert(data)
|
24
|
+
CONTENT_PIPELINE.filter(data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/content/pipeline.rb
CHANGED
@@ -6,28 +6,64 @@ module Content
|
|
6
6
|
require_relative "pipeline/filters"
|
7
7
|
attr_reader :filters, :opts
|
8
8
|
|
9
|
-
#
|
9
|
+
# -------------------------------------------------------------------------
|
10
|
+
# @arg Array: The filters you would like to use or next:
|
11
|
+
# @arg Hash : Your "default options" that should be "global."
|
12
|
+
# -------------------------------------------------------------------------
|
10
13
|
|
11
|
-
def initialize(filters =
|
14
|
+
def initialize(filters = nil, opts = nil)
|
15
|
+
if filters.is_a?(Hash) && opts.nil?
|
16
|
+
opts = filters
|
17
|
+
filters = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
opts = {} if opts.nil?
|
22
|
+
filters = Filters::DEFAULT_FILTERS if filters.nil?
|
12
23
|
@opts, @filters = opts.freeze, [ filters ].flatten.freeze
|
13
24
|
end
|
14
25
|
|
15
|
-
#
|
26
|
+
# -------------------------------------------------------------------------
|
27
|
+
# @arg String: The incomming string that will be modified.
|
28
|
+
# @arg Hash : The secondary opts to override the "defaults".
|
29
|
+
# -------------------------------------------------------------------------
|
16
30
|
|
17
31
|
def filter(out, opts = {})
|
32
|
+
return out if out.nil? || out.empty? || @filters.empty?
|
33
|
+
|
18
34
|
opts = @opts.deep_merge(opts)
|
19
|
-
@filters.
|
20
|
-
|
35
|
+
@filters.each_with_index do |f, i|
|
36
|
+
fopts = opts.values_at(*to_opt(f)).delete_if(&:nil?). \
|
37
|
+
reduce({}, :merge)
|
38
|
+
|
39
|
+
out = f.new(out, fopts).run(@filters[i + 1])
|
21
40
|
end
|
22
41
|
|
23
42
|
out
|
24
43
|
end
|
25
44
|
|
26
|
-
#
|
45
|
+
# -------------------------------------------------------------------------
|
46
|
+
# @arg Object: An object (preferably a class or module.)
|
47
|
+
# -------------------------------------------------------------------------
|
27
48
|
|
28
49
|
private
|
29
50
|
def to_opt(cls)
|
30
|
-
cls.name.split(/::/).last
|
51
|
+
cls = cls.name.split(/::/).last
|
52
|
+
|
53
|
+
[
|
54
|
+
cls.downcase,
|
55
|
+
underscore_cls(cls) ].uniq.map(&:to_sym)
|
56
|
+
end
|
57
|
+
|
58
|
+
# -------------------------------------------------------------------------
|
59
|
+
# @arg String: The name of the class you wish to adjust.
|
60
|
+
# -------------------------------------------------------------------------
|
61
|
+
|
62
|
+
private
|
63
|
+
def underscore_cls(cls)
|
64
|
+
(cls[0].downcase + cls[1..-1]).gsub(/([A-Z])/) do
|
65
|
+
"_" + $1.downcase
|
66
|
+
end
|
31
67
|
end
|
32
68
|
end
|
33
69
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: content-pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordon Bedwell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -30,56 +30,56 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '3.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: envygeeks-coveralls
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '0.2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '0.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec-collection_matchers
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '0.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
68
|
+
version: '0.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: luna-rspec-formatters
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '1'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '1'
|
83
83
|
description: A less restrictive version of html-pipeline for content.
|
84
84
|
email: envygeeks@gmail.com
|
85
85
|
executables: []
|
@@ -95,7 +95,9 @@ files:
|
|
95
95
|
- lib/content/pipeline/core_extensions/object_ext.rb
|
96
96
|
- lib/content/pipeline/filters.rb
|
97
97
|
- lib/content/pipeline/filters/code_highlight.rb
|
98
|
+
- lib/content/pipeline/filters/gemoji.rb
|
98
99
|
- lib/content/pipeline/filters/markdown.rb
|
100
|
+
- lib/content/pipeline/jekyll/convertor.rb
|
99
101
|
- lib/content/pipeline/version.rb
|
100
102
|
homepage: https://github.com/envygeeks/content-pipeline
|
101
103
|
licenses:
|
@@ -117,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
119
|
version: '0'
|
118
120
|
requirements: []
|
119
121
|
rubyforge_project:
|
120
|
-
rubygems_version: 2.2.
|
122
|
+
rubygems_version: 2.2.2
|
121
123
|
signing_key:
|
122
124
|
specification_version: 4
|
123
125
|
summary: Adds a pipeline for your content.
|