cloudcannon-jekyll-bookshop 2.6.1 → 3.0.0.pre.beta.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -8
- data/cloudcannon-jekyll-bookshop.gemspec +1 -9
- data/lib/cloudcannon-jekyll-bookshop/version.rb +1 -1
- data/lib/cloudcannon-jekyll-bookshop.rb +4 -13
- metadata +6 -145
- data/Gemfile.lock +0 -120
- data/Rakefile +0 -16
- data/lib/cloudcannon-jekyll-bookshop/output-site-data.rb +0 -34
- data/lib/cloudcannon-jekyll-bookshop/page-without-a-file.rb +0 -10
- data/lib/cloudcannon-jekyll-bookshop/structures.rb +0 -145
- data/lib/cloudcannon-jekyll-bookshop/tags/live-tag.rb +0 -44
- data/node_modules/@bookshop/cloudcannon-structures/main.js +0 -158
- data/node_modules/@bookshop/cloudcannon-structures/package.json +0 -29
- data/node_modules/@bookshop/cloudcannon-structures/vendored-pluralize.js +0 -503
- data/node_modules/@bookshop/toml-narrator/main.js +0 -27
- data/node_modules/@bookshop/toml-narrator/package.json +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1777349970effc2e949a49e90e993b622ecfc1cfb8fc467c135864b00ec189f
|
4
|
+
data.tar.gz: e3a51439059221284c0fe0c9a84279155a37e985d60127270fcf50bd7288a878
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 747b434c119aae9ffc8d3355eeaa020d6b00d762c1d169678874d3e1d806fea90b6ab05afc82a2fb58723365dff86c945937a1040028f0e3a8c3206219620ab0
|
7
|
+
data.tar.gz: 69621b4521a71c06f3fb32c777438202aacdd8c7c0800ef1c2d66f97e1ac3516fcbea7f0691e1d26a65dc3ba19c74d23ba503e770f55b45da8226915ed98a4de
|
data/Gemfile
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Liam Bigelow"]
|
9
9
|
spec.email = ["liam@cloudcannon.com"]
|
10
10
|
spec.homepage = "https://github.com/cloudcannon/bookshop"
|
11
|
-
spec.summary = "
|
11
|
+
spec.summary = "REMOVED: See the https://github.com/cloudcannon/bookshop migration guides"
|
12
12
|
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
14
|
|
@@ -19,12 +19,4 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
spec.license = "MIT"
|
22
|
-
|
23
|
-
spec.add_dependency "jekyll", ">= 3.7", "< 5.0"
|
24
|
-
spec.add_dependency "toml-rb", ">= 2.0", "< 3.0"
|
25
|
-
spec.add_dependency "node-runner-temp-fix-windows", ">= 1.0", "< 2.0"
|
26
|
-
spec.add_dependency "dry-inflector", ">= 0.1", "< 1.0"
|
27
|
-
spec.add_development_dependency "cloudcannon-jekyll", ">= 2.0", "< 3.0"
|
28
|
-
spec.add_development_dependency "rubocop", "~> 0.80"
|
29
|
-
spec.add_development_dependency "rubocop-jekyll", "~> 0.11"
|
30
22
|
end
|
@@ -1,16 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require_relative "./cloudcannon-jekyll-bookshop/tags/live-tag"
|
3
|
+
warn "CloudCannon Jekyll Bookshop has been removed in Bookshop 3.0"
|
4
|
+
warn "This functionality is now provided by the npm package @bookshop/generate"
|
5
|
+
warn "See the migration guide at https://github.com/cloudcannon/bookshop"
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
Jekyll::Hooks.register :site, :after_init do |site|
|
11
|
-
CloudCannonJekyllBookshop::Structures.build_structures(site)
|
12
|
-
end
|
13
|
-
|
14
|
-
Jekyll::Hooks.register :site, :post_write do |site|
|
15
|
-
CloudCannonJekyllBookshop::SiteData.output(site)
|
16
|
-
end
|
7
|
+
exit 1
|
metadata
CHANGED
@@ -1,143 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudcannon-jekyll-bookshop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre.beta.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liam Bigelow
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: jekyll
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '3.7'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '5.0'
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '3.7'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '5.0'
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: toml-rb
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - ">="
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '2.0'
|
40
|
-
- - "<"
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: '3.0'
|
43
|
-
type: :runtime
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '2.0'
|
50
|
-
- - "<"
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: '3.0'
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: node-runner-temp-fix-windows
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - ">="
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '1.0'
|
60
|
-
- - "<"
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '2.0'
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '1.0'
|
70
|
-
- - "<"
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: '2.0'
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
|
-
name: dry-inflector
|
75
|
-
requirement: !ruby/object:Gem::Requirement
|
76
|
-
requirements:
|
77
|
-
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: '0.1'
|
80
|
-
- - "<"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.0'
|
83
|
-
type: :runtime
|
84
|
-
prerelease: false
|
85
|
-
version_requirements: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0.1'
|
90
|
-
- - "<"
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: '1.0'
|
93
|
-
- !ruby/object:Gem::Dependency
|
94
|
-
name: cloudcannon-jekyll
|
95
|
-
requirement: !ruby/object:Gem::Requirement
|
96
|
-
requirements:
|
97
|
-
- - ">="
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
version: '2.0'
|
100
|
-
- - "<"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '3.0'
|
103
|
-
type: :development
|
104
|
-
prerelease: false
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - ">="
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '2.0'
|
110
|
-
- - "<"
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: '3.0'
|
113
|
-
- !ruby/object:Gem::Dependency
|
114
|
-
name: rubocop
|
115
|
-
requirement: !ruby/object:Gem::Requirement
|
116
|
-
requirements:
|
117
|
-
- - "~>"
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
version: '0.80'
|
120
|
-
type: :development
|
121
|
-
prerelease: false
|
122
|
-
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
requirements:
|
124
|
-
- - "~>"
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: '0.80'
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: rubocop-jekyll
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
requirements:
|
131
|
-
- - "~>"
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: '0.11'
|
134
|
-
type: :development
|
135
|
-
prerelease: false
|
136
|
-
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
requirements:
|
138
|
-
- - "~>"
|
139
|
-
- !ruby/object:Gem::Version
|
140
|
-
version: '0.11'
|
11
|
+
date: 2022-03-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
141
13
|
description:
|
142
14
|
email:
|
143
15
|
- liam@cloudcannon.com
|
@@ -146,20 +18,9 @@ extensions: []
|
|
146
18
|
extra_rdoc_files: []
|
147
19
|
files:
|
148
20
|
- Gemfile
|
149
|
-
- Gemfile.lock
|
150
|
-
- Rakefile
|
151
21
|
- cloudcannon-jekyll-bookshop.gemspec
|
152
22
|
- lib/cloudcannon-jekyll-bookshop.rb
|
153
|
-
- lib/cloudcannon-jekyll-bookshop/output-site-data.rb
|
154
|
-
- lib/cloudcannon-jekyll-bookshop/page-without-a-file.rb
|
155
|
-
- lib/cloudcannon-jekyll-bookshop/structures.rb
|
156
|
-
- lib/cloudcannon-jekyll-bookshop/tags/live-tag.rb
|
157
23
|
- lib/cloudcannon-jekyll-bookshop/version.rb
|
158
|
-
- node_modules/@bookshop/cloudcannon-structures/main.js
|
159
|
-
- node_modules/@bookshop/cloudcannon-structures/package.json
|
160
|
-
- node_modules/@bookshop/cloudcannon-structures/vendored-pluralize.js
|
161
|
-
- node_modules/@bookshop/toml-narrator/main.js
|
162
|
-
- node_modules/@bookshop/toml-narrator/package.json
|
163
24
|
homepage: https://github.com/cloudcannon/bookshop
|
164
25
|
licenses:
|
165
26
|
- MIT
|
@@ -175,12 +36,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
36
|
version: 2.3.0
|
176
37
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
38
|
requirements:
|
178
|
-
- - "
|
39
|
+
- - ">"
|
179
40
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
41
|
+
version: 1.3.1
|
181
42
|
requirements: []
|
182
43
|
rubygems_version: 3.0.3
|
183
44
|
signing_key:
|
184
45
|
specification_version: 4
|
185
|
-
summary:
|
46
|
+
summary: 'REMOVED: See the https://github.com/cloudcannon/bookshop migration guides'
|
186
47
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
cloudcannon-jekyll-bookshop (2.6.1)
|
5
|
-
dry-inflector (>= 0.1, < 1.0)
|
6
|
-
jekyll (>= 3.7, < 5.0)
|
7
|
-
node-runner-temp-fix-windows (>= 1.0, < 2.0)
|
8
|
-
toml-rb (>= 2.0, < 3.0)
|
9
|
-
|
10
|
-
GEM
|
11
|
-
remote: https://rubygems.org/
|
12
|
-
specs:
|
13
|
-
addressable (2.8.0)
|
14
|
-
public_suffix (>= 2.0.2, < 5.0)
|
15
|
-
ansi (1.5.0)
|
16
|
-
ast (2.4.2)
|
17
|
-
builder (3.2.4)
|
18
|
-
citrus (3.0.2)
|
19
|
-
cloudcannon-jekyll (2.3.1)
|
20
|
-
jekyll (>= 2.4.0, < 5)
|
21
|
-
colorator (1.1.0)
|
22
|
-
concurrent-ruby (1.1.9)
|
23
|
-
dry-inflector (0.2.1)
|
24
|
-
em-websocket (0.5.3)
|
25
|
-
eventmachine (>= 0.12.9)
|
26
|
-
http_parser.rb (~> 0)
|
27
|
-
eventmachine (1.2.7)
|
28
|
-
ffi (1.15.4)
|
29
|
-
forwardable-extended (2.6.0)
|
30
|
-
hashdiff (1.0.1)
|
31
|
-
http_parser.rb (0.8.0)
|
32
|
-
i18n (1.8.11)
|
33
|
-
concurrent-ruby (~> 1.0)
|
34
|
-
jaro_winkler (1.5.4)
|
35
|
-
jekyll (4.2.1)
|
36
|
-
addressable (~> 2.4)
|
37
|
-
colorator (~> 1.0)
|
38
|
-
em-websocket (~> 0.5)
|
39
|
-
i18n (~> 1.0)
|
40
|
-
jekyll-sass-converter (~> 2.0)
|
41
|
-
jekyll-watch (~> 2.0)
|
42
|
-
kramdown (~> 2.3)
|
43
|
-
kramdown-parser-gfm (~> 1.0)
|
44
|
-
liquid (~> 4.0)
|
45
|
-
mercenary (~> 0.4.0)
|
46
|
-
pathutil (~> 0.9)
|
47
|
-
rouge (~> 3.0)
|
48
|
-
safe_yaml (~> 1.0)
|
49
|
-
terminal-table (~> 2.0)
|
50
|
-
jekyll-sass-converter (2.1.0)
|
51
|
-
sassc (> 2.0.1, < 3.0)
|
52
|
-
jekyll-watch (2.2.1)
|
53
|
-
listen (~> 3.0)
|
54
|
-
kramdown (2.3.1)
|
55
|
-
rexml
|
56
|
-
kramdown-parser-gfm (1.1.0)
|
57
|
-
kramdown (~> 2.0)
|
58
|
-
liquid (4.0.3)
|
59
|
-
listen (3.7.0)
|
60
|
-
rb-fsevent (~> 0.10, >= 0.10.3)
|
61
|
-
rb-inotify (~> 0.9, >= 0.9.10)
|
62
|
-
mercenary (0.4.0)
|
63
|
-
minitest (5.14.4)
|
64
|
-
minitest-reporters (1.4.3)
|
65
|
-
ansi
|
66
|
-
builder
|
67
|
-
minitest (>= 5.0)
|
68
|
-
ruby-progressbar
|
69
|
-
node-runner-temp-fix-windows (1.0.1)
|
70
|
-
parallel (1.20.1)
|
71
|
-
parser (3.0.2.0)
|
72
|
-
ast (~> 2.4.1)
|
73
|
-
pathutil (0.16.2)
|
74
|
-
forwardable-extended (~> 2.6)
|
75
|
-
public_suffix (4.0.6)
|
76
|
-
rainbow (3.0.0)
|
77
|
-
rake (13.0.6)
|
78
|
-
rb-fsevent (0.11.0)
|
79
|
-
rb-inotify (0.10.1)
|
80
|
-
ffi (~> 1.0)
|
81
|
-
rexml (3.2.5)
|
82
|
-
rouge (3.26.1)
|
83
|
-
rubocop (0.80.1)
|
84
|
-
jaro_winkler (~> 1.5.1)
|
85
|
-
parallel (~> 1.10)
|
86
|
-
parser (>= 2.7.0.1)
|
87
|
-
rainbow (>= 2.2.2, < 4.0)
|
88
|
-
rexml
|
89
|
-
ruby-progressbar (~> 1.7)
|
90
|
-
unicode-display_width (>= 1.4.0, < 1.7)
|
91
|
-
rubocop-jekyll (0.11.0)
|
92
|
-
rubocop (>= 0.68.0, < 0.81.0)
|
93
|
-
rubocop-performance (~> 1.2)
|
94
|
-
rubocop-performance (1.6.1)
|
95
|
-
rubocop (>= 0.71.0)
|
96
|
-
ruby-progressbar (1.11.0)
|
97
|
-
safe_yaml (1.0.5)
|
98
|
-
sassc (2.4.0)
|
99
|
-
ffi (~> 1.9)
|
100
|
-
terminal-table (2.0.0)
|
101
|
-
unicode-display_width (~> 1.1, >= 1.1.1)
|
102
|
-
toml-rb (2.1.2)
|
103
|
-
citrus (~> 3.0, > 3.0)
|
104
|
-
unicode-display_width (1.6.1)
|
105
|
-
|
106
|
-
PLATFORMS
|
107
|
-
ruby
|
108
|
-
|
109
|
-
DEPENDENCIES
|
110
|
-
cloudcannon-jekyll (>= 2.0, < 3.0)
|
111
|
-
cloudcannon-jekyll-bookshop!
|
112
|
-
hashdiff
|
113
|
-
minitest
|
114
|
-
minitest-reporters
|
115
|
-
rake
|
116
|
-
rubocop
|
117
|
-
rubocop-jekyll (~> 0.11)
|
118
|
-
|
119
|
-
BUNDLED WITH
|
120
|
-
2.1.4
|
data/Rakefile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rake'
|
4
|
-
require 'rake/testtask'
|
5
|
-
|
6
|
-
Rake::TestTask.new do |t|
|
7
|
-
t.libs.push 'lib'
|
8
|
-
t.libs.push 'specs'
|
9
|
-
t.verbose = true
|
10
|
-
t.warning = false
|
11
|
-
t.pattern = "spec/**/*_spec.rb"
|
12
|
-
t.test_files = FileList['spec/**/*_spec.rb']
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Run tests"
|
16
|
-
task :default => [:test]
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "json/ext"
|
4
|
-
require_relative "./page-without-a-file"
|
5
|
-
|
6
|
-
module CloudCannonJekyllBookshop
|
7
|
-
class SiteData
|
8
|
-
def self.output(site)
|
9
|
-
@site = site
|
10
|
-
return unless @site.data["_bookshop_site_data"]
|
11
|
-
|
12
|
-
output_payload = @site.data["_bookshop_site_data"].to_json
|
13
|
-
|
14
|
-
filename = "bookshop-site-data"
|
15
|
-
generate_file(filename, output_payload)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.generate_file(filename, content)
|
19
|
-
dest = destination_json_path(filename)
|
20
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
21
|
-
File.open(dest, "w") { |file| file.write(content) }
|
22
|
-
@site.keep_files ||= []
|
23
|
-
@site.keep_files << json_path(filename)
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.destination_json_path(filename)
|
27
|
-
Jekyll.sanitized_path(@site.dest, json_path(filename))
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.json_path(filename)
|
31
|
-
"_cloudcannon/#{filename}.json"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,145 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pathname"
|
4
|
-
require "toml-rb"
|
5
|
-
require "dry/inflector"
|
6
|
-
require "node-runner"
|
7
|
-
|
8
|
-
module CloudCannonJekyllBookshop
|
9
|
-
# Parses a bookshop and creates CloudCannon CMS structures
|
10
|
-
class Structures
|
11
|
-
def self.get_default_component_name(path)
|
12
|
-
@node_bookshop.NiceLabel(get_component_key(path))
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.get_component_key(path)
|
16
|
-
@node_bookshop.GetComponentKey(path)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.rewrite_bookshop_toml(content)
|
20
|
-
@node_bookshop.RewriteTOML(content)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.parse_bookshop_toml(content)
|
24
|
-
rewritten_content = rewrite_bookshop_toml(content)
|
25
|
-
TomlRB.parse(rewritten_content)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.load_component(path)
|
29
|
-
begin
|
30
|
-
component = parse_bookshop_toml(path)
|
31
|
-
rescue StandardError => e
|
32
|
-
Jekyll.logger.error "Bookshop:",
|
33
|
-
"❌ Error Parsing Story: #{e}"
|
34
|
-
Jekyll.logger.error "",
|
35
|
-
e.message
|
36
|
-
end
|
37
|
-
component
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.transform_component(path, component)
|
41
|
-
transformed_components = @node_bookshop.TransformComponent(path, component)
|
42
|
-
@structure_count += transformed_components.size
|
43
|
-
transformed_components
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.add_structure(hash, component)
|
47
|
-
array_structures = component.delete("structures")
|
48
|
-
array_structures.each do |key|
|
49
|
-
hash[key] ||= {}
|
50
|
-
hash[key]["id_key"] = "_bookshop_name"
|
51
|
-
hash[key]["values"] ||= []
|
52
|
-
hash[key]["values"].push(component)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.build_from_location(base_path, site)
|
57
|
-
site.config["_select_data"] ||= {}
|
58
|
-
site.config["_array_structures"] ||= {}
|
59
|
-
Jekyll.logger.info "Bookshop:",
|
60
|
-
"Parsing Stories from #{base_path}"
|
61
|
-
|
62
|
-
files = Dir.glob("**/*.{bookshop}.{toml,tml,tom,tm}", :base => base_path);
|
63
|
-
|
64
|
-
read_attempts = 0
|
65
|
-
while files.size > 0 && read_attempts < 5
|
66
|
-
processing = files.map(&:clone)
|
67
|
-
files = []
|
68
|
-
threads = []
|
69
|
-
processing.each do |f|
|
70
|
-
threads << Thread.new do
|
71
|
-
begin
|
72
|
-
raw_file = File.read(base_path + "/" + f)
|
73
|
-
component = load_component(raw_file)
|
74
|
-
|
75
|
-
transform_component(f, component).each do |transformed_component|
|
76
|
-
add_structure(site.config["_array_structures"], transformed_component)
|
77
|
-
end
|
78
|
-
rescue
|
79
|
-
Thread.current[:output] = f
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
threads.each do |t|
|
84
|
-
t.join
|
85
|
-
files << t[:output] if t[:output]
|
86
|
-
end
|
87
|
-
Jekyll.logger.info "Bookshop:",
|
88
|
-
"Had trouble reading #{files.size} file(s), retrying" if files.size > 0
|
89
|
-
read_attempts += 1
|
90
|
-
end
|
91
|
-
|
92
|
-
if files.size > 0
|
93
|
-
Jekyll.logger.error "Bookshop:",
|
94
|
-
"❌ Failed to read #{files.size} file(s)"
|
95
|
-
files.each do |f|
|
96
|
-
Jekyll.logger.error "Bookshop:",
|
97
|
-
"❌ Failed to read #{f}"
|
98
|
-
end
|
99
|
-
Jekyll.logger.error "Bookshop:",
|
100
|
-
"❌ Check your TOML files are valid."
|
101
|
-
exit 1
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.setup_helpers
|
106
|
-
@inflector = Dry::Inflector.new
|
107
|
-
@node_bookshop = NodeRunner.new(
|
108
|
-
<<~JAVASCRIPT
|
109
|
-
const {Version: TNVersion, RewriteTOML} = require('#{__dir__}/../../node_modules/@bookshop/toml-narrator');
|
110
|
-
const {Version: CSVersion, TransformComponent, GetComponentKey, NiceLabel} = require('#{__dir__}/../../node_modules/@bookshop/cloudcannon-structures');
|
111
|
-
JAVASCRIPT
|
112
|
-
)
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.tn_version
|
116
|
-
@node_bookshop.TNVersion
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.cs_version
|
120
|
-
@node_bookshop.CSVersion
|
121
|
-
end
|
122
|
-
|
123
|
-
def self.build_structures(site)
|
124
|
-
structure_start = Time.now
|
125
|
-
@structure_count = 0
|
126
|
-
|
127
|
-
setup_helpers
|
128
|
-
|
129
|
-
bookshop_locations = site.config["bookshop_locations"]&.collect do |location|
|
130
|
-
Pathname.new("#{site.source}/#{location}/components").cleanpath.to_s
|
131
|
-
end
|
132
|
-
bookshop_locations = bookshop_locations&.select do |location|
|
133
|
-
Dir.exist?(location)
|
134
|
-
end
|
135
|
-
bookshop_locations&.each do |base_path|
|
136
|
-
build_from_location(base_path, site)
|
137
|
-
end
|
138
|
-
|
139
|
-
elapsed_time = Time.now - structure_start
|
140
|
-
Jekyll.logger.info "Bookshop:",
|
141
|
-
"#{@structure_count} structure#{@structure_count == 1 ? "" : "s"}
|
142
|
-
built in #{elapsed_time.round(2)}s ✅"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CloudCannonJekyllBookshop
|
4
|
-
class LiveTag < Liquid::Tag
|
5
|
-
def initialize(tag_name, markup, tokens)
|
6
|
-
super
|
7
|
-
@script = markup.strip
|
8
|
-
end
|
9
|
-
|
10
|
-
def render(context)
|
11
|
-
site = context.registers[:site]
|
12
|
-
|
13
|
-
"<script>
|
14
|
-
(function(){
|
15
|
-
const bookshopLiveSetup = (CloudCannon) => {
|
16
|
-
CloudCannon.enableEvents();
|
17
|
-
|
18
|
-
const head = document.querySelector('head');
|
19
|
-
const script = document.createElement('script');
|
20
|
-
script.src = `/#{@script}`;
|
21
|
-
script.onload = function() {
|
22
|
-
window.bookshopLive = new window.BookshopLive({
|
23
|
-
remoteGlobals: ['/_cloudcannon/bookshop-site-data.json']
|
24
|
-
});
|
25
|
-
const updateBookshopLive = async () => {
|
26
|
-
const frontMatter = await CloudCannon.value();
|
27
|
-
const options = window.bookshopLiveOptions || {};
|
28
|
-
await window.bookshopLive.update(frontMatter, options);
|
29
|
-
CloudCannon?.refreshInterface?.();
|
30
|
-
}
|
31
|
-
document.addEventListener('cloudcannon:update', updateBookshopLive);
|
32
|
-
updateBookshopLive();
|
33
|
-
}
|
34
|
-
head.appendChild(script);
|
35
|
-
}
|
36
|
-
|
37
|
-
document.addEventListener('cloudcannon:load', function (e) {
|
38
|
-
bookshopLiveSetup(e.detail.CloudCannon);
|
39
|
-
});
|
40
|
-
})();
|
41
|
-
</script>"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,158 +0,0 @@
|
|
1
|
-
var pkg = require('./package.json');
|
2
|
-
// Pluralize is vendored for distribution to the generator plugins
|
3
|
-
const pluralize = require('./vendored-pluralize.js');
|
4
|
-
|
5
|
-
// Generates the bookshop key used to reference this component
|
6
|
-
// Turns "a/b/b.bookshop.toml" into "a/b"
|
7
|
-
const GetComponentKey = (componentPath) => {
|
8
|
-
let base = componentPath.replace(/^.*components\//, '').split(".")[0];
|
9
|
-
let parts = base.split("/");
|
10
|
-
const l = parts.length;
|
11
|
-
if (l >= 2 && parts[l-1] === parts[l-2]) {
|
12
|
-
parts.pop();
|
13
|
-
base = parts.join("/");
|
14
|
-
}
|
15
|
-
return base;
|
16
|
-
}
|
17
|
-
|
18
|
-
const NiceLabel = (key) => {
|
19
|
-
return key.split(/-|_|\//)
|
20
|
-
.filter(part => part.length)
|
21
|
-
.map(part => part[0].toUpperCase() + part.slice(1)).join(" ");
|
22
|
-
}
|
23
|
-
|
24
|
-
// Main function that takes in an entire Bookshop component structure
|
25
|
-
// and returns a set of structures to add to CloudCannon
|
26
|
-
const TransformComponent = (path, component) => {
|
27
|
-
const result = {
|
28
|
-
value: {
|
29
|
-
_bookshop_name: GetComponentKey(path)
|
30
|
-
},
|
31
|
-
label: NiceLabel(GetComponentKey(path)), // Used as a fallback when no label is supplied inside [component]
|
32
|
-
structures: [],
|
33
|
-
...component["component"]
|
34
|
-
}
|
35
|
-
if (component["props"]) {
|
36
|
-
TransformComponentProps(component["props"], result, null);
|
37
|
-
}
|
38
|
-
if (!result["_hidden"] && !result["structures"].includes("bookshop_components")) {
|
39
|
-
result["structures"].push("bookshop_components");
|
40
|
-
}
|
41
|
-
|
42
|
-
const results = [result];
|
43
|
-
|
44
|
-
delete result["_hidden"];
|
45
|
-
delete result["raw_fields"];
|
46
|
-
|
47
|
-
return results;
|
48
|
-
}
|
49
|
-
|
50
|
-
// Recursive function for processing the [props] section of a bookshop component spec,
|
51
|
-
// and populating sub-structures, comments, select data, et cetera.
|
52
|
-
const TransformComponentProps = (props, structure, value_context) => {
|
53
|
-
["_select_data","_array_structures","_comments","_instance_values","value"].forEach(k => {
|
54
|
-
structure[k] = structure[k] || {};
|
55
|
-
});
|
56
|
-
|
57
|
-
value_context = value_context || structure["value"];
|
58
|
-
Object.entries(props).forEach(([key, value]) => {
|
59
|
-
if (Object.hasOwnProperty.call(value_context, key)) return;
|
60
|
-
|
61
|
-
if (Array.isArray(value)) {
|
62
|
-
TransformArray(key, value, structure, value_context);
|
63
|
-
return;
|
64
|
-
}
|
65
|
-
|
66
|
-
if (value && typeof value === "object") {
|
67
|
-
TransformObject(key, value, structure, value_context);
|
68
|
-
return;
|
69
|
-
}
|
70
|
-
|
71
|
-
if (value === true || value === false) {
|
72
|
-
value_context[key] = value;
|
73
|
-
return;
|
74
|
-
}
|
75
|
-
|
76
|
-
if (/--bookshop_comment/.test(key)) {
|
77
|
-
const base_key = key.split(/--bookshop_comment/)[0];
|
78
|
-
if (!base_key.length) return;
|
79
|
-
structure["_comments"][base_key] = value;
|
80
|
-
return;
|
81
|
-
}
|
82
|
-
|
83
|
-
value_context[key] = null;
|
84
|
-
});
|
85
|
-
}
|
86
|
-
|
87
|
-
// Handle an object somewhere within the large props object
|
88
|
-
// If reserved bookshop keys lie within, the object is treated as a value
|
89
|
-
// Otherwise, recurse into it as a normal object
|
90
|
-
const TransformObject = (key, obj, structure, value_context) => {
|
91
|
-
const comment = GetCommentFromObject(obj);
|
92
|
-
if (comment) {
|
93
|
-
structure["_comments"][key] = comment;
|
94
|
-
}
|
95
|
-
|
96
|
-
if (Object.hasOwnProperty.call(obj, "instance")) {
|
97
|
-
value_context[key] = null;
|
98
|
-
structure["_instance_values"][key] = obj["instance"]
|
99
|
-
return
|
100
|
-
}
|
101
|
-
|
102
|
-
if (Object.hasOwnProperty.call(obj, "select")) {
|
103
|
-
value_context[key] = obj["default"] ?? null;
|
104
|
-
structure["_select_data"][pluralize(key)] = obj["select"]
|
105
|
-
return
|
106
|
-
}
|
107
|
-
|
108
|
-
if (Object.hasOwnProperty.call(obj, "preview") || Object.hasOwnProperty.call(obj, "default")) {
|
109
|
-
value_context[key] = obj["default"] ?? null;
|
110
|
-
return
|
111
|
-
}
|
112
|
-
|
113
|
-
value_context[key] = {};
|
114
|
-
TransformComponentProps(obj, structure, value_context[key]);
|
115
|
-
}
|
116
|
-
|
117
|
-
// Handle an array somewhere within the large props object
|
118
|
-
// If it is an object array, create a sub-structure based on the first array item
|
119
|
-
const TransformArray = (key, array, structure, value_context) => {
|
120
|
-
if (array[0] && typeof array[0] === "object") {
|
121
|
-
if (array[0]["--bookshop_comment"]) {
|
122
|
-
structure["_comments"][key] = array[0]["--bookshop_comment"];
|
123
|
-
}
|
124
|
-
|
125
|
-
if (Array.isArray(structure["raw_fields"]) && structure["raw_fields"].includes(key)) {
|
126
|
-
value_context[key] = null;
|
127
|
-
return
|
128
|
-
}
|
129
|
-
|
130
|
-
const singular_title = NiceLabel(pluralize.singular(key));
|
131
|
-
structure["_array_structures"][key] = {
|
132
|
-
values: [{
|
133
|
-
label: singular_title,
|
134
|
-
icon: "add_box",
|
135
|
-
value: {}
|
136
|
-
}]
|
137
|
-
}
|
138
|
-
|
139
|
-
TransformComponentProps(array[0],
|
140
|
-
structure["_array_structures"][key]["values"][0],
|
141
|
-
structure["_array_structures"][key]["values"][0]["value"]);
|
142
|
-
}
|
143
|
-
value_context[key] = [];
|
144
|
-
}
|
145
|
-
|
146
|
-
const GetCommentFromObject = (object) => {
|
147
|
-
return object["--bookshop_comment"]
|
148
|
-
|| object["select--bookshop_comment"]
|
149
|
-
|| object["preview--bookshop_comment"]
|
150
|
-
|| object["default--bookshop_comment"]
|
151
|
-
}
|
152
|
-
|
153
|
-
module.exports = {
|
154
|
-
Version: () => pkg.version,
|
155
|
-
TransformComponent,
|
156
|
-
GetComponentKey,
|
157
|
-
NiceLabel,
|
158
|
-
}
|
@@ -1,29 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"name": "@bookshop/cloudcannon-structures",
|
3
|
-
"packageManager": "yarn@3.0.0",
|
4
|
-
"version": "2.6.1",
|
5
|
-
"description": "Convert a Bookshop object into a CloudCannon structure",
|
6
|
-
"main": "main.js",
|
7
|
-
"scripts": {
|
8
|
-
"test": "nyc ava -v"
|
9
|
-
},
|
10
|
-
"files": [
|
11
|
-
"main.js",
|
12
|
-
"vendored-pluralize.js"
|
13
|
-
],
|
14
|
-
"author": "@bglw",
|
15
|
-
"license": "MIT",
|
16
|
-
"publishConfig": {
|
17
|
-
"access": "public"
|
18
|
-
},
|
19
|
-
"devDependencies": {
|
20
|
-
"@bookshop/toml-narrator": "2.6.1",
|
21
|
-
"@ltd/j-toml": "^1.17.0",
|
22
|
-
"ava": "^3.15.0",
|
23
|
-
"nyc": "^15.1.0",
|
24
|
-
"pluralize": "^8.0.0"
|
25
|
-
},
|
26
|
-
"engines": {
|
27
|
-
"node": ">=14.16"
|
28
|
-
}
|
29
|
-
}
|
@@ -1,503 +0,0 @@
|
|
1
|
-
/* global define */
|
2
|
-
|
3
|
-
(function (root, pluralize) {
|
4
|
-
/* istanbul ignore else */
|
5
|
-
if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
|
6
|
-
// Node.
|
7
|
-
module.exports = pluralize();
|
8
|
-
} else if (typeof define === 'function' && define.amd) {
|
9
|
-
// AMD, registers as an anonymous module.
|
10
|
-
define(function () {
|
11
|
-
return pluralize();
|
12
|
-
});
|
13
|
-
} else {
|
14
|
-
// Browser global.
|
15
|
-
root.pluralize = pluralize();
|
16
|
-
}
|
17
|
-
})(this, function () {
|
18
|
-
// Rule storage - pluralize and singularize need to be run sequentially,
|
19
|
-
// while other rules can be optimized using an object for instant lookups.
|
20
|
-
var pluralRules = [];
|
21
|
-
var singularRules = [];
|
22
|
-
var uncountables = {};
|
23
|
-
var irregularPlurals = {};
|
24
|
-
var irregularSingles = {};
|
25
|
-
|
26
|
-
/**
|
27
|
-
* Sanitize a pluralization rule to a usable regular expression.
|
28
|
-
*
|
29
|
-
* @param {(RegExp|string)} rule
|
30
|
-
* @return {RegExp}
|
31
|
-
*/
|
32
|
-
function sanitizeRule (rule) {
|
33
|
-
if (typeof rule === 'string') {
|
34
|
-
return new RegExp('^' + rule + '$', 'i');
|
35
|
-
}
|
36
|
-
|
37
|
-
return rule;
|
38
|
-
}
|
39
|
-
|
40
|
-
/**
|
41
|
-
* Pass in a word token to produce a function that can replicate the case on
|
42
|
-
* another word.
|
43
|
-
*
|
44
|
-
* @param {string} word
|
45
|
-
* @param {string} token
|
46
|
-
* @return {Function}
|
47
|
-
*/
|
48
|
-
function restoreCase (word, token) {
|
49
|
-
// Tokens are an exact match.
|
50
|
-
if (word === token) return token;
|
51
|
-
|
52
|
-
// Lower cased words. E.g. "hello".
|
53
|
-
if (word === word.toLowerCase()) return token.toLowerCase();
|
54
|
-
|
55
|
-
// Upper cased words. E.g. "WHISKY".
|
56
|
-
if (word === word.toUpperCase()) return token.toUpperCase();
|
57
|
-
|
58
|
-
// Title cased words. E.g. "Title".
|
59
|
-
if (word[0] === word[0].toUpperCase()) {
|
60
|
-
return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
|
61
|
-
}
|
62
|
-
|
63
|
-
// Lower cased words. E.g. "test".
|
64
|
-
return token.toLowerCase();
|
65
|
-
}
|
66
|
-
|
67
|
-
/**
|
68
|
-
* Interpolate a regexp string.
|
69
|
-
*
|
70
|
-
* @param {string} str
|
71
|
-
* @param {Array} args
|
72
|
-
* @return {string}
|
73
|
-
*/
|
74
|
-
function interpolate (str, args) {
|
75
|
-
return str.replace(/\$(\d{1,2})/g, function (match, index) {
|
76
|
-
return args[index] || '';
|
77
|
-
});
|
78
|
-
}
|
79
|
-
|
80
|
-
/**
|
81
|
-
* Replace a word using a rule.
|
82
|
-
*
|
83
|
-
* @param {string} word
|
84
|
-
* @param {Array} rule
|
85
|
-
* @return {string}
|
86
|
-
*/
|
87
|
-
function replace (word, rule) {
|
88
|
-
return word.replace(rule[0], function (match, index) {
|
89
|
-
var result = interpolate(rule[1], arguments);
|
90
|
-
|
91
|
-
if (match === '') {
|
92
|
-
return restoreCase(word[index - 1], result);
|
93
|
-
}
|
94
|
-
|
95
|
-
return restoreCase(match, result);
|
96
|
-
});
|
97
|
-
}
|
98
|
-
|
99
|
-
/**
|
100
|
-
* Sanitize a word by passing in the word and sanitization rules.
|
101
|
-
*
|
102
|
-
* @param {string} token
|
103
|
-
* @param {string} word
|
104
|
-
* @param {Array} rules
|
105
|
-
* @return {string}
|
106
|
-
*/
|
107
|
-
function sanitizeWord (token, word, rules) {
|
108
|
-
// Empty string or doesn't need fixing.
|
109
|
-
if (!token.length || uncountables.hasOwnProperty(token)) {
|
110
|
-
return word;
|
111
|
-
}
|
112
|
-
|
113
|
-
var len = rules.length;
|
114
|
-
|
115
|
-
// Iterate over the sanitization rules and use the first one to match.
|
116
|
-
while (len--) {
|
117
|
-
var rule = rules[len];
|
118
|
-
|
119
|
-
if (rule[0].test(word)) return replace(word, rule);
|
120
|
-
}
|
121
|
-
|
122
|
-
return word;
|
123
|
-
}
|
124
|
-
|
125
|
-
/**
|
126
|
-
* Replace a word with the updated word.
|
127
|
-
*
|
128
|
-
* @param {Object} replaceMap
|
129
|
-
* @param {Object} keepMap
|
130
|
-
* @param {Array} rules
|
131
|
-
* @return {Function}
|
132
|
-
*/
|
133
|
-
function replaceWord (replaceMap, keepMap, rules) {
|
134
|
-
return function (word) {
|
135
|
-
// Get the correct token and case restoration functions.
|
136
|
-
var token = word.toLowerCase();
|
137
|
-
|
138
|
-
// Check against the keep object map.
|
139
|
-
if (keepMap.hasOwnProperty(token)) {
|
140
|
-
return restoreCase(word, token);
|
141
|
-
}
|
142
|
-
|
143
|
-
// Check against the replacement map for a direct word replacement.
|
144
|
-
if (replaceMap.hasOwnProperty(token)) {
|
145
|
-
return restoreCase(word, replaceMap[token]);
|
146
|
-
}
|
147
|
-
|
148
|
-
// Run all the rules against the word.
|
149
|
-
return sanitizeWord(token, word, rules);
|
150
|
-
};
|
151
|
-
}
|
152
|
-
|
153
|
-
/**
|
154
|
-
* Check if a word is part of the map.
|
155
|
-
*/
|
156
|
-
function checkWord (replaceMap, keepMap, rules, bool) {
|
157
|
-
return function (word) {
|
158
|
-
var token = word.toLowerCase();
|
159
|
-
|
160
|
-
if (keepMap.hasOwnProperty(token)) return true;
|
161
|
-
if (replaceMap.hasOwnProperty(token)) return false;
|
162
|
-
|
163
|
-
return sanitizeWord(token, token, rules) === token;
|
164
|
-
};
|
165
|
-
}
|
166
|
-
|
167
|
-
/**
|
168
|
-
* Pluralize or singularize a word based on the passed in count.
|
169
|
-
*
|
170
|
-
* @param {string} word The word to pluralize
|
171
|
-
* @param {number} count How many of the word exist
|
172
|
-
* @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks)
|
173
|
-
* @return {string}
|
174
|
-
*/
|
175
|
-
function pluralize (word, count, inclusive) {
|
176
|
-
var pluralized = count === 1
|
177
|
-
? pluralize.singular(word) : pluralize.plural(word);
|
178
|
-
|
179
|
-
return (inclusive ? count + ' ' : '') + pluralized;
|
180
|
-
}
|
181
|
-
|
182
|
-
/**
|
183
|
-
* Pluralize a word.
|
184
|
-
*
|
185
|
-
* @type {Function}
|
186
|
-
*/
|
187
|
-
pluralize.plural = replaceWord(
|
188
|
-
irregularSingles, irregularPlurals, pluralRules
|
189
|
-
);
|
190
|
-
|
191
|
-
/**
|
192
|
-
* Check if a word is plural.
|
193
|
-
*
|
194
|
-
* @type {Function}
|
195
|
-
*/
|
196
|
-
pluralize.isPlural = checkWord(
|
197
|
-
irregularSingles, irregularPlurals, pluralRules
|
198
|
-
);
|
199
|
-
|
200
|
-
/**
|
201
|
-
* Singularize a word.
|
202
|
-
*
|
203
|
-
* @type {Function}
|
204
|
-
*/
|
205
|
-
pluralize.singular = replaceWord(
|
206
|
-
irregularPlurals, irregularSingles, singularRules
|
207
|
-
);
|
208
|
-
|
209
|
-
/**
|
210
|
-
* Check if a word is singular.
|
211
|
-
*
|
212
|
-
* @type {Function}
|
213
|
-
*/
|
214
|
-
pluralize.isSingular = checkWord(
|
215
|
-
irregularPlurals, irregularSingles, singularRules
|
216
|
-
);
|
217
|
-
|
218
|
-
/**
|
219
|
-
* Add a pluralization rule to the collection.
|
220
|
-
*
|
221
|
-
* @param {(string|RegExp)} rule
|
222
|
-
* @param {string} replacement
|
223
|
-
*/
|
224
|
-
pluralize.addPluralRule = function (rule, replacement) {
|
225
|
-
pluralRules.push([sanitizeRule(rule), replacement]);
|
226
|
-
};
|
227
|
-
|
228
|
-
/**
|
229
|
-
* Add a singularization rule to the collection.
|
230
|
-
*
|
231
|
-
* @param {(string|RegExp)} rule
|
232
|
-
* @param {string} replacement
|
233
|
-
*/
|
234
|
-
pluralize.addSingularRule = function (rule, replacement) {
|
235
|
-
singularRules.push([sanitizeRule(rule), replacement]);
|
236
|
-
};
|
237
|
-
|
238
|
-
/**
|
239
|
-
* Add an uncountable word rule.
|
240
|
-
*
|
241
|
-
* @param {(string|RegExp)} word
|
242
|
-
*/
|
243
|
-
pluralize.addUncountableRule = function (word) {
|
244
|
-
if (typeof word === 'string') {
|
245
|
-
uncountables[word.toLowerCase()] = true;
|
246
|
-
return;
|
247
|
-
}
|
248
|
-
|
249
|
-
// Set singular and plural references for the word.
|
250
|
-
pluralize.addPluralRule(word, '$0');
|
251
|
-
pluralize.addSingularRule(word, '$0');
|
252
|
-
};
|
253
|
-
|
254
|
-
/**
|
255
|
-
* Add an irregular word definition.
|
256
|
-
*
|
257
|
-
* @param {string} single
|
258
|
-
* @param {string} plural
|
259
|
-
*/
|
260
|
-
pluralize.addIrregularRule = function (single, plural) {
|
261
|
-
plural = plural.toLowerCase();
|
262
|
-
single = single.toLowerCase();
|
263
|
-
|
264
|
-
irregularSingles[single] = plural;
|
265
|
-
irregularPlurals[plural] = single;
|
266
|
-
};
|
267
|
-
|
268
|
-
/**
|
269
|
-
* Irregular rules.
|
270
|
-
*/
|
271
|
-
[
|
272
|
-
// Pronouns.
|
273
|
-
['I', 'we'],
|
274
|
-
['me', 'us'],
|
275
|
-
['he', 'they'],
|
276
|
-
['she', 'they'],
|
277
|
-
['them', 'them'],
|
278
|
-
['myself', 'ourselves'],
|
279
|
-
['yourself', 'yourselves'],
|
280
|
-
['itself', 'themselves'],
|
281
|
-
['herself', 'themselves'],
|
282
|
-
['himself', 'themselves'],
|
283
|
-
['themself', 'themselves'],
|
284
|
-
['is', 'are'],
|
285
|
-
['was', 'were'],
|
286
|
-
['has', 'have'],
|
287
|
-
['this', 'these'],
|
288
|
-
['that', 'those'],
|
289
|
-
// Words ending in with a consonant and `o`.
|
290
|
-
['echo', 'echoes'],
|
291
|
-
['dingo', 'dingoes'],
|
292
|
-
['volcano', 'volcanoes'],
|
293
|
-
['tornado', 'tornadoes'],
|
294
|
-
['torpedo', 'torpedoes'],
|
295
|
-
// Ends with `us`.
|
296
|
-
['genus', 'genera'],
|
297
|
-
['viscus', 'viscera'],
|
298
|
-
// Ends with `ma`.
|
299
|
-
['stigma', 'stigmata'],
|
300
|
-
['stoma', 'stomata'],
|
301
|
-
['dogma', 'dogmata'],
|
302
|
-
['lemma', 'lemmata'],
|
303
|
-
['schema', 'schemata'],
|
304
|
-
['anathema', 'anathemata'],
|
305
|
-
// Other irregular rules.
|
306
|
-
['ox', 'oxen'],
|
307
|
-
['axe', 'axes'],
|
308
|
-
['die', 'dice'],
|
309
|
-
['yes', 'yeses'],
|
310
|
-
['foot', 'feet'],
|
311
|
-
['eave', 'eaves'],
|
312
|
-
['goose', 'geese'],
|
313
|
-
['tooth', 'teeth'],
|
314
|
-
['quiz', 'quizzes'],
|
315
|
-
['human', 'humans'],
|
316
|
-
['proof', 'proofs'],
|
317
|
-
['carve', 'carves'],
|
318
|
-
['valve', 'valves'],
|
319
|
-
['looey', 'looies'],
|
320
|
-
['thief', 'thieves'],
|
321
|
-
['groove', 'grooves'],
|
322
|
-
['pickaxe', 'pickaxes'],
|
323
|
-
['passerby', 'passersby']
|
324
|
-
].forEach(function (rule) {
|
325
|
-
return pluralize.addIrregularRule(rule[0], rule[1]);
|
326
|
-
});
|
327
|
-
|
328
|
-
/**
|
329
|
-
* Pluralization rules.
|
330
|
-
*/
|
331
|
-
[
|
332
|
-
[/s?$/i, 's'],
|
333
|
-
[/[^\u0000-\u007F]$/i, '$0'],
|
334
|
-
[/([^aeiou]ese)$/i, '$1'],
|
335
|
-
[/(ax|test)is$/i, '$1es'],
|
336
|
-
[/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'],
|
337
|
-
[/(e[mn]u)s?$/i, '$1s'],
|
338
|
-
[/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'],
|
339
|
-
[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'],
|
340
|
-
[/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'],
|
341
|
-
[/(seraph|cherub)(?:im)?$/i, '$1im'],
|
342
|
-
[/(her|at|gr)o$/i, '$1oes'],
|
343
|
-
[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'],
|
344
|
-
[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'],
|
345
|
-
[/sis$/i, 'ses'],
|
346
|
-
[/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'],
|
347
|
-
[/([^aeiouy]|qu)y$/i, '$1ies'],
|
348
|
-
[/([^ch][ieo][ln])ey$/i, '$1ies'],
|
349
|
-
[/(x|ch|ss|sh|zz)$/i, '$1es'],
|
350
|
-
[/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'],
|
351
|
-
[/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'],
|
352
|
-
[/(pe)(?:rson|ople)$/i, '$1ople'],
|
353
|
-
[/(child)(?:ren)?$/i, '$1ren'],
|
354
|
-
[/eaux$/i, '$0'],
|
355
|
-
[/m[ae]n$/i, 'men'],
|
356
|
-
['thou', 'you']
|
357
|
-
].forEach(function (rule) {
|
358
|
-
return pluralize.addPluralRule(rule[0], rule[1]);
|
359
|
-
});
|
360
|
-
|
361
|
-
/**
|
362
|
-
* Singularization rules.
|
363
|
-
*/
|
364
|
-
[
|
365
|
-
[/s$/i, ''],
|
366
|
-
[/(ss)$/i, '$1'],
|
367
|
-
[/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'],
|
368
|
-
[/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'],
|
369
|
-
[/ies$/i, 'y'],
|
370
|
-
[/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'],
|
371
|
-
[/\b(mon|smil)ies$/i, '$1ey'],
|
372
|
-
[/\b((?:tit)?m|l)ice$/i, '$1ouse'],
|
373
|
-
[/(seraph|cherub)im$/i, '$1'],
|
374
|
-
[/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'],
|
375
|
-
[/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'],
|
376
|
-
[/(movie|twelve|abuse|e[mn]u)s$/i, '$1'],
|
377
|
-
[/(test)(?:is|es)$/i, '$1is'],
|
378
|
-
[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'],
|
379
|
-
[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'],
|
380
|
-
[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'],
|
381
|
-
[/(alumn|alg|vertebr)ae$/i, '$1a'],
|
382
|
-
[/(cod|mur|sil|vert|ind)ices$/i, '$1ex'],
|
383
|
-
[/(matr|append)ices$/i, '$1ix'],
|
384
|
-
[/(pe)(rson|ople)$/i, '$1rson'],
|
385
|
-
[/(child)ren$/i, '$1'],
|
386
|
-
[/(eau)x?$/i, '$1'],
|
387
|
-
[/men$/i, 'man']
|
388
|
-
].forEach(function (rule) {
|
389
|
-
return pluralize.addSingularRule(rule[0], rule[1]);
|
390
|
-
});
|
391
|
-
|
392
|
-
/**
|
393
|
-
* Uncountable rules.
|
394
|
-
*/
|
395
|
-
[
|
396
|
-
// Singular words with no plurals.
|
397
|
-
'adulthood',
|
398
|
-
'advice',
|
399
|
-
'agenda',
|
400
|
-
'aid',
|
401
|
-
'aircraft',
|
402
|
-
'alcohol',
|
403
|
-
'ammo',
|
404
|
-
'analytics',
|
405
|
-
'anime',
|
406
|
-
'athletics',
|
407
|
-
'audio',
|
408
|
-
'bison',
|
409
|
-
'blood',
|
410
|
-
'bream',
|
411
|
-
'buffalo',
|
412
|
-
'butter',
|
413
|
-
'carp',
|
414
|
-
'cash',
|
415
|
-
'chassis',
|
416
|
-
'chess',
|
417
|
-
'clothing',
|
418
|
-
'cod',
|
419
|
-
'commerce',
|
420
|
-
'cooperation',
|
421
|
-
'corps',
|
422
|
-
'debris',
|
423
|
-
'diabetes',
|
424
|
-
'digestion',
|
425
|
-
'elk',
|
426
|
-
'energy',
|
427
|
-
'equipment',
|
428
|
-
'excretion',
|
429
|
-
'expertise',
|
430
|
-
'firmware',
|
431
|
-
'flounder',
|
432
|
-
'fun',
|
433
|
-
'gallows',
|
434
|
-
'garbage',
|
435
|
-
'graffiti',
|
436
|
-
'hardware',
|
437
|
-
'headquarters',
|
438
|
-
'health',
|
439
|
-
'herpes',
|
440
|
-
'highjinks',
|
441
|
-
'homework',
|
442
|
-
'housework',
|
443
|
-
'information',
|
444
|
-
'jeans',
|
445
|
-
'justice',
|
446
|
-
'kudos',
|
447
|
-
'labour',
|
448
|
-
'literature',
|
449
|
-
'machinery',
|
450
|
-
'mackerel',
|
451
|
-
'mail',
|
452
|
-
'media',
|
453
|
-
'mews',
|
454
|
-
'moose',
|
455
|
-
'music',
|
456
|
-
'mud',
|
457
|
-
'manga',
|
458
|
-
'news',
|
459
|
-
'only',
|
460
|
-
'personnel',
|
461
|
-
'pike',
|
462
|
-
'plankton',
|
463
|
-
'pliers',
|
464
|
-
'police',
|
465
|
-
'pollution',
|
466
|
-
'premises',
|
467
|
-
'rain',
|
468
|
-
'research',
|
469
|
-
'rice',
|
470
|
-
'salmon',
|
471
|
-
'scissors',
|
472
|
-
'series',
|
473
|
-
'sewage',
|
474
|
-
'shambles',
|
475
|
-
'shrimp',
|
476
|
-
'software',
|
477
|
-
'species',
|
478
|
-
'staff',
|
479
|
-
'swine',
|
480
|
-
'tennis',
|
481
|
-
'traffic',
|
482
|
-
'transportation',
|
483
|
-
'trout',
|
484
|
-
'tuna',
|
485
|
-
'wealth',
|
486
|
-
'welfare',
|
487
|
-
'whiting',
|
488
|
-
'wildebeest',
|
489
|
-
'wildlife',
|
490
|
-
'you',
|
491
|
-
/pok[eé]mon$/i,
|
492
|
-
// Regexes.
|
493
|
-
/[^aeiou]ese$/i, // "chinese", "japanese"
|
494
|
-
/deer$/i, // "deer", "reindeer"
|
495
|
-
/fish$/i, // "fish", "blowfish", "angelfish"
|
496
|
-
/measles$/i,
|
497
|
-
/o[iu]s$/i, // "carnivorous"
|
498
|
-
/pox$/i, // "chickpox", "smallpox"
|
499
|
-
/sheep$/i
|
500
|
-
].forEach(pluralize.addUncountableRule);
|
501
|
-
|
502
|
-
return pluralize;
|
503
|
-
});
|
@@ -1,27 +0,0 @@
|
|
1
|
-
var pkg = require('./package.json');
|
2
|
-
module.exports = {
|
3
|
-
Version: () => pkg.version,
|
4
|
-
RewriteTOML: (input_toml) => {
|
5
|
-
return input_toml.split(`\n`).map(line => {
|
6
|
-
// some_variable.etc = "some value" #: Some comment
|
7
|
-
const isVariableComment = /^[a-z0-9\-_\.\s]+=.*?#.+?$/i;
|
8
|
-
// [some_section] #: Some comment
|
9
|
-
const isBlockComment = /^\s*?\[.*?#.+?$/i;
|
10
|
-
const extractComment = /#:([^#]+)$/i;
|
11
|
-
const extractVariable = /^\s*?([a-z0-9\-_\.]+)\s?=/i;
|
12
|
-
|
13
|
-
if (isVariableComment.test(line)) {
|
14
|
-
const [, comment] = extractComment.exec(line) || [];
|
15
|
-
const [, variable_name] = extractVariable.exec(line) || [];
|
16
|
-
if (!comment || !variable_name) return line;
|
17
|
-
return `${variable_name}--bookshop_comment = "${comment.replace(/"/g, '\"').trim()}"\n${line}`
|
18
|
-
} else if (isBlockComment.test(line)) {
|
19
|
-
const [, comment] = extractComment.exec(line) || [];
|
20
|
-
if (!comment) return line;
|
21
|
-
return `${line}\n--bookshop_comment = "${comment.trim()}"`
|
22
|
-
} else {
|
23
|
-
return line;
|
24
|
-
}
|
25
|
-
}).join(`\n`);
|
26
|
-
}
|
27
|
-
}
|
@@ -1,25 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"name": "@bookshop/toml-narrator",
|
3
|
-
"packageManager": "yarn@3.0.0",
|
4
|
-
"version": "2.6.1",
|
5
|
-
"description": "Rewrite Bookshop TOML files to preserve comments",
|
6
|
-
"main": "main.js",
|
7
|
-
"scripts": {
|
8
|
-
"test": "nyc ava -v"
|
9
|
-
},
|
10
|
-
"files": [
|
11
|
-
"main.js"
|
12
|
-
],
|
13
|
-
"author": "@bglw",
|
14
|
-
"license": "MIT",
|
15
|
-
"publishConfig": {
|
16
|
-
"access": "public"
|
17
|
-
},
|
18
|
-
"devDependencies": {
|
19
|
-
"ava": "^3.15.0",
|
20
|
-
"nyc": "^15.1.0"
|
21
|
-
},
|
22
|
-
"engines": {
|
23
|
-
"node": ">=14.16"
|
24
|
-
}
|
25
|
-
}
|