content-pipeline 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.