html-pipeline 2.14.3 → 3.0.2

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +11 -3
  3. data/.github/dependabot.yml +27 -0
  4. data/.github/workflows/automerge.yml +13 -0
  5. data/.github/workflows/ci.yml +22 -0
  6. data/.github/workflows/lint.yml +23 -0
  7. data/.github/workflows/publish.yml +19 -0
  8. data/.rubocop.yml +17 -0
  9. data/.ruby-version +1 -0
  10. data/.vscode/settings.json +8 -0
  11. data/CHANGELOG.md +119 -2
  12. data/Gemfile +31 -15
  13. data/{LICENSE → LICENSE.txt} +2 -2
  14. data/README.md +241 -224
  15. data/Rakefile +14 -7
  16. data/UPGRADING.md +34 -0
  17. data/html-pipeline.gemspec +31 -21
  18. data/lib/html-pipeline.rb +3 -0
  19. data/lib/html_pipeline/convert_filter/markdown_filter.rb +26 -0
  20. data/lib/html_pipeline/convert_filter.rb +17 -0
  21. data/lib/html_pipeline/filter.rb +89 -0
  22. data/lib/html_pipeline/node_filter/absolute_source_filter.rb +54 -0
  23. data/lib/html_pipeline/node_filter/asset_proxy_filter.rb +86 -0
  24. data/lib/{html/pipeline → html_pipeline/node_filter}/emoji_filter.rb +58 -54
  25. data/lib/html_pipeline/node_filter/https_filter.rb +22 -0
  26. data/lib/html_pipeline/node_filter/image_max_width_filter.rb +40 -0
  27. data/lib/{html/pipeline/@mention_filter.rb → html_pipeline/node_filter/mention_filter.rb} +54 -68
  28. data/lib/html_pipeline/node_filter/syntax_highlight_filter.rb +62 -0
  29. data/lib/html_pipeline/node_filter/table_of_contents_filter.rb +70 -0
  30. data/lib/html_pipeline/node_filter/team_mention_filter.rb +105 -0
  31. data/lib/html_pipeline/node_filter.rb +31 -0
  32. data/lib/html_pipeline/sanitization_filter.rb +188 -0
  33. data/lib/{html/pipeline → html_pipeline/text_filter}/image_filter.rb +3 -3
  34. data/lib/{html/pipeline → html_pipeline/text_filter}/plain_text_input_filter.rb +3 -5
  35. data/lib/html_pipeline/text_filter.rb +21 -0
  36. data/lib/html_pipeline/version.rb +5 -0
  37. data/lib/html_pipeline.rb +281 -0
  38. metadata +58 -54
  39. data/.travis.yml +0 -43
  40. data/Appraisals +0 -19
  41. data/CONTRIBUTING.md +0 -60
  42. data/bin/html-pipeline +0 -78
  43. data/lib/html/pipeline/@team_mention_filter.rb +0 -99
  44. data/lib/html/pipeline/absolute_source_filter.rb +0 -52
  45. data/lib/html/pipeline/autolink_filter.rb +0 -34
  46. data/lib/html/pipeline/body_content.rb +0 -44
  47. data/lib/html/pipeline/camo_filter.rb +0 -105
  48. data/lib/html/pipeline/email_reply_filter.rb +0 -69
  49. data/lib/html/pipeline/filter.rb +0 -165
  50. data/lib/html/pipeline/https_filter.rb +0 -29
  51. data/lib/html/pipeline/image_max_width_filter.rb +0 -37
  52. data/lib/html/pipeline/markdown_filter.rb +0 -56
  53. data/lib/html/pipeline/sanitization_filter.rb +0 -144
  54. data/lib/html/pipeline/syntax_highlight_filter.rb +0 -50
  55. data/lib/html/pipeline/text_filter.rb +0 -16
  56. data/lib/html/pipeline/textile_filter.rb +0 -25
  57. data/lib/html/pipeline/toc_filter.rb +0 -69
  58. data/lib/html/pipeline/version.rb +0 -7
  59. data/lib/html/pipeline.rb +0 -210
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HTMLPipeline
4
+ class TextFilter < Filter
5
+ attr_reader :text
6
+
7
+ def initialize(text, context: {}, result: {})
8
+ raise TypeError, "text must be a String" unless text.is_a?(String)
9
+
10
+ # Ensure that this is always a string
11
+ @text = text.respond_to?(:to_str) ? text.to_str : text.to_s
12
+ super(context: context, result: result)
13
+ end
14
+
15
+ class << self
16
+ def call(input, context: {}, result: {})
17
+ new(input, context: context, result: result).call
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HTMLPipeline
4
+ VERSION = "3.0.2"
5
+ end
@@ -0,0 +1,281 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zeitwerk"
4
+ lib_dir = File.join(File.dirname(__dir__), "lib")
5
+ lib_html_pipeline_dir = File.join(File.dirname(__dir__), "lib", "html_pipeline")
6
+ gem_loader = Zeitwerk::Loader.for_gem
7
+ gem_loader.inflector.inflect(
8
+ "html_pipeline" => "HTMLPipeline",
9
+ )
10
+
11
+ gem_loader.ignore(File.join(lib_html_pipeline_dir, "convert_filter"))
12
+ gem_loader.ignore(File.join(lib_html_pipeline_dir, "node_filter"))
13
+ gem_loader.ignore(File.join(lib_html_pipeline_dir, "text_filter"))
14
+ gem_loader.ignore(File.join(lib_dir, "html-pipeline.rb"))
15
+ gem_loader.setup
16
+
17
+ if ENV.fetch("DEBUG", false)
18
+ require "amazing_print"
19
+ require "debug"
20
+ end
21
+
22
+ class HTMLPipeline
23
+ # HTML processing filters and utilities. This module includes a small
24
+ # framework for defining DOM based content filters and applying them to user
25
+ # provided content.
26
+ #
27
+ # See HTMLPipeline::Filter for information on building filters.
28
+ #
29
+ # Construct a Pipeline for running multiple HTML filters. A pipeline is created once
30
+ # with one to many filters, and it then can be `call`ed many times over the course
31
+ # of its lifetime with input.
32
+ #
33
+ # filters - Array of Filter objects. Each must respond to call(doc,
34
+ # context). Filters are performed in the order provided.
35
+ # default_context - The default context hash. Values specified here will be merged
36
+ # into values from the each individual pipeline run. Can NOT be
37
+ # nil. Default: empty Hash.
38
+ # result_class - The default Class of the result object for individual
39
+ # calls. Default: Hash. Protip: Pass in a Struct to get
40
+ # some semblance of type safety.
41
+ class MissingDependencyError < RuntimeError; end
42
+ class InvalidFilterError < ArgumentError; end
43
+
44
+ class << self
45
+ def optional_dependency(name, requirer)
46
+ require name
47
+ rescue LoadError # rubocop:disable Lint/SuppressedException:
48
+ end
49
+
50
+ def require_dependency(name, requirer)
51
+ require name
52
+ rescue LoadError => e
53
+ raise MissingDependencyError,
54
+ "Missing dependency '#{name}' for #{requirer}. See README.md for details.\n#{e.class.name}: #{e}"
55
+ end
56
+
57
+ def require_dependencies(names, requirer)
58
+ dependency_list = names.dup
59
+ loaded = false
60
+
61
+ while !loaded && names.length > 1
62
+ name = names.shift
63
+
64
+ begin
65
+ require_dependency(name, requirer)
66
+ loaded = true # we got a dependency
67
+ define_dependency_loaded_method(name, true)
68
+ # try the next dependency
69
+ rescue MissingDependencyError
70
+ define_dependency_loaded_method(name, false)
71
+ end
72
+ end
73
+
74
+ return if loaded
75
+
76
+ begin
77
+ name = names.shift
78
+ require name
79
+ define_dependency_loaded_method(name, true)
80
+ rescue LoadError => e
81
+ raise MissingDependencyError,
82
+ "Missing all dependencies '#{dependency_list.join(", ")}' for #{requirer}. See README.md for details.\n#{e.class.name}: #{e}"
83
+ end
84
+ end
85
+
86
+ def define_dependency_loaded_method(name, value)
87
+ self.class.define_method(:"#{name}_loaded?", -> { value })
88
+ end
89
+ end
90
+ # Public: Returns an Array of Filter objects for this Pipeline.
91
+ attr_reader :text_filters, :node_filters
92
+
93
+ # Public: A hash representing the sanitization configuration settings
94
+ attr_reader :sanitization_config
95
+
96
+ # Public: Instrumentation service for the pipeline.
97
+ # Set an ActiveSupport::Notifications compatible object to enable.
98
+ attr_accessor :instrumentation_service
99
+
100
+ # Public: String name for this Pipeline. Defaults to Class name.
101
+ attr_writer :instrumentation_name
102
+
103
+ def instrumentation_name
104
+ return @instrumentation_name if defined?(@instrumentation_name)
105
+
106
+ @instrumentation_name = self.class.name
107
+ end
108
+
109
+ class << self
110
+ # Public: Default instrumentation service for new pipeline objects.
111
+ attr_accessor :default_instrumentation_service
112
+ end
113
+
114
+ def initialize(text_filters: [], convert_filter: nil, sanitization_config: SanitizationFilter::DEFAULT_CONFIG, node_filters: [], default_context: {}, result_class: Hash)
115
+ raise ArgumentError, "default_context cannot be nil" if default_context.nil?
116
+
117
+ @text_filters = text_filters.flatten.freeze || []
118
+ validate_filters(@text_filters, HTMLPipeline::TextFilter)
119
+
120
+ @node_filters = node_filters.flatten.freeze || []
121
+ validate_filters(@node_filters, HTMLPipeline::NodeFilter)
122
+
123
+ @convert_filter = convert_filter
124
+
125
+ if @convert_filter.nil? && (!@text_filters.empty? && !@node_filters.empty?)
126
+ raise InvalidFilterError, "Must provide `convert_filter` if `text_filters` and `node_filters` are also provided"
127
+ elsif !@convert_filter.nil?
128
+ validate_filter(@convert_filter, HTMLPipeline::ConvertFilter)
129
+ end
130
+
131
+ @sanitization_config = sanitization_config.nil? ? nil : Selma::Sanitizer.new(sanitization_config)
132
+
133
+ @default_context = default_context.freeze
134
+ @instrumentation_service = self.class.default_instrumentation_service
135
+ end
136
+
137
+ # Apply all filters in the pipeline to the given HTML.
138
+ #
139
+ # html - A UTF-8 String comprised of HTML.
140
+ # context - The context hash passed to each filter. See the Filter docs
141
+ # for more info on possible values. This object MUST NOT be modified
142
+ # in place by filters. Use the Result for passing state back.
143
+ # result - The result Hash passed to each filter for modification. This
144
+ # is where Filters store extracted information from the content.
145
+ #
146
+ # Returns the result Hash after being filtered by this Pipeline. Contains an
147
+ # :output key with the String HTML markup based on the
148
+ # output of the last filter in the pipeline.
149
+ def call(text, context: {}, result: {})
150
+ context = @default_context.merge(context)
151
+ context = context.freeze
152
+ result ||= {}
153
+
154
+ if @text_filters.any?
155
+ payload = default_payload({
156
+ text_filters: @text_filters.map(&:name),
157
+ context: context,
158
+ result: result,
159
+ })
160
+ instrument("call_text_filters.html_pipeline", payload) do
161
+ result[:output] =
162
+ @text_filters.inject(text) do |doc, filter|
163
+ perform_filter(filter, doc, context: context, result: result)
164
+ end
165
+ end
166
+ end
167
+
168
+ text = result[:output] || text
169
+
170
+ html = if @convert_filter.nil?
171
+ text
172
+ else
173
+ instrument("call_convert_filter.html_pipeline", payload) do
174
+ html = @convert_filter.call(text)
175
+ end
176
+ end
177
+
178
+ unless @node_filters.empty?
179
+ instrument("call_node_filters.html_pipeline", payload) do
180
+ result[:output] = Selma::Rewriter.new(sanitizer: @sanitization_config, handlers: @node_filters).rewrite(html)
181
+ html = result[:output]
182
+ payload = default_payload({
183
+ node_filters: @node_filters.map { |f| f.class.name },
184
+ context: context,
185
+ result: result,
186
+ })
187
+ end
188
+ end
189
+
190
+ instrument("html_pipeline.sanitization", payload) do
191
+ result[:output] = Selma::Rewriter.new(sanitizer: @sanitization_config, handlers: @node_filters).rewrite(html)
192
+ end
193
+
194
+ result = result.merge(@node_filters.collect(&:result).reduce({}, :merge))
195
+ @node_filters.each(&:reset!)
196
+
197
+ result
198
+ end
199
+
200
+ # Internal: Applies a specific filter to the supplied doc.
201
+ #
202
+ # The filter is instrumented.
203
+ #
204
+ # Returns the result of the filter.
205
+ def perform_filter(filter, doc, context: {}, result: {})
206
+ payload = default_payload({
207
+ filter: filter.name,
208
+ context: context,
209
+ result: result,
210
+ })
211
+
212
+ instrument("call_filter.html_pipeline", payload) do
213
+ filter.call(doc, context: context, result: result)
214
+ end
215
+ end
216
+
217
+ # Like call but guarantee the value returned is a string of HTML markup.
218
+ def to_html(input, context: {}, result: {})
219
+ result = call(input, context: context, result: result)
220
+ output = result[:output]
221
+ if output.respond_to?(:to_html)
222
+ output.to_html
223
+ else
224
+ output.to_s
225
+ end
226
+ end
227
+
228
+ # Public: setup instrumentation for this pipeline.
229
+ #
230
+ # Returns nothing.
231
+ def setup_instrumentation(name, service: nil)
232
+ self.instrumentation_name = name
233
+ self.instrumentation_service =
234
+ service || self.class.default_instrumentation_service
235
+ end
236
+
237
+ # Internal: if the `instrumentation_service` object is set, instruments the
238
+ # block, otherwise the block is ran without instrumentation.
239
+ #
240
+ # Returns the result of the provided block.
241
+ def instrument(event, payload = {}, &block)
242
+ payload ||= default_payload
243
+ return yield(payload) unless instrumentation_service
244
+
245
+ instrumentation_service.instrument(event, payload, &block)
246
+ end
247
+
248
+ # Internal: Default payload for instrumentation.
249
+ #
250
+ # Accepts a Hash of additional payload data to be merged.
251
+ #
252
+ # Returns a Hash.
253
+ def default_payload(payload = {})
254
+ { pipeline: instrumentation_name }.merge(payload)
255
+ end
256
+
257
+ private def validate_filter(filter, klass)
258
+ unless correctly_ancestored?(filter, klass)
259
+ raise InvalidFilterError, "Filter must inherit from `#{klass}`; #{filter} does not"
260
+ end
261
+ end
262
+
263
+ private def validate_filters(filters, klass)
264
+ return if filters.nil? || filters.empty?
265
+
266
+ invalid_filters = filters.reject { |f| correctly_ancestored?(f, klass) }
267
+
268
+ unless invalid_filters.empty?
269
+ verb = invalid_filters.count == 1 ? "does" : "do"
270
+ raise InvalidFilterError, "All filters must inherit from `#{klass}`; #{invalid_filters.join(", ")} #{verb} not"
271
+ end
272
+ end
273
+
274
+ private def correctly_ancestored?(filter, klass)
275
+ if filter.respond_to?(:ancestors)
276
+ filter.ancestors.include?(klass)
277
+ else
278
+ filter.class.ancestors.include?(klass)
279
+ end
280
+ end
281
+ end
metadata CHANGED
@@ -1,114 +1,118 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.3
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
- - Ryan Tomayko
8
- - Jerry Cheung
9
7
  - Garen J. Torikian
