将 Font Awesome Pro 转换为 Iconify JSON
使用 FontAwesome Pro git 仓库
本示例展示了如何将 FontAwesome Pro 的 SVG 文件转换为 Iconify JSON 格式。
本示例假设您有权访问 FontAwesome Pro 仓库。如果您拥有有效的许可证,您应该能够访问它。
创建文件 convert-fa-pro.ts 并填入以下内容:
convert-fa-pro.ts
ts
import { promises as fs } from 'fs';
import {
downloadGitRepo,
importDirectory,
cleanupSVG,
parseColors,
isEmptyColor,
runSVGO,
} from '@iconify/tools';
import type { IconifyInfo } from '@iconify/types';
// Clone repository?
// Set to false if repository is already unpacked to directory set in 'faRepoDir' variable.
const cloneFromGitHub = true;
const faRepoURL: string | null =
'git@github.com:FortAwesome/Font-Awesome-Pro.git';
const faRepoBranch = 'master';
// Directory for FontAwesome Pro repository (automatically downloaded if information above is set)
const faRepoDir = 'fa-pro';
// Themes to parse
const themes = ['brands', 'duotone', 'light', 'regular', 'solid'];
// Directory to export icon sets to
const targetDirectory = 'json';
// Information
const baseInfo: IconifyInfo = {
name: 'Font Awesome',
author: {
name: 'Font Awesome',
},
license: {
title: 'Commercial License',
url: 'https://fontawesome.com/license',
},
height: 32,
};
// Base prefix without theme
const basePrefix = 'fa-pro-';
// Do stuff
(async function () {
// Download repository
let sourceDir = faRepoDir;
if (cloneFromGitHub) {
const downloadResult = await downloadGitRepo({
target: faRepoDir,
remote: faRepoURL,
branch: faRepoBranch,
log: true,
});
sourceDir = downloadResult.contentsDir;
}
// Create directory for output if missing
try {
await fs.mkdir(targetDirectory, {
recursive: true,
});
} catch (err) {
//
}
// Parse all configured themes
for (let i = 0; i < themes.length; i++) {
const theme = themes[i];
const source = sourceDir + '/svgs/' + theme;
const prefix = basePrefix + theme;
// Import icons
const iconSet = await importDirectory(source, {
prefix,
});
// Set info
const info: IconifyInfo = JSON.parse(JSON.stringify(baseInfo));
const themeName = theme.toUpperCase().slice(0, 1) + theme.slice(1);
info.name += ' ' + themeName;
iconSet.info = info;
// Validate, clean up, fix palette and optimise
iconSet.forEachSync((name, type) => {
if (type !== 'icon') {
return;
}
// Get SVG instance for parsing
const svg = iconSet.toSVG(name);
if (!svg) {
// Invalid icon
iconSet.remove(name);
return;
}
// Clean up and optimise icons
try {
// Clean up icon code
cleanupSVG(svg);
// Replace color with currentColor, add if missing
parseColors(svg, {
defaultColor: 'currentColor',
callback: (attr, colorStr, color) => {
return !color || isEmptyColor(color) ? colorStr : 'currentColor';
},
});
// Optimise
runSVGO(svg);
} catch (err) {
// Invalid icon
console.error(`Error parsing ${name}:`, err);
iconSet.remove(name);
return;
}
// Update icon from SVG instance
iconSet.fromSVG(name, svg);
});
console.log(`Imported ${iconSet.count()} icons for ${info.name}`);
// Export to IconifyJSON, convert to string
const output = JSON.stringify(iconSet.export(), null, '\t');
// Save to file
const target = targetDirectory + '/' + prefix + '.json';
await fs.writeFile(target, output, 'utf8');
console.log(`Saved ${target} (${output.length} bytes)`);
}
})().catch((err) => {
console.error(err);
});假设 TypeScript 已配置为编译到 lib 目录,将文件编译为 JavaScript 并运行:
node lib/convert-fa-pro如果您不使用 TypeScript,请从代码中移除类型声明。 这应该不难,因为需要移除的行数并不多。
准备好的项目可在 Iconify Tools GitHub 仓库 中获取。
使用 FontAwesome Pro npm 库
生成 JSON 文件的另一种方法是使用 FontAwesome 提供的 NPM 库。
本示例假设您有权访问 FontAwesome Pro npm 库。如果您尚未获得库的访问权限,请参阅官方指南。
创建文件 convert-fa-pro-npm.ts 并填入以下内容:
convert-fa-pro-npm.ts
ts
import fs from 'fs';
import { blankIconSet } from '@iconify/tools';
import { dirname, join } from 'path';
// import the fonts you want to convert
import {
far as faProRegularIcons,
prefix as faProRegularPrefix,
} from '@fortawesome/pro-regular-svg-icons';
import {
fas as faProSolidIcons,
prefix as faProSolidPrefix,
} from '@fortawesome/pro-solid-svg-icons';
import {
fat as faProThinIcons,
prefix as faProThinPrefix,
} from '@fortawesome/pro-thin-svg-icons';
import {
fal as faProLightIcons,
prefix as faProLightPrefix,
} from '@fortawesome/pro-light-svg-icons';
import type { IconifyInfo } from '@iconify/types';
// put the icons and the prefix you want them to have together in one object.
const icons = [
{ icons: faProRegularIcons, prefix: /* faProRegularPrefix */ 'fa' },
{ icons: faProSolidIcons, prefix: faProSolidPrefix },
{ icons: faProThinIcons, prefix: faProThinPrefix },
{ icons: faProLightIcons, prefix: faProLightPrefix },
] as const;
// set the location where you want the generated json files to appear.
const collectionTargetDir = join(
import.meta.dirname,
'font-awesome-iconify'
);
// set the base info
const baseInfo = {
name: 'Font Awesome',
author: {
name: 'Font Awesome',
},
license: {
title: 'Commercial License',
url: 'https://fontawesome.com/license',
},
height: 512,
} as const satisfies IconifyInfo;
// iterate through the icons and generate the json files
for (const iconData of icons) {
const iconSet = blankIconSet(iconData.prefix);
iconSet.info = structuredClone(baseInfo);
for (const { icon, iconName } of Object.values(iconData.icons)) {
const [width, height, ligatures, unicode, svgPathData] = icon;
// handle strings and array differently from each other
const body =
typeof svgPathData === 'string'
? `<path fill="currentColor" d="${svgPathData}" />`
: `<g fill="currentColor">${svgPathData.map((x) => `<path d="${x}" />`).join('')}</g>`;
iconSet.setIcon(iconName, {
body,
height,
width,
});
ligatures.forEach((x) => {
// ignore the aliases that are numbers.
if (Number.isNaN(+x)) iconSet.setAlias(x, iconName);
});
}
// generate the json
const data = iconSet.export();
const dataJson = JSON.stringify(data, null, 2);
// set the path target for the json file
const jsonTargetDir = join(collectionTargetDir, iconData.prefix);
const fileName = join(jsonTargetDir, 'icons.json');
// create the file
fs.mkdirSync(jsonTargetDir, { recursive: true });
fs.writeFileSync(fileName, dataJson, {
encoding: 'utf-8',
});
}如果您使用的是 Node.js V22.6.0 或更高版本,您可以原生运行 TypeScript 文件。
node convert-fa-pro-npm.ts如果您的 Node.js 版本低于 v22.6.0,则需要在命令中添加 --experimental-strip-types。
node --experimental-strip-types convert-fa-pro-npm.ts或者,您也可以手动从代码中移除类型声明,然后将其作为 JS 文件运行。