{"version":3,"file":"remarkColor.mjs","names":[],"sources":["../../../src/Markdown/plugins/remarkColor.ts"],"sourcesContent":["import { visit } from 'unist-util-visit';\n\ninterface RemarkColorOptions {\n  /**\n   * 自定义颜色验证函数\n   */\n  colorValidator?: (colorString: string) => boolean;\n}\n\n/**\n * Remark plugin to handle color syntax in markdown code spans\n * Supports GitHub-style color visualization for HEX, RGB, and HSL colors\n *\n * @example\n * `#FF0000` -> renders with red color preview\n * `rgb(255, 0, 0)` -> renders with red color preview\n * `hsl(0, 100%, 50%)` -> renders with red color preview\n */\nexport const remarkColor = (options: RemarkColorOptions = {}) => {\n  const { colorValidator } = options;\n\n  /**\n   * 验证并标准化颜色值\n   */\n  const validateAndNormalizeColor = (colorString: string): string | null => {\n    const trimmed = colorString.trim();\n\n    // 如果有自定义验证函数，使用它\n    if (colorValidator && !colorValidator(trimmed)) {\n      return null;\n    }\n\n    // HEX 颜色: #RRGGBB 或 #RGB\n    const hexPattern = /^#([\\da-f]{6}|[\\da-f]{3})$/i;\n    if (hexPattern.test(trimmed)) {\n      // 标准化为 6 位 HEX\n      if (trimmed.length === 4) {\n        const [, r, g, b] = trimmed;\n        return `#${r}${r}${g}${g}${b}${b}`;\n      }\n      return trimmed.toUpperCase();\n    }\n\n    // RGB 颜色: rgb(r, g, b)\n    const rgbPattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n    const rgbMatch = trimmed.match(rgbPattern);\n    if (rgbMatch) {\n      const [, r, g, b] = rgbMatch;\n      const rNum = parseInt(r, 10);\n      const gNum = parseInt(g, 10);\n      const bNum = parseInt(b, 10);\n\n      // 验证 RGB 值范围\n      if (rNum >= 0 && rNum <= 255 && gNum >= 0 && gNum <= 255 && bNum >= 0 && bNum <= 255) {\n        return `rgb(${rNum}, ${gNum}, ${bNum})`;\n      }\n    }\n\n    // HSL 颜色: hsl(h, s%, l%)\n    const hslPattern = /^hsl\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)$/i;\n    const hslMatch = trimmed.match(hslPattern);\n    if (hslMatch) {\n      const [, h, s, l] = hslMatch;\n      const hNum = parseInt(h, 10);\n      const sNum = parseInt(s, 10);\n      const lNum = parseInt(l, 10);\n\n      // 验证 HSL 值范围\n      if (hNum >= 0 && hNum <= 360 && sNum >= 0 && sNum <= 100 && lNum >= 0 && lNum <= 100) {\n        return `hsl(${hNum}, ${sNum}%, ${lNum}%)`;\n      }\n    }\n\n    return null;\n  };\n\n  return (tree: any) => {\n    // 处理 inlineCode 节点（反引号包围的代码）\n    visit(tree, 'inlineCode', (node, index = 0, parent) => {\n      if (!node.value || typeof node.value !== 'string') return;\n\n      const colorValue = validateAndNormalizeColor(node.value);\n\n      if (colorValue) {\n        // 创建自定义颜色节点\n        const colorNode = {\n          children: [{ type: 'text', value: node.value }],\n          color: colorValue,\n          data: {\n            hName: 'code',\n            hProperties: {\n              'className': 'color-preview',\n              'data-color': colorValue,\n              'data-original': node.value,\n              'style': `--color-preview-color: ${colorValue}`,\n            },\n          },\n          type: 'colorPreview',\n          value: node.value,\n        };\n\n        // 替换 inlineCode 节点\n        parent.children.splice(index, 1, colorNode);\n        return index;\n      }\n    });\n\n    // 处理文本节点中的颜色语法（作为备用，处理可能的边缘情况）\n    visit(tree, 'text', (node, index = 0, parent) => {\n      if (!node.value || typeof node.value !== 'string') return;\n\n      // 查找反引号包围的颜色值\n      const colorPattern = /`([^`]+)`/g;\n      const text = node.value;\n\n      let hasColorMatch = false;\n      const newNodes = [];\n      let lastIndex = 0;\n      let match;\n\n      while ((match = colorPattern.exec(text)) !== null) {\n        const [fullMatch, colorCandidate] = match;\n        const colorValue = validateAndNormalizeColor(colorCandidate);\n\n        if (colorValue) {\n          hasColorMatch = true;\n          const startIndex = match.index;\n\n          // 添加匹配前的文本\n          if (startIndex > lastIndex) {\n            newNodes.push({\n              type: 'text',\n              value: text.slice(lastIndex, startIndex),\n            });\n          }\n\n          // 添加颜色节点\n          newNodes.push({\n            children: [{ type: 'text', value: colorCandidate }],\n            color: colorValue,\n            data: {\n              hName: 'code',\n              hProperties: {\n                'className': 'color-preview',\n                'data-color': colorValue,\n                'data-original': colorCandidate,\n                'style': `--color-preview-color: ${colorValue}`,\n              },\n            },\n            type: 'colorPreview',\n            value: colorCandidate,\n          });\n\n          lastIndex = startIndex + fullMatch.length;\n        }\n      }\n\n      if (hasColorMatch) {\n        // 添加剩余文本\n        if (lastIndex < text.length) {\n          newNodes.push({\n            type: 'text',\n            value: text.slice(lastIndex),\n          });\n        }\n\n        // 替换当前节点\n        if (newNodes.length > 0 && parent) {\n          parent.children.splice(index, 1, ...newNodes);\n          return index + newNodes.length - 1;\n        }\n      }\n    });\n  };\n};\n"],"mappings":"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"}