prolog-services-replace_content 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9dd8722087ca2e53d4e72dd77e1f6ae1213f6168
4
+ data.tar.gz: af89b216099e0209bade77ac66a70838d3b6817c
5
+ SHA512:
6
+ metadata.gz: d32288b39c0f49b71e9998d13c79e11f63e2864c9c9f77e3319de7eed435c94fa19c74512c597e4fe7e92e4d53d01fd3994879ee645174540319a3f44aa4ed70
7
+ data.tar.gz: d840e8bfe0bb3162e705e5cef4f11c8273cb77be1a94432eeb86e746bbf6987664fb846b3e5d496de1a7730140f78bbf04cad102dd0b944a816640a3ebb80e44
data/.codeclimate.yml ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - ruby
8
+ fixme:
9
+ enabled: true
10
+ rubocop:
11
+ enabled: true
12
+ ratings:
13
+ paths:
14
+ - "**.rb"
15
+ exclude_paths:
16
+ - test/
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /o-rdoc/
11
+ /log/
12
+ !/log/.keep
data/.rubocop.yml ADDED
@@ -0,0 +1,43 @@
1
+
2
+ # CodeClimate runs an older version of RuboCop, which apparently doesn't
3
+ # understand the `AllCops` setting. So we do it The Hard Way.
4
+
5
+ Metrics/LineLength:
6
+ Exclude:
7
+ - Rakefile
8
+ - prolog-services-replace_content.gemspec
9
+
10
+ Style/PercentLiteralDelimiters:
11
+ Exclude:
12
+ - prolog-services-replace_content.gemspec
13
+
14
+ Style/PercentQLiterals:
15
+ Exclude:
16
+ - prolog-services-replace_content.gemspec
17
+
18
+ Style/StringLiterals:
19
+ Exclude:
20
+ - Rakefile
21
+ - prolog-services-replace_content.gemspec
22
+ - bin/console
23
+
24
+ Style/UnneededPercentQ:
25
+ Exclude:
26
+ - prolog-services-replace_content.gemspec
27
+
28
+ Style/WordArray:
29
+ Exclude:
30
+ - Rakefile
31
+
32
+ # 'Real' settings follow. ###################################
33
+
34
+ AllCops:
35
+ TargetRubyVersion: 2.3
36
+
37
+ Metrics/AbcSize:
38
+ Exclude:
39
+ - test/prolog/use_cases/propose_edit_contribution_test.rb
40
+
41
+ Metrics/MethodLength:
42
+ Exclude:
43
+ - test/prolog/use_cases/propose_edit_contribution_test.rb
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at jdickey@seven-sigma.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in prolog-services-replace_content.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Jeff Dickey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,236 @@
1
+ # Prolog::Services::ReplaceContent
2
+
3
+ [ ![Codeship Status for TheProlog/prolog-services-replace_content](https://codeship.com/projects/de342330-da58-0133-0093-5a647b2fc712/status?branch=master)](https://codeship.com/projects/143778) [![Code Climate](https://codeclimate.com/github/TheProlog/prolog-services-replace_content/badges/gpa.svg)](https://codeclimate.com/github/TheProlog/prolog-services-replace_content) [![Test Coverage](https://codeclimate.com/github/TheProlog/prolog-services-replace_content/badges/coverage.svg)](https://codeclimate.com/github/TheProlog/prolog-services-replace_content/coverage) [![Issue Count](https://codeclimate.com/github/TheProlog/prolog-services-replace_content/badges/issue_count.svg)](https://codeclimate.com/github/TheProlog/prolog-services-replace_content) [![Dependency Status](https://gemnasium.com/TheProlog/prolog-services-replace_content.svg)](https://gemnasium.com/TheProlog/prolog-services-replace_content)
4
+
5
+
6
+ This Gem was extracted from an internally-developed application, which should somewhat explain the namespacing.
7
+
8
+ The Gem provides an (extremely) simple API for replacing a substring of "existing" HTML content, specified by zero-based endpoint indexes, with valid HTML content, which may be partly or completely comprised of embedded HTML. Detailed API usage is documented below.
9
+
10
+ **Important:** The initial release of this Gem *only* supports HTML for source and replacement content; no Markdown content is supported. This means that, for example,. specifying a simple string with­out tags as replacement content will attempt to replace the selected range with *just that text*; if that causes the resulting HTML to be invalid, it will be reported as an error.
11
+
12
+ A future release of this Gem is expected to support specification of source and/or replacement content in *either* HTML or Markdown (which, remember, is a proper superset of HTML). The tools presently available for supporting this, however, are presently stumped by several corner cases we have devised that are likely enough to occur "in the wild" to be of serious concern.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'prolog-services-replace_content'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ ```
25
+ $ bundle
26
+ ```
27
+
28
+ Or install it yourself as:
29
+
30
+ ```
31
+ $ gem install prolog-services-replace_content
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```ruby
37
+ require 'prolog/services/replace_centent'
38
+
39
+ content = '<p>This is a <em>simple</em> test.</p>'
40
+ endpoint_begin = content.index ' <em>'
41
+ endpoint_end = content.index ' test.'
42
+
43
+ # ...
44
+
45
+ endpoints = (endpoint_begin..endpoint_end)
46
+ converter = Prolog::Services::ReplaceContent.new(content: content,
47
+ endpoints: endpoints,
48
+ replacement: 'basic' )
49
+
50
+ # Would replacing the specified range with the specified content result in valid
51
+ # and well-formed HTML?
52
+ converter.valid? # => true
53
+
54
+ # Replace content without using any surrounding markers
55
+ converter.convert # => true
56
+ converter.converted_content # => '<p>Tis is a basic test.</p>'
57
+
58
+ converter.markers = :a
59
+ converter.convert # need to repeat this after changing markers
60
+ converter.converted_content
61
+ # => '<p>This is a <a id="selection-begin"></a>basic<a id="selection-end"></a> test.</p>'
62
+ converter.errors.empty? # => true
63
+ converter.valid? # => true
64
+
65
+ # Conversion inserting marker tag pairs (tag symbol required; text optional)
66
+
67
+ converter.markers = :span, 'testing-again'
68
+ converter.convert
69
+ converter.converted_content
70
+ # => '<p>This is a <span id="testing-again-begin"></span>basic<span id="testing-again-end"></span> test.</p>'
71
+
72
+ # Error conditions
73
+ # Error Condition #1: Bad endpoints
74
+
75
+ content = '<p>This is a <em>simple</em> test.</p>'
76
+ endpoints = (15..28)
77
+ converter = Prolog::Services::ReplaceContent.new(content: content,
78
+ endpoints: endpoints,
79
+ replacement: 'basic' )
80
+ # with these params, `#converted_content` would return something like
81
+ # '<p>This is a <e<a id="foo"></a>m>simple</em><a id="foo-end"></a> test.</p>'
82
+ # if we let it. Nope; no joy.
83
+
84
+ converter.valid? # <= false
85
+ converter.errors # <= { endpoints: ['force invalid HTML'] }
86
+ converter.convert # <= false
87
+ converter.converted_content # <= :failed_conversion ### *NOT* a string!
88
+
89
+ # Error Condition #2: Bad source content
90
+ converter.content = '<p>This is bad content.</div>'
91
+ converter.valid? # => false
92
+ converter.convert # => false
93
+ converter.errors # => { content => ['invalid HTML'] }
94
+ converter.converted_content # => :failed_conversion
95
+
96
+ # Error Condition #3: Replacement forces bad HTML
97
+ converter.content = '<p>This is <em>simple</em> content.</p>'
98
+ converter.replacement = 'bad '
99
+ converter.endpoints = (11..14)
100
+ # would convert to '<p>This is bad>simple</em> content.</p>'
101
+ converter.valid? # <= false
102
+ converter.errors # => { replacement: ['invalidates HTML'] }
103
+ converter.convert # => false
104
+ converter.converted_content # <= :failed_conversion
105
+
106
+ # Error Condition #4: Attributes changed but `#convert` not called
107
+ converter = Prolog::Services::ReplaceContent.new(content: content,
108
+ endpoints: endpoints,
109
+ replacement: 'basic' )
110
+
111
+ converter.replacement = 'simplistic'
112
+ converter.valid? # => false
113
+ converter.errors # => { conversion: ['not called'] }
114
+ ```
115
+
116
+
117
+
118
+ ## API Reference
119
+
120
+ ### Initialisation
121
+
122
+ #### `#initialize(**params = {})`
123
+
124
+ Creates an instance of the converter class, populating the `#content`, `#endpoints`, and `#replacement` attributes of the instance based on the specified values. Any of these may be omitted, which has the effect of using default values of `''`, `(-1..-1)`, and `''`, respectively.
125
+
126
+ ### Attribute getters and setters
127
+
128
+ #### `#content`
129
+
130
+ The HTML content specified as *source content* for the conversion, as specified either from the initialiser or the `#content=` method. Is guaranteed to return either an empty string or valid HTML.
131
+
132
+ #### `#content=(str)`
133
+
134
+ Specifies HTML *source content* that will be used for the conversion in `#convert`. Specifying a new value using this method, and then calling `#converted_content` without having previously called `#convert`, will trigger an error condition (see `#convert` and/or `#errors` for details).
135
+
136
+ #### `#endpoints`
137
+
138
+ Returns the endpoints specified for the range within the `#content` which is to be replaced with the `#replacement_content`. This is a range of integers that follow Ruby conventions for string indexing (zero is the start of the string; `-1` is the last character in the string, `-2` is the second-to-last, etc). If not set by either `#initialize` or `#endpoints=`, defaults to `(-1..-1)`, which is rarely what is desired.
139
+
140
+ #### `#endpoints=(range)`
141
+
142
+ Assigns the endpoints of the range within the source `#content` which is to be replaced by the re­placement content. Can be either an integer (specifying the ending endpoint, where the starting endpoint is set to zero, the beginning of the string) or a range of non-negative integers. If the speci­fied value is invalid (either because it is not a valid range of non-negative integers or because the ending endpoint exceeds the length of the `#content` when `#convert` is called), will default to `(-1..-1)` and cause an error to be reported (see `#errors`, below).
143
+
144
+ #### `#markers=`
145
+
146
+ Specifies the details of the marker tag pairs to be used to wrap the content within the endpoints. If not explicitly set, no such tag pairs will be used. May be set using a symbolic HTML tag name (e.g. `:span` for the HTML `<span>` tag pair) and, optionally, an "identifier" string.
147
+
148
+ Examples:
149
+
150
+ ```ruby
151
+ # Setting the HTML tag used for the tag pairs to the `<a>` tag
152
+ # ...
153
+ converter.markers = :a
154
+ converter.convert
155
+ converter.converted_content
156
+ # => '<p>This is a <a id="selection-begin"></a>basic<a id="selection-end"></a> test.</p>'
157
+
158
+ # Setting the markers to the '<a>' tag and the identifier prefix to 'mambo-no-5'
159
+ converter.markers = :a, 'mambo-no-5'
160
+ converter.convert
161
+ converter.converted_content
162
+ # => '<p>This is a <a id="mambo-no-5-begin"></a>basic<a id="mambo-no-5-end"></a> test.</p>'
163
+
164
+ # Setting the HTML tag without setting the identifier resets the latter to 'selection'
165
+ converter.markers = :span
166
+ converter.convert
167
+ converter.converted_content
168
+ # => '<p>This is a <span id="selection-begin"></span>basic<span id="selection-end"></span> test.</p>'
169
+
170
+ ```
171
+
172
+ **Note** that setting the markers, as with setting any of the other attributes, invalidates any previous conversion and requires the `#convert` method to be called again prior to calling `#converted_content`.
173
+
174
+ #### `#replacement`
175
+
176
+ Returns the content string specified to replace the existing content within the endpoints, specified by either `#initialize` or `#replacement=`. This is guaranteed to be either an empty string or a valid HTML string.
177
+
178
+ #### `#replacement=(str)`
179
+
180
+ Specifies content, as an HTML string, that will be used to replace an existing range of content by a successful call to `#convert`. Assigning to this, or any of the other attributes and then calling `#converted_content` without first calling `#convert` will report an error (see `#convert` and/or `#errors` for details).
181
+
182
+ If a string without HTML tags is specified, then it will be used literally; if replacing the content between the endpoints with that replacement string results in invalid HTML, then that also will cause an error to be reported.
183
+
184
+ The default value is the empty string.
185
+
186
+ ### Action methods
187
+
188
+ #### `#convert`
189
+
190
+ Inserts marker tag pairs, if specified (see `#markers`), in the source content at the specified end­points, and then replaces the content corresponding to the original endpoints (whether or not bounded by marker tag pairs) with the `#replacement_content`, then ensures that the resulting HTML is valid and well-formed. If no `#markers` were specified, removes them from the resulting HTML before assigning it to the `converted_content` attribute.
191
+
192
+ If the conversion was successful in all respects, returns `true`; else returns `false` and sets internal `errors` describing the failure which aborted the conversion.
193
+
194
+ ### Query methods
195
+
196
+ #### `#converted_content`
197
+
198
+ Returns the product of the `#convert` method if that was successful, or `:failed_conversion` if it was not. Will also return `:failed_conversion` if not all prerequisite attributes (for content, endpoints, and replacement content) were set before calling `#convert`, or if any of these attributes were set but `#convert` was not called before calling `#converted_content`.
199
+
200
+ #### `#errors`
201
+
202
+ Returns a Hash-like object whose keys are attribute symbols (`:content`, `:endpoints`, `:replacement`), or the additional key `:conversion`, and whose values are an Array of simple strings identifying an error condition.
203
+
204
+ If the instance is valid, and no error condition has yet been triggered, then this method will return an empty Hash-like instance.
205
+
206
+ **Important Note:** Even though only one possible value for each key has yet been identified, that may change in future; with that in mind, the value associated with each key will always be an Array.
207
+
208
+ The keys and values for the Hash are enumerated below:
209
+
210
+ | Key | Value |
211
+ | -------------- | ------------------------ |
212
+ | `:conversion` | `['not called']` |
213
+ | `:content` | `['invalid HTML']` |
214
+ | `:endpoints` | `['force invalid HTML']` |
215
+ | `:replacement` | `['invalidates HTML']` |
216
+
217
+
218
+
219
+ #### `#valid?`
220
+
221
+ Returns `true` if no attributes have been modified since a successful call to `#convert`. If no call to `#convert` has yet been made, regardless of attribute state, returns `false`.
222
+
223
+ ## Development
224
+
225
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
226
+
227
+ To install this gem onto your local machine, run `rake install`. *If you are a maintainer with write access to this repository,* to release a new version, update the version number in `version.rb`, and then run `rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). *Non-maintainers must not run this command*, and attempting to do so will fail.
228
+
229
+ ## Contributing
230
+
231
+ Bug reports and pull requests are welcome on GitHub at https://github.com/TheProlog/prolog-services-markdown_to_html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
232
+
233
+ ## License
234
+
235
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
236
+
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ require 'rake/tasklib'
6
+ require 'flay_task'
7
+ require 'flog'
8
+ require 'flog_task'
9
+ require 'reek/rake/task'
10
+ require 'rubocop/rake_task'
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << "test"
14
+ t.libs << "lib"
15
+ t.test_files = FileList['test/**/*_test.rb']
16
+ end
17
+
18
+ RuboCop::RakeTask.new(:rubocop) do |task|
19
+ task.patterns = [
20
+ 'lib/**/*.rb',
21
+ 'test/**/*.rb'
22
+ ]
23
+ task.formatters = ['simple', 'd']
24
+ task.fail_on_error = true
25
+ # task.options << '--rails'
26
+ task.options << '--display-cop-names'
27
+ end
28
+
29
+ Reek::Rake::Task.new do |t|
30
+ t.config_file = 'config.reek'
31
+ t.source_files = '{app,lib,test}/**/*.rb'
32
+ t.reek_opts = '--sort-by smelliness -s'
33
+ end
34
+
35
+ FlayTask.new do |t|
36
+ t.verbose = true
37
+ t.dirs = %w(app lib)
38
+ end
39
+
40
+ FlogTask.new do |t|
41
+ t.verbose = true
42
+ t.threshold = 200 # default is 200
43
+ t.instance_variable_set :@methods_only, true
44
+ t.dirs = %w(app lib) # Look, Ma; no tests! Run the tool manually every so often for those.
45
+ end
46
+
47
+ task(:default).clear
48
+ task default: [:test, :rubocop, :flay, :flog, :reek]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "prolog/services/replace_content"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+ find ~/.cabal/bin/pandoc 2>&1 >/dev/null && exit 0
3
+ # Not there; build it
4
+ mkdir /tmp/$$
5
+ pushd /tmp/$$
6
+ wget https://github.com/jgm/pandoc/archive/1.17.0.3.tar.gz
7
+ mv 1.17.0.3.tar.gz pandoc-1.17.0.3.tar.gz
8
+ tar zxf pandoc-1.17.0.3.tar.gz
9
+ rm pandoc-1.17.0.3.tar.gz
10
+ cabal update
11
+ cabal install --user pandoc regex-posix regex-compat
12
+ export PATH=~/.cabal/bin:$PATH
13
+ echo Leaving `pwd`
14
+ popd
data/bin/setup ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ gem install nokogiri -- --use-system-libraries --with-xml2-config=/usr/bin/xml2-config --with-xslt-config=/usr/bin/xslt-config
7
+ gem install bundler flay flog reek rubocop pry-byebug simplecov awesome_print codeclimate-test-reporter minitest-matchers minitest-reporters minitest-tagz pandoc-ruby prolog-services-markdown_to_html semantic_logger
8
+ bundle config build.nokogiri --use-system-libraries
9
+ bundle install
data/config.reek ADDED
@@ -0,0 +1,8 @@
1
+
2
+ LongParameterList:
3
+ max_params: 4 # If it's good enough for Sandi, it's good enough for us.
4
+
5
+ NestedIterators:
6
+ max_allowed_nesting: 2
7
+ ignore_iterators:
8
+ - lambda
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ox'
4
+
5
+ require 'prolog/services/replace_content/splitter/factory'
6
+ require 'prolog/services/replace_content/version'
7
+
8
+ module Prolog
9
+ module Services
10
+ # Replaces content within an HTML string based on endpoints and content.
11
+ # FIXME: Reek thinks this has :reek:TooManyInstanceVariables; cleanup soonn.
12
+ class ReplaceContent
13
+ attr_reader :content, :endpoints, :errors, :markers, :replacement
14
+
15
+ def initialize(content: '', endpoints: (-1..-1), replacement: '')
16
+ @content = content
17
+ @endpoints = endpoints
18
+ @replacement = replacement
19
+ @content_after_conversion = nil
20
+ @errors = {}
21
+ self
22
+ end
23
+
24
+ def convert
25
+ validate
26
+ return false unless valid?
27
+ set_converted_content
28
+ valid?
29
+ end
30
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
31
+
32
+ def converted_content
33
+ errors[:conversion] = ['not called'] unless @content_after_conversion
34
+ @content_after_conversion || :oops
35
+ end
36
+
37
+ # Setting markers also invalidates the conversion.
38
+ def markers=(*params)
39
+ @content_after_conversion = nil
40
+ @markers = Array(params).flatten
41
+ end
42
+
43
+ def valid?
44
+ errors.empty?
45
+ end
46
+
47
+ def self.set_content(obj, content)
48
+ new endpoints: obj.endpoints, replacement: obj.replacement,
49
+ content: content
50
+ end
51
+
52
+ def self.set_endpoints(obj, endpoints)
53
+ new content: obj.content, replacement: obj.replacement,
54
+ endpoints: endpoints
55
+ end
56
+
57
+ def self.set_replacement(obj, replacement)
58
+ new content: obj.content, endpoints: obj.endpoints,
59
+ replacement: replacement
60
+ end
61
+
62
+ private
63
+
64
+ def build_converted_content
65
+ replace_inner_content_in splitter.source
66
+ end
67
+
68
+ def replace_inner_content_in(markup)
69
+ markup.sub(splitter.inner, replacement)
70
+ end
71
+
72
+ def set_converted_content
73
+ html = build_converted_content
74
+ @content_after_conversion = html if validate_markup(html, :replacement)
75
+ @content_after_conversion
76
+ end
77
+
78
+ def parse_with_comments
79
+ comment = '<!-- -->'
80
+ twiddled = splitter(comment).source
81
+ ret = Ox.parse twiddled # raises on most errors
82
+ ret
83
+ end
84
+
85
+ def splitter(marker = Splitter::Symmetric::DEFAULT_MARKER)
86
+ ret = Splitter::Factory.call(self, marker)
87
+ ret
88
+ end
89
+
90
+ def validate
91
+ validate_content && validate_endpoints
92
+ end
93
+
94
+ def validate_content
95
+ validate_markup @content, :content
96
+ end
97
+
98
+ def validate_markup(markup, error_key)
99
+ Ox.parse markup
100
+ true
101
+ rescue Ox::ParseError
102
+ errors[error_key] = ['invalid']
103
+ false
104
+ end
105
+
106
+ def _invalidate_endpoints
107
+ errors[:endpoints] = %w(invalid)
108
+ false
109
+ end
110
+
111
+ def validate_endpoints
112
+ parse_with_comments
113
+ true
114
+ rescue Ox::ParseError
115
+ _invalidate_endpoints
116
+ rescue RangeError
117
+ _invalidate_endpoints
118
+ end
119
+ end # class Prolog::Services::ReplaceContent
120
+ end
121
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './paired'
4
+ require_relative './symmetric'
5
+ require_relative './splitter_params'
6
+ require_relative './paired_params'
7
+ require_relative './symmetric_params'
8
+
9
+ module Prolog
10
+ module Services
11
+ # Replaces content within an HTML string based on endpoints and content.
12
+ class ReplaceContent
13
+ module Splitter
14
+ # Should we use a symmetric or paired (identifier) splitter?
15
+ class Factory
16
+ # Methods independent of any instance state.
17
+ module Internals
18
+ def self.splitter_with_markers(data)
19
+ Paired.new _splitter_marker_params(data)
20
+ end
21
+
22
+ def self.symmetric_splitter(data, marker)
23
+ Symmetric.new _symmetric_marker_params(data, marker)
24
+ end
25
+
26
+ def self._build_splitter_marker_params(data)
27
+ markers = data.markers
28
+ identifier = _splitter_identifier_from markers
29
+ [data.content, data.endpoints, markers[0], identifier]
30
+ end
31
+
32
+ def self._splitter_identifier_from(markers)
33
+ markers[1] || Paired::DEFAULT_ID
34
+ end
35
+
36
+ def self._splitter_marker_params(data)
37
+ params = _build_splitter_marker_params(data)
38
+ PairedSplitterParams.new(*params)
39
+ end
40
+
41
+ def self._symmetric_marker_params(data, marker)
42
+ SymmetricSplitterParams.new data.content, data.endpoints, marker
43
+ end
44
+ end # module Internals
45
+ private_constant :Internals
46
+
47
+ def self.call(data, marker)
48
+ return Internals.splitter_with_markers(data) if data.markers
49
+ Internals.symmetric_splitter data, marker
50
+ end
51
+ end # class Prolog::Services::ReplaceContent::Splitter::Factory
52
+ end
53
+ end # class Prolog::Services::ReplaceContent
54
+ end
55
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prolog
4
+ module Services
5
+ # Replaces content within an HTML string based on endpoints and content.
6
+ class ReplaceContent
7
+ module Splitter
8
+ # A "paired" splitter inserts an empty pair of HTML tags before the
9
+ # selected content, and another such empty tag pair afterwards. The tag
10
+ # pairs each have an ID attribute string which ends in '-begin' for the
11
+ # tag pair before the selection, and '-end' for the tag pair after the
12
+ # content. The default for the tag is the anchor tag (:a), though that
13
+ # may be changed by specifying a synbolic `tag` parameter (such as
14
+ # :span). The default text before the '-begin'/'-end' text in the ID
15
+ # attribute strings is 'selection'; that may similary be changed by
16
+ # specifying the `identifier` parameter to the initialiser.
17
+ class Paired
18
+ DEFAULT_ID = 'selection'
19
+
20
+ def initialize(content:, endpoints:, tag: :a, identifier: DEFAULT_ID)
21
+ @content = content
22
+ @endpoints = endpoints
23
+ @identifier = identifier
24
+ @tag = tag
25
+ self
26
+ end
27
+
28
+ def inner
29
+ content[endpoints]
30
+ end
31
+
32
+ def source
33
+ parts.join
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :content, :endpoints, :identifier, :tag
39
+
40
+ def leading_content
41
+ content[0...endpoints.begin]
42
+ end
43
+
44
+ def trailing_content
45
+ content[endpoints.end..-1]
46
+ end
47
+
48
+ def leading_marker
49
+ marker :begin
50
+ end
51
+
52
+ def trailing_marker
53
+ marker :end
54
+ end
55
+
56
+ def marker(which_end)
57
+ format_str = %(<%s id="%s-%s"></%s>)
58
+ format format_str, tag, identifier, which_end, tag
59
+ end
60
+
61
+ def parts
62
+ [leading_content, leading_marker, inner, trailing_marker,
63
+ trailing_content]
64
+ end
65
+ end # class Prolog::Services::ReplaceContent::Splitter::Paired
66
+ end
67
+ end # class Prolog::Services::ReplaceContent
68
+ end
69
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # frozen_string_literal: true
3
+ require_relative './splitter_params'
4
+
5
+ module Prolog
6
+ module Services
7
+ # Replaces content within an HTML string based on endpoints and content.
8
+ class ReplaceContent
9
+ module Splitter
10
+ # Builds splitter params for symmetric splitter; same marker text before
11
+ # and after selected content.
12
+ class PairedSplitterParams < SplitterParams
13
+ def initialize(content, endpoints, tag, identifier)
14
+ super content, endpoints
15
+ add(tag: tag, identifier: identifier)
16
+ self
17
+ end
18
+ end # class ...::ReplaceContent::Splitter::PairedSplitterParams
19
+ end
20
+ end # class Prolog::Services::ReplaceContent::SplitterParams
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+
2
+ # frozen_string_literal: true
3
+ module Prolog
4
+ module Services
5
+ # Replaces content within an HTML string based on endpoints and content.
6
+ class ReplaceContent
7
+ module Splitter
8
+ # Simple class to move splitter parameter munging out of ReplaceContent.
9
+ class SplitterParams
10
+ def initialize(content, endpoints)
11
+ @params = { content: content, endpoints: endpoints }
12
+ self
13
+ end
14
+
15
+ def add(**extra_params)
16
+ @params.merge! extra_params
17
+ self
18
+ end
19
+
20
+ def to_hash
21
+ @params
22
+ end
23
+ end # class Prolog::Services::ReplaceContent::Splitter::SplitterParams
24
+ end
25
+ end # class Prolog::Services::ReplaceContent::SplitterParams
26
+ end
27
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prolog
4
+ module Services
5
+ # Replaces content within an HTML string based on endpoints and content.
6
+ class ReplaceContent
7
+ module Splitter
8
+ # A "symmetric" splitter inserts the same marker text before and after
9
+ # the selected range. This defaults to an empty string, but can be any
10
+ # simple string.
11
+ class Symmetric
12
+ DEFAULT_MARKER = ''
13
+
14
+ attr_reader :inner, :source
15
+
16
+ # Methods neither affecting nor affected by instance state.
17
+ module Internals
18
+ def self.build_inner(content, endpoints, marker)
19
+ [marker, marker].join content[endpoints]
20
+ end
21
+ end
22
+ private_constant :Internals
23
+
24
+ # Simplemindedly splits content string based on endpoints, returning
25
+ # bounding segments (not including substring *within* endpoints).
26
+ # Nobody should care what the marker actually is; just that it wrapps
27
+ # the `inner` value and makes the combination unique within the
28
+ # content.
29
+ class Parts
30
+ def self.parts(content, endpoints)
31
+ _twiddle(_split(content.dup, endpoints))
32
+ end
33
+
34
+ def self._marker
35
+ 'z|q|x' * 8
36
+ end
37
+
38
+ def self._split(working, endpoints)
39
+ marker = _marker
40
+ working[endpoints] = marker
41
+ working.split marker
42
+ end
43
+
44
+ def self._twiddle(items)
45
+ return ['', ''] if items.empty?
46
+ items
47
+ end
48
+ end # class Prolog::Services::ReplaceContent::ContentSplitter::Parts
49
+
50
+ def initialize(content:, endpoints:, marker: DEFAULT_MARKER)
51
+ @inner = Internals.build_inner(content, endpoints, marker)
52
+ @source = rebuild_source(content, endpoints)
53
+ self
54
+ end
55
+
56
+ private
57
+
58
+ def rebuild_source(content, endpoints)
59
+ Parts.parts(content, endpoints).join inner
60
+ end
61
+ end # class Prolog::Services::ReplaceContent::Splitter::Symmetric
62
+ end
63
+ end # class Prolog::Services::ReplaceContent
64
+ end
65
+ end
@@ -0,0 +1,23 @@
1
+
2
+
3
+ # frozen_string_literal: true
4
+ require_relative './splitter_params'
5
+
6
+ module Prolog
7
+ module Services
8
+ # Replaces content within an HTML string based on endpoints and content.
9
+ class ReplaceContent
10
+ module Splitter
11
+ # Builds splitter params for symmetric splitter; same marker text before
12
+ # and after selected content.
13
+ class SymmetricSplitterParams < SplitterParams
14
+ def initialize(content, endpoints, marker)
15
+ super content, endpoints
16
+ add(marker: marker)
17
+ self
18
+ end
19
+ end # class ...::ReplaceContent::Splitter::SymmetricSplitterParams
20
+ end
21
+ end # class Prolog::Services::ReplaceContent::SplitterParams
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prolog
4
+ module Services
5
+ # Replaces content within an HTML string based on endpoints and content.
6
+ class ReplaceContent
7
+ VERSION = '0.1.2'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,53 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'prolog/services/replace_content/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'prolog-services-replace_content'
8
+ spec.version = Prolog::Services::ReplaceContent::VERSION
9
+ spec.authors = ['Jeff Dickey']
10
+ spec.email = ['jdickey@seven-sigma.com']
11
+
12
+ spec.summary = %q{Replaces HTML within a specified range with HTML replacement content.}
13
+ # TOODOO should be an obvious typo; added to silence CodeClimate scan.
14
+ # spec.description = %q{TOODOO: Write a longer description or delete this line.}
15
+ spec.homepage = 'https://github.com/TheProlog/prolog-services-replace_content'
16
+ spec.license = 'MIT'
17
+
18
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
19
+ # delete this section to allow pushing this gem to any host.
20
+ # if spec.respond_to?(:metadata)
21
+ # spec.metadata['allowed_push_host'] = 'TOODOO: Set to 'http://mygemserver.com''
22
+ # else
23
+ # raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
24
+ # end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ # spec.add_dependency 'pandoc-ruby', '~> 2'
32
+ # spec.add_dependency 'prolog-services-markdown_to_html', '~> 1.0'
33
+ spec.add_dependency 'semantic_logger', '~> 3.2'
34
+ spec.add_dependency 'ox', '~> 2.3'
35
+
36
+ spec.add_development_dependency 'bundler', '~> 1.11'
37
+ spec.add_development_dependency 'rake', '~> 11'
38
+ spec.add_development_dependency 'minitest', '~> 5.0'
39
+
40
+ spec.add_development_dependency "minitest-matchers", "~> 1.4"
41
+ spec.add_development_dependency "minitest-reporters", "~> 1.0"
42
+ spec.add_development_dependency "minitest-tagz", "~> 1.2"
43
+ spec.add_development_dependency "flay", "~> 2.6"
44
+ spec.add_development_dependency "flog", "~> 4.3", ">= 4.3.2"
45
+ spec.add_development_dependency "reek", "~> 4.0"
46
+ spec.add_development_dependency "rubocop", "0.39.0"
47
+ spec.add_development_dependency "simplecov", "~> 0.10"
48
+ spec.add_development_dependency "pry-byebug", "~> 3.2"
49
+ spec.add_development_dependency "pry-doc", "~> 0.8"
50
+ spec.add_development_dependency "colorize", "~> 0.7", ">= 0.7.7"
51
+ spec.add_development_dependency "awesome_print", "~> 1.6", ">= 1.6.1"
52
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 0.5"
53
+ end
metadata ADDED
@@ -0,0 +1,338 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prolog-services-replace_content
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Dickey
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: semantic_logger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ox
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-matchers
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.4'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-reporters
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: minitest-tagz
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: flay
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.6'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.6'
139
+ - !ruby/object:Gem::Dependency
140
+ name: flog
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '4.3'
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 4.3.2
149
+ type: :development
150
+ prerelease: false
151
+ version_requirements: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '4.3'
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 4.3.2
159
+ - !ruby/object:Gem::Dependency
160
+ name: reek
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '4.0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '4.0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rubocop
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '='
178
+ - !ruby/object:Gem::Version
179
+ version: 0.39.0
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - '='
185
+ - !ruby/object:Gem::Version
186
+ version: 0.39.0
187
+ - !ruby/object:Gem::Dependency
188
+ name: simplecov
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '0.10'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '0.10'
201
+ - !ruby/object:Gem::Dependency
202
+ name: pry-byebug
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '3.2'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '3.2'
215
+ - !ruby/object:Gem::Dependency
216
+ name: pry-doc
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '0.8'
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '0.8'
229
+ - !ruby/object:Gem::Dependency
230
+ name: colorize
231
+ requirement: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - "~>"
234
+ - !ruby/object:Gem::Version
235
+ version: '0.7'
236
+ - - ">="
237
+ - !ruby/object:Gem::Version
238
+ version: 0.7.7
239
+ type: :development
240
+ prerelease: false
241
+ version_requirements: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - "~>"
244
+ - !ruby/object:Gem::Version
245
+ version: '0.7'
246
+ - - ">="
247
+ - !ruby/object:Gem::Version
248
+ version: 0.7.7
249
+ - !ruby/object:Gem::Dependency
250
+ name: awesome_print
251
+ requirement: !ruby/object:Gem::Requirement
252
+ requirements:
253
+ - - "~>"
254
+ - !ruby/object:Gem::Version
255
+ version: '1.6'
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: 1.6.1
259
+ type: :development
260
+ prerelease: false
261
+ version_requirements: !ruby/object:Gem::Requirement
262
+ requirements:
263
+ - - "~>"
264
+ - !ruby/object:Gem::Version
265
+ version: '1.6'
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: 1.6.1
269
+ - !ruby/object:Gem::Dependency
270
+ name: codeclimate-test-reporter
271
+ requirement: !ruby/object:Gem::Requirement
272
+ requirements:
273
+ - - "~>"
274
+ - !ruby/object:Gem::Version
275
+ version: '0.5'
276
+ type: :development
277
+ prerelease: false
278
+ version_requirements: !ruby/object:Gem::Requirement
279
+ requirements:
280
+ - - "~>"
281
+ - !ruby/object:Gem::Version
282
+ version: '0.5'
283
+ description:
284
+ email:
285
+ - jdickey@seven-sigma.com
286
+ executables: []
287
+ extensions: []
288
+ extra_rdoc_files: []
289
+ files:
290
+ - ".codeclimate.yml"
291
+ - ".gitignore"
292
+ - ".rubocop.yml"
293
+ - ".travis.yml"
294
+ - CODE_OF_CONDUCT.md
295
+ - Gemfile
296
+ - LICENSE.txt
297
+ - README.md
298
+ - Rakefile
299
+ - bin/console
300
+ - bin/install-pandoc-from-cabal
301
+ - bin/setup
302
+ - config.reek
303
+ - lib/prolog/services/replace_content.rb
304
+ - lib/prolog/services/replace_content/splitter/factory.rb
305
+ - lib/prolog/services/replace_content/splitter/paired.rb
306
+ - lib/prolog/services/replace_content/splitter/paired_params.rb
307
+ - lib/prolog/services/replace_content/splitter/splitter_params.rb
308
+ - lib/prolog/services/replace_content/splitter/symmetric.rb
309
+ - lib/prolog/services/replace_content/splitter/symmetric_params.rb
310
+ - lib/prolog/services/replace_content/version.rb
311
+ - log/.keep
312
+ - prolog-services-replace_content.gemspec
313
+ homepage: https://github.com/TheProlog/prolog-services-replace_content
314
+ licenses:
315
+ - MIT
316
+ metadata: {}
317
+ post_install_message:
318
+ rdoc_options: []
319
+ require_paths:
320
+ - lib
321
+ required_ruby_version: !ruby/object:Gem::Requirement
322
+ requirements:
323
+ - - ">="
324
+ - !ruby/object:Gem::Version
325
+ version: '0'
326
+ required_rubygems_version: !ruby/object:Gem::Requirement
327
+ requirements:
328
+ - - ">="
329
+ - !ruby/object:Gem::Version
330
+ version: '0'
331
+ requirements: []
332
+ rubyforge_project:
333
+ rubygems_version: 2.6.3
334
+ signing_key:
335
+ specification_version: 4
336
+ summary: Replaces HTML within a specified range with HTML replacement content.
337
+ test_files: []
338
+ has_rdoc: