All files index.ts

100% Statements 19/19
96.77% Branches 30/31
100% Functions 3/3
100% Lines 19/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84                                                                                                    1x 53x 53x 53x 100x 13x 13x 13x 13x 9x 9x 8x 8x           100x 81x 81x 39x 39x 36x                    
import type { Plugin } from 'unified';
import type { Root, Element, Comment, Properties, Literal } from 'hast';
import { visit } from 'unist-util-visit';
import { propertiesHandle, nextChild, prevChild, getCommentObject } from './utils.js';
 
export type RehypeAttrsOptions = {
  /**
   * ## `data`
   * 
   * ```markdown
   * text
   * <!--rehype:title=Rehype Attrs&abc=2-->
   * ```
   * 👇👇👇👇👇
   * ```html
   * <p data-config="data-config='[object Object]'">text</p>
   * ```
   * 
   * ## `string`
   * 
   * ```markdown
   * text
   * <!--rehype:title=Rehype Attrs-->
   * ```
   * 
   * 👇👇👇👇👇
   * 
   * ```html
   * <p data-config="{&#x22;title&#x22;:&#x22;Rehype Attrs&#x22;,&#x22;rehyp&#x22;:true}">text</p>
   * ```
   * 
   * ## attr
   * 
   * ```markdown
   * text
   * <!--rehype:title=Rehype Attrs-->
   * ```
   * 👇👇👇👇👇
   * ```html
   * <p title="Rehype Attrs">text</p>
   * ```
   * @default `data`
   */
  properties?: 'data' | 'string' | 'attr';
  /**
   * Code block passing parameters
   */
  codeBlockParames?: boolean;
}
 
const rehypeAttrs: Plugin<[RehypeAttrsOptions?], Root> = (options = {}) => {
  const { properties = 'data', codeBlockParames = true } = options;
  return (tree) => {
    visit(tree, 'element', (node, index, parent) => {
      if (codeBlockParames && node.tagName === 'pre' && node && Array.isArray(node.children) && parent && Array.isArray(parent.children) && parent.children.length > 1) {
        const firstChild = node.children[0] as Element;
        Eif (firstChild && firstChild.tagName === 'code' && typeof index === 'number') {
          const child = prevChild(parent.children as Literal[], index);
          if (child) {
            const attr = getCommentObject(child);
            if (Object.keys(attr).length > 0) {
              node.properties = { ...node.properties, ...{ 'data-type': 'rehyp' } }
              firstChild.properties = propertiesHandle(firstChild.properties, attr, properties) as Properties
            }
          }
        }
      }
 
      if (/^(em|strong|b|a|i|p|pre|kbd|blockquote|h(1|2|3|4|5|6)|code|table|img|del|ul|ol)$/.test(node.tagName) && parent && Array.isArray(parent.children) && typeof index === 'number') {
        const child = nextChild(parent.children, index, '', codeBlockParames)
        if (child) {
          const attr = getCommentObject(child as Comment)
          if (Object.keys(attr).length > 0) {
            node.properties = propertiesHandle(node.properties, attr, properties) as Properties
          }
        }
      }
    });
  }
}
 
 
export default rehypeAttrs