parent
3fbac24759
commit
30d2922bf9
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"name": "fork-awesome-customizer", |
||||||
|
"version": "0.0.1", |
||||||
|
"description": "Fork-Awesome subset builder", |
||||||
|
"scripts": {}, |
||||||
|
"license": "MIT", |
||||||
|
"dependencies": { |
||||||
|
"js-yaml": "^3.12.0" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"standard": "^11.0.1" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
.applied-aliases.json |
@ -1,90 +1,149 @@ |
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const fs = require('fs') |
const util = require("./util") |
||||||
|
|
||||||
|
let wanted_icons = util.fread('../wanted.ini').split('\n') |
||||||
function rmInDir(dirPath) { |
.filter((x) => x.length && x[0] !== '#') |
||||||
try { var files = fs.readdirSync(dirPath) } |
.map((x) => x.trim().replace(/\s*#.*/, '')) |
||||||
catch(e) { return } |
|
||||||
if (files.length > 0) { |
|
||||||
for (var i = 0; i < files.length; i++) { |
let iconsfile = util.fread('templates/icons.yml') |
||||||
var filePath = dirPath + '/' + files[i] |
let fontcustom = util.fread('../fontcustom.yml') |
||||||
if (fs.statSync(filePath).isFile()) |
if (!fontcustom.fonts_path_relative_to_css) { |
||||||
fs.unlinkSync(filePath) |
fontcustom.fonts_path_relative_to_css = './' |
||||||
else |
|
||||||
rmDir(filePath) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|
||||||
function cp(src, dest) { |
|
||||||
if (!fs.existsSync(src)) { |
// find which aliases are defined
|
||||||
return false; |
let alias_map = {} |
||||||
|
iconsfile.icons.forEach((icon) => { |
||||||
|
if (icon.aliases) { |
||||||
|
icon.aliases.forEach((alias) => { |
||||||
|
alias_map[alias] = icon.id |
||||||
|
}) |
||||||
} |
} |
||||||
|
}) |
||||||
|
|
||||||
var data = fs.readFileSync(src, 'utf-8'); |
console.log(`Including ${wanted_icons.length} icons out of ${iconsfile.icons.length}`) |
||||||
fs.writeFileSync(dest, data); |
console.log(`Found ${Object.keys(alias_map).length} aliases defined in the dictionary`) |
||||||
return true |
|
||||||
} |
|
||||||
|
|
||||||
|
console.log('Preparing icons.yml...') |
||||||
|
|
||||||
// let manifest = JSON.parse(fs.readFileSync('templates/.fontcustom-manifest.json', 'utf-8'))
|
let wanted_all = [] |
||||||
let fcyml = fs.readFileSync('../fontcustom.yml', 'utf-8') |
let applied_aliases = {} |
||||||
let desired = fs.readFileSync('../wanted.ini', 'utf-8').split('\n') |
for(let id of wanted_icons) { |
||||||
.filter((x) => x.length && x[0] !== '#') |
wanted_all.push(id) |
||||||
.map((x) => x.trim().replace(/\s*#.*/, '')) |
if (alias_map[id]) { |
||||||
|
applied_aliases[id] = alias_map[id] |
||||||
|
wanted_all.push(alias_map[id]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
let iconsfile_filtered = { |
||||||
|
icons: iconsfile.icons.filter((x) => { |
||||||
|
return wanted_all.indexOf(x.id) !== -1 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
// TODO deal with aliases properly
|
// store the result for the postprocessing script
|
||||||
|
util.fwrite('../Fork-Awesome/src/icons/icons.yml', iconsfile_filtered) |
||||||
|
util.fwrite('../Fork-Awesome/src/icons/fontcustom.yml', fontcustom) |
||||||
|
|
||||||
console.log(`Including ${desired.length} icons`) |
if (util.exists('../Fork-Awesome/src/icons/.fontcustom-manifest.json')) { |
||||||
|
util.rm('../Fork-Awesome/src/icons/.fontcustom-manifest.json') |
||||||
|
} |
||||||
|
|
||||||
console.log('Preparing icons.yml...') |
let font_name = fontcustom.font_name |
||||||
|
let fa_output_dir = `../Fork-Awesome/src/icons/${font_name}` |
||||||
|
|
||||||
|
util.rmInDir('../Fork-Awesome/src/icons/svg') |
||||||
|
util.rmInDir(fa_output_dir) |
||||||
|
util.rmInDir('../output') |
||||||
|
|
||||||
|
console.log('Copying icons ...') |
||||||
|
for (let a of wanted_all) { |
||||||
|
if (typeof alias_map[a] !== 'undefined') { |
||||||
|
console.log(`Skipping alias ${a}`) |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
// this would be prettier with some yaml module, but to avoid installing anything...
|
if (!util.cp(`./templates/svg/${a}.svg`, |
||||||
|
`../Fork-Awesome/src/icons/svg/${a}.svg`, |
||||||
|
false)) { |
||||||
|
console.log(`- \x1b[31,1mFile "${a}.svg" not found!\x1b[m`) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
let iconsy = fs.readFileSync('templates/icons.yml', 'utf-8') |
console.log('Running builder script') |
||||||
|
|
||||||
let pieces = iconsy.substring(iconsy.indexOf('\n')+1).split(' - name:') |
util.exec('bundle exec fontcustom compile', '../Fork-Awesome/src/icons/') |
||||||
pieces.shift() // remove first
|
|
||||||
// now we have the entries, without leading ' - name'
|
|
||||||
|
|
||||||
let pattern = /id:\s+([a-z_0-9-]+)\n/ |
if (!util.exists(`${fa_output_dir}/${font_name}.css`)) { |
||||||
|
util.abort('\x1b[31;1mBuild failed, no CSS in output directory.\x1b[m') |
||||||
|
} |
||||||
|
|
||||||
pieces = pieces.filter((x) => { |
let suffixes = ['.css', '.eot', '.svg', '.ttf', '.woff', '.woff2', '-preview.html'] |
||||||
let ar = pattern.exec(x) |
suffixes.forEach((x) => { |
||||||
return ar !== null && desired.indexOf(ar[1]) !== -1 |
util.cp(`${fa_output_dir}/${font_name}${x}`, `../output/${font_name}${x}`) |
||||||
}) |
}) |
||||||
|
|
||||||
let combined = 'icons:\n - name:' + pieces.join(' - name:') |
let cssfile = `../output/${font_name}.css` |
||||||
|
let htmlfile = `../output/${font_name}-preview.html` |
||||||
|
|
||||||
console.log('\x1b[32m[Writing]\x1b[m FA~icons.yml') |
console.log('Post-processing CSS') |
||||||
fs.writeFileSync('../Fork-Awesome/src/icons/icons.yml', combined) |
let orig_css = util.fread(cssfile) |
||||||
|
|
||||||
console.log('\x1b[32m[Writing]\x1b[m FA~fontcustom.yml') |
let iconstyles_begin_token = 'antialiased;\n}\n' |
||||||
fs.writeFileSync('../Fork-Awesome/src/icons/fontcustom.yml', fcyml) |
let iconstyles = orig_css |
||||||
|
.substr(orig_css.indexOf(iconstyles_begin_token) + iconstyles_begin_token.length) |
||||||
|
|
||||||
|
let template = util.fread('./css-template.css') |
||||||
|
|
||||||
console.log('Deleting FA~.fontcustom-manifest.json, to force a rebuilt ...') |
let prefix = fontcustom.css_selector |
||||||
if (fs.existsSync('../Fork-Awesome/src/icons/.fontcustom-manifest.json')) { |
if (!prefix.endsWith('{{glyph}}')) { |
||||||
fs.unlinkSync('../Fork-Awesome/src/icons/.fontcustom-manifest.json') |
util.abort(`CSS selector must end with {{glyph}}`) |
||||||
} |
} |
||||||
|
prefix = prefix.replace('{{glyph}}', '').replace('.', '') |
||||||
|
|
||||||
|
|
||||||
|
let fa_packagejson = util.fread('../Fork-Awesome/package.json') |
||||||
|
|
||||||
console.log('Deleting files in FA~svg/ ...') |
let fontpath = fontcustom.fonts_path_relative_to_css |
||||||
rmInDir('../Fork-Awesome/src/icons/svg') |
if (!fontpath.endsWith('/')) fontpath += '/' |
||||||
|
|
||||||
|
console.log('Collected information:') |
||||||
|
console.log(` \x1b[36mFont name:\x1b[m ${font_name}`) |
||||||
|
console.log(` \x1b[36mFont path:\x1b[m ${fontpath} (relative to CSS)`) |
||||||
|
console.log(` \x1b[36mCSS class prefix:\x1b[m ${prefix}`) |
||||||
|
console.log(` \x1b[36mFork-Awesome version:\x1b[m ${fa_packagejson.version}`) |
||||||
|
|
||||||
console.log('Copying desired files to FA~svg/ ...') |
let html_content = util.fread(htmlfile) |
||||||
let any_bad = false |
|
||||||
for (let a of desired) { |
let css_header = template.replace(/\$prefix/g, prefix) |
||||||
if (!cp(`./templates/svg/${a}.svg`, `../Fork-Awesome/src/icons/svg/${a}.svg`)) { |
.replace(/\$fontname/g, font_name) |
||||||
console.log(`- \x1b[33mFile \x1b[31m"${a}.svg"\x1b[33m not found, probably a typo or alias\x1b[m`) |
.replace(/\$fontpath/g, fontpath) |
||||||
any_bad = true |
.replace(/\$version/g, fa_packagejson.version) |
||||||
|
|
||||||
|
for (let alias in applied_aliases) { |
||||||
|
if (applied_aliases.hasOwnProperty(alias)) { |
||||||
|
let orig = `.${prefix}${applied_aliases[alias]}:before` |
||||||
|
let added = `.${prefix}${alias}:before` |
||||||
|
console.log(`Adding CSS alias ${added} -> ${orig}`) |
||||||
|
|
||||||
|
iconstyles = iconstyles.replace(orig, `${orig}, ${added}`) |
||||||
|
|
||||||
|
html_content = html_content.replace( |
||||||
|
`value=".${prefix}${applied_aliases[alias]}" />`, |
||||||
|
`value=".${prefix}${applied_aliases[alias]}" />
|
||||||
|
<input class="class" type="text" readonly="readonly" onClick="this.select();" value="${added.replace(':before','')}" />` |
||||||
|
) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
if (any_bad) { |
util.fwrite(cssfile, |
||||||
console.log(`\x1b[31mSome files were not found. If you included their aliases (e.g. save -> floppy-o), this is correct.\x1b[m`) |
css_header + iconstyles.replace(/([^:]):before/g, '$1::before')) |
||||||
} |
|
||||||
|
util.fwrite(htmlfile, html_content) |
||||||
|
|
||||||
|
console.log(`\x1b[32;1m=== Your font "${font_name}" is ready in the output directory ===\x1b[m`) |
||||||
|
|
||||||
|
@ -0,0 +1,40 @@ |
|||||||
|
/*! |
||||||
|
* Based on Fork Awesome $version, originaly by Dave Gandy - http://forkawesome.github.io/Fork-Awesome/ |
||||||
|
* License - http://forkawesome.github.io/Fork-Awesome//license (Font: SIL OFL 1.1, CSS: MIT License) |
||||||
|
*/ |
||||||
|
@font-face { |
||||||
|
font-family: '$fontname'; |
||||||
|
src: url('$fontpath$fontname.eot?v=$version'); |
||||||
|
src: url('$fontpath$fontname.eot?#iefix&v=$version') format('embedded-opentype'), |
||||||
|
url('$fontpath$fontname.woff2?v=$version') format('woff2'), |
||||||
|
url('$fontpath$fontname.woff?v=$version') format('woff'), |
||||||
|
url('$fontpath$fontname.ttf?v=$version') format('truetype'), |
||||||
|
url('$fontpath$fontname.svg?v=$version#$fontname') format('svg'); |
||||||
|
font-weight: normal; |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
|
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio:0) { |
||||||
|
@font-face { |
||||||
|
font-family: "$fontname"; |
||||||
|
src: url("$fontpath$fontname.svg#$fontname") format("svg"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[data-icon]::before { content: attr(data-icon); } |
||||||
|
|
||||||
|
[data-icon]::before, [class^="$prefix"]::before, [class*=" $prefix"]::before { |
||||||
|
display: inline-block; |
||||||
|
font-family: "$fontname"; |
||||||
|
font-style: normal; |
||||||
|
font-weight: normal; |
||||||
|
font-variant: normal; |
||||||
|
line-height: 1; |
||||||
|
text-decoration: inherit; |
||||||
|
font-size: inherit; |
||||||
|
text-rendering: optimizeLegibility; |
||||||
|
text-transform: none; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
font-smoothing: antialiased; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const util = require("./util") |
||||||
|
|
||||||
|
// the manifest file is easier to parse for us, but the actual source file is icons.yml
|
||||||
|
let manifest = util.fread('./templates/.fontcustom-manifest.json') |
||||||
|
let all_enabled = [] |
||||||
|
let all_disabled = [] |
||||||
|
|
||||||
|
for (let key in manifest.glyphs){ |
||||||
|
if (manifest.glyphs.hasOwnProperty(key)) { |
||||||
|
all_enabled.push(key) |
||||||
|
all_disabled.push(`#${key}`) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`Found ${all_enabled.length} icons in manifest, writing template files`) |
||||||
|
|
||||||
|
util.fwrite('../wanted.all.ini', all_enabled.join('\n') + '\n') |
||||||
|
util.fwrite('../wanted.none.ini', all_disabled.join('\n') + '\n') |
||||||
|
|
||||||
|
let fontcustom = util.fread('./templates/fontcustom.yml') |
||||||
|
fontcustom.fonts_path_relative_to_css = './' |
||||||
|
|
||||||
|
util.fwrite('../fontcustom.default.yml', fontcustom) |
||||||
|
|
||||||
|
if (!util.exists('../fontcustom.yml')) { |
||||||
|
util.cp('../fontcustom.default.yml', '../fontcustom.yml') |
||||||
|
} |
@ -1,34 +0,0 @@ |
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
const fs = require('fs') |
|
||||||
|
|
||||||
// the manifest file is easier to parse for us, but the actual source file is icons.yml
|
|
||||||
let manifest = JSON.parse(fs.readFileSync('./templates/.fontcustom-manifest.json', 'utf-8')) |
|
||||||
let fcyml = fs.readFileSync('./templates/fontcustom.yml', 'utf-8') |
|
||||||
|
|
||||||
let all_enabled = [] |
|
||||||
let all_disabled = [] |
|
||||||
|
|
||||||
for (var key in manifest.glyphs){ |
|
||||||
if (manifest.glyphs.hasOwnProperty(key)) { |
|
||||||
all_enabled.push(key) |
|
||||||
all_disabled.push(`#${key}`) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
console.log(`Found ${all_enabled.length} icons in manifest, writing template files`) |
|
||||||
|
|
||||||
console.log(`\x1b[32m[Writing]\x1b[m wanted.all.ini`) |
|
||||||
fs.writeFileSync('../wanted.all.ini', all_enabled.join('\n') + '\n') |
|
||||||
|
|
||||||
console.log(`\x1b[32m[Writing]\x1b[m wanted.none.ini`) |
|
||||||
fs.writeFileSync('../wanted.none.ini', all_disabled.join('\n') + '\n') |
|
||||||
|
|
||||||
|
|
||||||
console.log(`\x1b[32m[Writing]\x1b[m fontcustom.default.yml`) |
|
||||||
fs.writeFileSync('../fontcustom.default.yml', fcyml) |
|
||||||
|
|
||||||
if (!fs.existsSync('../fontcustom.yml')) { |
|
||||||
console.log(`\x1b[32m[Writing]\x1b[m fontcustom.yml (did not exist)`) |
|
||||||
fs.writeFileSync('../fontcustom.yml', fcyml) |
|
||||||
} |
|
@ -0,0 +1,157 @@ |
|||||||
|
const fs = require('fs') |
||||||
|
const yaml = require('js-yaml') |
||||||
|
const chproc = require('child_process') |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Delete all files in a directory |
||||||
|
* |
||||||
|
* @param dirPath : string |
||||||
|
*/ |
||||||
|
function rmInDir(dirPath) { |
||||||
|
let files |
||||||
|
|
||||||
|
console.log(`\x1b[32m[Clean]\x1b[m ${dirPath}`) |
||||||
|
|
||||||
|
try { |
||||||
|
files = fs.readdirSync(dirPath) |
||||||
|
} catch (e) { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if (files.length > 0) { |
||||||
|
for (let i = 0; i < files.length; i++) { |
||||||
|
let filePath = dirPath + '/' + files[i] |
||||||
|
|
||||||
|
if (filePath.endsWith('.gitignore') || filePath.endsWith('.gitkeep')) |
||||||
|
continue // preserve special files
|
||||||
|
|
||||||
|
if (fs.statSync(filePath).isFile()) |
||||||
|
fs.unlinkSync(filePath) |
||||||
|
else |
||||||
|
rmInDir(filePath) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Copy a file |
||||||
|
* |
||||||
|
* @param src : string |
||||||
|
* @param dest : string |
||||||
|
* @param verbose : boolean, default true |
||||||
|
* @returns {boolean} |
||||||
|
*/ |
||||||
|
function cp(src, dest, verbose=true) { |
||||||
|
if (!fs.existsSync(src)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (verbose) console.log(`\x1b[32m[Copy]\x1b[m ${src} -> ${dest}`) |
||||||
|
let data = fs.readFileSync(src); |
||||||
|
fs.writeFileSync(dest, data); |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Write with automatic encoding to JSON or YAML |
||||||
|
* |
||||||
|
* @param path : string |
||||||
|
* @param content : object|string |
||||||
|
*/ |
||||||
|
function fwrite(path, content) { |
||||||
|
let towrite = content |
||||||
|
let format = 'plain' |
||||||
|
|
||||||
|
if (typeof towrite !== 'string') { |
||||||
|
if (path.endsWith('.json')) { |
||||||
|
towrite = JSON.stringify(towrite, null, 4) |
||||||
|
format = 'json' |
||||||
|
} |
||||||
|
else if (path.endsWith('.yaml') || path.endsWith('.yml')) { |
||||||
|
towrite = yaml.safeDump(towrite) |
||||||
|
format = 'yaml' |
||||||
|
} |
||||||
|
else { |
||||||
|
throw `Can't figure out data encoding (at ${path})` |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`\x1b[32m[Writing]\x1b[m ${path} (${format})`) |
||||||
|
fs.writeFileSync(path, towrite) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Read with automatic decoding from JSON or YAML |
||||||
|
* |
||||||
|
* @param path : string |
||||||
|
* @return string|object|array |
||||||
|
*/ |
||||||
|
function fread(path) { |
||||||
|
let content = fs.readFileSync(path, 'utf-8') |
||||||
|
let format = 'plain' |
||||||
|
|
||||||
|
if (path.endsWith('.json')) { |
||||||
|
content = JSON.parse(content) |
||||||
|
format = 'json' |
||||||
|
} else if (path.endsWith('.yaml') || path.endsWith('.yml')) { |
||||||
|
content = yaml.safeLoad(content) |
||||||
|
format = 'yaml' |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`\x1b[32m[Reading]\x1b[m ${path} (${format})`) |
||||||
|
return content |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test if a file exists |
||||||
|
* |
||||||
|
* @param path : string |
||||||
|
* @returns {boolean} exists |
||||||
|
*/ |
||||||
|
function exists (path) { |
||||||
|
return fs.existsSync(path) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Delete a file |
||||||
|
* |
||||||
|
* @param path : string |
||||||
|
* @returns {boolean} success |
||||||
|
*/ |
||||||
|
function rm (path) { |
||||||
|
if (!exists(path)) { |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
fs.unlinkSync(path) |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Execute a command |
||||||
|
* |
||||||
|
* @param command |
||||||
|
* @param cwd |
||||||
|
*/ |
||||||
|
function exec (command, cwd='.') { |
||||||
|
return chproc.execSync(command, { |
||||||
|
cwd: cwd, |
||||||
|
stdio: [0,1,2] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
rmInDir, |
||||||
|
cp, |
||||||
|
fwrite, |
||||||
|
fread, |
||||||
|
exists, |
||||||
|
rm, |
||||||
|
exec, |
||||||
|
abort: (msg) => { |
||||||
|
console.log(`\x1b[31;1m${msg}\x1b[m`) |
||||||
|
process.exit() |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue