iconfont build
This commit is contained in:
parent
34dda0cb41
commit
489afa542f
|
|
@ -1,6 +1,6 @@
|
|||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import { PACKAGES_DIR, readAliases, toPascalCase, getAllIcons } from './helpers.mjs'
|
||||
import { PACKAGES_DIR, getAliases, toPascalCase, getAllIcons } from './helpers.mjs'
|
||||
import { stringify } from 'svgson'
|
||||
import prettier from "@prettier/sync"
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export const buildJsIcons = ({
|
|||
indexFile = 'icons.ts'
|
||||
}) => {
|
||||
const DIST_DIR = path.resolve(PACKAGES_DIR, name);
|
||||
const aliases = readAliases(),
|
||||
const aliases = getAliases(),
|
||||
allIcons = getAllIcons(false, true)
|
||||
|
||||
let index = []
|
||||
|
|
|
|||
|
|
@ -150,23 +150,39 @@ export const readSvgDirectory = (directory) => {
|
|||
return fs.readdirSync(directory).filter((file) => path.extname(file) === '.svg')
|
||||
}
|
||||
|
||||
export const readAliases = () => {
|
||||
export const getAliases = (groupped = false) => {
|
||||
const allAliases = JSON.parse(fs.readFileSync(resolve(HOME_DIR, 'aliases.json'), 'utf-8'));
|
||||
const allIcons = getAllIcons()
|
||||
|
||||
let aliases = [];
|
||||
if (groupped) {
|
||||
let aliases = [];
|
||||
types.forEach(type => {
|
||||
const icons = allIcons[type].map(i => i.name);
|
||||
|
||||
types.forEach(type => {
|
||||
const icons = allIcons[type].map(i => i.name);
|
||||
aliases[type] = {};
|
||||
|
||||
for (const [key, value] of Object.entries(allAliases[type])) {
|
||||
if (icons.includes(value)) {
|
||||
aliases[`${key}${type !== 'outline' ? `-${type}` : ''}`] = `${value}${type !== 'outline' ? `-${type}` : ''}`;
|
||||
for (const [key, value] of Object.entries(allAliases[type])) {
|
||||
if (icons.includes(value)) {
|
||||
aliases[type][key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return aliases
|
||||
return aliases
|
||||
} else {
|
||||
let aliases = [];
|
||||
types.forEach(type => {
|
||||
const icons = allIcons[type].map(i => i.name);
|
||||
|
||||
for (const [key, value] of Object.entries(allAliases[type])) {
|
||||
if (icons.includes(value)) {
|
||||
aliases[`${key}${type !== 'outline' ? `-${type}` : ''}`] = `${value}${type !== 'outline' ? `-${type}` : ''}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return aliases
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
"**/CVS": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/Thumbs.db": true,
|
||||
"**/.idea/": true,
|
||||
"icons": false
|
||||
"**/.idea/": true
|
||||
},
|
||||
"explorerExclude.backup": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import outlineStroke from 'svg-outline-stroke'
|
||||
import { asyncForEach, getCompileOptions, getPackageDir, HOME_DIR, readSvgs } from '../../../.build/helpers.mjs'
|
||||
import { asyncForEach, getAllIcons, getCompileOptions, getPackageDir, HOME_DIR } from '../../../.build/helpers.mjs'
|
||||
import fs from 'fs'
|
||||
import { resolve, basename } from 'path'
|
||||
import crypto from 'crypto'
|
||||
|
|
@ -9,98 +9,102 @@ import { execSync } from 'child_process'
|
|||
const DIR = getPackageDir('icons-webfont')
|
||||
|
||||
const buildOutline = async () => {
|
||||
let files = readSvgs(),
|
||||
filesList = []
|
||||
let filesList = {}
|
||||
const icons = getAllIcons(true)
|
||||
|
||||
const compileOptions = getCompileOptions(),
|
||||
iconfontUnicode = JSON.parse(fs.readFileSync(resolve(HOME_DIR, 'tags.json'), 'utf-8'))
|
||||
const compileOptions = getCompileOptions()
|
||||
|
||||
await asyncForEach(files, async function ({ name, contents }) {
|
||||
if (compileOptions.includeIcons.length === 0 || compileOptions.includeIcons.indexOf(name) >= 0) {
|
||||
await asyncForEach(Object.entries(icons), async ([type, icons]) => {
|
||||
fs.mkdirSync(resolve(DIR, `icons-outlined/${type}`), { recursive: true })
|
||||
filesList[type] = []
|
||||
|
||||
if (iconfontUnicode[name]) {
|
||||
const unicode = iconfontUnicode[name].unicode
|
||||
console.log('Stroke for:', name, unicode)
|
||||
await asyncForEach(icons, async function ({ name, content, unicode }) {
|
||||
console.log(type, name);
|
||||
|
||||
if (compileOptions.includeIcons.length === 0 || compileOptions.includeIcons.indexOf(name) >= 0) {
|
||||
|
||||
let filename = `${name}.svg`
|
||||
if (unicode) {
|
||||
filename = `u${unicode.toUpperCase()}-${name}.svg`
|
||||
}
|
||||
console.log('Stroke for:', name, unicode)
|
||||
|
||||
filesList.push(filename)
|
||||
|
||||
contents = contents
|
||||
.replace('width="24"', 'width="1000"')
|
||||
.replace('height="24"', 'height="1000"')
|
||||
|
||||
if (compileOptions.strokeWidth) {
|
||||
contents = contents
|
||||
.replace('stroke-width="2"', `stroke-width="${compileOptions.strokeWidth}"`)
|
||||
}
|
||||
|
||||
const cachedFilename = `u${unicode.toUpperCase()}-${name}.svg`;
|
||||
|
||||
if (unicode && fs.existsSync(resolve(DIR, `icons-outlined/${cachedFilename}`))) {
|
||||
// Get content
|
||||
let cachedContent = fs.readFileSync(resolve(DIR, `icons-outlined/${cachedFilename}`), 'utf-8')
|
||||
|
||||
// Get hash
|
||||
let cachedHash = '';
|
||||
cachedContent = cachedContent.replace(/<!--\!cache:([a-z0-9]+)-->/, function (m, hash) {
|
||||
cachedHash = hash;
|
||||
return '';
|
||||
})
|
||||
|
||||
// Check hash
|
||||
if (crypto.createHash('sha1').update(cachedContent).digest("hex") === cachedHash) {
|
||||
console.log('Cached stroke for:', name, unicode)
|
||||
return true;
|
||||
let filename = `${name}.svg`
|
||||
if (unicode) {
|
||||
filename = `u${unicode.toUpperCase()}-${name}.svg`
|
||||
}
|
||||
|
||||
filesList[type].push(filename)
|
||||
|
||||
content = content
|
||||
.replace('width="24"', 'width="1000"')
|
||||
.replace('height="24"', 'height="1000"')
|
||||
|
||||
if (compileOptions.strokeWidth) {
|
||||
content = content
|
||||
.replace('stroke-width="2"', `stroke-width="${compileOptions.strokeWidth}"`)
|
||||
}
|
||||
|
||||
const cachedFilename = `u${unicode.toUpperCase()}-${name}.svg`;
|
||||
|
||||
if (unicode && fs.existsSync(resolve(DIR, `icons-outlined/${type}/${cachedFilename}`))) {
|
||||
// Get content
|
||||
let cachedContent = fs.readFileSync(resolve(DIR, `icons-outlined/${type}/${cachedFilename}`), 'utf-8')
|
||||
|
||||
// Get hash
|
||||
let cachedHash = '';
|
||||
cachedContent = cachedContent.replace(/<!--\!cache:([a-z0-9]+)-->/, function (m, hash) {
|
||||
cachedHash = hash;
|
||||
return '';
|
||||
})
|
||||
|
||||
// Check hash
|
||||
if (crypto.createHash('sha1').update(cachedContent).digest("hex") === cachedHash) {
|
||||
console.log('Cached stroke for:', name, unicode)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
await outlineStroke(content, {
|
||||
optCurve: true,
|
||||
steps: 4,
|
||||
round: 0,
|
||||
centerHorizontally: true,
|
||||
fixedWidth: false,
|
||||
color: 'black'
|
||||
}).then(outlined => {
|
||||
// Save file
|
||||
fs.writeFileSync(resolve(DIR, `icons-outlined/${type}/${filename}`), outlined, 'utf-8')
|
||||
|
||||
// Fix outline
|
||||
execSync(`fontforge -lang=py -script .build/fix-outline.py icons-outlined/${type}/${filename}`).toString()
|
||||
execSync(`svgo icons-outlined/${type}/${filename}`).toString()
|
||||
|
||||
// Add hash
|
||||
const fixedFileContent = fs
|
||||
.readFileSync(resolve(DIR, `icons-outlined/${type}/${filename}`), 'utf-8')
|
||||
.replace(/\n/g, ' ')
|
||||
.trim(),
|
||||
hashString = `<!--!cache:${crypto.createHash('sha1').update(fixedFileContent).digest("hex")}-->`
|
||||
|
||||
// Save file
|
||||
fs.writeFileSync(
|
||||
resolve(DIR, `icons-outlined/${type}/${filename}`),
|
||||
fixedFileContent + hashString,
|
||||
'utf-8'
|
||||
)
|
||||
}).catch(error => console.log(error))
|
||||
}
|
||||
|
||||
await outlineStroke(contents, {
|
||||
optCurve: true,
|
||||
steps: 4,
|
||||
round: 0,
|
||||
centerHorizontally: true,
|
||||
fixedWidth: false,
|
||||
color: 'black'
|
||||
}).then(outlined => {
|
||||
filesList[filename]
|
||||
|
||||
// Save file
|
||||
fs.writeFileSync(resolve(DIR, `icons-outlined/${filename}`), outlined, 'utf-8')
|
||||
|
||||
// Fix outline
|
||||
execSync(`fontforge -lang=py -script .build/fix-outline.py icons-outlined/${filename}`)
|
||||
execSync(`svgo icons-outlined/${filename}`)
|
||||
|
||||
// Add hash
|
||||
const fixedFileContent = fs
|
||||
.readFileSync(resolve(DIR, `icons-outlined/${filename}`), 'utf-8')
|
||||
.replace(/\n/g, ' ')
|
||||
.trim(),
|
||||
hashString = `<!--!cache:${crypto.createHash('sha1').update(fixedFileContent).digest("hex")}-->`
|
||||
|
||||
// Save file
|
||||
fs.writeFileSync(
|
||||
resolve(DIR, `icons-outlined/${filename}`),
|
||||
fixedFileContent + hashString,
|
||||
'utf-8'
|
||||
)
|
||||
}).catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Remove old files
|
||||
const existedFiles = (await glob(resolve(DIR, `icons-outlined/*.svg`))).map(file => basename(file))
|
||||
|
||||
existedFiles.forEach(file => {
|
||||
if (filesList.indexOf(file) === -1) {
|
||||
console.log('Remove:', file)
|
||||
fs.unlinkSync(resolve(DIR, `icons-outlined/${file}`))
|
||||
}
|
||||
await asyncForEach(Object.entries(icons), async ([type, icons]) => {
|
||||
const existedFiles = (await glob(resolve(DIR, `icons-outlined/${type}/*.svg`))).map(file => basename(file))
|
||||
existedFiles.forEach(file => {
|
||||
if (filesList[type].indexOf(file) === -1) {
|
||||
console.log('Remove:', file)
|
||||
fs.unlinkSync(resolve(DIR, `icons-outlined/${type}/${file}`))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
console.log('Done')
|
||||
|
|
|
|||
|
|
@ -1,54 +1,61 @@
|
|||
import { webfont } from "webfont";
|
||||
import * as fs from 'fs'
|
||||
import template from 'lodash.template'
|
||||
import { getPackageDir, getPackageJson, PACKAGES_DIR, readAliases } from '../../../.build/helpers.mjs'
|
||||
import { getPackageDir, getPackageJson, getAliases, types, asyncForEach } from '../../../.build/helpers.mjs'
|
||||
|
||||
const formats = ['ttf', 'eot', 'woff', 'woff2']
|
||||
const formats = ['ttf', 'woff', 'woff2']
|
||||
const p = getPackageJson()
|
||||
const DIR = getPackageDir('icons-webfont')
|
||||
const fontHeight = 1000
|
||||
|
||||
const aliases = readAliases()
|
||||
const aliases = getAliases(true)
|
||||
|
||||
webfont({
|
||||
files: 'icons-outlined/*.svg',
|
||||
fontName: 'tabler-icons',
|
||||
prependUnicode: true,
|
||||
formats,
|
||||
normalize: true,
|
||||
fontHeight,
|
||||
descent: 100,
|
||||
ascent: 900,
|
||||
fixedWidth: false
|
||||
})
|
||||
fs.mkdirSync(`${DIR}/dist/fonts`, { recursive: true })
|
||||
|
||||
asyncForEach(types, async type => {
|
||||
console.log(`Building webfont for ${type} icons`)
|
||||
|
||||
await webfont({
|
||||
files: `icons-outlined/${type}/*.svg`,
|
||||
fontName: 'tabler-icons',
|
||||
prependUnicode: true,
|
||||
formats,
|
||||
normalize: true,
|
||||
fontHeight,
|
||||
descent: 100,
|
||||
ascent: 900,
|
||||
fixedWidth: false
|
||||
})
|
||||
.then((result) => {
|
||||
formats.forEach(format => {
|
||||
fs.writeFileSync(`${PACKAGES_DIR}/icons-webfont/fonts/tabler-icons.${format}`, result[format])
|
||||
fs.writeFileSync(`${DIR}/dist/fonts/tabler-icons${type !== 'outline' ? `-${type}` : ''}.${format}`, result[format])
|
||||
})
|
||||
|
||||
const glyphs = result.glyphsData
|
||||
.map(icon => icon.metadata)
|
||||
.sort(function(a, b) {
|
||||
return ('' + a.name).localeCompare(b.name)
|
||||
})
|
||||
.map(icon => icon.metadata)
|
||||
.sort(function (a, b) {
|
||||
return ('' + a.name).localeCompare(b.name)
|
||||
})
|
||||
|
||||
let options = {
|
||||
console.log(aliases[type])
|
||||
const options = {
|
||||
fileName: 'tabler-icons',
|
||||
glyphs,
|
||||
v: p.version,
|
||||
aliases
|
||||
aliases: aliases[type] || {}
|
||||
}
|
||||
|
||||
//scss
|
||||
const compiled = template(fs.readFileSync(`${DIR}/.build/iconfont.scss`).toString())
|
||||
const resultSCSS = compiled(options)
|
||||
fs.writeFileSync(`${DIR}/tabler-icons.scss`, resultSCSS)
|
||||
fs.writeFileSync(`${DIR}/dist/tabler-icons${type !== 'outline' ? `-${type}` : ''}.scss`, resultSCSS)
|
||||
|
||||
//html
|
||||
const compiledHtml = template(fs.readFileSync(`${DIR}/.build/iconfont.html`).toString())
|
||||
const resultHtml = compiledHtml(options)
|
||||
fs.writeFileSync(`${DIR}/tabler-icons.html`, resultHtml)
|
||||
fs.writeFileSync(`${DIR}/dist/tabler-icons${type !== 'outline' ? `-${type}` : ''}.html`, resultHtml)
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ $ti-prefix: 'ti' !default;
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: $ti-font-display;
|
||||
src: url('#{$ti-font-path}/<%= fileName %>.eot?v<%= v %>');
|
||||
src: url('#{$ti-font-path}/<%= fileName %>.eot?#iefix-v<%= v %>') format('embedded-opentype'),
|
||||
url('#{$ti-font-path}/<%= fileName %>.woff2?v<%= v %>') format('woff2'),
|
||||
src: url('#{$ti-font-path}/<%= fileName %>.woff2?v<%= v %>') format('woff2'),
|
||||
url('#{$ti-font-path}/<%= fileName %>.woff?') format('woff'),
|
||||
url('#{$ti-font-path}/<%= fileName %>.ttf?v<%= v %>') format('truetype');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,13 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "pnpm run copy && pnpm run build:prepare && pnpm run build:outline && pnpm run build:webfont && pnpm run build:css",
|
||||
"build:prepare": "mkdir -p icons-outlined fonts && rm -fd fonts/*",
|
||||
"build:prepare": "mkdir -p icons-outlined dist && rm -fdr dist/*",
|
||||
"build:outline": "node .build/build-outline.mjs",
|
||||
"build:webfont": "rm -fd fonts/* && node .build/build-webfont.mjs",
|
||||
"build:css": "sass tabler-icons.scss tabler-icons.css --style expanded && sass tabler-icons.scss tabler-icons.min.css --style compressed",
|
||||
"build:clean": "rm -rf ./icons-outlined",
|
||||
"build:webfont": "rm -fd dist/fonts/* && node .build/build-webfont.mjs",
|
||||
"build:css": "pnpm run build:css:outline && pnpm run build:css:filled",
|
||||
"build:css:outline": "sass dist/tabler-icons.scss dist/tabler-icons.css --style expanded && sass dist/tabler-icons.scss dist/tabler-icons.min.css --style compressed",
|
||||
"build:css:filled": "sass dist/tabler-icons-filled.scss dist/tabler-icons-filled.css --style expanded && sass dist/tabler-icons-filled.scss dist/tabler-icons-filled.min.css --style compressed",
|
||||
"clean": "rm -rf dist && rm -rf ./icons-outlined",
|
||||
"copy": "pnpm run copy:license",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE"
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue