build-outline.mjs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import outlineStroke from 'svg-outline-stroke'
  2. import { asyncForEach, getAllIcons, getCompileOptions, getPackageDir, HOME_DIR } from '../../../.build/helpers.mjs'
  3. import fs from 'fs'
  4. import { resolve, basename } from 'path'
  5. import crypto from 'crypto'
  6. import { glob } from 'glob'
  7. import { execSync } from 'child_process'
  8. const DIR = getPackageDir('icons-webfont')
  9. const buildOutline = async () => {
  10. let filesList = {}
  11. const icons = getAllIcons(true)
  12. const compileOptions = getCompileOptions()
  13. await asyncForEach(Object.entries(icons), async ([type, icons]) => {
  14. fs.mkdirSync(resolve(DIR, `icons-outlined/${type}`), { recursive: true })
  15. filesList[type] = []
  16. await asyncForEach(icons, async function ({ name, content, unicode }) {
  17. console.log(type, name);
  18. if (compileOptions.includeIcons.length === 0 || compileOptions.includeIcons.indexOf(name) >= 0) {
  19. if (unicode) {
  20. console.log('Stroke for:', name, unicode)
  21. let filename = `${name}.svg`
  22. if (unicode) {
  23. filename = `u${unicode.toUpperCase()}-${name}.svg`
  24. }
  25. filesList[type].push(filename)
  26. content = content
  27. .replace('width="24"', 'width="1000"')
  28. .replace('height="24"', 'height="1000"')
  29. if (compileOptions.strokeWidth) {
  30. content = content
  31. .replace('stroke-width="2"', `stroke-width="${compileOptions.strokeWidth}"`)
  32. }
  33. const cachedFilename = `u${unicode.toUpperCase()}-${name}.svg`;
  34. if (unicode && fs.existsSync(resolve(DIR, `icons-outlined/${type}/${cachedFilename}`))) {
  35. // Get content
  36. let cachedContent = fs.readFileSync(resolve(DIR, `icons-outlined/${type}/${cachedFilename}`), 'utf-8')
  37. // Get hash
  38. let cachedHash = '';
  39. cachedContent = cachedContent.replace(/<!--\!cache:([a-z0-9]+)-->/, function (m, hash) {
  40. cachedHash = hash;
  41. return '';
  42. })
  43. // Check hash
  44. if (crypto.createHash('sha1').update(cachedContent).digest("hex") === cachedHash) {
  45. console.log('Cached stroke for:', name, unicode)
  46. return true;
  47. }
  48. }
  49. await outlineStroke(content, {
  50. optCurve: true,
  51. steps: 4,
  52. round: 0,
  53. centerHorizontally: true,
  54. fixedWidth: false,
  55. color: 'black'
  56. }).then(outlined => {
  57. // Save file
  58. fs.writeFileSync(resolve(DIR, `icons-outlined/${type}/${filename}`), outlined, 'utf-8')
  59. // Fix outline
  60. execSync(`fontforge -lang=py -script .build/fix-outline.py icons-outlined/${type}/${filename}`).toString()
  61. execSync(`svgo icons-outlined/${type}/${filename}`).toString()
  62. // Add hash
  63. const fixedFileContent = fs
  64. .readFileSync(resolve(DIR, `icons-outlined/${type}/${filename}`), 'utf-8')
  65. .replace(/\n/g, ' ')
  66. .trim(),
  67. hashString = `<!--!cache:${crypto.createHash('sha1').update(fixedFileContent).digest("hex")}-->`
  68. // Save file
  69. fs.writeFileSync(
  70. resolve(DIR, `icons-outlined/${type}/${filename}`),
  71. fixedFileContent + hashString,
  72. 'utf-8'
  73. )
  74. }).catch(error => console.log(error))
  75. }
  76. }
  77. })
  78. })
  79. // Remove old files
  80. await asyncForEach(Object.entries(icons), async ([type, icons]) => {
  81. const existedFiles = (await glob(resolve(DIR, `icons-outlined/${type}/*.svg`))).map(file => basename(file))
  82. existedFiles.forEach(file => {
  83. if (filesList[type].indexOf(file) === -1) {
  84. console.log('Remove:', file)
  85. fs.unlinkSync(resolve(DIR, `icons-outlined/${type}/${file}`))
  86. }
  87. })
  88. })
  89. // Copy icons from firs to all directory
  90. await asyncForEach(Object.entries(icons), async ([type, icons]) => {
  91. fs.mkdirSync(resolve(DIR, `icons-outlined/all`), { recursive: true })
  92. await asyncForEach(icons, async function ({ name, unicode }) {
  93. const iconName = `u${unicode.toUpperCase()}-${name}`
  94. if (fs.existsSync(resolve(DIR, `icons-outlined/${type}/${iconName}.svg`))) {
  95. // Copy file
  96. console.log(`Copy ${iconName} to all directory`)
  97. fs.copyFileSync(
  98. resolve(DIR, `icons-outlined/${type}/${iconName}.svg`),
  99. resolve(DIR, `icons-outlined/all/${iconName}${type !== 'outline' ? `-${type}` : ''}.svg`)
  100. )
  101. }
  102. })
  103. })
  104. console.log('Done')
  105. }
  106. await buildOutline()