content-pipeline 0.2.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2bcbf0d25b53581c0b7f6ed8c23281a97d76bc83
4
- data.tar.gz: 9d9308892002f4c9e89f65b07ab5f8a03d80bc35
3
+ metadata.gz: 3b4bedc6ec80720723af0e97a392f3a37f689395
4
+ data.tar.gz: 62896591dd8f82f947454c3663e1e08091cb4547
5
5
  SHA512:
6
- metadata.gz: eb3cdd69b7f4894864c7345577b27cbdc7f0c3f8b66b211d8634630ab5bf77742e7cce3789ba7fc26c49d0b13841212be1268bbdc1033809285e170221562029
7
- data.tar.gz: 79d6ac899d53826cb6510606e5bc0d31705052118aee07cc36f5e0694d4e69d38c5eb86053d3d2fb7bda3716308f35e0fbef75fcbb75ff33e2f7fce50771037e
6
+ metadata.gz: 438d637a65de37a5ebb51be0fb6a664217753d421fb04336c53dd31809c342b974ab69868d8f4de8161124192cf2eb2afe1143f6740b19774fbf9fde4ea433ee
7
+ data.tar.gz: 83aa17a0b86c98161622010f5a52718f1215e7d75c3f0001f6c8a73893c91d98e78604a2ab2ccf8402c01761a68a24561e8efb27f4d92903c66f8983330734f2
data/Gemfile CHANGED
@@ -2,10 +2,6 @@ source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
4
  group :development do
5
- unless ENV["CI"]
6
- gem "pry"
7
- end
8
-
9
5
  gem "kramdown"
10
6
  gem "rake"
11
7
 
data/License CHANGED
@@ -1,11 +1,11 @@
1
1
  Copyright 2013 Jordon Bedwell
2
2
 
3
- Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
- use this file except in compliance with the License. You may obtain a copy of
5
- the License at: http://www.apache.org/licenses/LICENSE-2.0
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ not use this file except in compliance with the License. You may obtain
5
+ a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
6
6
 
7
7
  Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
- License for the specific language governing permissions and limitations under
11
- the License.
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10
+ implied. See the License for the specific language governing
11
+ permissions and limitations under the License.
data/Rakefile CHANGED
@@ -1,3 +1,3 @@
1
- require 'rspec/core/rake_task'
1
+ require "rspec/core/rake_task"
2
2
  task :default => :spec
3
3
  RSpec::Core::RakeTask.new :spec
data/Readme.md CHANGED
@@ -20,8 +20,17 @@ gem 'content-pipeline', '~> <VERSION>'
20
20
  Content Pipeline is extremely simple to use out of the box:
21
21
 
22
22
  ```ruby
23
- pipeline = Content::Pipeline.new([ MyFilter ], :my_filter => { :o1 => true })
24
- pipeline.filter('# Markdown', :my_filter => { :o1 => false })
23
+ pipeline = Content::Pipeline.new([ MyFilter ], {
24
+ :my_filter => {
25
+ :o1 => true
26
+ }
27
+ })
28
+
29
+ pipeline.filter('# Markdown', {
30
+ :my_filter => {
31
+ :o1 => false
32
+ }
33
+ })
25
34
  ```
26
35
 
