{"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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"}