All files utils.ts

98.18% Statements 54/55
94.11% Branches 64/68
100% Functions 7/7
100% Lines 50/50

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 85 86 87 88 89 90      1x 50x   52x         1x 18x 18x 29x 29x 27x 15x 12x     1x     1x 128x 128x 163x 163x 48x 48x 7x     115x 115x 77x 77x 47x 3x   44x 41x 41x 38x 38x   3x 3x         36x                 1x 50x 50x 52x 1x   52x 1x   52x 3x     50x             1x 51x 6x 45x 42x   3x  
import type { Element, Comment, Literal, ElementContent, RootContent, Properties } from 'hast';
import type { RehypeAttrsOptions } from './index.js';
 
export const getURLParameters = (url: string = '') =>
  ((url.match(/([^?=&]+)(=([^&]*))/g) || []) as string[]).reduce(
      (a: Record<string, string | number | boolean>, v: string) => (
        (a[v.slice(0, v.indexOf('=')) as keyof typeof a] = v.slice(v.indexOf('=') + 1)), a
      ),
      {}
    )
 
export const prevChild = (data: Literal[] = [], index: number): Comment | undefined => {
  let i = index;
  while (i > -1) {
    i--;
    if (!data[i]) return
    if ((data[i] && data[i].value && (data[i].value as string).replace(/(\n|\s)/g, '') !== '') || data[i].type !== 'text') {
      if (!/^rehype:/.test(data[i].value as string) || (data[i].type as string) !== 'comment') return;
      return data[i] as unknown as Comment;
    }
  }
  return;
}
 
export const nextChild = (data: RootContent[] | ElementContent[] = [], index: number, tagName?: string, codeBlockParames?: boolean): ElementContent | undefined => {
  let i = index;
  while (i < data.length) {
    i++;
    if (tagName) {
      const element = data[i] as Literal & Element;
      if (element && element.value && (element.value as string).replace(/(\n|\s)/g, '') !== '' || data[i] && (data[i].type as string) === 'element') {
        return element.tagName === tagName ? element : undefined
      }
    } else {
      const element = data[i] as ElementContent & Literal;
      if (!element || element.type === 'element') return;
      Iif (element.type === 'text' && element.value.replace(/(\n|\s)/g, '') !== '') return;
      if (element.type && /^(comment|raw)$/ig.test(element.type)) {
        if (element.value && !/^rehype:/.test(element.value.replace(/^(\s+)?<!--(.*?)-->/, '$2') || '')) {
          return
        };
        if (codeBlockParames) {
          const nextNode = nextChild(data, i, 'pre', codeBlockParames)
          if (nextNode) return;
          element.value = (element.value || '').replace(/^(\n|\s)+/, '')
          return element;
        } else {
          element.value = (element.value || '').replace(/^(\n|\s)+/, '')
          return element;
        }
      }
    }
  }
  return
}
 
/**
 * 获取代码注视的位置
 * @param data 数据
 * @param index 当前数据所在的位置
 * @returns 返回 当前参数数据 Object,`{}`
 */
export const getCommentObject = ({ value = '' }: Comment): Properties => {
  const param = getURLParameters(value.replace(/^<!--(.*?)-->/, '$1').replace(/^rehype:/, ''));
  Object.keys(param).forEach((keyName: string) => {
    if (param[keyName] === 'true') {
      param[keyName] = true;
    }
    if (param[keyName] === 'false') {
      param[keyName] = false;
    }
    if (typeof param[keyName] === 'string' && !/^0/.test(param[keyName] as string) && !isNaN(+param[keyName])) {
      param[keyName] = +param[keyName];
    }
  })
  return param;
}
 
export type DataConfig = {
  'data-config': Properties
}
 
export const propertiesHandle = (defaultAttrs?: Properties | null, attrs?: Properties, type?: RehypeAttrsOptions['properties']): Properties | DataConfig => {
  if (type === 'string') {
    return { ...defaultAttrs, 'data-config': JSON.stringify({ ...attrs, rehyp: true })}
  } else if (type === 'attr') {
    return { ...defaultAttrs, ...attrs}
  }
  return { ...defaultAttrs, 'data-config': { ...attrs, rehyp: true }}
}