chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
const defaultDelimiters = [
{ left: '\\[', right: '\\]', display: true },
{ left: '\\(', right: '\\)', display: false },
];
// 转义括号规则 - 通用数学公式解析器
function escapedBracketRule(delimiters: any) {
return (text: string, startPos: number = 0) => {
const max = text.length;
const start = startPos;
for (const { left, right, display } of delimiters) {
// 检查是否以左标记开始
if (!text.slice(start).startsWith(left)) continue;
// 跳过左标记的长度
let pos = start + left.length;
// 寻找匹配的右标记
while (pos < max) {
if (text.slice(pos).startsWith(right)) {
break;
}
pos++;
}
// 没找到匹配的右标记,跳过,进入下个匹配
if (pos >= max) continue;
// 提取数学公式内容
const content = text.slice(start + left.length, pos);
const endPos = pos + right.length;
return {
formula: content,
display,
start,
end: endPos,
left,
right,
success: true,
};
}
return {
formula: '',
display: false,
start: 0,
end: 0,
left: '',
right: '',
success: false,
};
};
}
/**
* 根据规则将连续的过程标签ToolCall, Skill等合并
* 规则:
* 1. 连续 2 个及以上的过程标签合并
* 2. 中间包含“执行计划”的不合并(作为分隔符)
* 3. 标签间只包含空白字符时不中断合并
* 4. 支持 :::container 语法和 PC 端的 HTML 标签语法
* @param text - 待处理的 Markdown 文本
* @returns 处理后的文本
*/
export function groupMarkdownContainers(text : string) : string {
if (!text) return '';
// 1. 匹配 HTML 格式的过程标签 (markdown-custom-process)
// 2. 匹配 :::container 格式的标签
const blockRegex = /(?:[\r\n\s]*)(?:(?:<(?:div|p)\b[^>]*>)?\s*(<markdown-custom-process\b[^>]*?>(?:<\/markdown-custom-process>|\/>)?)\s*(?:<\/(?:div|p)>)?|(:::container\b[^\n]*?\n:::))/g;
let result = '';
let lastIndex = 0;
let currentGroup : string[] = [];
let match : RegExpExecArray | null;
const flushGroup = () => {
if (currentGroup.length > 0) {
if (currentGroup.length >= 2) {
// 多个时,为了支持层级,必须使用规范化后的 HTML 标签
const groupContent = `\n\n<markdown-custom-process-group>\n${normalizedGroup.join('\n')}\n</markdown-custom-process-group>\n\n`;
result += groupContent;
} else {
// 只有一个工具时,保持原样输出,最稳妥
result += `\n\n${currentGroup[0]}\n\n`;
}
currentGroup = [];
normalizedGroup = [];
}
};
let count = 0;
let normalizedGroup : string[] = [];
while ((match = blockRegex.exec(text)) !== null) {
count++;
const textBefore = text.slice(lastIndex, match.index);
if (textBefore.trim() !== '') {
flushGroup();
result += textBefore;
} else {
if (currentGroup.length === 0) {
result += textBefore;
}
}
let tagMatch = match[1] || match[2] || '';
// 为了分组显示,我们依然需要一份规范化后的 HTML 标签
let normalizedTag = '';
if (tagMatch.startsWith(':::container')) {
const executeId = extractAttribute(tagMatch, 'executeId');
const type = extractAttribute(tagMatch, 'type');
const status = extractAttribute(tagMatch, 'status');
const name = extractAttribute(tagMatch, 'name');
const safeName = name.replace(/"/g, '&quot;');
normalizedTag = `<markdown-custom-process executeid="${executeId}" type="${type || ''}" status="${status || ''}" name="${safeName}"></markdown-custom-process>`;
} else {
normalizedTag = tagMatch;
if (!normalizedTag.includes('</markdown-custom-process>') && !normalizedTag.endsWith('/>')) {
normalizedTag = normalizedTag.replace('>', '></markdown-custom-process>');
}
}
const isPlan = /type=["']Plan["']/.test(normalizedTag);
if (isPlan) {
flushGroup();
// Plan 类型保持原样输出
result += `\n\n${tagMatch}\n\n`;
} else {
currentGroup.push(tagMatch);
normalizedGroup.push(normalizedTag);
}
lastIndex = blockRegex.lastIndex;
}
flushGroup();
result += text.slice(lastIndex);
const finalResult = result.replace(/\n{3,}/g, '\n\n').trim();
return finalResult;
}
/**
* 从属性字符串中提取指定属性的值
*/
function extractAttribute(attrString : string, attrName : string) : string {
const regex = new RegExp(`${attrName}=["']([^"']*)["']`);
const match = attrString.match(regex);
if (match != null) {
const val = match[1];
// 还原 HTML 实体,避免在后续处理中出现双重转义
return val.replace(/&quot;/g, '"');
}
return '';
}
// 新的数学公式替换函数 - 直接替换为 $$ 分隔符
export function replaceMathBracket(text : string) : string {
// return text; //临时关闭
// 创建只包含非美元符号分隔符的选项
const nonDollarDelimiters = defaultDelimiters.filter(
(delimiter) =>
!delimiter.left.includes('$') && !delimiter.right.includes('$'),
);
const rule = escapedBracketRule(nonDollarDelimiters);
let result = '';
let pos = 0;
while (pos < text.length) {
const match = rule(text, pos);
if (match.success) {
// 添加匹配前的文本
result += text.slice(pos, match.start);
// 替换为 $$ 分隔符
const delimiter = match.display ? '$$' : '$';
result += `${delimiter}${match.formula}${delimiter}`;
pos = match.end;
} else {
// 没有匹配,添加当前字符
result += text[pos];
pos++;
}
}
return result;
}