27
36
  ```ruby
@@ -1,47 +1,29 @@
1
1
  require_relative "pipeline/core_extensions/object_ext"
2
2
  require_relative "pipeline/core_extensions/hash_ext"
3
- $:.unshift(File.expand_path("../../", __FILE__))
4
3
 
5
4
  module Content
6
-
7
- # --------------------------------------------------------------------------
8
- # Content pipeline is a class that runs content through a pipeline of user
9
- # set and/or defined filters returning the final result. It can be mixed
10
- # and matched anyway and filters can even be skipped and removed.
11
- # --------------------------------------------------------------------------
12
-
13
5
  class Pipeline
14
6
  require_relative "pipeline/filters"
15
7
  attr_reader :filters, :opts
16
8
 
17
- # ------------------------------------------------------------------------
18
- # Allows the user to initialize with a custom set of filters or to auto
19
- # load our filters and use them, the base filters we provider are
20
- # redcarpet and pygments.
21
- # ------------------------------------------------------------------------
9
+ # -----------------------------------------------------------------
22
10
 
23
- def initialize(filters = Filters::DEFAULT_FILTERS, opts = nil)
24
- @opts, @filters = (opts || {}).freeze, [ filters ].flatten.freeze
11
+ def initialize(filters = Filters::DEFAULT_FILTERS, opts = {})
12
+ @opts, @filters = opts.freeze, [ filters ].flatten.freeze
25
13
  end
26
14
 
27
- # ------------------------------------------------------------------------
28
- # Runs through each of the extensions chosen by the user and then calls
29
- # them, returning the final result as the final HTML string.
30
- # ------------------------------------------------------------------------
15
+ # -----------------------------------------------------------------
31
16
 
32
- def filter(content, opts = nil)
33
- opts = @opts.deep_merge(opts || {})
34
- @filters.each do |filter|
35
- content = filter.new(content, opts[to_opt(filter)]).run
17
+ def filter(out, opts = {})
18
+ opts = @opts.deep_merge(opts)
19
+ @filters.each do |f|
20
+ out = f.new(out, opts[to_opt(f)]).run
36
21
  end
37
22
 
38
- content
23
+ out
39
24
  end
40
25
 
41
- # ------------------------------------------------------------------------
42
- # Convert a class and it's name into an opt by splitting up it's name
43
- # and downcasing the last part returning it as a symbol for opts.
44
- # ------------------------------------------------------------------------
26
+ # -----------------------------------------------------------------
45
27
 
46
28
  private
47
29
  def to_opt(cls)
@@ -1,18 +1,20 @@
1
1
  module CoreExtensions
2
2
 
3
- # --------------------------------------------------------------------------
3
+ # -------------------------------------------------------------------
4
4
  # Hash Extensions.
5
- # --------------------------------------------------------------------------
5
+ # -------------------------------------------------------------------
6
6
 
7
7
  module HashExt
8
8
 
9
- # ------------------------------------------------------------------------
10
- # Merge a hash, merging hashes in hashes with hashes in hashes if hashes.
11
- # ------------------------------------------------------------------------
9
+ # -----------------------------------------------------------------
10
+ # Merge a hash, merging hashes in hashes with hashes in hashes.
11
+ # -----------------------------------------------------------------
12
12
 
13
- def deep_merge(new_hash)
14
- merge(new_hash) do |k, o, n|
15
- Hash === o && Hash === n ? o.deep_merge(n) : n
13
+ unless method_defined?(:deep_merge)
14
+ def deep_merge(new_hash)
15
+ merge(new_hash) do |k, o, n|
16
+ o.is_a?(Hash) && n.is_a?(Hash) ? o.deep_merge(n) : n
17
+ end
16
18
  end
17
19
  end
18
20
  end
@@ -2,18 +2,18 @@ require "nokogiri"
2
2
 
3
3
  module CoreExtensions
4
4
 
5
- # --------------------------------------------------------------------------
5
+ # -------------------------------------------------------------------
6
6
  # Object Extensions.
7
- # --------------------------------------------------------------------------
7
+ # -------------------------------------------------------------------
8
8
 
9
9
  module ObjectExt
10
10
  def jruby?
11
11
  RbConfig::CONFIG["ruby_install_name"] == "jruby"
12
12
  end
13
13
 
14
- # ------------------------------------------------------------------------
14
+ # -----------------------------------------------------------------
15
15
  # Convert an element to a Nokogiri document fragment.
16
- # ------------------------------------------------------------------------
16
+ # -----------------------------------------------------------------
17
17
 
18
18
  def to_nokogiri_fragment
19
19
  Nokogiri::HTML.fragment(self.to_s)
@@ -21,6 +21,6 @@ module CoreExtensions
21
21
  end
22
22
  end
23
23
 
24
- # ----------------------------------------------------------------------------
24
+ # ---------------------------------------------------------------------
25
25
 
26
26
  Object.send(:include, CoreExtensions::ObjectExt)
@@ -1,25 +1,12 @@
1
1
  class Content::Pipeline
2
-
3
- # --------------------------------------------------------------------------
4
- # Pipeline is an "abstract" class meant to be inherited from in a defined
5
- # filter. It provides a set of base methods, namely initialize which
6
- # spawns the str not to mention add_filter which allows the filter author
7
- # to define a set of methods that need to be run on this filter.
8
- # --------------------------------------------------------------------------
9
-
10
2
  class Filter
11
-
12
- # ------------------------------------------------------------------------
13
- # Initialize.
14
- # ------------------------------------------------------------------------
15
-
16
3
  def initialize(str, opts = nil)
17
4
  @opts, @str = (opts || {}), str
18
5
  end
19
6
 
20
- # ------------------------------------------------------------------------
7
+ # -----------------------------------------------------------------
21
8
  # Run the set of filters the user wants ran on the filter.
22
- # ------------------------------------------------------------------------
9
+ # -----------------------------------------------------------------
23
10
 
24
11
  def run
25
12
  self.class.filters.each do |f|
@@ -29,14 +16,11 @@ class Content::Pipeline
29
16
  @str.to_s
30
17
  end
31
18
 
19
+ # -----------------------------------------------------------------
20
+
32
21
  class << self
33
22
  attr_reader :filters
34
23
 
35
- # ----------------------------------------------------------------------
36
- # Allows the author of a filter to set a method to be run on this,
37
- # filter, without us having to enforce a specific type of name.
38
- # ----------------------------------------------------------------------
39
-
40
24
  def add_filter(*filters)
41
25
  @filters ||= []
42
26
  @filters.push(*filters.flatten)
@@ -44,17 +28,11 @@ class Content::Pipeline
44
28
  end
45
29
  end
46
30
 
47
- # --------------------------------------------------------------------------
31
+ # -------------------------------------------------------------------
48
32
 
49
33
  module Filters
50
34
  require_relative "filters/code_highlight"
51
35
  require_relative "filters/markdown"
52
-
53
- # ------------------------------------------------------------------------
54
- # A set of default filters that we use if the user does not supply their
55
- # own filters for us to use.
56
- # ------------------------------------------------------------------------
57
-
58
36
  DEFAULT_FILTERS = [ Markdown, CodeHighlight ].freeze
59
37
  end
60
38
  end
@@ -1,10 +1,5 @@
1
1
  require "pygments" unless jruby?
2
2
 
3
- # ----------------------------------------------------------------------------
4
- # A filter that discovers pre tags and then syntax highlights them, also
5
- # allowing for fallback to just wrapping them so they stay consistent.
6
- # ----------------------------------------------------------------------------
7
-
8
3
  class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
9
4
  add_filter :highlight
10
5
 
@@ -32,22 +27,18 @@ class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
32
27
  HTML
33
28
  }
34
29
 
35
- # --------------------------------------------------------------------------
36
- # Searches for elements we want to transform and transforms them.
37
- # --------------------------------------------------------------------------
30
+ # -------------------------------------------------------------------
38
31
 
39
32
  private
40
33
  def highlight
41
34
  @str = @str.to_nokogiri_fragment
42
- @str.search('pre').each do |node|
35
+ @str.search("pre").each do |node|
43
36
  lang = node[:lang] || @opts[:default] || "ruby"
44
37
  node.replace Templates[:wrap] % wrap(pygments(node.inner_text, lang), lang)
45
38
  end
46
39
  end
47
40
 
48
- # --------------------------------------------------------------------------
49
- # Goes through each line and wraps it as well as creates line numbers.
50
- # --------------------------------------------------------------------------
41
+ # -------------------------------------------------------------------
51
42
 
52
43
  private
53
44
  def wrap(str, lang)
@@ -59,14 +50,11 @@ class Content::Pipeline::Filters::CodeHighlight < Content::Pipeline::Filter
59
50
  [numbs, lang, lines]
60
51
  end
61
52
 
62
- # --------------------------------------------------------------------------
63
- # Wraps around Pygments catching a timeout error so that it can cont.
64
- # --------------------------------------------------------------------------
53
+ # -------------------------------------------------------------------
65
54
 
66
55
  private
67
56
  def pygments(str, lang)
68
57
  return str if jruby? || !Pygments::Lexer[lang]
69
- # Protects you against a possible Pygments error.
70
58
  Pygments::Lexer[lang].highlight(str) =~ Matcher ? $1 : str
71
59
  end
72
60
  end
@@ -1,38 +1,30 @@
1
- # ----------------------------------------------------------------------------
2
- # A filter that supports Github-Markdown and also has a few filters to strip
3
- # the most basic unsafe content, if the user chooses this to be done.
4
- # ----------------------------------------------------------------------------
5
-
6
1
  class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
7
2
  add_filter :markdown, :strip_html
8
3
 
9
- # --------------------------------------------------------------------------
10
- # Parse Markdown content.
11
- # --------------------------------------------------------------------------
4
+ private
5
+ def default_markdown
6
+ (jruby?) ? :kramdown : :gfm
7
+ end
8
+
9
+ # -------------------------------------------------------------------
12
10
 
13
11
  private
14
12
  def markdown
15
- type = @opts.fetch(:type, ((jruby?) ? (:kramdown) : (:gfm)))
13
+ type = @opts.fetch(:type, default_markdown)
14
+ @str = convert_backtick(@str)
16
15
 
17
16
  @str = case
18
17
  when type =~ /\Amarkdown|gfm\Z/
19
18
  require "github/markdown"
20
- GitHub::Markdown.to_html(@str, @opts.fetch(:type, :gfm)).strip
19
+ GitHub::Markdown.to_html(@str, type).strip
21
20
  else
22
21
  require "kramdown"
23
- fix_kramdown_wraps(Kramdown::Document.
24
- new(convert_backtick(@str), :enable_coderay => false).to_html).strip
22
+ str = Kramdown::Document.new(@str, :enable_coderay => false)
23
+ normalize_kramdown(str.to_html).strip
25
24
  end
26
25
  end
27
26
 
28
- # --------------------------------------------------------------------------
29
- # Discovers private methods that start with strip_ and runs them if the
30
- # filter is in safe mode. Which will strip certain tags from the data.
31
- #
32
- # Doing it this way allows us to allow people to extend this class and add
33
- # what they wish to it, while us preventing them from monkey patching key
34
- # methods and having to keep those up-to-date.
35
- # --------------------------------------------------------------------------
27
+ # -------------------------------------------------------------------
36
28
 
37
29
  private
38
30
  def strip_html
@@ -46,44 +38,35 @@ class Content::Pipeline::Filters::Markdown < Content::Pipeline::Filter
46
38
  end
47
39
  end
48
40
 
49
- # --------------------------------------------------------------------------
50
- # Strip anchor tags.
51
- # --------------------------------------------------------------------------
41
+ # -------------------------------------------------------------------
52
42
 
53
43
  private
54
44
  def strip_links
55
- @str.search("a").each do |node|
56
- node.replace(node[:href])
45
+ @str.search("a").each do |n|
46
+ n.replace(n[:href])
57
47
  end
58
48
  end
59
49
 
60
- # --------------------------------------------------------------------------
61
- # Strip image tags.
62
- # --------------------------------------------------------------------------
50
+ # -------------------------------------------------------------------
63
51
 
64
52
  private
65
53
  def strip_image
66
- @str.search("img").each do |node|
67
- # Tries to cover single line images wrapped in a paragraph.
68
- node.parent.children.count == 1 ? node.parent.remove : node.remove
54
+ @str.search("img").each do |n|
55
+ n.parent.children.count == 1 ? n.parent.remove : n.remove
69
56
  end
70
57
  end
71
58
 
72
- # --------------------------------------------------------------------------
73
- # Converts Github style backticks over to Portable ~~~.
74
- # --------------------------------------------------------------------------
59
+ # -------------------------------------------------------------------
75
60
 
76
61
  private
77
62
  def convert_backtick(str)
78
63
  str.gsub(/^`{3}(\s?[a-zA-Z0-9]+)?$/, "~~~\\1")
