function plugin()

in packages/posthtml-rename-id/index.js [21:117]


function plugin(pattern) {
  const p = pattern || defaultPattern;

  return (tree) => {
    const mappedIds = {};

    tree.match({ attrs: { id: /.*/ } }, (node) => {
      const { attrs } = node;
      const currentId = attrs.id;
      const newId = renameId(currentId, p);
      attrs.id = newId;

      mappedIds[currentId] = {
        id: newId,
        referenced: false,
        node
      };

      return node;
    });

    tree.match({ tag: /.*/ }, (node) => {
      const { attrs } = node;

      if (node.tag === 'style') {
        while (true) {
          const content = Array.isArray(node.content) ? node.content.join('') : node.content.toString();
          const match = URL_PATTERN.exec(content);
          if (match === null) {
            break;
          }

          const id = match[1];
          if (mappedIds[id]) {
            mappedIds[id].referenced = true;
            const re = new RegExp(escapeForRegexp(match[0]), 'g');
            node.content = content.replace(re, `url(#${mappedIds[id].id})`);
          }
        }
      }

      if ('attrs' in node === false) {
        return node;
      }

      Object.keys(attrs).forEach((attrName) => {
        const value = attrs[attrName];
        let id;
        let match;

        while ((match = URL_PATTERN.exec(value)) !== null) {
          id = match[1];
          if (mappedIds[id]) {
            mappedIds[id].referenced = true;
            const re = new RegExp(escapeForRegexp(match[0]), 'g');
            attrs[attrName] = value.replace(re, `url(#${mappedIds[id].id})`);
          }
        }

        let idObj;

        switch (attrName) {
          case 'href':
          case 'xlink:href':
            if (value.substring(0, 1) !== '#') {
              break;
            }

            id = value.substring(1);
            idObj = mappedIds[id];
            if (idObj) {
              idObj.referenced = false;
              attrs[attrName] = `#${idObj.id}`;
            }
            break;

          case 'for':
            if (node.tag !== 'label') {
              break;
            }

            id = value;
            idObj = mappedIds[id];
            if (idObj) {
              idObj.referenced = false;
              attrs[attrName] = idObj.id;
            }
            break;
        }
      });

      return node;
    });

    return tree;
  };
}