10
- autorequire:
8
+ autorequire:
11
9
  bindir: bin
12
10
  cert_chain: []
13
- date: 2022-10-14 00:00:00.000000000 Z
11
+ date: 2024-01-08 00:00:00.000000000 Z
14
12
  dependencies:
15
13
  - !ruby/object:Gem::Dependency
16
- name: activesupport
14
+ name: selma
17
15
  requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ">="
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '2'
19
+ version: '0.1'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
23
  requirements:
26
- - - ">="
24
+ - - "~>"
27
25
  - !ruby/object:Gem::Version
28
- version: '2'
26
+ version: '0.1'
27
+ force_ruby_platform: false
29
28
  - !ruby/object:Gem::Dependency
30
- name: nokogiri
29
+ name: zeitwerk
31
30
  requirement: !ruby/object:Gem::Requirement
32
31
  requirements:
33
- - - ">="
32
+ - - "~>"
34
33
  - !ruby/object:Gem::Version
35
- version: '1.4'
34
+ version: '2.5'
36
35
  type: :runtime
37
36
  prerelease: false
38
37
  version_requirements: !ruby/object:Gem::Requirement
39
38
  requirements:
40
- - - ">="
39
+ - - "~>"
41
40
  - !ruby/object:Gem::Version
42
- version: '1.4'
43
- description: GitHub HTML processing filters and utilities
41
+ version: '2.5'
42
+ force_ruby_platform: false
43
+ description: HTML processing filters and utilities
44
44
  email:
