svg-generator.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. const fs = require("fs");
  2. const { upperFirst } = require("lodash");
  3. const path = require("path");
  4. let pathName = path.join(__dirname, "../src/assets/icons/svg");
  5. fs.readdir(pathName, function (err, files) {
  6. let icons = [];
  7. (function iterator(i) {
  8. const fileName = files[i];
  9. if (i == files.length) {
  10. fs.writeFileSync(
  11. path.join(__dirname, "../src/assets/icons/index.ts"),
  12. templet_svg(icons)
  13. );
  14. return;
  15. }
  16. let fileUrl = path.join(pathName, fileName);
  17. fs.stat(fileUrl, function (err, data) {
  18. if (data.isFile()) {
  19. const value = formatSvg(fs.readFileSync(fileUrl, "utf-8"));
  20. fs.writeFileSync(fileUrl, value);
  21. const name = ("icon_" + fileName.slice(0, -4))
  22. .split("_")
  23. .map((s) => upperFirst(s))
  24. .join("");
  25. fs.writeFileSync(
  26. path.join(__dirname, `../src/assets/icons/components/${name}.tsx`),
  27. templet_icon({ name, value })
  28. );
  29. icons.push(name);
  30. }
  31. iterator(i + 1);
  32. });
  33. })(0);
  34. });
  35. const templet_svg = template`
  36. ${(icons) =>
  37. icons.map((icon) => `export * from "./components/${icon}";`).join("\n")}
  38. `;
  39. const templet_icon = template`
  40. import { createIcon } from '@queenjs/icons';
  41. export const ${(props) => props.name} = createIcon(${(props) => props.value})
  42. `;
  43. function template(arr1, ...arr2) {
  44. return function (props) {
  45. let tpl_str = "";
  46. for (let i = 0; i <= arr1.length; i++) {
  47. tpl_str += (arr1[i] || "") + (arr2[i] ? arr2[i](props) : "");
  48. }
  49. return tpl_str;
  50. };
  51. }
  52. const formatSvg = function (data) {
  53. let classList = {};
  54. let [, styles] = data.match(/<style>((.|\n|\r)+?)<\/style>/) || [];
  55. let [, svgAttr] = data.match(/<svg((.|\n|\r)+?)>/) || [];
  56. const attrs = [];
  57. svgAttr.split(" ").forEach((attr) => {
  58. if (!/^(xmlns|width|height|version|xmlns:xlink|isolation)=/.test(attr)) {
  59. attrs.push(attr);
  60. }
  61. });
  62. let fmtSvgStr = data.replace(/<svg((.|\n|\r)+?)>/, `<svg${attrs.join(" ")}>`);
  63. if (styles) {
  64. styles = styles.replace(/\s/g, "");
  65. const attrs = styles.split(";}");
  66. attrs.forEach((attr) => {
  67. if (!attr) return;
  68. let [cNames, values] = attr.split("{");
  69. valuesObj = {};
  70. values.split(";").forEach((value) => {
  71. let [key, val] = value.split(":");
  72. valuesObj[key] = val;
  73. });
  74. cNames.split(",").forEach((name) => {
  75. name = name.slice(1);
  76. classList[name] = Object.assign({}, classList[name], valuesObj);
  77. });
  78. });
  79. }
  80. fmtSvgStr = fmtSvgStr.replace(/<defs>(.|\n|\r)+?<\/defs>/, "");
  81. for (let className in classList) {
  82. fmtSvgStr = fmtSvgStr.replace(
  83. new RegExp(`class="${className}"`, "g"),
  84. fmtVals(classList[className])
  85. );
  86. }
  87. fmtSvgStr = fmtSvgStr.replace(
  88. / (stroke|fill|class|id|data\-name|p\-id)="(.+?)"/g,
  89. (str, key, value) => {
  90. if (["class", "id", "data-name", "p-id"].indexOf(key) != -1) return "";
  91. if (value === "#000" || value === "#000000") {
  92. return ` ${key}="currentColor"`;
  93. }
  94. return str;
  95. }
  96. );
  97. function fmtVals(obj) {
  98. let valArr = [];
  99. for (let name in obj) {
  100. valArr.push(`${name}="${obj[name]}"`);
  101. }
  102. return valArr.join(" ");
  103. }
  104. return fmtSvgStr;
  105. };