見出し画像

svg-parserライブラリを使ってsvgをHAST Treeに分解してみた

こんにちわ。nap5です。


svg-parserライブラリを使ってsvgをHAST Treeに分解してみたので、その紹介です。


普段使うことはあんまりないですが、生DOMを木構造へ構造化できると便利なことがあるので、その方法について少し調べて、素振りした記事になります。


使用するsvg-parserライブラリはこちらです。


HASTトークンについては以下のリンクにのっています。
フレームワークの中で使われるライブラリの印象です。


他にもこのようなライブラリもありました。便利そうです。


以下が素振りしたコードです。


import { parse } from "svg-parser";
const walk = (children, resultList) => {
  children.forEach((child, index) => {
    const children = child.children;
    resultList.push({
      properties: child.properties,
      tagName: child.tagName,
    });
    walk(children, resultList);
  });
  return resultList;
};

const domText = `
<svg viewBox="0 0 100 100">
  <g data-name="Group 1095">
    <g filter="url(#h)">
      <rect
        transform="translate(2719.1 390.33)"
        width="343.06"
        height="336.32"
        rx="10"
        fill="#fff"
        data-name="Rectangle 1434"
      />
    </g>
    <rect
      transform="translate(2719 462)"
      width="343"
      height="211"
      fill="#f3f3f6"
      data-name="Rectangle 1435"
    />
    <line
      transform="translate(1723.5 703.19)"
      x2="15.097"
      fill="none"
      stroke="#1e1e1e"
      strokeMiterlimit="10"
      data-name="Line 3"
    />
    <path
      d="m1707.5 711.19v-4.417a3.586 3.586 0 0 0-3.585-3.586h-7.793"
      fill="none"
      stroke="#1e1e1e"
      strokeMiterlimit="10"
      data-name="Path 111618"
    />
  </g>
  <g>
    <path
      d="M -57.191 807.76 C 83.869 854.095 213.909 759.254 151.609 636.42 C 106.962 548.379 67.224 638.643 74.703 706.62 C 85.737 806.92 150.609 897.43 291.373 850.4 C 406.303 812.001 470.173 700.22 568.893 676.51 C 663.878 653.697 706.613 753.932 809.303 753.932 C 999.183 753.932 1012.233 567.192 1194.103 608.712 C 1264.954 624.888 1313.463 705.482 1509.433 700.421 C 1618.163 697.613 1692.723 520.821 1833.533 478.411 C 1969.943 437.32 1979.373 533.717 2123.563 533.489 C 2344.583 533.141 2356.023 281.569 2570.413 268.179 C 2714.913 259.15 2799.663 358.648 2935.383 213.647 C 2961.499 185.747 2988.155 169.39 3012.462 160.088 C 3051.393 145.188 3094.106 146.94 3132.312 163.883 C 3184.545 187.048 3274.492 221.101 3357.892 119.345 C 3456.271 -0.695 3510.932 -63.635 3510.932 -63.635"
    />
  </g>
</svg>
`;

const parsed = parse(domText);
const result = walk(parsed.children, []);
console.log(result);


こちらが実行結果になります。DOMを上から下に向かって舐めてフラットになっていることが確認できました。

$ time node index.js
[
  {
    properties: { viewBox: '0 0 100 100' },
    tagName: 'svg',
    type: 'element'
  },
  {
    properties: { 'data-name': 'Group 1095' },
    tagName: 'g',
    type: 'element'
  },
  { properties: { filter: 'url(#h)' }, tagName: 'g', type: 'element' },
  {
    properties: {
      transform: 'translate(2719.1 390.33)',
      width: 343.06,
      height: 336.32,
      rx: 10,
      fill: '#fff',
      'data-name': 'Rectangle 1434'
    },
    tagName: 'rect',
    type: 'element'
  },
  {
    properties: {
      transform: 'translate(2719 462)',
      width: 343,
      height: 211,
      fill: '#f3f3f6',
      'data-name': 'Rectangle 1435'
    },
    tagName: 'rect',
    type: 'element'
  },
  {
    properties: {
      transform: 'translate(1723.5 703.19)',
      x2: 15.097,
      fill: 'none',
      stroke: '#1e1e1e',
      strokeMiterlimit: 10,
      'data-name': 'Line 3'
    },
    tagName: 'line',
    type: 'element'
  },
  {
    properties: {
      d: 'm1707.5 711.19v-4.417a3.586 3.586 0 0 0-3.585-3.586h-7.793',
      fill: 'none',
      stroke: '#1e1e1e',
      strokeMiterlimit: 10,
      'data-name': 'Path 111618'
    },
    tagName: 'path',
    type: 'element'
  },
  { properties: {}, tagName: 'g', type: 'element' },
  {
    properties: {
      d: 'M -57.191 807.76 C 83.869 854.095 213.909 759.254 151.609 636.42 C 106.962 548.379 67.224 638.643 74.703 706.62 C 85.737 806.92 150.609 897.43 291.373 850.4 C 406.303 812.001 470.173 700.22 568.893 676.51 C 663.878 653.697 706.613 753.932 809.303 753.932 C 999.183 753.932 1012.233 567.192 1194.103 608.712 C 1264.954 624.888 1313.463 705.482 1509.433 700.421 C 1618.163 697.613 1692.723 520.821 1833.533 478.411 C 1969.943 437.32 1979.373 533.717 2123.563 533.489 C 2344.583 533.141 2356.023 281.569 2570.413 268.179 C 2714.913 259.15 2799.663 358.648 2935.383 213.647 C 2961.499 185.747 2988.155 169.39 3012.462 160.088 C 3051.393 145.188 3094.106 146.94 3132.312 163.883 C 3184.545 187.048 3274.492 221.101 3357.892 119.345 C 3456.271 -0.695 3510.932 -63.635 3510.932 -63.635'
    },
    tagName: 'path',
    type: 'element'
  }
]

real    0m0.086s
user    0m0.122s
sys     0m0.000s


最近では、Twitterでモックアップ動画を公開しているので、こちらもよかったら、覗いてみてください。


最後に、Udemyでコースを公開しました。
良かったら覗いてみてください。


また、コースの内容紹介記事は以下になります。


簡単ですが、以上です。

この記事が気に入ったらサポートをしてみませんか?