45
- - ryan@github.com
46
- - jerry@github.com
47
45
  - gjtorikian@gmail.com
48
46
  executables: []
49
47
  extensions: []
50
48
  extra_rdoc_files: []
51
49
  files:
52
50
  - ".github/FUNDING.yml"
51
+ - ".github/dependabot.yml"
52
+ - ".github/workflows/automerge.yml"
53
+ - ".github/workflows/ci.yml"
54
+ - ".github/workflows/lint.yml"
55
+ - ".github/workflows/publish.yml"
53
56
  - ".gitignore"
54
- - ".travis.yml"
55
- - Appraisals
57
+ - ".rubocop.yml"
58
+ - ".ruby-version"
59
+ - ".vscode/settings.json"
56
60
  - CHANGELOG.md
57
- - CONTRIBUTING.md
58
61
  - Gemfile
59
- - LICENSE
62
+ - LICENSE.txt
60
63
  - README.md
61
64
  - Rakefile
62
- - bin/html-pipeline
65
+ - UPGRADING.md
63
66
  - html-pipeline.gemspec
64
- - lib/html/pipeline.rb
65
- - lib/html/pipeline/@mention_filter.rb
66
- - lib/html/pipeline/@team_mention_filter.rb
67
- - lib/html/pipeline/absolute_source_filter.rb
68
- - lib/html/pipeline/autolink_filter.rb
69
- - lib/html/pipeline/body_content.rb
70
- - lib/html/pipeline/camo_filter.rb
71
- - lib/html/pipeline/email_reply_filter.rb
72
- - lib/html/pipeline/emoji_filter.rb
73
- - lib/html/pipeline/filter.rb
74
- - lib/html/pipeline/https_filter.rb
75
- - lib/html/pipeline/image_filter.rb
76
- - lib/html/pipeline/image_max_width_filter.rb
77
- - lib/html/pipeline/markdown_filter.rb
78
- - lib/html/pipeline/plain_text_input_filter.rb
79
- - lib/html/pipeline/sanitization_filter.rb
80
- - lib/html/pipeline/syntax_highlight_filter.rb
81
- - lib/html/pipeline/text_filter.rb
82
- - lib/html/pipeline/textile_filter.rb
83
- - lib/html/pipeline/toc_filter.rb
84
- - lib/html/pipeline/version.rb
85
- homepage: https://github.com/jch/html-pipeline
67
+ - lib/html-pipeline.rb
68
+ - lib/html_pipeline.rb
69
+ - lib/html_pipeline/convert_filter.rb
70
+ - lib/html_pipeline/convert_filter/markdown_filter.rb
71
+ - lib/html_pipeline/filter.rb
72
+ - lib/html_pipeline/node_filter.rb
73
+ - lib/html_pipeline/node_filter/absolute_source_filter.rb
74
+ - lib/html_pipeline/node_filter/asset_proxy_filter.rb
75
+ - lib/html_pipeline/node_filter/emoji_filter.rb
76
+ - lib/html_pipeline/node_filter/https_filter.rb
77
+ - lib/html_pipeline/node_filter/image_max_width_filter.rb
78
+ - lib/html_pipeline/node_filter/mention_filter.rb
79
+ - lib/html_pipeline/node_filter/syntax_highlight_filter.rb
80
+ - lib/html_pipeline/node_filter/table_of_contents_filter.rb
81
+ - lib/html_pipeline/node_filter/team_mention_filter.rb
82
+ - lib/html_pipeline/sanitization_filter.rb
83
+ - lib/html_pipeline/text_filter.rb
84
+ - lib/html_pipeline/text_filter/image_filter.rb
85
+ - lib/html_pipeline/text_filter/plain_text_input_filter.rb
86
+ - lib/html_pipeline/version.rb
87
+ homepage: https://github.com/gjtorikian/html-pipeline
86
88
  licenses:
87
89
  - MIT
88
- metadata: {}
90
+ metadata:
91
+ funding_uri: https://github.com/sponsors/gjtorikian/
92
+ rubygems_mfa_required: 'true'
89
93
  post_install_message: |
90
94
  -------------------------------------------------
91
95
  Thank you for installing html-pipeline!
92
- You must bundle Filter gem dependencies.
93
- See html-pipeline README.md for more details.
94
- https://github.com/jch/html-pipeline#dependencies
96
+ You must bundle filter gem dependencies.
97
+ See the html-pipeline README.md for more details:
98
+ https://github.com/gjtorikian/html-pipeline#dependencies
95
99
  -------------------------------------------------
96
100
  rdoc_options: []
97
101
  require_paths:
98
102
  - lib
99
103
  required_ruby_version: !ruby/object:Gem::Requirement
100
104
  requirements:
101
- - - ">="
105
+ - - "~>"
102
106
  - !ruby/object:Gem::Version
103
- version: '0'
107
+ version: '3.1'
104
108
  required_rubygems_version: !ruby/object:Gem::Requirement
105
109
  requirements:
106
110
  - - ">="
107
111
  - !ruby/object:Gem::Version
108
- version: '0'
112
+ version: 3.3.22
109
113
  requirements: []
110
- rubygems_version: 3.3.7
111
- signing_key:
114
+ rubygems_version: 3.5.4
115
+ signing_key:
112
116
  specification_version: 4
