@hibi_10000/grunt-webfont 2.0.1 → 2.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.
- package/Gruntfile.ts +370 -0
- package/{License.md → LICENSE.md} +1 -0
- package/bin/fontforge/generate.py +1 -1
- package/dist/engines/fontforge.js +10 -5
- package/dist/engines/fontforge.js.map +1 -1
- package/dist/engines/node.js +16 -13
- package/dist/engines/node.js.map +1 -1
- package/dist/package.js +3 -102
- package/dist/package.js.map +1 -1
- package/dist/types.d.ts +13 -13
- package/dist/util/util.js +15 -4
- package/dist/util/util.js.map +1 -1
- package/dist/webfont.d.ts +5 -5
- package/dist/webfont.js +76 -60
- package/dist/webfont.js.map +1 -1
- package/package.json +34 -22
- package/pnpm-workspace.yaml +4 -0
- package/tasks/engines/fontforge.ts +5 -5
- package/tasks/engines/node.ts +3 -4
- package/tasks/types.ts +14 -12
- package/tasks/util/util.ts +18 -12
- package/tasks/webfont.ts +63 -47
- package/templates/demo.html +1 -1
- package/tsconfig.json +3 -10
package/dist/webfont.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webfont.js","names":["logger: Logger","wf.consolaLogger","o: OptionsInternal","wf.fontFormats","wf.UNICODE_PUA_START","name","wf.generatedFontFiles","packageJson","node","fontforge","wf.getFontPath","codepoints: string[]","fontSrcs: { 0: string[], 1: string[] }","wf.fontsSrcsMap","wf.fontSrcSeparators","template","wf.cssFilePrefixes","target"],"sources":["../tasks/webfont.ts"],"sourcesContent":["/**\n * SVG to webfont converter for Grunt\n *\n * @requires ttfautohint\n * @author Artem Sapegin (http://sapegin.me), Hibi_10000\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { globSync } from 'glob';\nimport chalk from 'chalk';\nimport _ from 'lodash';\nimport ttf2woff2 from 'ttf2woff2';\n\nimport fontforge from './engines/fontforge.ts';\nimport node from './engines/node.ts';\nimport * as wf from './util/util.ts';\nimport type { Logger, CustomOutput, TemplateOptions, Config, Options, OptionsInternal, Context } from './types.ts';\n\nimport packageJson from '../package.json' with { type: \"json\" };\n\nexport default (grunt: IGrunt): void => {\n\tgrunt.registerMultiTask('webfont', 'Compile separate SVG files to webfont', function() {\n\t\t/**\n\t\t * Consola to Grunt logger adapter.\n\t\t */\n\t\tconst logger: Logger = {\n\t\t\tlog: {\n\t\t\t\twarn: (...args) => {\n\t\t\t\t\tgrunt.log.warn.apply(null, args);\n\t\t\t\t},\n\t\t\t\terror: (...args) => {\n\t\t\t\t\tgrunt.warn.apply(null, args);\n\t\t\t\t},\n\t\t\t\tinfo: (...args) => {\n\t\t\t\t\tgrunt.log.writeln.apply(null, args);\n\t\t\t\t},\n\t\t\t\tverbose: (...args) => {\n\t\t\t\t\tgrunt.log.verbose.writeln.apply(null, args);\n\t\t\t\t},\n\t\t\t},\n\t\t\tfail: {\n\t\t\t\tfatal: (...args) => {\n\t\t\t\t\tgrunt.fail.fatal.apply(null, args);\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tconst allDone = this.async();\n\t\tconst params = this.data;\n\t\tconst options = this.options<Options>(undefined);\n\n\t\t/*\n\t\t * Check for `src` param on target config\n\t\t */\n\t\tthis.requiresConfig([this.name, this.target, 'src'].join('.'));\n\n\t\twebfont(this.name, this.target, this.filesSrc, params, options, logger).finally(allDone);\n\t});\n};\n\nexport const webfont = async (name: string, target: string, filesSrc: string[], params: Config, options: Options, logger?: Logger): Promise<void> => {\n\tif (!logger) logger = wf.consolaLogger;\n\tconst md5 = crypto.createHash('md5');\n\n\t/*\n\t * Check for `dest` param on either target config or global options object\n\t */\n\tif ((params.dest === undefined) && (options.dest === undefined)) {\n\t\tlogger.log.warn(`Required property ${name}.${target}.dest or ${name}.${target}.options.dest missing.`);\n\t}\n\n\tif (options.skip) {\n\t\tcompleteTask();\n\t\treturn;\n\t}\n\n\t// Source files\n\tconst files = filesSrc.filter(isSvgFile)\n\tif (!files.length) {\n\t\tlogger.log.warn('Specified empty list of source SVG files.');\n\t\tcompleteTask();\n\t\treturn;\n\t}\n\n\t// path must be a string, see https://nodejs.org/api/path.html#path_path_extname_path\n\tif (typeof options.template !== 'string') {\n\t\toptions.template = '';\n\t}\n\n\t// Options\n\tlet o: OptionsInternal = {\n\t\tlogger: logger,\n\t\tfontBaseName: options.font || 'icons',\n\t\tdestCss: options.destCss || params.destCss || params.dest,\n\t\tdestScss: options.destScss || params.destScss || params.destCss || params.dest,\n\t\tdestSass: options.destSass || params.destSass || params.destCss || params.dest,\n\t\tdestLess: options.destLess || params.destLess || params.destCss || params.dest,\n\t\tdestStyl: options.destStyl || params.destStyl || params.destCss || params.dest,\n\t\tdest: options.dest || params.dest,\n\t\trelativeFontPath: options.relativeFontPath,\n\t\tfontPathVariables: options.fontPathVariables || false,\n\t\taddHashes: options.hashes !== false,\n\t\taddLigatures: options.ligatures === true,\n\t\ttemplate: options.template,\n\t\tsyntax: options.syntax || 'bem',\n\t\ttemplateOptions: options.templateOptions || {},\n\t\tstylesheets: options.stylesheets || [options.stylesheet || path.extname(options.template).replace(/^\\./, '') || 'css'],\n\t\thtmlDemo: options.htmlDemo !== false,\n\t\thtmlDemoTemplate: options.htmlDemoTemplate,\n\t\thtmlDemoFilename: options.htmlDemoFilename,\n\t\tstyles: optionToArray(options.styles, 'font,icon'),\n\t\ttypes: optionToArray(options.types, 'eot,woff,ttf'),\n\t\torder: optionToArray(options.order, wf.fontFormats),\n\t\tembed: options.embed === true ? ['woff'] : optionToArray(options.embed, false),\n\t\trename: options.rename || path.basename,\n\t\tengine: options.engine || 'fontforge',\n\t\tautoHint: options.autoHint !== false,\n\t\tcodepoints: options.codepoints,\n\t\tcodepointsFile: options.codepointsFile,\n\t\tstartCodepoint: options.startCodepoint || wf.UNICODE_PUA_START,\n\t\tie7: options.ie7 === true,\n\t\tnormalize: options.normalize === true,\n\t\toptimize: options.optimize === false ? false : true,\n\t\tround: options.round !== undefined ? options.round : 10e12,\n\t\tfontHeight: options.fontHeight !== undefined ? options.fontHeight : 512,\n\t\tdescent: options.descent !== undefined ? options.descent : 64,\n\t\tversion: options.version !== undefined ? options.version : false,\n\t\tcache: options.cache || path.join(import.meta.dirname, '..', '.cache'),\n\t\tcallback: options.callback,\n\t\tcustomOutputs: options.customOutputs,\n\t\texecMaxBuffer: options.execMaxBuffer || 1024 * 200,\n\t};\n\n\to = Object.assign<OptionsInternal, Partial<OptionsInternal>>(o, {\n\t\tfontName: o.fontBaseName,\n\t\tdestCssPaths: {\n\t\t\tcss: o.destCss,\n\t\t\tscss: o.destScss,\n\t\t\tsass: o.destSass,\n\t\t\tless: o.destLess,\n\t\t\tstyl: o.destStyl\n\t\t},\n\t\trelativeFontPath: o.relativeFontPath || path.relative(o.destCss, o.dest),\n\t\tdestHtml: options.destHtml || o.destCss,\n\t\tfontfaceStyles: has(o.styles, 'font'),\n\t\tbaseStyles: has(o.styles, 'icon'),\n\t\textraStyles: has(o.styles, 'extra'),\n\t\tfiles: files,\n\t\tglyphs: [],\n\t});\n\n\to.hash = getHash();\n\to.fontFilename = template(options.fontFilename || o.fontBaseName, o);\n\to.fontFamilyName = template(options.fontFamilyName || o.fontBaseName, o);\n\n\t// “Rename” files\n\to.glyphs = o.files.map((file) => {\n\t\treturn o.rename(file).replace(path.extname(file), '');\n\t});\n\n\t// Check or generate codepoints\n\t// @todo Codepoint can be a Unicode code or character.\n\tlet currentCodepoint = o.startCodepoint;\n\tif (!o.codepoints) o.codepoints = {};\n\tif (o.codepointsFile) o.codepoints = readCodepointsFromFile();\n\to.glyphs.forEach((name) => {\n\t\tif (!o.codepoints[name]) {\n\t\t\to.codepoints[name] = getNextCodepoint();\n\t\t}\n\t});\n\tif (o.codepointsFile) saveCodepointsToFile();\n\n\t// Check if we need to generate font\n\tconst previousHash = readHash(name, target);\n\tlogger.log.verbose('New hash:', o.hash, '- previous hash:', previousHash);\n\tif (o.hash === previousHash) {\n\t\tlogger.log.verbose('Config and source files weren’t changed since last run, checking resulting files...');\n\t\tlet regenerationNeeded = false;\n\n\t\tconst generatedFiles = wf.generatedFontFiles(o);\n\t\tif (!generatedFiles.length){\n\t\t\tregenerationNeeded = true;\n\t\t} else {\n\t\t\tgeneratedFiles.push(getDemoFilePath());\n\t\t\to.stylesheets.forEach((stylesheet) => {\n\t\t\t\tgeneratedFiles.push(getCssFilePath(stylesheet));\n\t\t\t});\n\n\t\t\tregenerationNeeded = generatedFiles.some((filename) => {\n\t\t\t\tif (!filename) return false;\n\t\t\t\tif (!fs.existsSync(filename)) {\n\t\t\t\t\tlogger.log.verbose('File', filename, ' is missed.');\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t\tif (!regenerationNeeded) {\n\t\t\tlogger.log.info(`Font ${chalk.cyan(o.fontName)} wasn’t changed since last run.`);\n\t\t\tcompleteTask();\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Save new hash and run\n\tsaveHash(name, target, o.hash);\n\ttry {\n\t\tcreateOutputDirs();\n\t\tcleanOutputDir();\n\t\tawait generateFont();\n\t\tgenerateWoff2Font();\n\t\tgenerateStylesheets();\n\t\tawait generateDemoHtml();\n\t\tgenerateCustomOutputs();\n\t\tprintDone();\n\t} finally {\n\t\tcompleteTask();\n\t}\n\n\t/**\n\t * Call callback function if it was specified in the options.\n\t */\n\tfunction completeTask(): void {\n\t\tif (o && ((typeof o.callback) === 'function')) {\n\t\t\to.callback(o.fontName, o.types, o.glyphs, o.hash);\n\t\t}\n\t}\n\n\t/**\n\t * Calculate hash to flush browser cache.\n\t * Hash is based on source SVG files contents, task options and grunt-webfont version.\n\t */\n\tfunction getHash(): string {\n\t\t// Source SVG files contents\n\t\to.files.forEach((file) => {\n\t\t\tmd5.update(fs.readFileSync(file, 'utf8'));\n\t\t});\n\n\t\t// Options\n\t\tmd5.update(JSON.stringify(o));\n\n\t\t// grunt-webfont version\n\t\tmd5.update(packageJson.version);\n\n\t\t// Templates\n\t\tif (o.template) {\n\t\t\tmd5.update(fs.readFileSync(o.template, 'utf8'));\n\t\t}\n\t\tif (o.htmlDemoTemplate) {\n\t\t\tmd5.update(fs.readFileSync(o.htmlDemoTemplate, 'utf8'));\n\t\t}\n\n\t\treturn md5.digest('hex');\n\t}\n\n\t/**\n\t * Create output directory\n\t */\n\tfunction createOutputDirs(): void {\n\t\to.stylesheets.forEach((stylesheet) => {\n\t\t\tfs.mkdirSync(option(o.destCssPaths, stylesheet), { recursive: true });\n\t\t});\n\t\tfs.mkdirSync(o.dest, { recursive: true });\n\t}\n\n\t/**\n\t * Clean output directory\n\t */\n\tfunction cleanOutputDir(): void {\n\t\tconst htmlDemoFileMask = path.posix.join(o.destCss, `${o.fontBaseName}*.{css,html}`);\n\t\tconst files = globSync(htmlDemoFileMask).concat(wf.generatedFontFiles(o));\n\t\tfiles.forEach(file => {\n\t\t\tfs.unlinkSync(file);\n\t\t});\n\t}\n\n\t/**\n\t * Generate font using selected engine\n\t */\n\tasync function generateFont(): Promise<void> {\n\t\tconst f = o.engine === 'node' ? node : fontforge;\n\t\tconst result = await f(o);\n\t\tif (result === false) {\n\t\t\t// Font was not created, exit\n\t\t\tcompleteTask();\n\t\t\treturn;\n\t\t}\n\n\t\tif (result) {\n\t\t\to = Object.assign(o, result);\n\t\t}\n\t}\n\n\t/**\n\t * Converts TTF font to WOFF2.\n\t */\n\tfunction generateWoff2Font(): void {\n\t\tif (!has(o.types, 'woff2')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Read TTF font\n\t\tconst ttfFontPath = wf.getFontPath(o, 'ttf');\n\t\tconst ttfFont = fs.readFileSync(ttfFontPath);\n\n\t\t// Remove TTF font if not needed\n\t\tif (!has(o.types, 'ttf')) {\n\t\t\tfs.unlinkSync(ttfFontPath);\n\t\t}\n\n\t\t// Convert to WOFF2\n\t\tconst woffFont = ttf2woff2(ttfFont);\n\n\t\t// Save\n\t\tconst woff2FontPath = wf.getFontPath(o, 'woff2');\n\t\tfs.writeFileSync(woff2FontPath, woffFont);\n\t}\n\n\t/**\n\t * Generate CSS\n\t */\n\tfunction generateStylesheets(): void {\n\t\t// Convert codepoints to array of strings\n\t\tconst codepoints: string[] = [];\n\t\to.glyphs.forEach((name) => {\n\t\t\tcodepoints.push(o.codepoints[name].toString(16));\n\t\t});\n\t\t//@ts-ignore\n\t\to.codepoints = codepoints;\n\n\t\t// Prepage glyph names to use as CSS classes\n\t\to.glyphs = o.glyphs.map(classnameize);\n\n\t\to.stylesheets.sort((a, b) => {\n\t\t\treturn a === 'css' ? 1 : -1;\n\t\t}).forEach(generateStylesheet);\n\t}\n\n\t/**\n\t * Generate CSS\n\t *\n\t * @param stylesheet type: css, scss, ...\n\t */\n\tfunction generateStylesheet(stylesheet: string): void {\n\t\to.relativeFontPath = normalizePath(o.relativeFontPath);\n\n\t\t// Generate font URLs to use in @font-face\n\t\tconst fontSrcs: { 0: string[], 1: string[] } = { 0: [], 1: [] };\n\t\to.order.forEach((type: 'eot'|'woff2'|'woff'|'ttf'|'svg') => {\n\t\t\tif (!has(o.types, type)) return;\n\t\t\tconst fontSrc1 = wf.fontsSrcsMap[type][0];\n\t\t\tif (fontSrc1) fontSrcs[0].push(generateFontSrc(type, fontSrc1, stylesheet));\n\t\t\tfontSrcs[1].push(generateFontSrc(type, wf.fontsSrcsMap[type][1], stylesheet));\n\t\t});\n\n\t\t// Convert urls to strings that could be used in CSS\n\t\tconst fontSrcSeparator = option(wf.fontSrcSeparators, stylesheet);\n\t\to.fontSrc1 = fontSrcs[0].join(fontSrcSeparator);\n\t\to.fontSrc2 = fontSrcs[1].join(fontSrcSeparator);\n\t\to.fontRawSrcs = [fontSrcs[0], fontSrcs[1]];\n\n\t\t// Read JSON file corresponding to CSS template\n\t\tconst templateJson = readTemplate(o.template, o.syntax, '.json', true);\n\t\tif (templateJson) o = Object.assign<OptionsInternal, Required<TemplateOptions>>(o, JSON.parse(templateJson.template));\n\n\t\t// Now override values with templateOptions\n\t\tif (o.templateOptions) o = Object.assign(o, o.templateOptions);\n\n\t\t// Generate CSS\n\t\tconst ext = path.extname(o.template) || '.css'; // Use extension of o.template file if given, or default to .css\n\t\to.cssTemplate = readTemplate(o.template, o.syntax, ext);\n\t\tconst cssContext = Object.assign<OptionsInternal, Partial<Context>>(o, {\n\t\t\ticonsStyles: true,\n\t\t\tstylesheet: stylesheet,\n\t\t});\n\n\t\tlet css = renderTemplate(o.cssTemplate, cssContext);\n\n\t\t// Fix CSS preprocessors comments: single line comments will be removed after compilation\n\t\tif (has(['sass', 'scss', 'less', 'styl'], stylesheet)) {\n\t\t\tcss = css.replace(/\\/\\* *(.*?) *\\*\\//g, '// $1');\n\t\t}\n\n\t\t// Save file\n\t\tfs.writeFileSync(getCssFilePath(stylesheet), css);\n\t}\n\n\t/**\n\t * Gets the codepoints from the set filepath in o.codepointsFile\n\t */\n\tfunction readCodepointsFromFile(): { [key: string]: number } {\n\t\tif (!o.codepointsFile) return {};\n\t\tif (!fs.existsSync(o.codepointsFile)){\n\t\t\tlogger.log.verbose('Codepoints file not found');\n\t\t\treturn {};\n\t\t}\n\n\t\tconst buffer = fs.readFileSync(o.codepointsFile);\n\t\treturn JSON.parse(buffer.toString());\n\t}\n\n\t/**\n\t * Saves the codespoints to the set file\n\t */\n\tfunction saveCodepointsToFile(): void {\n\t\tif (!o.codepointsFile) return;\n\t\tconst codepointsToString = JSON.stringify(o.codepoints, null, 4);\n\t\ttry {\n\t\t\tfs.writeFileSync(o.codepointsFile, codepointsToString);\n\t\t\tlogger.log.verbose(`Codepoints saved to file \"${o.codepointsFile}\".`);\n\t\t} catch (err) {\n\t\t\tlogger.log.error(err.message);\n\t\t}\n\t}\n\n\t/*\n\t * Prepares base context for templates\n\t */\n\tfunction prepareBaseTemplateContext(): Context {\n\t\tconst context = Object.assign<{}, Context>({}, o);\n\t\treturn context;\n\t}\n\n\t/*\n\t * Makes custom extends necessary for use with preparing the template context\n\t * object for the HTML demo.\n\t */\n\tfunction prepareHtmlTemplateContext(): Context {\n\n\t\tlet context = prepareBaseTemplateContext();\n\n\t\tlet htmlStyles;\n\n\t\t// Prepare relative font paths for injection into @font-face refs in HTML\n\t\tconst relativeRe = new RegExp(_.escapeRegExp(o.relativeFontPath).replace(/[=!:\\/]/g, '\\\\$&'), 'g');\n\t\tconst htmlRelativeFontPath = normalizePath(path.relative(o.destHtml, o.dest));\n\t\tconst _fontSrc1 = o.fontSrc1.replace(relativeRe, htmlRelativeFontPath);\n\t\tconst _fontSrc2 = o.fontSrc2.replace(relativeRe, htmlRelativeFontPath);\n\n\t\tcontext = Object.assign<Context, Partial<Context>>(context, {\n\t\t\tfontSrc1: _fontSrc1,\n\t\t\tfontSrc2: _fontSrc2,\n\t\t\tfontfaceStyles: true,\n\t\t\tbaseStyles: true,\n\t\t\textraStyles: false,\n\t\t\ticonsStyles: true,\n\t\t\tstylesheet: 'css',\n\t\t});\n\n\t\t// Prepares CSS for injection into <style> tag at to of HTML\n\t\thtmlStyles = renderTemplate(o.cssTemplate, context);\n\t\tcontext = Object.assign<Context, Partial<Context>>(context, {\n\t\t\tstyles: htmlStyles,\n\t\t});\n\n\t\treturn context;\n\t}\n\n\t/**\n\t * Iterator function used as callback by looping construct below to\n\t * render \"custom output\" via mini configuration objects specified in\n\t * the array `options.customOutputs`.\n\t *\n\t * @param outputConfig\n\t */\n\tfunction generateCustomOutput(outputConfig: CustomOutput): void {\n\n\t\t// Accesses context\n\t\tlet context = prepareBaseTemplateContext();\n\t\tcontext = Object.assign(context, outputConfig.context);\n\n\t\t// Prepares config attributes related to template filepath\n\t\tconst templatePath = outputConfig.template;\n\t\tconst extension = path.extname(templatePath);\n\t\tconst syntax = outputConfig.syntax || '';\n\n\t\t// Renders template with given context\n\t\tconst template = readTemplate(templatePath, syntax, extension);\n\t\tconst output = renderTemplate(template, context);\n\n\t\t// Prepares config attributes related to destination filepath\n\t\tconst dest = outputConfig.dest || o.dest;\n\n\t\tlet filepath;\n\t\tlet destParent;\n\t\tlet destName;\n\n\t\tif (path.extname(dest) === '') {\n\t\t\t// If user specifies a directory, filename should be same as template\n\t\t\tdestParent = dest;\n\t\t\tdestName = path.basename(outputConfig.template);\n\t\t\tfilepath = path.join(dest, destName);\n\t\t} else {\n\t\t\t// If user specifies a file, that is our filepath\n\t\t\tdestParent = path.dirname(dest);\n\t\t\tfilepath = dest;\n\t\t}\n\n\t\t// Ensure existence of parent directory and output to file as desired\n\t\tfs.mkdirSync(destParent, { recursive: true });\n\t\tfs.writeFileSync(filepath, output);\n\t}\n\n\t/*\n\t * Iterates over entries in the `options.customOutputs` object and,\n\t * on a config-by-config basis, generates the desired results.\n\t */\n\tfunction generateCustomOutputs(): void {\n\t\tif (!o.customOutputs || o.customOutputs.length < 1) {\n\t\t\treturn;\n\t\t}\n\n\t\to.customOutputs.forEach(generateCustomOutput);\n\t}\n\n\t/**\n\t * Generate HTML demo page\n\t */\n\tasync function generateDemoHtml(): Promise<void> {\n\t\tif (!o.htmlDemo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst context = prepareHtmlTemplateContext();\n\n\t\t// Generate HTML\n\t\tconst demoTemplate = readTemplate(o.htmlDemoTemplate, 'demo', '.html');\n\t\tconst demo = renderTemplate(demoTemplate, context);\n\n\t\ttry {\n\t\t\tawait fs.promises.mkdir(getDemoPath(), { recursive: true });\n\t\t} catch (err) {\n\t\t\tif (err) {\n\t\t\t\tlogger.log.info(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// Save file\n\t\tfs.writeFileSync(getDemoFilePath(), demo);\n\n\t}\n\n\t/**\n\t * Print log\n\t */\n\tfunction printDone(): void {\n\t\tlogger.log.info(`Font ${chalk.cyan(o.fontName)} with ${o.glyphs.length} glyphs created.`);\n\t}\n\n\n\t/**\n\t * Helpers\n\t */\n\n\t/**\n\t * Convert a string of comma separated words into an array\n\t *\n\t * @param val Input string\n\t * @param defVal Default value\n\t */\n\tfunction optionToArray(val: string | false, defVal: string | false): string[] {\n\t\tif (val === undefined) {\n\t\t\tval = defVal;\n\t\t}\n\t\tif (!val) {\n\t\t\treturn [];\n\t\t}\n\t\tif (typeof val !== 'string') {\n\t\t\treturn val;\n\t\t}\n\t\treturn val.split(',').map((value) => value.trim());\n\t}\n\n\t/**\n\t * Check if a value exists in an array\n\t *\n\t * @param haystack Array to find the needle in\n\t * @param needle Value to find\n\t * @return Needle was found\n\t */\n\tfunction has(haystack: string[] | string, needle: string): boolean {\n\t\treturn haystack.indexOf(needle) !== -1;\n\t}\n\n\t/**\n\t * Return a specified option if it exists in an object or `_default` otherwise\n\t *\n\t * @param map Options object\n\t * @param key Option to find in the object\n\t */\n\tfunction option(map: { _default?: string, [key: string]: string }, key: string): string {\n\t\tif (key in map) {\n\t\t\treturn map[key];\n\t\t} else {\n\t\t\treturn map._default;\n\t\t}\n\t}\n\n\t/**\n\t * Find next unused codepoint.\n\t */\n\tfunction getNextCodepoint(): number {\n\t\twhile (Object.values(o.codepoints).includes(currentCodepoint)) {\n\t\t\tcurrentCodepoint++;\n\t\t}\n\t\treturn currentCodepoint;\n\t}\n\n\t/**\n\t * Check whether file is SVG or not\n\t *\n\t * @param filepath File path\n\t */\n\tfunction isSvgFile(filepath: string): boolean {\n\t\treturn path.extname(filepath).toLowerCase() === '.svg';\n\t}\n\n\t/**\n\t * Convert font file to data:uri and remove source file\n\t *\n\t * @param fontFile Font file path\n\t * @return Base64 encoded string\n\t */\n\tfunction embedFont(fontFile: string): string {\n\t\t// Convert to data:uri\n\t\tconst dataUri = fs.readFileSync(fontFile, 'base64');\n\t\tconst type = path.extname(fontFile).substring(1);\n\t\tconst fontUrl = `data:application/x-font-${type};charset=utf-8;base64,${dataUri}`;\n\n\t\t// Remove font file\n\t\tfs.unlinkSync(fontFile);\n\n\t\treturn fontUrl;\n\t}\n\n\t/**\n\t * Append a slash to end of a filepath if it not exists and make all slashes forward\n\t *\n\t * @param filepath File path\n\t */\n\tfunction normalizePath(filepath: string): string {\n\t\tif (!filepath.length) return filepath;\n\n\t\t// Make all slashes forward\n\t\tfilepath = filepath.replace(/\\\\/g, '/');\n\n\t\t// Make sure path ends with a slash\n\t\tif (!filepath.endsWith('/')) {\n\t\t\tfilepath += '/';\n\t\t}\n\n\t\treturn filepath;\n\t}\n\n\t/**\n\t * Generate URL for @font-face\n\t *\n\t * @param type Type of font\n\t * @param font URL or Base64 string\n\t * @param stylesheet type: css, scss, ...\n\t */\n\tfunction generateFontSrc(type: string, font: { ext: string, format?: string, embeddable?: boolean }, stylesheet: string): string {\n\t\tconst filename = template(`${o.fontFilename}${font.ext}`, o);\n\t\tlet fontPathVariableName = `${o.fontFamilyName}-font-path`;\n\n\t\tlet url;\n\t\tif (font.embeddable && has(o.embed, type)) {\n\t\t\turl = embedFont(path.join(o.dest, filename));\n\t\t} else {\n\t\t\tif (o.fontPathVariables && stylesheet !== 'css') {\n\t\t\t\tif (stylesheet === 'less') {\n\t\t\t\t\tfontPathVariableName = `@${fontPathVariableName}`;\n\t\t\t\t\to.fontPathVariable = `${fontPathVariableName} : \"${o.relativeFontPath}\";`;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfontPathVariableName = `$${fontPathVariableName}`;\n\t\t\t\t\to.fontPathVariable = `${fontPathVariableName} : \"${o.relativeFontPath}\" !default;`;\n\t\t\t\t}\n\t\t\t\turl = filename;\n\t\t\t}\n\t\t\telse {\n\t\t\t\turl = `${o.relativeFontPath}${filename}`;\n\t\t\t}\n\t\t\tif (o.addHashes) {\n\t\t\t\tif (url.indexOf('#iefix') === -1) { // Do not add hashes for OldIE\n\t\t\t\t\t// Put hash at the end of an URL or before #hash\n\t\t\t\t\turl = url.replace(/(#|$)/, `?${o.hash}$1`);\n\t\t\t\t} else {\n\t\t\t\t\turl = url.replace(/(#|$)/, `${o.hash}$1`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet src = `url(\"${url}\")`;\n\t\tif (o.fontPathVariables && stylesheet !== 'css') {\n\t\t\tif (stylesheet === 'less') {\n\t\t\t\tsrc = `url(\"@{${fontPathVariableName.replace('@','')}}${url}\")`;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsrc = `url(${fontPathVariableName} + \"${url}\")`;\n\t\t\t}\n\t\t}\n\n\t\tif (font.format) src += ` format(\"${font.format}\")`;\n\n\t\treturn src;\n\t}\n\n\t/**\n\t * Read the template file\n\t *\n\t * @param template Template file path\n\t * @param syntax Syntax (bem, bootstrap, etc.)\n\t * @param ext Extension of the template\n\t * @return \\{filename: 'Template filename', template: 'Template code'}\n\t */\n\tfunction readTemplate(template: string, syntax: string, ext: string, optional?: boolean): { filename: string, template: string } {\n\t\tconst filename = template\n\t\t\t? path.resolve(template.replace(path.extname(template), ext))\n\t\t\t: path.join(import.meta.dirname, `../templates/${syntax}${ext}`)\n\t\t;\n\t\tif (fs.existsSync(filename)) {\n\t\t\treturn {\n\t\t\t\tfilename: filename,\n\t\t\t\ttemplate: fs.readFileSync(filename, 'utf8'),\n\t\t\t};\n\t\t} else if (!optional) {\n\t\t\tlogger.fail.fatal(`Cannot find template at path: ${filename}`);\n\t\t}\n\t}\n\n\t/**\n\t * Render template with error reporting\n\t *\n\t * @param template {filename: 'Template filename', template: 'Template code'}\n\t * @param context Template context\n\t */\n\tfunction renderTemplate(template: { filename: string, template: string }, context: Context): string {\n\t\ttry {\n\t\t\tconst func = _.template(template.template);\n\t\t\treturn func(context);\n\t\t} catch (e) {\n\t\t\tlogger.fail.fatal(`Error while rendering template ${template.filename}: ${e.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Basic template function: replaces {variables}\n\t *\n\t * @param tmpl Template code\n\t * @param context Values object\n\t */\n\tfunction template(tmpl: string, context: OptionsInternal): string {\n\t\treturn tmpl.replace(/\\{([^\\}]+)\\}/g, (m, key: keyof OptionsInternal) => {\n\t\t\treturn context[key] as string;\n\t\t});\n\t}\n\n\t/**\n\t * Prepare string to use as CSS class name\n\t *\n\t * @param str\n\t */\n\tfunction classnameize(str: string): string {\n\t\treturn str.trim().replace(/\\s+/g, '-');\n\t}\n\n\t/**\n\t * Return path of CSS file.\n\t *\n\t * @param stylesheet (css, scss, ...)\n\t */\n\tfunction getCssFilePath(stylesheet: string): string {\n\t\tconst cssFilePrefix = option(wf.cssFilePrefixes, stylesheet);\n\t\treturn path.join(option(o.destCssPaths, stylesheet), `${cssFilePrefix}${o.fontBaseName}.${stylesheet}`);\n\t}\n\n\t/**\n\t * Return path of HTML demo file or `null` if its generation was disabled.\n\t */\n\tfunction getDemoFilePath(): string {\n\t\tif (!o.htmlDemo) return null;\n\t\tconst name = o.htmlDemoFilename || o.fontBaseName;\n\t\treturn path.join(o.destHtml, `${name}.html`);\n\t}\n\n\t/**\n\t * Return path of HTML demo file or `null` if feature was disabled\n\t */\n\tfunction getDemoPath(): string {\n\t\tif (!o.htmlDemo) return null;\n\t\treturn o.destHtml;\n\t}\n\n\t/**\n\t * Save hash to cache file.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t * @param hash Hash.\n\t */\n\tfunction saveHash(name: string, target: string, hash: string): void {\n\t\tconst filepath = getHashPath(name, target);\n\t\tfs.mkdirSync(path.dirname(filepath), { recursive: true });\n\t\tfs.writeFileSync(filepath, hash);\n\t}\n\n\t/**\n\t * Read hash from cache file or `null` if file don’t exist.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t */\n\tfunction readHash(name: string, target: string): string {\n\t\tconst filepath = getHashPath(name, target);\n\t\tif (fs.existsSync(filepath)) {\n\t\t\treturn fs.readFileSync(filepath, 'utf8');\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Return path to cache file.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t */\n\tfunction getHashPath(name: string, target: string): string {\n\t\treturn path.join(o.cache, name, target, 'hash');\n\t}\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webfont.js","names":["wf.consolaLogger","wf.fontFormats","wf.generatedFontFiles","packageJson.version","node","fontforge","wf.getFontPath","wf.fontsSrcsMap","wf.fontSrcSeparators","wf.cssFilePrefixes"],"sources":["../tasks/webfont.ts"],"sourcesContent":["/**\n * SVG to webfont converter for Grunt\n *\n * @requires ttfautohint\n * @author Artem Sapegin (http://sapegin.me), Hibi_10000\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { globSync } from 'glob';\nimport chalk from 'chalk';\nimport { Eta } from 'eta';\nimport ttf2woff2 from 'ttf2woff2';\n\nimport fontforge from './engines/fontforge.ts';\nimport node from './engines/node.ts';\nimport * as wf from './util/util.ts';\nimport type { Logger, FontFormat, CustomOutput, TemplateOptions, Config, Options, OptionsInternal, Context } from './types.ts';\n\nimport packageJson from '../package.json' with { type: \"json\" };\n\nexport const webfontGrunt = (grunt: IGrunt): void => {\n\tgrunt.registerMultiTask('webfont', 'Compile separate SVG files to webfont', function() {\n\t\t/**\n\t\t * Consola to Grunt logger adapter.\n\t\t */\n\t\tconst logger: Logger = {\n\t\t\tlog: {\n\t\t\t\terror: grunt.warn,\n\t\t\t\twarn: grunt.log.warn,\n\t\t\t\tinfo: grunt.log.writeln,\n\t\t\t\tverbose: grunt.log.verbose.writeln,\n\t\t\t},\n\t\t\tfail: {\n\t\t\t\tfatal: grunt.fail.fatal,\n\t\t\t},\n\t\t} as const;\n\n\t\tconst allDone = this.async();\n\t\tconst params = this.data;\n\t\tconst options = this.options<Options>(undefined);\n\n\t\t/*\n\t\t * Check for `src` param on target config\n\t\t */\n\t\tthis.requiresConfig([this.name, this.target, 'src'].join('.'));\n\n\t\twebfontMain(this.name, this.target, this.filesSrc, params, options, logger).finally(allDone);\n\t});\n};\n\nexport const webfont = async (targetName: string, config: Config): Promise<void> => {\n\tconst filesSrc = globSync(config.src, { posix: true });\n\tawait webfontMain(\"webfont\", targetName, filesSrc, config);\n}\n\nconst webfontGruntCjs = (grunt: IGrunt): void => webfontGrunt(grunt);\nObject.assign(webfontGruntCjs, {\n\tdefault: webfontGrunt,\n\twebfont: webfont,\n});\n\nexport { webfontGrunt as default, webfontGruntCjs as \"module.exports\" };\n\nconst webfontMain = async (\n\tname: string,\n\ttarget: string,\n\tfilesSrc: string[],\n\tparams: Config,\n\toptions: Options = params.options ?? {},\n\tlogger: Logger = wf.consolaLogger,\n): Promise<void> => {\n\tconst md5 = crypto.createHash('md5');\n\n\t/*\n\t * Check for `dest` param on either target config or global options object\n\t */\n\tif ((params.dest === undefined) && (options.dest === undefined)) {\n\t\tlogger.log.warn(`Required property ${name}.${target}.dest or ${name}.${target}.options.dest missing.`);\n\t}\n\n\tif (options.skip) {\n\t\tcompleteTask();\n\t\treturn;\n\t}\n\n\t// Source files\n\tconst files = filesSrc.filter(isSvgFile)\n\tif (!files.length) {\n\t\tlogger.log.warn('Specified empty list of source SVG files.');\n\t\tcompleteTask();\n\t\treturn;\n\t}\n\n\t// path must be a string, see https://nodejs.org/api/path.html#path_path_extname_path\n\tif (typeof options.template !== 'string') {\n\t\toptions.template = '';\n\t}\n\n\t// Options\n\tlet o: OptionsInternal = {\n\t\tlogger: logger,\n\t\tfontBaseName: options.font || 'icons',\n\t\tdestCss: options.destCss || params.destCss || params.dest,\n\t\tdestScss: options.destScss || params.destScss || params.destCss || params.dest,\n\t\tdestSass: options.destSass || params.destSass || params.destCss || params.dest,\n\t\tdestLess: options.destLess || params.destLess || params.destCss || params.dest,\n\t\tdestStyl: options.destStyl || params.destStyl || params.destCss || params.dest,\n\t\tdest: options.dest || params.dest,\n\t\trelativeFontPath: options.relativeFontPath,\n\t\tfontPathVariables: options.fontPathVariables || false,\n\t\taddHashes: options.hashes !== false,\n\t\taddLigatures: options.ligatures === true,\n\t\ttemplate: options.template,\n\t\tsyntax: options.syntax || 'bem',\n\t\ttemplateOptions: options.templateOptions || {},\n\t\tstylesheets: options.stylesheets || [options.stylesheet || path.extname(options.template).replace(/^\\./, '') || 'css'],\n\t\thtmlDemo: options.htmlDemo !== false,\n\t\thtmlDemoTemplate: options.htmlDemoTemplate,\n\t\thtmlDemoFilename: options.htmlDemoFilename,\n\t\tstyles: optionToArray(options.styles, ['font', 'icon']),\n\t\ttypes: optionToArray<FontFormat>(options.types, ['eot', 'woff', 'ttf']),\n\t\torder: optionToArray<FontFormat>(options.order, wf.fontFormats),\n\t\tembed: options.embed === true ? ['woff'] : optionToArray<FontFormat>(options.embed, false),\n\t\trename: options.rename || path.basename,\n\t\tengine: options.engine || 'fontforge',\n\t\tautoHint: options.autoHint !== false,\n\t\tcodepoints: options.codepoints,\n\t\tcodepointsFile: options.codepointsFile,\n\t\tstartCodepoint: options.startCodepoint || wf.UNICODE_PUA_START,\n\t\tie7: options.ie7 === true,\n\t\tnormalize: options.normalize === true,\n\t\toptimize: options.optimize === false ? false : true,\n\t\tround: options.round !== undefined ? options.round : 10e12,\n\t\tfontHeight: options.fontHeight !== undefined ? options.fontHeight : 512,\n\t\tdescent: options.descent !== undefined ? options.descent : 64,\n\t\tversion: options.version !== undefined ? options.version : false,\n\t\tcache: options.cache || path.join(import.meta.dirname, '..', '.cache'),\n\t\tcallback: options.callback,\n\t\tcustomOutputs: options.customOutputs,\n\t\texecMaxBuffer: options.execMaxBuffer || 1024 * 200,\n\t};\n\n\to = Object.assign<OptionsInternal, Partial<OptionsInternal>>(o, {\n\t\tfontName: o.fontBaseName,\n\t\tdestCssPaths: {\n\t\t\tcss: o.destCss,\n\t\t\tscss: o.destScss,\n\t\t\tsass: o.destSass,\n\t\t\tless: o.destLess,\n\t\t\tstyl: o.destStyl\n\t\t},\n\t\trelativeFontPath: o.relativeFontPath || path.relative(o.destCss, o.dest),\n\t\tdestHtml: options.destHtml || o.destCss,\n\t\tfontfaceStyles: has(o.styles, 'font'),\n\t\tbaseStyles: has(o.styles, 'icon'),\n\t\textraStyles: has(o.styles, 'extra'),\n\t\tfiles: files,\n\t\tglyphs: [],\n\t});\n\n\to.hash = getHash();\n\to.fontFilename = template(options.fontFilename || o.fontBaseName, o);\n\to.fontFamilyName = template(options.fontFamilyName || o.fontBaseName, o);\n\n\t// “Rename” files\n\to.glyphs = o.files.map((file) => {\n\t\treturn o.rename(file).replace(path.extname(file), '');\n\t});\n\n\t// Check or generate codepoints\n\t// @todo Codepoint can be a Unicode code or character.\n\tlet currentCodepoint = o.startCodepoint;\n\tif (!o.codepoints) o.codepoints = {};\n\tif (o.codepointsFile) o.codepoints = readCodepointsFromFile();\n\to.glyphs.forEach((name) => {\n\t\tif (!o.codepoints[name]) {\n\t\t\to.codepoints[name] = getNextCodepoint();\n\t\t}\n\t});\n\tif (o.codepointsFile) saveCodepointsToFile();\n\n\t// Check if we need to generate font\n\tconst previousHash = readHash(name, target);\n\tlogger.log.verbose(`New hash: ${o.hash} - previous hash: ${previousHash}`);\n\tif (o.hash === previousHash) {\n\t\tlogger.log.verbose('Config and source files weren’t changed since last run, checking resulting files...');\n\t\tlet regenerationNeeded = false;\n\n\t\tconst generatedFiles = wf.generatedFontFiles(o);\n\t\tif (!generatedFiles.length){\n\t\t\tregenerationNeeded = true;\n\t\t} else {\n\t\t\tgeneratedFiles.push(getDemoFilePath());\n\t\t\to.stylesheets.forEach((stylesheet) => {\n\t\t\t\tgeneratedFiles.push(getCssFilePath(stylesheet));\n\t\t\t});\n\n\t\t\tregenerationNeeded = generatedFiles.some((filename) => {\n\t\t\t\tif (!filename) return false;\n\t\t\t\tif (!fs.existsSync(filename)) {\n\t\t\t\t\tlogger.log.verbose(`File ${filename} is missed.`);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t\tif (!regenerationNeeded) {\n\t\t\tlogger.log.info(`Font ${chalk.cyan(o.fontName)} wasn’t changed since last run.`);\n\t\t\tcompleteTask();\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Save new hash and run\n\tsaveHash(name, target, o.hash);\n\ttry {\n\t\tcreateOutputDirs();\n\t\tcleanOutputDir();\n\t\tawait generateFont();\n\t\tgenerateWoff2Font();\n\t\tgenerateStylesheets();\n\t\tawait generateDemoHtml();\n\t\tgenerateCustomOutputs();\n\t\tprintDone();\n\t} finally {\n\t\tcompleteTask();\n\t}\n\n\t/**\n\t * Call callback function if it was specified in the options.\n\t */\n\tfunction completeTask(): void {\n\t\tif (o && ((typeof o.callback) === 'function')) {\n\t\t\to.callback(o.fontName, o.types, o.glyphs, o.hash);\n\t\t}\n\t}\n\n\t/**\n\t * Calculate hash to flush browser cache.\n\t * Hash is based on source SVG files contents, task options and grunt-webfont version.\n\t */\n\tfunction getHash(): string {\n\t\t// Source SVG files contents\n\t\to.files.forEach((file) => {\n\t\t\tmd5.update(fs.readFileSync(file, 'utf8'));\n\t\t});\n\n\t\t// Options\n\t\tmd5.update(JSON.stringify(o));\n\n\t\t// grunt-webfont version\n\t\tmd5.update(packageJson.version);\n\n\t\t// Templates\n\t\tif (o.template) {\n\t\t\tmd5.update(fs.readFileSync(o.template, 'utf8'));\n\t\t}\n\t\tif (o.htmlDemoTemplate) {\n\t\t\tmd5.update(fs.readFileSync(o.htmlDemoTemplate, 'utf8'));\n\t\t}\n\n\t\treturn md5.digest('hex');\n\t}\n\n\t/**\n\t * Create output directory\n\t */\n\tfunction createOutputDirs(): void {\n\t\to.stylesheets.forEach((stylesheet) => {\n\t\t\tfs.mkdirSync(option(o.destCssPaths, stylesheet), { recursive: true });\n\t\t});\n\t\tfs.mkdirSync(o.dest, { recursive: true });\n\t}\n\n\t/**\n\t * Clean output directory\n\t */\n\tfunction cleanOutputDir(): void {\n\t\tconst htmlDemoFileMask = path.posix.join(o.destCss, `${o.fontBaseName}*.{css,html}`);\n\t\tconst files = globSync(htmlDemoFileMask).concat(wf.generatedFontFiles(o));\n\t\tfiles.forEach(file => {\n\t\t\tfs.unlinkSync(file);\n\t\t});\n\t}\n\n\t/**\n\t * Generate font using selected engine\n\t */\n\tasync function generateFont(): Promise<void> {\n\t\tconst f = o.engine === 'node' ? node : fontforge;\n\t\tconst result = await f(o);\n\t\tif (result === false) {\n\t\t\t// Font was not created, exit\n\t\t\tcompleteTask();\n\t\t\treturn;\n\t\t}\n\n\t\tif (result) {\n\t\t\to = Object.assign(o, result);\n\t\t}\n\t}\n\n\t/**\n\t * Converts TTF font to WOFF2.\n\t */\n\tfunction generateWoff2Font(): void {\n\t\tif (!has(o.types, 'woff2')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Read TTF font\n\t\tconst ttfFontPath = wf.getFontPath(o, 'ttf');\n\t\tconst ttfFont = fs.readFileSync(ttfFontPath);\n\n\t\t// Remove TTF font if not needed\n\t\tif (!has(o.types, 'ttf')) {\n\t\t\tfs.unlinkSync(ttfFontPath);\n\t\t}\n\n\t\t// Convert to WOFF2\n\t\tconst woffFont = ttf2woff2(ttfFont);\n\n\t\t// Save\n\t\tconst woff2FontPath = wf.getFontPath(o, 'woff2');\n\t\tfs.writeFileSync(woff2FontPath, woffFont);\n\t}\n\n\t/**\n\t * Generate CSS\n\t */\n\tfunction generateStylesheets(): void {\n\t\t// Convert codepoints to array of strings\n\t\tconst codepoints: string[] = [];\n\t\to.glyphs.forEach((name) => {\n\t\t\tcodepoints.push(o.codepoints[name].toString(16));\n\t\t});\n\t\t//@ts-ignore\n\t\to.codepoints = codepoints;\n\n\t\t// Prepage glyph names to use as CSS classes\n\t\to.glyphs = o.glyphs.map(classnameize);\n\n\t\to.stylesheets.sort((a, b) => {\n\t\t\treturn a === 'css' ? 1 : -1;\n\t\t}).forEach(generateStylesheet);\n\t}\n\n\t/**\n\t * Generate CSS\n\t *\n\t * @param stylesheet type: css, scss, ...\n\t */\n\tfunction generateStylesheet(stylesheet: string): void {\n\t\to.relativeFontPath = normalizePath(o.relativeFontPath);\n\n\t\t// Generate font URLs to use in @font-face\n\t\tconst fontSrcs: { readonly 0: string[], readonly 1: string[] } = { 0: [], 1: [] };\n\t\to.order.forEach((type) => {\n\t\t\tif (!has(o.types, type)) return;\n\t\t\tconst fontSrc1 = wf.fontsSrcsMap[type][0];\n\t\t\tif (fontSrc1) fontSrcs[0].push(generateFontSrc(type, fontSrc1, stylesheet));\n\t\t\tfontSrcs[1].push(generateFontSrc(type, wf.fontsSrcsMap[type][1], stylesheet));\n\t\t});\n\n\t\t// Convert urls to strings that could be used in CSS\n\t\tconst fontSrcSeparator = option(wf.fontSrcSeparators, stylesheet);\n\t\to.fontSrc1 = fontSrcs[0].join(fontSrcSeparator);\n\t\to.fontSrc2 = fontSrcs[1].join(fontSrcSeparator);\n\t\to.fontRawSrcs = [fontSrcs[0], fontSrcs[1]];\n\n\t\t// Read JSON file corresponding to CSS template\n\t\tconst templateJson = readTemplate(o.template, o.syntax, '.json', true);\n\t\tif (templateJson) o = Object.assign<OptionsInternal, Required<TemplateOptions>>(o, JSON.parse(templateJson.template));\n\n\t\t// Now override values with templateOptions\n\t\tif (o.templateOptions) o = Object.assign(o, o.templateOptions);\n\n\t\t// Generate CSS\n\t\tconst ext = path.extname(o.template) || '.css'; // Use extension of o.template file if given, or default to .css\n\t\to.cssTemplate = readTemplate(o.template, o.syntax, ext);\n\t\tconst cssContext = Object.assign<OptionsInternal, Partial<Context>>(o, {\n\t\t\ticonsStyles: true,\n\t\t\tstylesheet: stylesheet,\n\t\t});\n\n\t\tlet css = renderTemplate(o.cssTemplate, cssContext);\n\n\t\t// Fix CSS preprocessors comments: single line comments will be removed after compilation\n\t\tif (has(['sass', 'scss', 'less', 'styl'], stylesheet)) {\n\t\t\tcss = css.replace(/\\/\\* *(.*?) *\\*\\//g, '// $1');\n\t\t}\n\n\t\t// Save file\n\t\tfs.writeFileSync(getCssFilePath(stylesheet), css);\n\t}\n\n\t/**\n\t * Gets the codepoints from the set filepath in o.codepointsFile\n\t */\n\tfunction readCodepointsFromFile(): { [key: string]: number } {\n\t\tif (!o.codepointsFile) return {};\n\t\tif (!fs.existsSync(o.codepointsFile)){\n\t\t\tlogger.log.verbose('Codepoints file not found');\n\t\t\treturn {};\n\t\t}\n\n\t\tconst buffer = fs.readFileSync(o.codepointsFile);\n\t\treturn JSON.parse(buffer.toString());\n\t}\n\n\t/**\n\t * Saves the codespoints to the set file\n\t */\n\tfunction saveCodepointsToFile(): void {\n\t\tif (!o.codepointsFile) return;\n\t\tconst codepointsToString = JSON.stringify(o.codepoints, null, 4);\n\t\ttry {\n\t\t\tfs.writeFileSync(o.codepointsFile, codepointsToString);\n\t\t\tlogger.log.verbose(`Codepoints saved to file \"${o.codepointsFile}\".`);\n\t\t} catch (err) {\n\t\t\tlogger.log.error((err as Error).message);\n\t\t}\n\t}\n\n\t/*\n\t * Prepares base context for templates\n\t */\n\tfunction prepareBaseTemplateContext(): Context {\n\t\tconst context = Object.assign<{}, Context>({}, o);\n\t\treturn context;\n\t}\n\n\t/*\n\t * Makes custom extends necessary for use with preparing the template context\n\t * object for the HTML demo.\n\t */\n\tfunction prepareHtmlTemplateContext(): Context {\n\n\t\tlet context = prepareBaseTemplateContext();\n\n\t\tlet htmlStyles: string;\n\n\t\t// Prepare relative font paths for injection into @font-face refs in HTML\n\t\tconst relativeRe = new RegExp(o.relativeFontPath.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&').replace(/[=!:\\/]/g, '\\\\$&'), 'g');\n\t\tconst htmlRelativeFontPath = normalizePath(path.relative(o.destHtml, o.dest));\n\t\tconst _fontSrc1 = o.fontSrc1.replace(relativeRe, htmlRelativeFontPath);\n\t\tconst _fontSrc2 = o.fontSrc2.replace(relativeRe, htmlRelativeFontPath);\n\n\t\tcontext = Object.assign<Context, Partial<Context>>(context, {\n\t\t\tfontSrc1: _fontSrc1,\n\t\t\tfontSrc2: _fontSrc2,\n\t\t\tfontfaceStyles: true,\n\t\t\tbaseStyles: true,\n\t\t\textraStyles: false,\n\t\t\ticonsStyles: true,\n\t\t\tstylesheet: 'css',\n\t\t});\n\n\t\t// Prepares CSS for injection into <style> tag at to of HTML\n\t\thtmlStyles = renderTemplate(o.cssTemplate, context);\n\t\tcontext = Object.assign<Context, Partial<Context>>(context, {\n\t\t\tstyles: htmlStyles,\n\t\t});\n\n\t\treturn context;\n\t}\n\n\t/**\n\t * Iterator function used as callback by looping construct below to\n\t * render \"custom output\" via mini configuration objects specified in\n\t * the array `options.customOutputs`.\n\t *\n\t * @param outputConfig\n\t */\n\tfunction generateCustomOutput(outputConfig: CustomOutput): void {\n\n\t\t// Accesses context\n\t\tlet context = prepareBaseTemplateContext();\n\t\tcontext = Object.assign(context, outputConfig.context);\n\n\t\t// Prepares config attributes related to template filepath\n\t\tconst templatePath = outputConfig.template;\n\t\tconst extension = path.extname(templatePath);\n\t\tconst syntax = outputConfig.syntax || '';\n\n\t\t// Renders template with given context\n\t\tconst template = readTemplate(templatePath, syntax, extension);\n\t\tconst output = renderTemplate(template, context);\n\n\t\t// Prepares config attributes related to destination filepath\n\t\tconst dest = outputConfig.dest || o.dest;\n\n\t\tlet filepath: string;\n\t\tlet destParent: string;\n\t\tlet destName: string;\n\n\t\tif (path.extname(dest) === '') {\n\t\t\t// If user specifies a directory, filename should be same as template\n\t\t\tdestParent = dest;\n\t\t\tdestName = path.basename(outputConfig.template);\n\t\t\tfilepath = path.join(dest, destName);\n\t\t} else {\n\t\t\t// If user specifies a file, that is our filepath\n\t\t\tdestParent = path.dirname(dest);\n\t\t\tfilepath = dest;\n\t\t}\n\n\t\t// Ensure existence of parent directory and output to file as desired\n\t\tfs.mkdirSync(destParent, { recursive: true });\n\t\tfs.writeFileSync(filepath, output);\n\t}\n\n\t/*\n\t * Iterates over entries in the `options.customOutputs` object and,\n\t * on a config-by-config basis, generates the desired results.\n\t */\n\tfunction generateCustomOutputs(): void {\n\t\tif (!o.customOutputs || o.customOutputs.length < 1) {\n\t\t\treturn;\n\t\t}\n\n\t\to.customOutputs.forEach(generateCustomOutput);\n\t}\n\n\t/**\n\t * Generate HTML demo page\n\t */\n\tasync function generateDemoHtml(): Promise<void> {\n\t\tif (!o.htmlDemo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst context = prepareHtmlTemplateContext();\n\n\t\t// Generate HTML\n\t\tconst demoTemplate = readTemplate(o.htmlDemoTemplate, 'demo', '.html');\n\t\tconst demo = renderTemplate(demoTemplate, context);\n\n\t\ttry {\n\t\t\tawait fs.promises.mkdir(getDemoPath(), { recursive: true });\n\t\t} catch (err) {\n\t\t\tif (err) {\n\t\t\t\tlogger.log.info(err as string);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// Save file\n\t\tfs.writeFileSync(getDemoFilePath(), demo);\n\n\t}\n\n\t/**\n\t * Print log\n\t */\n\tfunction printDone(): void {\n\t\tlogger.log.info(`Font ${chalk.cyan(o.fontName)} with ${o.glyphs.length} glyphs created.`);\n\t}\n\n\n\t/**\n\t * Helpers\n\t */\n\n\t/**\n\t * Convert a string of comma separated words into an array\n\t *\n\t * @param val Input string\n\t * @param defVal Default value\n\t */\n\tfunction optionToArray<T extends string>(val: string | false, defVal: T[] | false): T[] {\n\t\tif (val === undefined) {\n\t\t\treturn defVal || [];\n\t\t}\n\t\tif (!val) {\n\t\t\treturn [];\n\t\t}\n\t\tif (typeof val !== 'string') {\n\t\t\treturn val;\n\t\t}\n\t\treturn val.split(',').map((value) => value.trim() as T);\n\t}\n\n\t/**\n\t * Check if a value exists in an array\n\t *\n\t * @param haystack Array to find the needle in\n\t * @param needle Value to find\n\t * @return Needle was found\n\t */\n\tfunction has(haystack: readonly string[] | string, needle: string): boolean {\n\t\treturn haystack.indexOf(needle) !== -1;\n\t}\n\n\t/**\n\t * Return a specified option if it exists in an object or `_default` otherwise\n\t *\n\t * @param map Options object\n\t * @param key Option to find in the object\n\t */\n\tfunction option(map: { readonly _default?: string, readonly [key: string]: string }, key: string): string {\n\t\tif (key in map) {\n\t\t\treturn map[key];\n\t\t} else {\n\t\t\treturn map._default;\n\t\t}\n\t}\n\n\t/**\n\t * Find next unused codepoint.\n\t */\n\tfunction getNextCodepoint(): number {\n\t\twhile (Object.values(o.codepoints).includes(currentCodepoint)) {\n\t\t\tcurrentCodepoint++;\n\t\t}\n\t\treturn currentCodepoint;\n\t}\n\n\t/**\n\t * Check whether file is SVG or not\n\t *\n\t * @param filepath File path\n\t */\n\tfunction isSvgFile(filepath: string): boolean {\n\t\treturn path.extname(filepath).toLowerCase() === '.svg';\n\t}\n\n\t/**\n\t * Convert font file to data:uri and remove source file\n\t *\n\t * @param fontFile Font file path\n\t * @return Base64 encoded string\n\t */\n\tfunction embedFont(fontFile: string): string {\n\t\t// Convert to data:uri\n\t\tconst dataUri = fs.readFileSync(fontFile, 'base64');\n\t\tconst type = path.extname(fontFile).substring(1);\n\t\tconst fontUrl = `data:application/x-font-${type};charset=utf-8;base64,${dataUri}`;\n\n\t\t// Remove font file\n\t\tfs.unlinkSync(fontFile);\n\n\t\treturn fontUrl;\n\t}\n\n\t/**\n\t * Append a slash to end of a filepath if it not exists and make all slashes forward\n\t *\n\t * @param filepath File path\n\t */\n\tfunction normalizePath(filepath: string): string {\n\t\tif (!filepath.length) return filepath;\n\n\t\t// Make all slashes forward\n\t\tfilepath = filepath.replace(/\\\\/g, '/');\n\n\t\t// Make sure path ends with a slash\n\t\tif (!filepath.endsWith('/')) {\n\t\t\tfilepath += '/';\n\t\t}\n\n\t\treturn filepath;\n\t}\n\n\t/**\n\t * Generate URL for @font-face\n\t *\n\t * @param type Type of font\n\t * @param font URL or Base64 string\n\t * @param stylesheet type: css, scss, ...\n\t */\n\tfunction generateFontSrc(type: FontFormat, font: { readonly ext: string, readonly format?: string, readonly embeddable?: boolean }, stylesheet: string): string {\n\t\tconst filename = template(`${o.fontFilename}${font.ext}`, o);\n\t\tlet fontPathVariableName = `${o.fontFamilyName}-font-path`;\n\n\t\tlet url: string;\n\t\tif (font.embeddable && has(o.embed, type)) {\n\t\t\turl = embedFont(path.join(o.dest, filename));\n\t\t} else {\n\t\t\tif (o.fontPathVariables && stylesheet !== 'css') {\n\t\t\t\tif (stylesheet === 'less') {\n\t\t\t\t\tfontPathVariableName = `@${fontPathVariableName}`;\n\t\t\t\t\to.fontPathVariable = `${fontPathVariableName} : \"${o.relativeFontPath}\";`;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfontPathVariableName = `$${fontPathVariableName}`;\n\t\t\t\t\to.fontPathVariable = `${fontPathVariableName} : \"${o.relativeFontPath}\" !default;`;\n\t\t\t\t}\n\t\t\t\turl = filename;\n\t\t\t}\n\t\t\telse {\n\t\t\t\turl = `${o.relativeFontPath}${filename}`;\n\t\t\t}\n\t\t\tif (o.addHashes) {\n\t\t\t\tif (url.indexOf('#iefix') === -1) { // Do not add hashes for OldIE\n\t\t\t\t\t// Put hash at the end of an URL or before #hash\n\t\t\t\t\turl = url.replace(/(#|$)/, `?${o.hash}$1`);\n\t\t\t\t} else {\n\t\t\t\t\turl = url.replace(/(#|$)/, `${o.hash}$1`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet src = `url(\"${url}\")`;\n\t\tif (o.fontPathVariables && stylesheet !== 'css') {\n\t\t\tif (stylesheet === 'less') {\n\t\t\t\tsrc = `url(\"@{${fontPathVariableName.replace('@','')}}${url}\")`;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsrc = `url(${fontPathVariableName} + \"${url}\")`;\n\t\t\t}\n\t\t}\n\n\t\tif (font.format) src += ` format(\"${font.format}\")`;\n\n\t\treturn src;\n\t}\n\n\t/**\n\t * Read the template file\n\t *\n\t * @param template Template file path\n\t * @param syntax Syntax (bem, bootstrap, etc.)\n\t * @param ext Extension of the template\n\t * @return \\{filename: 'Template filename', template: 'Template code'}\n\t */\n\tfunction readTemplate(template: string, syntax: string, ext: string, optional?: boolean): { filename: string, template: string } {\n\t\tconst filename = template\n\t\t\t? path.resolve(template.replace(path.extname(template), ext))\n\t\t\t: path.join(import.meta.dirname, `../templates/${syntax}${ext}`)\n\t\t;\n\t\tif (fs.existsSync(filename)) {\n\t\t\treturn {\n\t\t\t\tfilename: filename,\n\t\t\t\ttemplate: fs.readFileSync(filename, 'utf8'),\n\t\t\t};\n\t\t} else if (!optional) {\n\t\t\tlogger.fail.fatal(`Cannot find template at path: ${filename}`);\n\t\t}\n\t}\n\n\t/**\n\t * Render template with error reporting\n\t *\n\t * @param template {filename: 'Template filename', template: 'Template code'}\n\t * @param context Template context\n\t */\n\tfunction renderTemplate(template: { filename: string, template: string }, context: Context): string {\n\t\ttry {\n\t\t\treturn new Eta({\n\t\t\t\tautoTrim: [\"nl\", false],\n\t\t\t\tparse: {\n\t\t\t\t\texec: \"\",\n\t\t\t\t\tinterpolate: \"~\",\n\t\t\t\t\traw: \"=\",\n\t\t\t\t},\n\t\t\t\tuseWith: true,\n\t\t\t}).renderString(template.template, context);\n\t\t} catch (e) {\n\t\t\tlogger.fail.fatal(`Error while rendering template ${template.filename}: ${(e as Error).message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Basic template function: replaces {variables}\n\t *\n\t * @param tmpl Template code\n\t * @param context Values object\n\t */\n\tfunction template(tmpl: string, context: OptionsInternal): string {\n\t\treturn tmpl.replace(/\\{([^\\}]+)\\}/g, (m, key: keyof OptionsInternal) => {\n\t\t\treturn context[key] as string;\n\t\t});\n\t}\n\n\t/**\n\t * Prepare string to use as CSS class name\n\t *\n\t * @param str\n\t */\n\tfunction classnameize(str: string): string {\n\t\treturn str.trim().replace(/\\s+/g, '-');\n\t}\n\n\t/**\n\t * Return path of CSS file.\n\t *\n\t * @param stylesheet (css, scss, ...)\n\t */\n\tfunction getCssFilePath(stylesheet: string): string {\n\t\tconst cssFilePrefix = option(wf.cssFilePrefixes, stylesheet);\n\t\treturn path.join(option(o.destCssPaths, stylesheet), `${cssFilePrefix}${o.fontBaseName}.${stylesheet}`);\n\t}\n\n\t/**\n\t * Return path of HTML demo file or `null` if its generation was disabled.\n\t */\n\tfunction getDemoFilePath(): string {\n\t\tif (!o.htmlDemo) return null;\n\t\tconst name = o.htmlDemoFilename || o.fontBaseName;\n\t\treturn path.join(o.destHtml, `${name}.html`);\n\t}\n\n\t/**\n\t * Return path of HTML demo file or `null` if feature was disabled\n\t */\n\tfunction getDemoPath(): string {\n\t\tif (!o.htmlDemo) return null;\n\t\treturn o.destHtml;\n\t}\n\n\t/**\n\t * Save hash to cache file.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t * @param hash Hash.\n\t */\n\tfunction saveHash(name: string, target: string, hash: string): void {\n\t\tconst filepath = getHashPath(name, target);\n\t\tfs.mkdirSync(path.dirname(filepath), { recursive: true });\n\t\tfs.writeFileSync(filepath, hash);\n\t}\n\n\t/**\n\t * Read hash from cache file or `null` if file don’t exist.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t */\n\tfunction readHash(name: string, target: string): string {\n\t\tconst filepath = getHashPath(name, target);\n\t\tif (fs.existsSync(filepath)) {\n\t\t\treturn fs.readFileSync(filepath, 'utf8');\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Return path to cache file.\n\t *\n\t * @param name Task name (webfont).\n\t * @param target Task target name.\n\t */\n\tfunction getHashPath(name: string, target: string): string {\n\t\treturn path.join(o.cache, name, target, 'hash');\n\t}\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hibi_10000/grunt-webfont",
|
|
3
3
|
"description": "Ultimate SVG to webfont converter for Grunt.",
|
|
4
|
-
"version": "2.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"homepage": "https://github.com/Hibi-10000/grunt-webfont",
|
|
6
6
|
"author": "Hibi_10000",
|
|
7
7
|
"contributors": [
|
|
@@ -33,52 +33,64 @@
|
|
|
33
33
|
"icon"
|
|
34
34
|
],
|
|
35
35
|
"license": "MIT",
|
|
36
|
-
"main": "dist/webfont.js",
|
|
36
|
+
"main": "./dist/webfont.js",
|
|
37
|
+
"exports": {
|
|
38
|
+
"types": "./dist/webfont.d.ts",
|
|
39
|
+
"default": "./dist/webfont.js"
|
|
40
|
+
},
|
|
37
41
|
"type": "module",
|
|
38
42
|
"scripts": {
|
|
39
43
|
"build": "tsdown",
|
|
40
44
|
"test:node": "node --test ./test/webfont.test.ts",
|
|
41
|
-
"test:
|
|
45
|
+
"test:node:cov": "node --experimental-test-coverage --test ./test/webfont.test.ts",
|
|
46
|
+
"pretest:grunt": "grunt clean webfont --gruntfile ./Gruntfile.ts --stack",
|
|
47
|
+
"test:grunt": "node --test-only ./test/webfont.test.ts --no-clean"
|
|
42
48
|
},
|
|
43
49
|
"engines": {
|
|
44
|
-
"node": ">=
|
|
45
|
-
|
|
50
|
+
"node": ">=20.11"
|
|
51
|
+
},
|
|
52
|
+
"devEngines": {
|
|
53
|
+
"runtime": {
|
|
54
|
+
"name": "node",
|
|
55
|
+
"version": "^24.11",
|
|
56
|
+
"onFail": "download"
|
|
57
|
+
},
|
|
58
|
+
"packageManager": {
|
|
59
|
+
"name": "pnpm",
|
|
60
|
+
"version": "^11",
|
|
61
|
+
"onFail": "warn"
|
|
62
|
+
}
|
|
46
63
|
},
|
|
47
64
|
"dependencies": {
|
|
48
65
|
"chalk": "^5.6.2",
|
|
49
66
|
"consola": "^3.4.2",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
67
|
+
"eta": "^4.6.0",
|
|
68
|
+
"glob": "^13.0.6",
|
|
52
69
|
"temp": "^0.9.4",
|
|
53
|
-
"ttf2woff2": "^8.0.
|
|
70
|
+
"ttf2woff2": "^8.0.1"
|
|
54
71
|
},
|
|
55
72
|
"optionalDependencies": {
|
|
56
|
-
"svg2ttf": "^6.0
|
|
57
|
-
"svgicons2svgfont": "
|
|
58
|
-
"svgo": "^4.
|
|
73
|
+
"svg2ttf": "^6.1.0",
|
|
74
|
+
"svgicons2svgfont": "^15.0.1",
|
|
75
|
+
"svgo": "^4.1.0",
|
|
59
76
|
"ttf2eot": "^3.1.0",
|
|
60
77
|
"ttf2woff": "^3.0.0",
|
|
61
|
-
"which": "^
|
|
78
|
+
"which": "^6.0.1"
|
|
62
79
|
},
|
|
63
80
|
"devDependencies": {
|
|
64
81
|
"@types/grunt": "^0.4.32",
|
|
65
|
-
"@types/
|
|
66
|
-
"@types/node": "^22.18.1",
|
|
67
|
-
"@types/nodeunit": "^0.0.36",
|
|
82
|
+
"@types/node": "^24.13.3",
|
|
68
83
|
"@types/stylus": "^0.48.43",
|
|
69
84
|
"@types/svg2ttf": "^5.0.3",
|
|
70
85
|
"@types/temp": "^0.9.4",
|
|
71
86
|
"@types/which": "^3.0.4",
|
|
72
|
-
"
|
|
73
|
-
"grunt": "^1.6.
|
|
87
|
+
"fast-xml-parser": "^5.11.1",
|
|
88
|
+
"grunt": "^1.6.3",
|
|
74
89
|
"grunt-cli": "^1.5.0",
|
|
75
90
|
"grunt-contrib-clean": "^2.0.1",
|
|
76
|
-
"grunt-contrib-nodeunit": "^5.0.0",
|
|
77
|
-
"load-grunt-tasks": "^5.1.0",
|
|
78
91
|
"stylus": "^0.64.0",
|
|
79
|
-
"tsdown": "^0.
|
|
80
|
-
"typescript": "^
|
|
81
|
-
"xml2js": "^0.6.2"
|
|
92
|
+
"tsdown": "^0.22.14",
|
|
93
|
+
"typescript": "^6.0.3"
|
|
82
94
|
},
|
|
83
95
|
"peerDependencies": {
|
|
84
96
|
"grunt": ">=0.4.0"
|
|
@@ -51,7 +51,7 @@ export default async (o: OptionsInternal): Promise<false | { fontName: string }>
|
|
|
51
51
|
"fontforge process has unexpectedly closed.\n" +
|
|
52
52
|
`1. Try to run grunt in verbose mode to see fontforge output: ${chalk.bold('grunt --verbose webfont')}.\n` +
|
|
53
53
|
`2. If stderr maxBuffer exceeded try to increase ${chalk.bold('execMaxBuffer')}, ` +
|
|
54
|
-
`see ${chalk.underline('https://github.com/
|
|
54
|
+
`see ${chalk.underline('https://github.com/Hibi-10000/grunt-webfont#execMaxBuffer')}. `
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
});
|
|
@@ -62,12 +62,12 @@ export default async (o: OptionsInternal): Promise<false | { fontName: string }>
|
|
|
62
62
|
proc.stdin.write(JSON.stringify(params));
|
|
63
63
|
proc.stdin.end();
|
|
64
64
|
|
|
65
|
-
let out;
|
|
65
|
+
let out: string;
|
|
66
66
|
try {
|
|
67
67
|
out = (await promise).stdout;
|
|
68
68
|
} catch (err: unknown) {
|
|
69
69
|
if (err instanceof Error && (err as ExecException).code === 127) {
|
|
70
|
-
logger.log.error(`fontforge not found. Please install fontforge and all other requirements: ${chalk.underline('https://github.com/
|
|
70
|
+
logger.log.error(`fontforge not found. Please install fontforge and all other requirements: ${chalk.underline('https://github.com/Hibi-10000/grunt-webfont#installation')}`);
|
|
71
71
|
return false;
|
|
72
72
|
}
|
|
73
73
|
if (err instanceof Error) {
|
|
@@ -111,8 +111,8 @@ export default async (o: OptionsInternal): Promise<false | { fontName: string }>
|
|
|
111
111
|
logger.log.verbose(`Webfont did not receive a proper JSON result from Python script: ${e}`);
|
|
112
112
|
logger.log.error(
|
|
113
113
|
'Something went wrong when running fontforge. Probably fontforge wasn’t installed correctly or one of your SVGs is too complicated for fontforge.\n\n' +
|
|
114
|
-
`1. Try to run Grunt in verbose mode: ${chalk.bold('grunt --verbose webfont')} and see what fontforge says. Then search GitHub issues for the solution: ${chalk.underline('https://github.com/
|
|
115
|
-
`2. Try to use “node” engine instead of “fontforge”: ${chalk.underline('https://github.com/
|
|
114
|
+
`1. Try to run Grunt in verbose mode: ${chalk.bold('grunt --verbose webfont')} and see what fontforge says. Then search GitHub issues for the solution: ${chalk.underline('https://github.com/Hibi-10000/grunt-webfont/issues')}.\n\n` +
|
|
115
|
+
`2. Try to use “node” engine instead of “fontforge”: ${chalk.underline('https://github.com/Hibi-10000/grunt-webfont#engine')}\n\n` +
|
|
116
116
|
'3. To find “bad” icon try to remove SVGs one by one until error disappears. Then try to simplify this SVG in Sketch, Illustrator, etc.\n\n'
|
|
117
117
|
);
|
|
118
118
|
return false;
|
package/tasks/engines/node.ts
CHANGED
|
@@ -9,7 +9,7 @@ import fs from 'node:fs';
|
|
|
9
9
|
import stream from 'node:stream';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import util from 'node:util';
|
|
12
|
-
import { exec } from 'node:child_process';
|
|
12
|
+
import { exec, type ExecException } from 'node:child_process';
|
|
13
13
|
import { StringDecoder } from 'node:string_decoder';
|
|
14
14
|
import temp from 'temp';
|
|
15
15
|
import { SVGIcons2SVGFontStream } from 'svgicons2svgfont';
|
|
@@ -99,7 +99,6 @@ export default async (o: OptionsInternal): Promise<false> => {
|
|
|
99
99
|
try {
|
|
100
100
|
for (const type of typesToGenerate) {
|
|
101
101
|
if (type === 'woff2') continue;
|
|
102
|
-
//@ts-ignore
|
|
103
102
|
await createFontWriter(type);
|
|
104
103
|
}
|
|
105
104
|
} catch (e) {
|
|
@@ -199,11 +198,11 @@ export default async (o: OptionsInternal): Promise<false> => {
|
|
|
199
198
|
try {
|
|
200
199
|
await execPromise(args, { maxBuffer: o.execMaxBuffer });
|
|
201
200
|
} catch (err) {
|
|
202
|
-
if (err.code === 127) {
|
|
201
|
+
if ((err as ExecException).code === 127) {
|
|
203
202
|
logger.log.verbose('Hinting skipped, ttfautohint not found.');
|
|
204
203
|
return false;
|
|
205
204
|
}
|
|
206
|
-
logger.log.error('Can’t run ttfautohint.\n\n' + err.message);
|
|
205
|
+
logger.log.error('Can’t run ttfautohint.\n\n' + (err as Error).message);
|
|
207
206
|
return false;
|
|
208
207
|
}
|
|
209
208
|
const hintedFont = fs.readFileSync(hintedFilepath);
|
package/tasks/types.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
export interface Logger {
|
|
2
|
-
log: {
|
|
3
|
-
error: (
|
|
4
|
-
warn: (
|
|
5
|
-
info: (
|
|
6
|
-
verbose: (
|
|
2
|
+
readonly log: {
|
|
3
|
+
readonly error: (args: string) => void,
|
|
4
|
+
readonly warn: (msg: string) => void,
|
|
5
|
+
readonly info: (msg: string) => void,
|
|
6
|
+
readonly verbose: (msg: string) => void,
|
|
7
7
|
},
|
|
8
|
-
fail: {
|
|
9
|
-
fatal: (
|
|
10
|
-
warn?: (
|
|
8
|
+
readonly fail: {
|
|
9
|
+
readonly fatal: (args: string) => void,
|
|
10
|
+
//readonly warn?: (args: string) => void,
|
|
11
11
|
},
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export type FontFormat = 'eot' | 'woff2' | 'woff' | 'ttf' | 'svg';
|
|
15
|
+
|
|
14
16
|
export interface CustomOutput {
|
|
15
17
|
template: string,
|
|
16
18
|
dest: string,
|
|
@@ -107,9 +109,9 @@ export interface OptionsInternal extends TemplateOptions {
|
|
|
107
109
|
htmlDemoTemplate: string,
|
|
108
110
|
htmlDemoFilename: string,
|
|
109
111
|
styles: string[] | string,
|
|
110
|
-
types:
|
|
111
|
-
order:
|
|
112
|
-
embed:
|
|
112
|
+
types: FontFormat[],
|
|
113
|
+
order: FontFormat[],
|
|
114
|
+
embed: FontFormat[],
|
|
113
115
|
rename: (path: string, suffix?: string) => string,
|
|
114
116
|
engine: 'fontforge' | 'node',
|
|
115
117
|
autoHint: boolean,
|
|
@@ -124,7 +126,7 @@ export interface OptionsInternal extends TemplateOptions {
|
|
|
124
126
|
descent: number,
|
|
125
127
|
version: string | boolean,
|
|
126
128
|
cache: string,
|
|
127
|
-
callback: (filename: string, types:
|
|
129
|
+
callback: (filename: string, types: FontFormat[], glyphs: string[], hash: string) => void,
|
|
128
130
|
customOutputs: CustomOutput[],
|
|
129
131
|
execMaxBuffer: number,
|
|
130
132
|
|
package/tasks/util/util.ts
CHANGED
|
@@ -8,22 +8,28 @@ import path from 'node:path';
|
|
|
8
8
|
import { globSync } from 'glob';
|
|
9
9
|
import { consola } from 'consola';
|
|
10
10
|
|
|
11
|
-
import type { Logger, OptionsInternal } from '../types.ts';
|
|
11
|
+
import type { FontFormat, Logger, OptionsInternal } from '../types.ts';
|
|
12
|
+
|
|
13
|
+
consola.options.throttle = 300;
|
|
12
14
|
|
|
13
15
|
export const consolaLogger: Logger = {
|
|
14
16
|
log: {
|
|
15
17
|
error: consola.error.raw,
|
|
16
18
|
warn: consola.warn.raw,
|
|
17
19
|
info: consola.info.raw,
|
|
18
|
-
verbose: consola.
|
|
20
|
+
verbose: consola.debug.raw,
|
|
19
21
|
},
|
|
20
22
|
fail: {
|
|
21
23
|
fatal: (...args) => {
|
|
22
24
|
consola.fatal.raw(...args);
|
|
23
25
|
process.exit(1);
|
|
24
|
-
}
|
|
26
|
+
},
|
|
25
27
|
},
|
|
26
|
-
}
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
export const showConsolaVerbose = () => {
|
|
31
|
+
consola.level = 4; // debug
|
|
32
|
+
};
|
|
27
33
|
|
|
28
34
|
/**
|
|
29
35
|
* Unicode Private Use Area start.
|
|
@@ -45,7 +51,7 @@ export const fontsSrcsMap = {
|
|
|
45
51
|
},
|
|
46
52
|
},
|
|
47
53
|
woff: {
|
|
48
|
-
0: false
|
|
54
|
+
0: false,
|
|
49
55
|
1: {
|
|
50
56
|
ext: '.woff',
|
|
51
57
|
format: 'woff',
|
|
@@ -53,7 +59,7 @@ export const fontsSrcsMap = {
|
|
|
53
59
|
},
|
|
54
60
|
},
|
|
55
61
|
woff2: {
|
|
56
|
-
0: false
|
|
62
|
+
0: false,
|
|
57
63
|
1: {
|
|
58
64
|
ext: '.woff2',
|
|
59
65
|
format: 'woff2',
|
|
@@ -61,7 +67,7 @@ export const fontsSrcsMap = {
|
|
|
61
67
|
},
|
|
62
68
|
},
|
|
63
69
|
ttf: {
|
|
64
|
-
0: false
|
|
70
|
+
0: false,
|
|
65
71
|
1: {
|
|
66
72
|
ext: '.ttf',
|
|
67
73
|
format: 'truetype',
|
|
@@ -69,13 +75,13 @@ export const fontsSrcsMap = {
|
|
|
69
75
|
},
|
|
70
76
|
},
|
|
71
77
|
svg: {
|
|
72
|
-
0: false
|
|
78
|
+
0: false,
|
|
73
79
|
1: {
|
|
74
80
|
ext: '.svg#{fontBaseName}',
|
|
75
81
|
format: 'svg',
|
|
76
82
|
},
|
|
77
83
|
},
|
|
78
|
-
};
|
|
84
|
+
} as const;
|
|
79
85
|
|
|
80
86
|
/**
|
|
81
87
|
* CSS fileaname prefixes: _icons.scss.
|
|
@@ -84,7 +90,7 @@ export const cssFilePrefixes = {
|
|
|
84
90
|
_default: '',
|
|
85
91
|
sass: '_',
|
|
86
92
|
scss: '_'
|
|
87
|
-
};
|
|
93
|
+
} as const;
|
|
88
94
|
|
|
89
95
|
/**
|
|
90
96
|
* @font-face’s src parts seperators.
|
|
@@ -92,12 +98,12 @@ export const cssFilePrefixes = {
|
|
|
92
98
|
export const fontSrcSeparators = {
|
|
93
99
|
_default: ',\n\t\t',
|
|
94
100
|
styl: ', '
|
|
95
|
-
};
|
|
101
|
+
} as const;
|
|
96
102
|
|
|
97
103
|
/**
|
|
98
104
|
* List of available font formats.
|
|
99
105
|
*/
|
|
100
|
-
export const fontFormats = 'eot,woff2,woff,ttf,svg';
|
|
106
|
+
export const fontFormats: FontFormat[] = ['eot', 'woff2', 'woff', 'ttf', 'svg'];
|
|
101
107
|
|
|
102
108
|
/**
|
|
103
109
|
* Returns list of all generated font files.
|