berns 1.3.0 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d86db169c443fbe77f5f22560d9e5dabec886e9dc4092258d0baf124a0d1cc0
4
- data.tar.gz: 11c1d828b8f26628dd813fdd3df8cd39a0e42e83b11f5b1df64f87716e8afdb4
3
+ metadata.gz: a8cce0df8142c8a2057ccaebe098b64e250c11d57ec2c1a6ddaa90a965b8d9d1
4
+ data.tar.gz: 367bc79f457574800fd20ec28a51a8a81fe8c45cfaa05bf94c4b47cdfdeac3ba
5
5
  SHA512:
6
- metadata.gz: a5d58daef750ba78d776c8ce34bc5ddcdb90701718b8f6110871363c05926219c60dddfbc1eba14a6decf5f2645b6c75f9a3d9f014b8c024a831e8fa13997b2e
7
- data.tar.gz: e184ef843bb995eaf0008c551e7f7d7bf86906d0c6a51f9f7b1c7ff7a4af1bea1c28cc2fde5e88c01d367cb6ec4e9d717d70ae0d8618331f3c6e479d48890c5d
6
+ metadata.gz: 9535d2513301b4b1a03eb0dd1105bdef5dc39b849c6964a5f79d218f695c7cfc40377147ef3262fc58290626b99b4d119698ae39812e37356a36315a0f3e95ab
7
+ data.tar.gz: 48ee25901e3d204953472b4a9e1e4e1193c71dee33711e5a8160bdcd8e9322cdfde7721f15bcc50f0b4cea03d254130c44a55a03920ec389bb2c04638e84c18b
data/.editorconfig ADDED
@@ -0,0 +1,20 @@
1
+ # http://EditorConfig.org
2
+ # This is the top most config file.
3
+ root = true
4
+
5
+ # All files
6
+ [*]
7
+
8
+ # Unix-style newlines with a newline ending every file
9
+ end_of_line = lf
10
+ insert_final_newline = true
11
+
12
+ # Character set
13
+ charset = utf-8
14
+
15
+ # Trim extra whitespace.
16
+ trim_trailing_whitespace = true
17
+
18
+ # Soft tabs and 2 spaces.
19
+ indent_style = space
20
+ indent_size = 2
@@ -0,0 +1,24 @@
1
+ name: Ruby
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ os: [ubuntu-latest, macos-latest]
11
+ ruby-version: ['3.0', 2.7, 2.6, 2.5]
12
+
13
+ runs-on: ${{ matrix.os }}
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+
17
+ - name: Set up Ruby ${{ matrix.ruby-version }}
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ bundler-cache: true
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+
23
+ - name: Run tests & lint
24
+ run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rubocop.yml ADDED
@@ -0,0 +1,58 @@
1
+ # http://rubocop.readthedocs.io
2
+ # https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
3
+ require:
4
+ - rubocop-minitest
5
+ - rubocop-performance
6
+ - rubocop-rake
7
+
8
+ AllCops:
9
+ DisplayCopNames: true
10
+ DisplayStyleGuide: true
11
+ ExtraDetails: true
12
+ NewCops: enable
13
+ TargetRubyVersion: 2.5
14
+
15
+ Layout/ParameterAlignment:
16
+ EnforcedStyle: with_fixed_indentation
17
+
18
+ Layout/EmptyLineAfterMagicComment:
19
+ Enabled: false
20
+
21
+ Layout/FirstHashElementIndentation:
22
+ EnforcedStyle: consistent
23
+
24
+ Layout/MultilineOperationIndentation:
25
+ EnforcedStyle: indented
26
+
27
+ Layout/SpaceInsideStringInterpolation:
28
+ EnforcedStyle: space
29
+
30
+ Layout/LineLength:
31
+ Enabled: false
32
+
33
+ Metrics/AbcSize:
34
+ Enabled: false
35
+
36
+ Metrics/BlockLength:
37
+ Enabled: false
38
+
39
+ Metrics/ClassLength:
40
+ Enabled: false
41
+
42
+ Metrics/CyclomaticComplexity:
43
+ Enabled: false
44
+
45
+ Metrics/MethodLength:
46
+ Enabled: false
47
+
48
+ Metrics/ModuleLength:
49
+ Enabled: false
50
+
51
+ Metrics/PerceivedComplexity:
52
+ Enabled: false
53
+
54
+ Style/IfUnlessModifier:
55
+ Enabled: false
56
+
57
+ Style/Next:
58
+ MinBodyLength: 8
data/CHANGELOG.org ADDED
@@ -0,0 +1,142 @@
1
+ * Berns Changelog
2
+
3
+ ** 3.0.3
4
+
5
+ Fix a buffer overflow error.
6
+
7
+ ** 3.0.2
8
+
9
+ Ensure all returned strings are UTF-8 encoded.
10
+
11
+ ** 3.0.1
12
+
13
+ Fix a regression when content blocks are nil. They should be treated the same as
14
+ if they are not there instead of throwing an error.
15
+
16
+ ** 3.0.0
17
+
18
+ Version 3.0 is another mostly API-compatible refactor of Berns, this time in
19
+ blazing fast C! I debated simply calling this version 2.1.0 but because it's a
20
+ complete rewrite it didn't seem right to do a simple point release and there may
21
+ be corner cases that I've not accounted for in this new C-backed version.
22
+
23
+ Running the same benchmarks as from 2.0 but pitting 2.0 against 3.0 yields some
24
+ great speed improvements, particularly for the =empty= and =simple= cases.
25
+
26
+ /These benchmarks were performed on a desktop with a AMD Ryzen 5 3600X 6-Core
27
+ Processor running Linux Mint 20.1 and kernel 5.4./
28
+
29
+ Before:
30
+
31
+ #+begin_example
32
+ empty 1.668M (± 0.6%) i/s - 8.356M in 5.011099s
33
+ simple 442.102k (± 1.3%) i/s - 2.214M in 5.008068s
34
+ nested 267.716k (± 0.4%) i/s - 1.357M in 5.068747s
35
+ #+end_example
36
+
37
+ After:
38
+
39
+ #+begin_example
40
+ empty 3.573M (± 1.2%) i/s - 17.881M in 5.005001s
41
+ simple 840.631k (± 0.6%) i/s - 4.253M in 5.059771s
42
+ nested 267.281k (± 0.5%) i/s - 1.347M in 5.037887s
43
+ #+end_example
44
+
45
+ With both empty and simple attributes we see performance effectively double, and
46
+ with nested attributes performance remains more or less the same.
47
+
48
+ This is another set of fairly contrived benchmarks, testing a singleton method,
49
+ =void= call, and =element= call against each other.
50
+
51
+ Before:
52
+
53
+ #+begin_example
54
+ br 3.061M (± 0.8%) i/s - 15.613M in 5.100154s
55
+ void("br") 6.141M (± 1.4%) i/s - 30.990M in 5.047338s
56
+ element("div") 2.789M (± 0.6%) i/s - 14.171M in 5.080626s
57
+ #+end_example
58
+
59
+ After:
60
+
61
+ #+begin_example
62
+ br 8.155M (± 1.0%) i/s - 41.339M in 5.069681s
63
+ void("br") 9.782M (± 1.5%) i/s - 49.096M in 5.020114s
64
+ element("div") 6.769M (± 1.1%) i/s - 33.983M in 5.021362s
65
+ #+end_example
66
+
67
+ Lastly, benchmarking =to_attributes= with the following hash as the only
68
+ argument shows about double the performance with 3.0.
69
+
70
+ #+begin_src ruby
71
+ ATTRS = { this: 'tag', should: 'work', data: { foo: 'bar', bar: { baz: 'foo' } } }.freeze
72
+ #+end_src
73
+
74
+ Before:
75
+
76
+ #+begin_example
77
+ to_attributes 228.829k (± 1.3%) i/s - 1.159M in 5.065714s
78
+ #+end_example
79
+
80
+ After:
81
+
82
+ #+begin_example
83
+ to_attributes 457.387k (± 1.2%) i/s - 2.305M in 5.041036s
84
+ #+end_example
85
+
86
+ ** 2.0.0
87
+
88
+ Version 2.0 is a mostly API-compatible refactor of all of the core
89
+ methods that make up Berns. The goal is to improve performance, mostly
90
+ using mutable strings and inlining variables that were otherwise short
91
+ lived.
92
+
93
+ In addition, the target Ruby version has been raised to 2.5 or later.
94
+ 2.4 has reached its end of life.
95
+
96
+ Running this benchmarking code:
97
+
98
+ #+begin_src ruby
99
+ Benchmark.ips do |x|
100
+ x.report('empty') { Berns.element(:a) { 'Link to something' } }
101
+ x.report('simple') { Berns.element(:a, { href: 'Something', class: 'my-class' }) { 'Link to something' } }
102
+ x.report('nested') { Berns.element(:a, { href: 'Something', class: 'my-class', data: { something: 'Else' } }) { 'Link to something' } }
103
+
104
+ x.compare!
105
+ end
106
+ #+end_src
107
+
108
+ Before:
109
+
110
+ #+begin_example
111
+ empty 993.521k (± 1.7%) i/s - 5.062M in 5.096368s
112
+ simple 340.795k (± 0.4%) i/s - 1.729M in 5.074101s
113
+ nested 215.160k (± 1.0%) i/s - 1.081M in 5.025324s
114
+ #+end_example
115
+
116
+ After:
117
+
118
+ #+begin_example
119
+ empty 1.769M (± 1.9%) i/s - 9.012M in 5.094973s
120
+ simple 441.020k (± 1.0%) i/s - 2.233M in 5.063326s
121
+ nested 280.255k (± 3.0%) i/s - 1.400M in 5.001009s
122
+ #+end_example
123
+
124
+ With empty attributes we see ~ 100% increase in iterations per second,
125
+ with simple attributes we see ~ 30% increase in the same, and with
126
+ nested attributes we see ~ 30% increase as well.
127
+
128
+ ** 1.3.0
129
+
130
+ With version 1.3, nested HTML attributes can be created with nil keys
131
+ and boolean values to produce e.g. "data-foo data-foo-bar='whatever'"
132
+ from =data: { foo: { nil => true, bar: 'whatever' } }=
133
+
134
+ ** 1.2.0 - 1.2.2
135
+
136
+ Starting with version 1.2, Berns will now HTML-escape all attribute
137
+ values using =CGI.escapeHTML=. This should prevent attribute values from
138
+ escaping themselves and injecting HTML into the DOM.
139
+
140
+ ** 1.1.0
141
+
142
+ - Add =#sanitize= method.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ source 'https://rubygems.org'
3
+
4
+ # Specify your gem's dependencies in berns.gemspec
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Taylor Beck
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.org ADDED
@@ -0,0 +1,117 @@
1
+ * Berns
2
+
3
+ [[https://badge.fury.io/rb/berns][https://badge.fury.io/rb/berns.svg]]
4
+
5
+ A utility library for generating HTML strings.
6
+
7
+ ** Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ #+begin_src ruby
12
+ gem 'berns'
13
+ #+end_src
14
+
15
+ And then execute:
16
+
17
+ #+begin_src sh
18
+ bundle
19
+ #+end_src
20
+
21
+ Or install it yourself as:
22
+
23
+ #+begin_src sh
24
+ gem install berns
25
+ #+end_src
26
+
27
+ ** Usage
28
+
29
+ All standard and void HTML elements are defined as methods on Berns, so you can
30
+ create e.g. a link with =Berns.a=. In addition, there are methods to sanitize
31
+ strings i.e. remove HTML from them, convert hashes into a string of HTML
32
+ attributes, and more.
33
+
34
+ *** =void(tag, attributes)=
35
+
36
+ The =void= method generates a void HTML element i.e. one without any content. It
37
+ takes either a symbol or a string and an optional hash of HTML attributes.
38
+
39
+ #+begin_src ruby
40
+ Berns.void('br') # => '<br>'
41
+ Berns.void('br', class: 'br-class') # => '<br class="br-class">'
42
+ #+end_src
43
+
44
+ *** =element(tag, attributes) { content }=
45
+
46
+ The =element= method generates a standard HTML element i.e. one with optional
47
+ content. It takes either a symbol or a string, an optional hash of HTML
48
+ attributes, and an optional block of content. If provided, the block should
49
+ return a string.
50
+
51
+ #+begin_src ruby
52
+ Berns.element('div') # => '<div></div>'
53
+ Berns.element('div', class: 'div-class') # => '<div class="div-class"></div>'
54
+ Berns.element('div', class: 'div-class') { 'Content' } # => '<div class="div-class">Content</div>'
55
+ #+end_src
56
+
57
+ *** =to_attribute(attribute, value)=
58
+
59
+ The =to_attribute= method generates an HTML attribute string. If the value is a
60
+ hash then the attribute is treated as a prefix.
61
+
62
+ #+begin_src ruby
63
+ Berns.to_attribute('class', 'my-class another-class') # => 'class="my-class another-class"'
64
+ Berns.to_attribute('data', { foo: 'bar' }) # => 'data-foo="bar"'
65
+ #+end_src
66
+
67
+ All attribute values are HTML-escaped using =CGI.escapeHTML=.
68
+
69
+ *** =to_attributes(attributes)=
70
+
71
+ The =to_attributes= method generates an HTML attribute string from a hash by
72
+ calling =to_attribute= for each key/value pair.
73
+
74
+ #+begin_src ruby
75
+ Berns.to_attributes({ 'data' => { foo: 'bar' }, 'class' => 'my-class another-class' }) # => 'data-foo="bar" class="my-class another-class"'
76
+ #+end_src
77
+
78
+ *** =escape_html(string)=
79
+
80
+ The =escape_html= method is a passthrough to =CGI.escapeHTML= and does what it
81
+ says on the tin.
82
+
83
+ #+begin_src ruby
84
+ Berns.escape_html('<"tag"') # => '&lt;&quot;tag&quot;'
85
+ #+end_src
86
+
87
+ *** =sanitize(string)=
88
+
89
+ The =sanitize= method strips HTML tags from strings.
90
+
91
+ #+begin_src ruby
92
+ Berns.sanitize('This <span>should be clean</span>') # => 'This should be clean'
93
+ #+end_src
94
+
95
+ *** Standard and void elements
96
+
97
+ As mentioned above, all standard and void HTML elements are defined as singleton
98
+ methods on the Berns module. Below is the full list of standard elements.
99
+
100
+ #+begin_example
101
+ a abbr address article aside audio b bdi bdo blockquote body button
102
+ canvas caption cite code colgroup datalist dd del details dfn dialog div
103
+ dl dt em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head
104
+ header html i iframe ins kbd label legend li main map mark menu meter nav
105
+ noscript object ol optgroup option output p picture pre progress q rp rt
106
+ ruby s samp script section select small span strong style sub summary
107
+ table tbody td template textarea tfoot th thead time title tr u ul var
108
+ video
109
+ #+end_example
110
+
111
+
112
+ Below is the full list of void elements that are defined as singleton methods on
113
+ Berns.
114
+
115
+ #+begin_example
116
+ area base br col embed hr img input link menuitem meta param source track wbr
117
+ #+end_example
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/extensiontask'
4
+ require 'rake/testtask'
5
+ require 'rubocop/rake_task'
6
+
7
+ Rake::ExtensionTask.new 'berns' do |ext|
8
+ ext.lib_dir = 'lib/berns'
9
+ end
10
+
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.deps = :compile
13
+ t.libs << 'test'
14
+ t.libs << 'lib'
15
+ t.test_files = FileList['test/**/*_test.rb']
16
+ end
17
+
18
+ RuboCop::RakeTask.new
19
+
20
+ task default: %i[test rubocop]
data/berns.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'lib/berns/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'berns'
6
+ spec.version = Berns::VERSION
7
+ spec.authors = ['Taylor Beck', 'Evan Lecklider']
8
+ spec.email = ['beck.taylorg@gmail.com', 'evan@lecklider.com']
9
+
10
+ spec.summary = 'A utility library for generating HTML strings.'
11
+ spec.description = 'A utility library for generating HTML strings.'
12
+ spec.homepage = 'https://github.com/evanleck/berns'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
15
+
16
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
18
+ end
19
+
20
+ spec.require_paths = ['lib']
21
+ spec.extensions = %w[ext/berns/extconf.rb]
22
+
23
+ spec.metadata = {
24
+ 'bug_tracker_uri' => 'https://github.com/evanleck/berns/issues',
25
+ 'source_code_uri' => 'https://github.com/evanleck/berns'
26
+ }
27
+
28
+ spec.add_dependency 'cgi'
29
+
30
+ spec.add_development_dependency 'bundler'
31
+ spec.add_development_dependency 'minitest'
32
+ spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'rake-compiler'
34
+ spec.add_development_dependency 'rubocop'
35
+ spec.add_development_dependency 'rubocop-minitest'
36
+ spec.add_development_dependency 'rubocop-performance'
37
+ spec.add_development_dependency 'rubocop-rake'
38
+ end