113
117
  summary: Helpers for processing content through a chain of filters
114
118
  test_files: []
data/.travis.yml DELETED
@@ -1,43 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- bundler_args: --path ../../vendor/bundle
4
-
5
- addons:
6
- apt:
7
- sources:
8
- - libicu-dev
9
- - kalakris-cmake
10
- packages:
11
- - cmake
12
-
13
- script: bundle exec rake
14
-
15
- gemfile:
16
- - gemfiles/rails_6.gemfile
17
- - gemfiles/rails_5.gemfile
18
- - gemfiles/rails_4.gemfile
19
- - gemfiles/rails_3.gemfile
20
-
21
- rvm:
22
- - 2.4.6
23
- - 2.3.8
24
- - 2.5.7
25
- - ruby-head
26
-
27
- matrix:
28
- fast_finish: true
29
- allow_failures:
30
- - rvm: ruby-head
31
- exclude:
32
- - gemfile: gemfiles/rails_6.gemfile
33
- rvm: 2.4.6
34
- - gemfile: gemfiles/rails_6.gemfile
35
- rvm: 2.3.8
36
- - gemfile: gemfiles/rails_4.gemfile
37
- rvm: 2.5.7
38
- - gemfile: gemfiles/rails_4.gemfile
39
- rvm: 2.4.6
40
- - gemfile: gemfiles/rails_3.gemfile
41
- rvm: 2.5.7
42
- - gemfile: gemfiles/rails_3.gemfile
43
- rvm: 2.4.6
data/Appraisals DELETED
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- appraise 'rails-3' do
4
- gem 'rack', '< 2'
5
- gem 'rails', '3.2.22.2'
6
- end
7
-
8
- appraise 'rails-4' do
9
- gem 'rack', '< 2'
10
- gem 'rails', '~> 4.2.6'
11
- end
12
-
13
- appraise 'rails-5' do
14
- gem 'rails', '~> 5.0.0'
15
- end
16
-
17
- appraise 'rails-6' do
18
- gem 'rails', '~> 6.0.0'
19
- end
data/CONTRIBUTING.md DELETED
@@ -1,60 +0,0 @@
1
- # Contributing
2
-
3
- Thanks for using and improving `HTML::Pipeline`!
4
-
5
- - [Submitting a New Issue](#submitting-a-new-issue)
6
- - [Sending a Pull Request](#sending-a-pull-request)
7
-
8
- ## Submitting a New Issue
9
-
10
- If there's an idea you'd like to propose, or a design change, feel free to file a new issue.
11
-
12
- If you have an implementation question or believe you've found a bug, please provide as many details as possible:
13
-
14
- - Input document
15
- - Output HTML document
16
- - the exact `HTML::Pipeline` code you are using
17
- - output of the following from your project
18
-
19
- ```
20
- ruby -v
21
- bundle exec nokogiri -v
22
- ```
23
-
24
- ## Sending a Pull Request
25
-
26
- [Pull requests][pr] are always welcome!
27
-
28
- Check out [the project's issues list][issues] for ideas on what could be improved.
29
-
30
- Before sending, please add tests and ensure the test suite passes.
31
-
32
- ### Running the Tests
33
-
34
- To run the full suite:
35
-
36
- `bundle exec rake`
37
-
38
- To run a specific test file:
39
-
40
- `bundle exec ruby -Itest test/html/pipeline_test.rb`
41
-
42
- To run a specific test:
43
-
44
- `bundle exec ruby -Itest test/html/pipeline/markdown_filter_test.rb -n test_disabling_gfm`
45
-
46
- To run the full suite with all [supported rubies][travisyaml] in bash:
47
-
48
- ```bash
49
- rubies=(ree-1.8.7-2011.03 1.9.2-p290 1.9.3-p429 2.0.0-p247)
50
- for r in ${rubies[*]}
51
- do
52
- rbenv local $r # switch to your version manager of choice
53
- bundle install
54
- bundle exec rake
55
- done
56
- ```
57
-
58
- [issues]: https://github.com/jch/html-pipeline/issues
59
- [pr]: https://help.github.com/articles/using-pull-requests
60
- [travisyaml]: https://github.com/jch/html-pipeline/blob/master/.travis.yml
data/bin/html-pipeline DELETED
@@ -1,78 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'html/pipeline'
3
-
4
- require 'optparse'
5
-
6
- # Accept "help", too
7
- .map! { |a| a == 'help' ? '--help' : a }
8
-
9
- onParser.new do |opts|
10
- opts.banner = <<-HELP.gsub(/^ /, '')
11
- Usage: html-pipeline [-h] [-f]
12
- html-pipeline [FILTER [FILTER [...]]] < file.md
13
- cat file.md | html-pipeline [FILTER [FILTER [...]]]
14
- HELP
15
-
16
- opts.separator 'Options:'
17
-
18
- opts.on('-f', '--filters', 'List the available filters') do
19
- filters = HTML::Pipeline.constants.grep(/\w+Filter$/)
20
- .map { |f| f.to_s.gsub(/Filter$/, '') }
21
-
22
- # Text filter doesn't work, no call method
23
- filters -= ['Text']
24
-
25
- abort <<-HELP.gsub(/^ /, '')
26
- Available filters:
27
- #{filters.join("\n ")}
28
- HELP
29
- end
30
- end.parse!
31
-
32
- # Default to a GitHub-ish pipeline
33
- if ARGV.empty?
34
-
35
- filters = [
36
- HTML::Pipeline::MarkdownFilter,
37
- HTML::Pipeline::SanitizationFilter,
38
- HTML::Pipeline::ImageMaxWidthFilter,
39
- HTML::Pipeline::EmojiFilter,
40
- HTML::Pipeline::AutolinkFilter,
41
- HTML::Pipeline::TableOfContentsFilter
42
- ]
43
-
44
- # Add syntax highlighting if rouge is present
45
- begin
46
- require 'rouge'
47
- filters << HTML::Pipeline::SyntaxHighlightFilter
48
- rescue LoadError
49
- end
50
-
51
- else
52
-
53
- def filter_named(name)
54
- case name
55
- when 'Text'
56
- raise NameError # Text filter doesn't work, no call method
57
- end
58
-
59
- HTML::Pipeline.const_get("#{name}Filter")
60
- rescue NameError => e
61
- abort "Unknown filter '#{name}'. List filters with the -f option."
62
- end
63
-
64
- filters = []
65
- until ARGV.empty?
66
- name = ARGV.shift
67
- filters << filter_named(name)
68
- end
69
-
70
- end
71
-
72
- context = {
73
- asset_root: '/assets',
74
- base_url: '/',
75
- gfm: true
76
- }
77
-
78
- puts HTML::Pipeline.new(filters, context).call(ARGF.read)[:output]