gen-keyline-avatars.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # 生成 packages/chat-ui/src/keyline-avatars.ts(机器人头像图标)
  2. # 用法:npm pack @iconify-json/keyline-icons@1.2.18 && tar xzf iconify-json-keyline-icons-1.2.18.tgz
  3. # python3 scripts/gen-keyline-avatars.py package/icons.json packages/chat-ui/src/keyline-avatars.ts
  4. import json, re, sys
  5. src, out = sys.argv[1], sys.argv[2]
  6. d = json.load(open(src))['icons']
  7. groups = [
  8. ('助手', 'bot bot-simple bot-square bot-circle bot-message bot-heart bot-star bot-cloud'),
  9. ('智能', 'bot-droplet brain brain-sparkles brain-circuit brain-cog cpu-sparkles message-sparkles wand-sparkles'),
  10. ('人物', 'user user-cog user-sparkles user-shield user-search user-pen user-voice headset'),
  11. ('数据', 'bar-chart chart-pie chart-area database table calculator coins scale'),
  12. ('文档', 'file file-chart-column book-open notebook-pen pen clipboard-list sticky-note folder-open'),
  13. ('技术', 'code terminal server cloud cpu bug wrench toolbox'),
  14. ('运维', 'shield-check lock key-round settings plug briefcase factory truck'),
  15. ('沟通', 'mail message megaphone bell calendar clock send inbox'),
  16. ('目标', 'rocket lightbulb target trophy crown sparkles flame star'),
  17. ('探索', 'globe compass map search flask-conical atom palette puzzle'),
  18. ]
  19. icons = {}
  20. for _, names in groups:
  21. for n in names.split():
  22. body = d[n]['body']
  23. # 只允许纯图形:没有脚本、事件属性、外部引用
  24. assert not re.search(r'<script|\son\w+=|href|url\(|<foreignObject', body, re.I), n
  25. assert set(re.findall(r'<(\w+)', body)) <= {'g', 'path', 'circle', 'rect', 'ellipse', 'line', 'polyline', 'polygon'}, (n, set(re.findall(r'<(\w+)', body)))
  26. icons[n] = body
  27. license = '''MIT License
  28. Copyright (c) 2026 Keyline Icons
  29. Permission is hereby granted, free of charge, to any person obtaining a copy
  30. of this software and associated documentation files (the "Software"), to deal
  31. in the Software without restriction, including without limitation the rights
  32. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  33. copies of the Software, and to permit persons to whom the Software is
  34. furnished to do so, subject to the following conditions:
  35. The above copyright notice and this permission notice shall be included in all
  36. copies or substantial portions of the Software.
  37. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  38. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  39. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  40. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  41. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  42. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  43. SOFTWARE.'''
  44. lines = ['// 机器人头像图标:Keyline Icons(https://keylineicons.com)的线条样式(stroke 2),24×24,取自 @iconify-json/keyline-icons 1.2.18。',
  45. '// 由 scripts/gen-keyline-avatars.py 生成,只收录头像用到的图标;新增图标时重新生成,不要手工修改 SVG。',
  46. '/*', *(' * ' + l if l else ' *' for l in license.splitlines()), ' */', '',
  47. '/** 头像选择面板中的分组(顺序即显示顺序) */',
  48. 'export const KEYLINE_AVATAR_GROUPS: { label: string; icons: string[] }[] = [']
  49. for label, names in groups:
  50. lines.append(f" {{ label: '{label}', icons: [{', '.join(repr(n) for n in names.split())}] }},")
  51. lines += [']', '', '/** 图标名称 → SVG 内容(viewBox 0 0 24 24,颜色为 currentColor) */', 'export const KEYLINE_AVATAR_SVGS: Record<string, string> = {']
  52. for n, b in icons.items():
  53. lines.append(f" {json.dumps(n)}: {json.dumps(b, ensure_ascii=False)},")
  54. lines += ['}', '']
  55. open(out, 'w').write('\n'.join(lines).replace("['", "['").replace("', '", "', '"))
  56. print(len(icons), 'icons')