括号列表支持更新
为了使代码能够支持在括号中的情况,例如 (1)、
, (1).
, [1]:
,我们需要调整正则表达式以匹配这些格式,并确保在 getNextNumber
函数中正确处理标点和括号。
下面是修改后的代码:
- 修改正则表达式:增加对括号和不同标点符号的支持。
- 调整
getNextNumber
函数:使其能够处理括号和不同的标点符号。
typescripttype PatternType = 'parabic' | 'arabic' | 'uppercaseLetter' | 'lowercaseLetter' | 'romanNumeral' | 'chineseNumeral';
function identifyPattern(lineText: string): PatternType | null {
const patterns: { [key in PatternType]: RegExp } = {
arabic: /^\(?(\d+)\)?[\)|\.|、|:]/,
uppercaseLetter: /^\(?[A-Z]\)?[\)|\.|、|:]/,
lowercaseLetter: /^\(?[a-z]\)?[\)|\.|、|:]/,
romanNumeral: /^\(?M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\)?[\)|\.|、|:]/,
chineseNumeral: /^\(?[\u4e00-\u9fa5]+\)?[\)|\.|、|:]/,
};
// ... 保持原有代码不变 ...
}
function getNextNumber(currentNumber: string, punctuation: string, patternType: PatternType): string | null {
// ... 保持原有代码不变 ...
// 根据标点符号的不同,可能需要添加括号
switch (punctuation) {
case ')':
return '(' + nextNumber + ')';
case '.':
case '、':
case ':':
return nextNumber + punctuation;
default:
return null;
}
}
// ... 其他函数保持不变 ...
这些更改将使代码能够处理带括号的不同列表样式,同时保持对原有格式的支持。记得测试这些更改以确保它们按预期工作。
了解了,我们需要进一步调整正则表达式以匹配括号后跟着的点号或顿号。此外,getNextNumber
函数也需要相应地处理这种情况。以下是改进后的代码:
- 修改正则表达式:确保它能匹配括号内的序号,后面跟着点号或顿号。
- 调整
getNextNumber
函数:处理括号和后续的标点符号。
typescripttype PatternType = 'parabic' | 'arabic' | 'uppercaseLetter' | 'lowercaseLetter' | 'romanNumeral' | 'chineseNumeral';
function identifyPattern(lineText: string): PatternType | null {
const patterns: { [key in PatternType]: RegExp } = {
arabic: /^\(?(\d+)\)?[、\.]/,
uppercaseLetter: /^\(?[A-Z]\)?[、\.]/,
lowercaseLetter: /^\(?[a-z]\)?[、\.]/,
romanNumeral: /^\(?M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\)?[、\.]/,
chineseNumeral: /^\(?[\u4e00-\u9fa5]+\)?[、\.]/,
};
// ... 保持原有代码不变 ...
}
function getNextNumber(currentNumber: string, patternType: PatternType): string | null {
let nextNumber: string | null;
let punctuation: string;
// 确定标点符号类型
if (currentNumber.endsWith(')')) {
punctuation = currentNumber.slice(-2, -1); // 获取括号内的标点符号
currentNumber = currentNumber.slice(1, -2); // 移除括号和标点符号
} else {
punctuation = currentNumber.slice(-1); // 获取标点符号
currentNumber = currentNumber.slice(0, -1); // 移除标点符号
}
// 根据不同的序号类型生成下一个序号
// ... 保持原有逻辑不变 ...
// 返回格式化的下一个序号
if (punctuation === '.' || punctuation === '、') {
return '(' + nextNumber + ')' + punctuation;
} else {
return nextNumber; // 如果无法确定标点符号,直接返回序号
}
}
// ... 其他函数保持不变 ...
这段代码现在应该能够正确地处理括号内的序号,后面跟着点号或顿号的情况。记得对代码进行测试,确保它按照预期工作。
为了在 checkForEnter
函数中先检测成对括号的存在,并根据这些括号进行内容分类,然后再进行内容判断,我们可以添加一些逻辑来实现这个需求。这个逻辑将在调用 identifyPattern
之前执行,用于处理成对的括号,并暂时移除它们以进行后续的模式识别。
具体来说,我们可以:
- 检测成对括号:在
identifyPattern
调用之前,检查文本中是否存在成对的(...)
、( ... )
、 或[ ... ]
括号。 - 移除成对括号:如果存在成对的括号,暂时从文本中移除它们,然后再进行内容的模式识别。
- 还原括号:在确定了模式后,我们需要还原原来的括号格式。
下面是修改后的 checkForEnter
函数:
typescriptfunction checkForEnter(transaction: Transaction, state: EditorState) {
const changes: ChangeSpec[] = [];
transaction.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
let text = inserted.toString();
if (text.includes('\n')) { // 检测到回车
let currentLineStart = state.doc.lineAt(fromA).from;
let currentLineText = state.doc.sliceString(currentLineStart, fromA);
// 检测并处理成对括号
let bracketPattern = /(\(.*\)|\(.*\)|\​``【oaicite:0】``​|\[.*\])/;
let hasBrackets = bracketPattern.test(currentLineText);
let originalBrackets = hasBrackets ? currentLineText.match(bracketPattern)[0] : '';
let textWithoutBrackets = hasBrackets ? currentLineText.replace(bracketPattern, '') : currentLineText;
let pattern = identifyPattern(textWithoutBrackets);
if (pattern) {
let currentNumber = textWithoutBrackets.match(/^[\w\u4e00-\u9fa5]+/)?.[0]; // 提取序号部分
let punctuation = textWithoutBrackets.match(/^[\w\u4e00-\u9fa5]+[\.\、]/)?.[0].slice(-1) || '.';
if (!currentNumber) return; // 如果没有序号,不进行处理
let nextNumber = getNextNumber(currentNumber, punctuation, pattern);
if (nextNumber !== null) {
// 如果存在成对括号,还原它们
nextNumber = hasBrackets ? originalBrackets.replace(/.*?([\w\u4e00-\u9fa5]+).*?/, nextNumber) : nextNumber;
let insertPosition = state.doc.lineAt(toB).to; // 新行的开始位置
let tChanges = { from: insertPosition, to: insertPosition, insert: nextNumber + (punctuation === "、" ? "" : " ") };
changes.push(tChanges);
}
}
}
});
return changes;
}
在这段代码中,我们首先检测文本中是否存在成对的括号。如果存在,我们将括号暂时从文本中移除,以便进行模式识别。之后,我们再将这些括号还原到识别出的新序号中。这样可以确保成对括号的格式在处理过程中保持一致。
您的观点是正确的。为了避免处理不在行首的括号,我们应该只检测行首的括号。在这种情况下,我们将使用一个正则表达式来匹配行首的成对括号,并在此基础上进行进一步的处理。
下面是针对您需求的 checkForEnter
函数的更新:
typescriptfunction checkForEnter(transaction: Transaction, state: EditorState) {
const changes: ChangeSpec[] = [];
transaction.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
let text = inserted.toString();
if (text.includes('\n')) { // 检测到回车
let currentLineStart = state.doc.lineAt(fromA).from;
let currentLineText = state.doc.sliceString(currentLineStart, fromA);
// 检测行首的成对括号
let bracketPattern = /^(?:\(|\(|\​``【oaicite:0】``​|\])/;
let bracketMatch = currentLineText.match(bracketPattern);
let hasBrackets = bracketMatch != null;
let textWithoutBrackets = hasBrackets ? currentLineText.replace(bracketPattern, '$1') : currentLineText;
let pattern = identifyPattern(textWithoutBrackets);
if (pattern) {
let currentNumber = textWithoutBrackets.match(/^[\w\u4e00-\u9fa5]+/)?.[0]; // 提取序号部分
let punctuation = textWithoutBrackets.match(/^[\w\u4e00-\u9fa5]+[\.\、]/)?.[0].slice(-1) || '.';
if (!currentNumber) return; // 如果没有序号,不进行处理
let nextNumber = getNextNumber(currentNumber, punctuation, pattern);
if (nextNumber !== null) {
// 如果存在成对括号,还原它们
nextNumber = hasBrackets ? bracketMatch[0].replace(bracketMatch[1], nextNumber) : nextNumber;
let insertPosition = state.doc.lineAt(toB).to; // 新行的开始位置
let tChanges = { from: insertPosition, to: insertPosition, insert: nextNumber + (punctuation === "、" ? "" : " ") };
changes.push(tChanges);
}
}
}
});
return changes;
}
这个更新确保只有当行首存在成对括号时,才会进行括号的处理。如果存在成对括号,它们将被暂时移除以进行模式识别,然后在生成新的序号时再加回去。这应该能够满足您的需求,避免意外处理不在行首的括号。