berns 1.3.0 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
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