79
64
  end
80
65
 
81
- # --------------------------------------------------------------------------
82
- # Converts <pre><code class="language-ruby"> to <pre lang="lang">.
83
- # --------------------------------------------------------------------------
66
+ # -------------------------------------------------------------------
84
67
 
85
68
  private
86
- def fix_kramdown_wraps(str)
69
+ def normalize_kramdown(str)
87
70
  str.gsub(/<pre><code class="language-([A-Za-z0-9]+)">/, '<pre lang="\\1"><code>')
88
71
  end
89
72
  end
@@ -1,5 +1,5 @@
1
1
  module Content
2
2
  class Pipeline
3
- VERSION = "0.2.2"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,101 +1,101 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: content-pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.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: 2013-11-06 00:00:00.000000000 Z
11
+ date: 2014-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: 1.6.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: 1.6.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '2.14'
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
40
  version: '2.14'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec-expect_error
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0.0'
47
+ version: '0'
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.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: envygeeks-coveralls
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0.1'
61
+ version: '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.1'
68
+ version: '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: '0.4'
75
+ version: '0'
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: '0.4'
82
+ version: '0'
83
83
  description: A less restrictive version of html-pipeline for content.
84
84
  email: envygeeks@gmail.com
85
85
  executables: []
86
86
  extensions: []
