UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

188 lines (175 loc) 7.59 kB
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } import { visit } from 'unist-util-visit'; /** * Remark plugin to handle color syntax in markdown code spans * Supports GitHub-style color visualization for HEX, RGB, and HSL colors * * @example * `#FF0000` -> renders with red color preview * `rgb(255, 0, 0)` -> renders with red color preview * `hsl(0, 100%, 50%)` -> renders with red color preview */ export var remarkColor = function remarkColor() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var colorValidator = options.colorValidator; /** * 验证并标准化颜色值 */ var validateAndNormalizeColor = function validateAndNormalizeColor(colorString) { var trimmed = colorString.trim(); // 如果有自定义验证函数,使用它 if (colorValidator && !colorValidator(trimmed)) { return null; } // HEX 颜色: #RRGGBB 或 #RGB var hexPattern = /^#([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/; if (hexPattern.test(trimmed)) { // 标准化为 6 位 HEX if (trimmed.length === 4) { var _trimmed = _slicedToArray(trimmed, 4), r = _trimmed[1], g = _trimmed[2], b = _trimmed[3]; return "#".concat(r).concat(r).concat(g).concat(g).concat(b).concat(b); } return trimmed.toUpperCase(); } // RGB 颜色: rgb(r, g, b) var rgbPattern = /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i; var rgbMatch = trimmed.match(rgbPattern); if (rgbMatch) { var _rgbMatch = _slicedToArray(rgbMatch, 4), _r = _rgbMatch[1], _g = _rgbMatch[2], _b = _rgbMatch[3]; var rNum = parseInt(_r, 10); var gNum = parseInt(_g, 10); var bNum = parseInt(_b, 10); // 验证 RGB 值范围 if (rNum >= 0 && rNum <= 255 && gNum >= 0 && gNum <= 255 && bNum >= 0 && bNum <= 255) { return "rgb(".concat(rNum, ", ").concat(gNum, ", ").concat(bNum, ")"); } } // HSL 颜色: hsl(h, s%, l%) var hslPattern = /^hsl\s*\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$/i; var hslMatch = trimmed.match(hslPattern); if (hslMatch) { var _hslMatch = _slicedToArray(hslMatch, 4), h = _hslMatch[1], s = _hslMatch[2], l = _hslMatch[3]; var hNum = parseInt(h, 10); var sNum = parseInt(s, 10); var lNum = parseInt(l, 10); // 验证 HSL 值范围 if (hNum >= 0 && hNum <= 360 && sNum >= 0 && sNum <= 100 && lNum >= 0 && lNum <= 100) { return "hsl(".concat(hNum, ", ").concat(sNum, "%, ").concat(lNum, "%)"); } } return null; }; return function (tree) { // 处理 inlineCode 节点(反引号包围的代码) visit(tree, 'inlineCode', function (node) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var parent = arguments.length > 2 ? arguments[2] : undefined; if (!node.value || typeof node.value !== 'string') return; var colorValue = validateAndNormalizeColor(node.value); if (colorValue) { // 创建自定义颜色节点 var colorNode = { children: [{ type: 'text', value: node.value }], color: colorValue, data: { hName: 'code', hProperties: { 'className': 'color-preview', 'data-color': colorValue, 'data-original': node.value, 'style': "--color-preview-color: ".concat(colorValue) } }, type: 'colorPreview', value: node.value }; // 替换 inlineCode 节点 parent.children.splice(index, 1, colorNode); return index; } }); // 处理文本节点中的颜色语法(作为备用,处理可能的边缘情况) visit(tree, 'text', function (node) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var parent = arguments.length > 2 ? arguments[2] : undefined; if (!node.value || typeof node.value !== 'string') return; // 查找反引号包围的颜色值 var colorPattern = /`([^`]+)`/g; var text = node.value; var hasColorMatch = false; var newNodes = []; var lastIndex = 0; var match; while ((match = colorPattern.exec(text)) !== null) { var _match = match, _match2 = _slicedToArray(_match, 2), fullMatch = _match2[0], colorCandidate = _match2[1]; var colorValue = validateAndNormalizeColor(colorCandidate); if (colorValue) { hasColorMatch = true; var startIndex = match.index; // 添加匹配前的文本 if (startIndex > lastIndex) { newNodes.push({ type: 'text', value: text.slice(lastIndex, startIndex) }); } // 添加颜色节点 newNodes.push({ children: [{ type: 'text', value: colorCandidate }], color: colorValue, data: { hName: 'code', hProperties: { 'className': 'color-preview', 'data-color': colorValue, 'data-original': colorCandidate, 'style': "--color-preview-color: ".concat(colorValue) } }, type: 'colorPreview', value: colorCandidate }); lastIndex = startIndex + fullMatch.length; } } if (hasColorMatch) { // 添加剩余文本 if (lastIndex < text.length) { newNodes.push({ type: 'text', value: text.slice(lastIndex) }); } // 替换当前节点 if (newNodes.length > 0 && parent) { var _parent$children; (_parent$children = parent.children).splice.apply(_parent$children, [index, 1].concat(newNodes)); return index + newNodes.length - 1; } } }); }; };