html-pipeline 2.14.2 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +11 -3
- data/.github/dependabot.yml +20 -0
- data/.github/workflows/automerge.yml +34 -0
- data/.github/workflows/lint.yml +23 -0
- data/.github/workflows/tag_and_release.yml +70 -0
- data/.github/workflows/test.yml +33 -0
- data/.rubocop.yml +17 -0
- data/CHANGELOG.md +762 -180
- data/Gemfile +29 -15
- data/{LICENSE → LICENSE.txt} +2 -2
- data/README.md +209 -218
- data/Rakefile +14 -7
- data/UPGRADING.md +35 -0
- data/html-pipeline.gemspec +31 -21
- data/lib/html-pipeline.rb +3 -0
- data/lib/html_pipeline/convert_filter/markdown_filter.rb +26 -0
- data/lib/html_pipeline/convert_filter.rb +17 -0
- data/lib/html_pipeline/filter.rb +89 -0
- data/lib/{html/pipeline → html_pipeline/node_filter}/absolute_source_filter.rb +23 -21
- data/lib/{html/pipeline → html_pipeline/node_filter}/emoji_filter.rb +58 -54
- data/lib/html_pipeline/node_filter/https_filter.rb +22 -0
- data/lib/html_pipeline/node_filter/image_max_width_filter.rb +40 -0
- data/lib/{html/pipeline/@mention_filter.rb → html_pipeline/node_filter/mention_filter.rb} +55 -69
- data/lib/html_pipeline/node_filter/table_of_contents_filter.rb +68 -0
- data/lib/html_pipeline/node_filter/team_mention_filter.rb +105 -0
- data/lib/html_pipeline/node_filter.rb +31 -0
- data/lib/html_pipeline/sanitization_filter.rb +65 -0
- data/lib/{html/pipeline → html_pipeline/text_filter}/image_filter.rb +3 -3
- data/lib/{html/pipeline → html_pipeline/text_filter}/plain_text_input_filter.rb +3 -5
- data/lib/html_pipeline/text_filter.rb +21 -0
- data/lib/html_pipeline/version.rb +5 -0
- data/lib/html_pipeline.rb +252 -0
- metadata +52 -54
- data/.travis.yml +0 -43
- data/Appraisals +0 -19
- data/CONTRIBUTING.md +0 -60
- data/bin/html-pipeline +0 -78
- data/lib/html/pipeline/@team_mention_filter.rb +0 -99
- data/lib/html/pipeline/autolink_filter.rb +0 -34
- data/lib/html/pipeline/body_content.rb +0 -44
- data/lib/html/pipeline/camo_filter.rb +0 -105
- data/lib/html/pipeline/email_reply_filter.rb +0 -68
- data/lib/html/pipeline/filter.rb +0 -165
- data/lib/html/pipeline/https_filter.rb +0 -29
- data/lib/html/pipeline/image_max_width_filter.rb +0 -37
- data/lib/html/pipeline/markdown_filter.rb +0 -56
- data/lib/html/pipeline/sanitization_filter.rb +0 -144
- data/lib/html/pipeline/syntax_highlight_filter.rb +0 -50
- data/lib/html/pipeline/text_filter.rb +0 -16
- data/lib/html/pipeline/textile_filter.rb +0 -25
- data/lib/html/pipeline/toc_filter.rb +0 -69
- data/lib/html/pipeline/version.rb +0 -7
- data/lib/html/pipeline.rb +0 -210
@@ -0,0 +1,252 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zeitwerk"
|
4
|
+
lib_dir = File.join(File.dirname(__dir__), "lib")
|
5
|
+
gem_loader = Zeitwerk::Loader.for_gem
|
6
|
+
gem_loader.inflector.inflect(
|
7
|
+
"html_pipeline" => "HTMLPipeline",
|
8
|
+
)
|
9
|
+
gem_loader.ignore(File.join(lib_dir, "html-pipeline.rb"))
|
10
|
+
gem_loader.setup
|
11
|
+
|
12
|
+
if ENV.fetch("DEBUG", false)
|
13
|
+
require "amazing_print"
|
14
|
+
require "debug"
|
15
|
+
end
|
16
|
+
|
17
|
+
class HTMLPipeline
|
18
|
+
# HTML processing filters and utilities. This module includes a small
|
19
|
+
# framework for defining DOM based content filters and applying them to user
|
20
|
+
# provided content.
|
21
|
+
#
|
22
|
+
# See HTMLPipeline::Filter for information on building filters.
|
23
|
+
#
|
24
|
+
# Construct a Pipeline for running multiple HTML filters. A pipeline is created once
|
25
|
+
# with one to many filters, and it then can be `call`ed many times over the course
|
26
|
+
# of its lifetime with input.
|
27
|
+
#
|
28
|
+
# filters - Array of Filter objects. Each must respond to call(doc,
|
29
|
+
# context). Filters are performed in the order provided.
|
30
|
+
# default_context - The default context hash. Values specified here will be merged
|
31
|
+
# into values from the each individual pipeline run. Can NOT be
|
32
|
+
# nil. Default: empty Hash.
|
33
|
+
# result_class - The default Class of the result object for individual
|
34
|
+
# calls. Default: Hash. Protip: Pass in a Struct to get
|
35
|
+
# some semblance of type safety.
|
36
|
+
class MissingDependencyError < RuntimeError; end
|
37
|
+
class InvalidFilterError < ArgumentError; end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def optional_dependency(name, requirer)
|
41
|
+
require name
|
42
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException:
|
43
|
+
end
|
44
|
+
|
45
|
+
def require_dependency(name, requirer)
|
46
|
+
require name
|
47
|
+
rescue LoadError => e
|
48
|
+
raise MissingDependencyError,
|
49
|
+
"Missing dependency '#{name}' for #{requirer}. See README.md for details.\n#{e.class.name}: #{e}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def require_dependencies(names, requirer)
|
53
|
+
dependency_list = names.dup
|
54
|
+
loaded = false
|
55
|
+
|
56
|
+
while !loaded && names.length > 1
|
57
|
+
name = names.shift
|
58
|
+
|
59
|
+
begin
|
60
|
+
require_dependency(name, requirer)
|
61
|
+
loaded = true # we got a dependency
|
62
|
+
define_dependency_loaded_method(name, true)
|
63
|
+
# try the next dependency
|
64
|
+
rescue MissingDependencyError
|
65
|
+
define_dependency_loaded_method(name, false)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
return if loaded
|
70
|
+
|
71
|
+
begin
|
72
|
+
name = names.shift
|
73
|
+
require name
|
74
|
+
define_dependency_loaded_method(name, true)
|
75
|
+
rescue LoadError => e
|
76
|
+
raise MissingDependencyError,
|
77
|
+
"Missing all dependencies '#{dependency_list.join(", ")}' for #{requirer}. See README.md for details.\n#{e.class.name}: #{e}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def define_dependency_loaded_method(name, value)
|
82
|
+
self.class.define_method(:"#{name}_loaded?", -> { value })
|
83
|
+
end
|
84
|
+
end
|
85
|
+
# Public: Returns an Array of Filter objects for this Pipeline.
|
86
|
+
attr_reader :text_filters, :node_filters
|
87
|
+
|
88
|
+
# Public: A hash representing the sanitization configuration settings
|
89
|
+
attr_reader :sanitization_config
|
90
|
+
|
91
|
+
# Public: Instrumentation service for the pipeline.
|
92
|
+
# Set an ActiveSupport::Notifications compatible object to enable.
|
93
|
+
attr_accessor :instrumentation_service
|
94
|
+
|
95
|
+
# Public: String name for this Pipeline. Defaults to Class name.
|
96
|
+
attr_writer :instrumentation_name
|
97
|
+
|
98
|
+
def instrumentation_name
|
99
|
+
return @instrumentation_name if defined?(@instrumentation_name)
|
100
|
+
|
101
|
+
@instrumentation_name = self.class.name
|
102
|
+
end
|
103
|
+
|
104
|
+
class << self
|
105
|
+
# Public: Default instrumentation service for new pipeline objects.
|
106
|
+
attr_accessor :default_instrumentation_service
|
107
|
+
end
|
108
|
+
|
109
|
+
def initialize(text_filters: [], convert_filter: nil, sanitization_config: SanitizationFilter::DEFAULT_CONFIG, node_filters: [], default_context: {}, result_class: Hash)
|
110
|
+
raise ArgumentError, "default_context cannot be nil" if default_context.nil?
|
111
|
+
|
112
|
+
@text_filters = text_filters.flatten.freeze
|
113
|
+
validate_filters(@text_filters, HTMLPipeline::TextFilter)
|
114
|
+
|
115
|
+
@node_filters = node_filters.flatten.freeze
|
116
|
+
validate_filters(@node_filters, HTMLPipeline::NodeFilter)
|
117
|
+
|
118
|
+
@convert_filter = convert_filter
|
119
|
+
if @convert_filter.nil? && !@node_filters.empty?
|
120
|
+
raise InvalidFilterError, "Must provide `convert_filter` if `node_filter`s is also provided"
|
121
|
+
elsif !@convert_filter.nil?
|
122
|
+
validate_filter(@convert_filter, HTMLPipeline::ConvertFilter)
|
123
|
+
end
|
124
|
+
|
125
|
+
@sanitization_config = sanitization_config.nil? ? nil : Selma::Sanitizer.new(sanitization_config)
|
126
|
+
|
127
|
+
@default_context = default_context.freeze
|
128
|
+
@instrumentation_service = self.class.default_instrumentation_service
|
129
|
+
end
|
130
|
+
|
131
|
+
# Apply all filters in the pipeline to the given HTML.
|
132
|
+
#
|
133
|
+
# html - A UTF-8 String comprised of HTML.
|
134
|
+
# context - The context hash passed to each filter. See the Filter docs
|
135
|
+
# for more info on possible values. This object MUST NOT be modified
|
136
|
+
# in place by filters. Use the Result for passing state back.
|
137
|
+
# result - The result Hash passed to each filter for modification. This
|
138
|
+
# is where Filters store extracted information from the content.
|
139
|
+
#
|
140
|
+
# Returns the result Hash after being filtered by this Pipeline. Contains an
|
141
|
+
# :output key with the String HTML markup based on the
|
142
|
+
# output of the last filter in the pipeline.
|
143
|
+
def call(text, context: {}, result: {})
|
144
|
+
context = @default_context.merge(context)
|
145
|
+
context = context.freeze
|
146
|
+
result ||= {}
|
147
|
+
|
148
|
+
payload = default_payload({ text_filters: @text_filters.map(&:name),
|
149
|
+
context: context, result: result, })
|
150
|
+
instrument("call_text_filters.html_pipeline", payload) do
|
151
|
+
result[:output] =
|
152
|
+
@text_filters.inject(text) do |doc, filter|
|
153
|
+
perform_filter(filter, doc, context: context, result: result)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
text = result[:output]
|
158
|
+
|
159
|
+
html = @convert_filter.call(text) unless @convert_filter.nil?
|
160
|
+
|
161
|
+
unless @node_filters.empty?
|
162
|
+
payload = default_payload({ node_filters: @node_filters.map { |f| f.class.name },
|
163
|
+
context: context, result: result, })
|
164
|
+
instrument("call_node_filters.html_pipeline", payload) do
|
165
|
+
result[:output] = Selma::Rewriter.new(sanitizer: @sanitization_config, handlers: @node_filters).rewrite(html)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
result = result.merge(Hash[*@node_filters.collect(&:result).flatten])
|
170
|
+
@node_filters.each(&:reset!)
|
171
|
+
|
172
|
+
result
|
173
|
+
end
|
174
|
+
|
175
|
+
# Internal: Applies a specific filter to the supplied doc.
|
176
|
+
#
|
177
|
+
# The filter is instrumented.
|
178
|
+
#
|
179
|
+
# Returns the result of the filter.
|
180
|
+
def perform_filter(filter, doc, context: {}, result: {})
|
181
|
+
payload = default_payload({ filter: filter.name,
|
182
|
+
context: context, result: result, })
|
183
|
+
instrument("call_filter.html_pipeline", payload) do
|
184
|
+
filter.call(doc, context: context, result: result)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Like call but guarantee the value returned is a string of HTML markup.
|
189
|
+
def to_html(input, context: {}, result: {})
|
190
|
+
result = call(input, context: context, result: result)
|
191
|
+
output = result[:output]
|
192
|
+
if output.respond_to?(:to_html)
|
193
|
+
output.to_html
|
194
|
+
else
|
195
|
+
output.to_s
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Public: setup instrumentation for this pipeline.
|
200
|
+
#
|
201
|
+
# Returns nothing.
|
202
|
+
def setup_instrumentation(name, service: nil)
|
203
|
+
self.instrumentation_name = name
|
204
|
+
self.instrumentation_service =
|
205
|
+
service || self.class.default_instrumentation_service
|
206
|
+
end
|
207
|
+
|
208
|
+
# Internal: if the `instrumentation_service` object is set, instruments the
|
209
|
+
# block, otherwise the block is ran without instrumentation.
|
210
|
+
#
|
211
|
+
# Returns the result of the provided block.
|
212
|
+
def instrument(event, payload = {}, &block)
|
213
|
+
payload ||= default_payload
|
214
|
+
return yield(payload) unless instrumentation_service
|
215
|
+
|
216
|
+
instrumentation_service.instrument(event, payload, &block)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Internal: Default payload for instrumentation.
|
220
|
+
#
|
221
|
+
# Accepts a Hash of additional payload data to be merged.
|
222
|
+
#
|
223
|
+
# Returns a Hash.
|
224
|
+
def default_payload(payload = {})
|
225
|
+
{ pipeline: instrumentation_name }.merge(payload)
|
226
|
+
end
|
227
|
+
|
228
|
+
private def validate_filter(filter, klass)
|
229
|
+
unless correctly_ancestored?(filter, klass)
|
230
|
+
raise InvalidFilterError, "Filter must inherit from `#{klass}`; #{filter} does not"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
private def validate_filters(filters, klass)
|
235
|
+
return if filters.nil? || filters.empty?
|
236
|
+
|
237
|
+
invalid_filters = filters.reject { |f| correctly_ancestored?(f, klass) }
|
238
|
+
|
239
|
+
unless invalid_filters.empty?
|
240
|
+
verb = invalid_filters.count == 1 ? "does" : "do"
|
241
|
+
raise InvalidFilterError, "All filters must inherit from `#{klass}`; #{invalid_filters.join(", ")} #{verb} not"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
private def correctly_ancestored?(filter, klass)
|
246
|
+
if filter.respond_to?(:ancestors)
|
247
|
+
filter.ancestors.include?(klass)
|
248
|
+
else
|
249
|
+
filter.class.ancestors.include?(klass)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
metadata
CHANGED
@@ -1,114 +1,112 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html-pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre1
|
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-
|
11
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
14
12
|
dependencies:
|
15
13
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
14
|
+
name: selma
|
17
15
|
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
|
-
- - "
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: 0.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:
|
26
|
+
version: 0.0.1
|
29
27
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
28
|
+
name: zeitwerk
|
31
29
|
requirement: !ruby/object:Gem::Requirement
|
32
30
|
requirements:
|
33
|
-
- - "
|
31
|
+
- - "~>"
|
34
32
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
33
|
+
version: '2.5'
|
36
34
|
type: :runtime
|
37
35
|
prerelease: false
|
38
36
|
version_requirements: !ruby/object:Gem::Requirement
|
39
37
|
requirements:
|
40
|
-
- - "
|
38
|
+
- - "~>"
|
41
39
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
43
|
-
description:
|
40
|
+
version: '2.5'
|
41
|
+
description: HTML processing filters and utilities
|
44
42
|
email:
|
45
|
-
- ryan@github.com
|
46
|
-
- jerry@github.com
|
47
43
|
- gjtorikian@gmail.com
|
48
44
|
executables: []
|
49
45
|
extensions: []
|
50
46
|
extra_rdoc_files: []
|
51
47
|
files:
|
52
48
|
- ".github/FUNDING.yml"
|
49
|
+
- ".github/dependabot.yml"
|
50
|
+
- ".github/workflows/automerge.yml"
|
51
|
+
- ".github/workflows/lint.yml"
|
52
|
+
- ".github/workflows/tag_and_release.yml"
|
53
|
+
- ".github/workflows/test.yml"
|
53
54
|
- ".gitignore"
|
54
|
-
- ".
|
55
|
-
- Appraisals
|
55
|
+
- ".rubocop.yml"
|
56
56
|
- CHANGELOG.md
|
57
|
-
- CONTRIBUTING.md
|
58
57
|
- Gemfile
|
59
|
-
- LICENSE
|
58
|
+
- LICENSE.txt
|
60
59
|
- README.md
|
61
60
|
- Rakefile
|
62
|
-
-
|
61
|
+
- UPGRADING.md
|
63
62
|
- html-pipeline.gemspec
|
64
|
-
- lib/html
|
65
|
-
- lib/
|
66
|
-
- lib/
|
67
|
-
- lib/
|
68
|
-
- lib/
|
69
|
-
- lib/
|
70
|
-
- lib/
|
71
|
-
- lib/
|
72
|
-
- lib/
|
73
|
-
- lib/
|
74
|
-
- lib/
|
75
|
-
- lib/
|
76
|
-
- lib/
|
77
|
-
- lib/
|
78
|
-
- lib/
|
79
|
-
- lib/
|
80
|
-
- lib/
|
81
|
-
- lib/
|
82
|
-
|
83
|
-
- lib/html/pipeline/toc_filter.rb
|
84
|
-
- lib/html/pipeline/version.rb
|
85
|
-
homepage: https://github.com/jch/html-pipeline
|
63
|
+
- lib/html-pipeline.rb
|
64
|
+
- lib/html_pipeline.rb
|
65
|
+
- lib/html_pipeline/convert_filter.rb
|
66
|
+
- lib/html_pipeline/convert_filter/markdown_filter.rb
|
67
|
+
- lib/html_pipeline/filter.rb
|
68
|
+
- lib/html_pipeline/node_filter.rb
|
69
|
+
- lib/html_pipeline/node_filter/absolute_source_filter.rb
|
70
|
+
- lib/html_pipeline/node_filter/emoji_filter.rb
|
71
|
+
- lib/html_pipeline/node_filter/https_filter.rb
|
72
|
+
- lib/html_pipeline/node_filter/image_max_width_filter.rb
|
73
|
+
- lib/html_pipeline/node_filter/mention_filter.rb
|
74
|
+
- lib/html_pipeline/node_filter/table_of_contents_filter.rb
|
75
|
+
- lib/html_pipeline/node_filter/team_mention_filter.rb
|
76
|
+
- lib/html_pipeline/sanitization_filter.rb
|
77
|
+
- lib/html_pipeline/text_filter.rb
|
78
|
+
- lib/html_pipeline/text_filter/image_filter.rb
|
79
|
+
- lib/html_pipeline/text_filter/plain_text_input_filter.rb
|
80
|
+
- lib/html_pipeline/version.rb
|
81
|
+
homepage: https://github.com/gjtorikian/html-pipeline
|
86
82
|
licenses:
|
87
83
|
- MIT
|
88
|
-
metadata:
|
84
|
+
metadata:
|
85
|
+
funding_uri: https://github.com/sponsors/gjtorikian/
|
86
|
+
rubygems_mfa_required: 'true'
|
89
87
|
post_install_message: |
|
90
88
|
-------------------------------------------------
|
91
89
|
Thank you for installing html-pipeline!
|
92
|
-
You must bundle
|
93
|
-
See html-pipeline README.md for more details
|
94
|
-
https://github.com/
|
90
|
+
You must bundle filter gem dependencies.
|
91
|
+
See the html-pipeline README.md for more details:
|
92
|
+
https://github.com/gjtorikian/html-pipeline#dependencies
|
95
93
|
-------------------------------------------------
|
96
94
|
rdoc_options: []
|
97
95
|
require_paths:
|
98
96
|
- lib
|
99
97
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
98
|
requirements:
|
101
|
-
- - "
|
99
|
+
- - "~>"
|
102
100
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
101
|
+
version: '3.1'
|
104
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
103
|
requirements:
|
106
104
|
- - ">="
|
107
105
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
106
|
+
version: 3.3.22
|
109
107
|
requirements: []
|
110
|
-
rubygems_version: 3.3.
|
111
|
-
signing_key:
|
108
|
+
rubygems_version: 3.3.26
|
109
|
+
signing_key:
|
112
110
|
specification_version: 4
|
113
111
|
summary: Helpers for processing content through a chain of filters
|
114
112
|
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]
|