heroicons_helper 0.1.0
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 +7 -0
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +14 -0
- data/heroicons_helper.gemspec +36 -0
- data/lib/heroicons_helper/data.json +1 -0
- data/lib/heroicons_helper/icon.rb +72 -0
- data/lib/heroicons_helper/version.rb +5 -0
- data/lib/heroicons_helper.rb +14 -0
- data/package-lock.json +1444 -0
- data/package.json +13 -0
- data/script/keywords.json +3 -0
- data/script/update_heroicons +169 -0
- metadata +64 -0
data/package.json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "heroicons_helper",
|
3
|
+
"private": true,
|
4
|
+
"devDependencies": {
|
5
|
+
"cheerio": "1.0.0-rc.11",
|
6
|
+
"heroicons": "^1.0.6",
|
7
|
+
"fs-extra": "^7.0.1",
|
8
|
+
"globby": "11.0.0",
|
9
|
+
"lodash.merge": "4.6.2",
|
10
|
+
"trim-newlines": "3.0.1",
|
11
|
+
"yargs": "15.1.0"
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,169 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
/* eslint-env node */
|
3
|
+
const fs = require("fs-extra");
|
4
|
+
const path = require("path");
|
5
|
+
const globby = require("globby");
|
6
|
+
const cheerio = require("cheerio");
|
7
|
+
const trimNewlines = require("trim-newlines");
|
8
|
+
const yargs = require("yargs");
|
9
|
+
const merge = require("lodash.merge");
|
10
|
+
const keywords = require("./keywords.json");
|
11
|
+
|
12
|
+
// This script generates a JSON file that contains
|
13
|
+
// information about input SVG files.
|
14
|
+
const { argv } = yargs
|
15
|
+
.usage("Usage: $0 --output <output filepath>")
|
16
|
+
.example("$0 --input icons/**/*.svg --output build/data.json")
|
17
|
+
.option("input", {
|
18
|
+
alias: "i",
|
19
|
+
type: "array",
|
20
|
+
describe: "Input SVG files",
|
21
|
+
default: [
|
22
|
+
"node_modules/heroicons/outline/*.svg",
|
23
|
+
"node_modules/heroicons/solid/*.svg",
|
24
|
+
],
|
25
|
+
})
|
26
|
+
.option("output", {
|
27
|
+
alias: "o",
|
28
|
+
type: "string",
|
29
|
+
describe:
|
30
|
+
"Output JSON file. Defaults to stdout if no output file is provided.",
|
31
|
+
default: "lib/heroicons_helper/data.json",
|
32
|
+
});
|
33
|
+
|
34
|
+
const filepaths = globby.sync(argv.input);
|
35
|
+
const svgFilepaths = filepaths.filter(
|
36
|
+
(filepath) => path.parse(filepath).ext === ".svg"
|
37
|
+
);
|
38
|
+
|
39
|
+
if (svgFilepaths.length === 0) {
|
40
|
+
// eslint-disable-next-line no-console
|
41
|
+
console.error(`No input SVG file(s) found in ${icon_file_path.join(", ")}`);
|
42
|
+
process.exit(1);
|
43
|
+
}
|
44
|
+
|
45
|
+
let exitCode = 0;
|
46
|
+
|
47
|
+
const validTypes = ["solid", "outline"];
|
48
|
+
const defaultOutlineWidth = "24";
|
49
|
+
const defaultSolidWidth = "20";
|
50
|
+
|
51
|
+
const icons = svgFilepaths.map((filepath) => {
|
52
|
+
try {
|
53
|
+
let filename = path.parse(filepath).base;
|
54
|
+
const type = path.parse(filepath).dir.split("/").pop();
|
55
|
+
let widthSize;
|
56
|
+
switch (type) {
|
57
|
+
case "outline":
|
58
|
+
widthSize = defaultOutlineWidth;
|
59
|
+
break;
|
60
|
+
case "solid":
|
61
|
+
widthSize = defaultSolidWidth;
|
62
|
+
break;
|
63
|
+
default:
|
64
|
+
throw new Error(`Unknown icon type: ${type}`);
|
65
|
+
}
|
66
|
+
|
67
|
+
const filenamePattern = /(.+)(?:-[0-9]{1,2})?-([0-9]{2}).svg$/;
|
68
|
+
const filenameReplacePattern = /\.svg$/;
|
69
|
+
|
70
|
+
if (!filenamePattern.test(filename)) {
|
71
|
+
filename = filename.replace(filenameReplacePattern, `-${widthSize}.svg`);
|
72
|
+
}
|
73
|
+
|
74
|
+
const [, name, height] = filename.match(filenamePattern);
|
75
|
+
|
76
|
+
const svg = fs.readFileSync(path.resolve(filepath), "utf8");
|
77
|
+
const svgElement = cheerio.load(svg)("svg");
|
78
|
+
let svgWidth = parseInt(svgElement.attr("width"));
|
79
|
+
let svgHeight = parseInt(svgElement.attr("height"));
|
80
|
+
const svgViewBox = svgElement.attr("viewBox");
|
81
|
+
const svgPath = trimNewlines(svgElement.html()).trim();
|
82
|
+
|
83
|
+
if (!svgWidth) {
|
84
|
+
svgWidth = parseInt(widthSize);
|
85
|
+
svgElement.attr("width", svgWidth);
|
86
|
+
}
|
87
|
+
|
88
|
+
if (!svgHeight) {
|
89
|
+
svgHeight = parseInt(widthSize);
|
90
|
+
svgElement.attr("height", svgHeight);
|
91
|
+
}
|
92
|
+
|
93
|
+
if (!svgViewBox) {
|
94
|
+
throw new Error(`${filename}: Missing viewBox attribute.`);
|
95
|
+
}
|
96
|
+
|
97
|
+
if (svgHeight != parseInt(height)) {
|
98
|
+
throw new Error(
|
99
|
+
`${filename}: Height in filename (${height}) does not match height attribute of SVG (${svgHeight})`
|
100
|
+
);
|
101
|
+
}
|
102
|
+
|
103
|
+
const viewBoxPattern = /0 0 ([0-9]+) ([0-9]+)/;
|
104
|
+
|
105
|
+
if (!viewBoxPattern.test(svgViewBox)) {
|
106
|
+
throw new Error(
|
107
|
+
`${filename}: Invalid viewBox attribute. The viewBox attribute should be in the following format: "0 0 <width> <height>"`
|
108
|
+
);
|
109
|
+
}
|
110
|
+
|
111
|
+
const [, viewBoxWidth, viewBoxHeight] = svgViewBox.match(viewBoxPattern);
|
112
|
+
|
113
|
+
if (svgWidth !== parseInt(viewBoxWidth)) {
|
114
|
+
throw new Error(
|
115
|
+
`${filename}: width attribute and viewBox width do not match.`
|
116
|
+
);
|
117
|
+
}
|
118
|
+
|
119
|
+
if (svgHeight !== parseInt(viewBoxHeight)) {
|
120
|
+
throw new Error(
|
121
|
+
`${filename}: height attribute and viewBox height do not match.`
|
122
|
+
);
|
123
|
+
}
|
124
|
+
|
125
|
+
return {
|
126
|
+
name,
|
127
|
+
keywords: keywords[name] || [],
|
128
|
+
type: type,
|
129
|
+
width: svgWidth,
|
130
|
+
height: svgHeight,
|
131
|
+
path: svgPath,
|
132
|
+
};
|
133
|
+
} catch (error) {
|
134
|
+
// eslint-disable-next-line no-console
|
135
|
+
console.error(error);
|
136
|
+
// Instead of exiting immediately, we set exitCode to 1 and continue
|
137
|
+
// iterating through the rest of the SVGs. This allows us to identify all
|
138
|
+
// the SVGs that have errors, not just the first one. An exit code of 1
|
139
|
+
// indicates that an error occurred.
|
140
|
+
// Reference: https://nodejs.org/api/process.html#process_exit_codes
|
141
|
+
exitCode = 1;
|
142
|
+
return null;
|
143
|
+
}
|
144
|
+
});
|
145
|
+
|
146
|
+
// Exit early if any errors occurred.
|
147
|
+
if (exitCode !== 0) {
|
148
|
+
process.exit(exitCode);
|
149
|
+
}
|
150
|
+
|
151
|
+
const iconsByName = icons.reduce(
|
152
|
+
(acc, icon) =>
|
153
|
+
merge(acc, {
|
154
|
+
[icon.name]: {
|
155
|
+
name: icon.name,
|
156
|
+
keywords: icon.keywords,
|
157
|
+
variants: {
|
158
|
+
[icon.type]: {
|
159
|
+
width: icon.width,
|
160
|
+
height: icon.height,
|
161
|
+
path: icon.path,
|
162
|
+
},
|
163
|
+
},
|
164
|
+
},
|
165
|
+
}),
|
166
|
+
{}
|
167
|
+
);
|
168
|
+
|
169
|
+
fs.outputJsonSync(path.resolve(argv.output), iconsByName);
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heroicons_helper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Garen J. Torikian
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A package that distributes Heroicons as a gem, for easy inclusion in
|
14
|
+
Ruby projects.
|
15
|
+
email:
|
16
|
+
- gjtorikian@users.noreply.github.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ".rubocop.yml"
|
22
|
+
- CHANGELOG.md
|
23
|
+
- Gemfile
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- heroicons_helper.gemspec
|
28
|
+
- lib/heroicons_helper.rb
|
29
|
+
- lib/heroicons_helper/data.json
|
30
|
+
- lib/heroicons_helper/icon.rb
|
31
|
+
- lib/heroicons_helper/version.rb
|
32
|
+
- package-lock.json
|
33
|
+
- package.json
|
34
|
+
- script/keywords.json
|
35
|
+
- script/update_heroicons
|
36
|
+
homepage: https://github.com/gjtorikian/heroicons_helper
|
37
|
+
licenses:
|
38
|
+
- MIT
|
39
|
+
metadata:
|
40
|
+
homepage_uri: https://github.com/gjtorikian/heroicons_helper
|
41
|
+
source_code_uri: https://github.com/gjtorikian/heroicons_helper
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.7.0
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 4.0.0
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubygems_version: 3.3.13
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: Heroicons port for Ruby
|
64
|
+
test_files: []
|