UNPKG

svgtofont

Version:

Converts SVG to TTF/EOT/WOFF/WOFF2/SVG format fonts.

231 lines 10.9 kB
import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs-extra'; import image2uri from 'image2uri'; import color from 'colors-cli'; import { autoConf, merge } from 'auto-config-loader'; import { log } from './log.js'; import { generateIconsSource, generateReactIcons, generateReactNativeIcons } from './generate.js'; import { createSVG, createTTF, createEOT, createWOFF, createWOFF2, createSvgSymbol, copyTemplate, createHTML, createTypescript } from './utils.js'; import { generateFontFaceCSS, getDefaultOptions } from './utils.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const loadConfig = async (options) => { const defaultOptions = getDefaultOptions(options); const data = await autoConf('svgtofont', { mustExist: true, default: defaultOptions, ...options.config, }); return merge(defaultOptions, data); }; const handlePkgConfig = (options) => { const pkgPath = path.join(process.cwd(), 'package.json'); if (fs.pathExistsSync(pkgPath)) { const pkg = fs.readJSONSync(pkgPath); if (pkg.svgtofont) { const cssOptions = options.css; options = merge(options, pkg.svgtofont); if (pkg.svgtofont.css && cssOptions && typeof cssOptions === 'object') { options.css = merge(cssOptions, pkg.svgtofont.css); } } if (options.website && pkg.version) { options.website.version = options.website.version ?? pkg.version; } } return options; }; export default async (options = {}) => { options = await loadConfig(options); options = handlePkgConfig(options); if (options.log === undefined) options.log = true; log.disabled = !options.log; if (options.logger && typeof options.logger === 'function') log.logger = options.logger; options.svgicons2svgfont.fontName = options.fontName; options.classNamePrefix = options.classNamePrefix || options.fontName; const excludeFormat = options.excludeFormat || []; const fontSizeOpt = typeof options.css !== 'boolean' && options.css.fontSize; const fontSize = typeof fontSizeOpt === 'boolean' ? (fontSizeOpt === true ? 'font-size: 16px;' : '') : `font-size: ${fontSizeOpt};`; // If you generate a font you need to generate a style. if (options.website && !options.css) options.css = true; const infoDataPath = path.resolve(options.dist, 'info.json'); try { if (options.emptyDist) { await fs.emptyDir(options.dist); } // Ensures that the directory exists. await fs.ensureDir(options.dist); const unicodeObject = await createSVG(options); /** @deprecated */ let cssToVars = []; let cssString = []; let cssRootVars = []; let cssIconHtml = []; let unicodeHtml = []; let symbolHtml = []; const prefix = options.classNamePrefix || options.fontName; const infoData = {}; Object.keys(unicodeObject).forEach((name, index, self) => { if (!infoData[name]) infoData[name] = {}; const _code = unicodeObject[name]; let symbolName = options.classNamePrefix + options.symbolNameDelimiter + name; let iconPart = symbolName + '">'; let encodedCodes = _code.charCodeAt(0); if (options.useNameAsUnicode) { symbolName = name; iconPart = prefix + '">' + name; encodedCodes = _code.split('').map(x => x.charCodeAt(0)).join(';&amp;#'); } else { cssToVars.push(`$${symbolName}: "\\${encodedCodes.toString(16)}";\n`); if (options.useCSSVars) { if (index === 0) cssRootVars.push(`:root {\n`); cssRootVars.push(`--${symbolName}: "\\${encodedCodes.toString(16)}";\n`); cssString.push(`.${symbolName}::before { content: var(--${symbolName}); }\n`); if (index === self.length - 1) cssRootVars.push(`}\n`); } else { cssString.push(`.${symbolName}::before { content: "\\${encodedCodes.toString(16)}"; }\n`); } } infoData[name].encodedCode = `\\${encodedCodes.toString(16)}`; infoData[name].prefix = prefix; infoData[name].className = symbolName; infoData[name].unicode = `&#${encodedCodes};`; cssIconHtml.push(`<li class="class-icon"><i class="${iconPart}</i><p class="name">${name}</p></li>`); unicodeHtml.push(`<li class="unicode-icon"><span class="iconfont">${_code}</span><h4>${name}</h4><span class="unicode">&amp;#${encodedCodes};</span></li>`); symbolHtml.push(` <li class="symbol"> <svg class="icon" aria-hidden="true"> <use xlink:href="${options.fontName}.symbol.svg#${symbolName}"></use> </svg> <h4>${symbolName}</h4> </li> `); }); if (options.useCSSVars) { cssString = [...cssRootVars, ...cssString]; } if (options.generateInfoData) { await fs.writeJSON(infoDataPath, infoData, { spaces: 2 }); log.log(`${color.green('SUCCESS')} Created ${infoDataPath} `); } const ttf = await createTTF(options); if (!excludeFormat.includes('eot')) await createEOT(options, ttf); if (!excludeFormat.includes('woff')) await createWOFF(options, ttf); if (!excludeFormat.includes('woff2')) await createWOFF2(options, ttf); if (!excludeFormat.includes('symbol.svg')) await createSvgSymbol(options); const ttfPath = path.join(options.dist, options.fontName + ".ttf"); if (excludeFormat.includes('ttf')) { fs.removeSync(ttfPath); } const svgPath = path.join(options.dist, options.fontName + ".svg"); if (excludeFormat.includes('svg')) { fs.removeSync(svgPath); } if (options.css) { const styleTemplatePath = options.styleTemplates || path.resolve(__dirname, 'styles'); const outDir = typeof options.css === 'object' ? options.css.output || options.dist : options.dist; const hasTimestamp = typeof options.css === 'object' ? options.css.hasTimestamp : true; const cssOptions = typeof options.css === 'object' ? options.css : {}; const fontFamilyString = generateFontFaceCSS(options.fontName, cssOptions.cssPath || "", Date.now(), excludeFormat, hasTimestamp); await copyTemplate(styleTemplatePath, outDir, { fontname: options.fontName, cssString: cssString.join(''), cssToVars: cssToVars.join(''), infoData, fontSize: fontSize, timestamp: new Date().getTime(), prefix, fontFamily: fontFamilyString, nameAsUnicode: options.useNameAsUnicode, _opts: cssOptions }); } if (options.typescript) { await createTypescript({ ...options, typescript: options.typescript }); } if (options.website) { const pageNames = ['font-class', 'unicode', 'symbol']; const htmlPaths = {}; // setting default home page. const indexName = pageNames.includes(options.website.index) ? options.website.index : 'font-class'; pageNames.forEach(name => { const fileName = name === indexName ? 'index.html' : `${name}.html`; htmlPaths[name] = path.join(options.dist, fileName); }); const fontClassPath = htmlPaths['font-class']; const unicodePath = htmlPaths['unicode']; const symbolPath = htmlPaths['symbol']; // default template options.website.template = options.website.template || path.join(__dirname, 'website', 'index.njk'); // template data const tempData = { meta: null, links: null, corners: null, description: null, footerInfo: null, ...options.website, fontname: options.fontName, classNamePrefix: options.classNamePrefix, _type: 'font-class', _link: `${(options.css && typeof options.css !== 'boolean' && options.css.fileName) || options.fontName}.css`, _IconHtml: cssIconHtml.join(''), _title: options.website.title || options.fontName }; // website logo if (options.website.logo && fs.pathExistsSync(options.website.logo) && path.extname(options.website.logo) === '.svg') { tempData.logo = fs.readFileSync(options.website.logo).toString(); } // website favicon if (options.website.favicon && fs.pathExistsSync(options.website.favicon)) { tempData.favicon = await image2uri(options.website.favicon); } else { tempData.favicon = ''; } const classHtmlStr = await createHTML(options.website.template, tempData); fs.outputFileSync(fontClassPath, classHtmlStr); log.log(`${color.green('SUCCESS')} Created ${fontClassPath} `); tempData._IconHtml = unicodeHtml.join(''); tempData._type = 'unicode'; const unicodeHtmlStr = await createHTML(options.website.template, tempData); fs.outputFileSync(unicodePath, unicodeHtmlStr); log.log(`${color.green('SUCCESS')} Created ${unicodePath} `); tempData._IconHtml = symbolHtml.join(''); tempData._type = 'symbol'; const symbolHtmlStr = await createHTML(options.website.template, tempData); fs.outputFileSync(symbolPath, symbolHtmlStr); log.log(`${color.green('SUCCESS')} Created ${symbolPath} `); } if (options.outSVGPath) { const outPath = await generateIconsSource(options); log.log(`${color.green('SUCCESS')} Created ${outPath} `); } if (options.outSVGReact) { const outPath = await generateReactIcons(options); log.log(`${color.green('SUCCESS')} Created React Components. `); } if (options.outSVGReactNative) { generateReactNativeIcons(options, unicodeObject); log.log(`${color.green('SUCCESS')} Created React Native Components. `); } return infoData; } catch (error) { log.log('SvgToFont:CLI:ERR:', error); } }; //# sourceMappingURL=index.js.map