87
87
  extra_rdoc_files: []
88
88
  files:
89
- - Readme.md
89
+ - Gemfile
90
90
  - License
91
91
  - Rakefile
92
- - Gemfile
92
+ - Readme.md
93
93
  - lib/content/pipeline.rb
94
- - lib/content/pipeline/filters.rb
95
- - lib/content/pipeline/filters/markdown.rb
96
- - lib/content/pipeline/filters/code_highlight.rb
97
94
  - lib/content/pipeline/core_extensions/hash_ext.rb
98
95
  - lib/content/pipeline/core_extensions/object_ext.rb
96
+ - lib/content/pipeline/filters.rb
97
+ - lib/content/pipeline/filters/code_highlight.rb
98
+ - lib/content/pipeline/filters/markdown.rb
99
99
  - lib/content/pipeline/version.rb
100
100
  homepage: https://github.com/envygeeks/content-pipeline
101
101
  licenses:
@@ -107,17 +107,17 @@ require_paths:
107
107
  - lib
108
108
  required_ruby_version: !ruby/object:Gem::Requirement
109
109
  requirements:
110
- - - '>='
110
+ - - ">="
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  requirements: []
119
119
  rubyforge_project:
120
- rubygems_version: 2.1.10
120
+ rubygems_version: 2.2.1
121
121
  signing_key:
122
122
  specification_version: 4
123
123
  summary: Adds a pipeline for your content.