- 写作配置 Q&A 改为「先流式生成大纲并多轮确认 → 再确认意图」,放宽轮数上限 - 意图识别出列表外的新文章类型时带上类型名+简介(仅本次写作临时使用) - 成稿支持参考文献:正文 [n] 角标 + 文末按出现顺序的「参考文献」列表(表单开关,默认开) - 流式接取未闭合 <think> 思考内容,首 token 前加「正在整理…」占位 - 修复右侧编辑器输入空格只出一次、光标跳字(避免自激回灌 setContent 重置光标) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
25 lines
1.2 KiB
TypeScript
25 lines
1.2 KiB
TypeScript
/**
|
|
* 中文语境下的「字数」统计,与后端 `nodes/_utils.py:count_words` 保持同一口径:
|
|
* 汉字逐字计 + 中文标点逐个计 + 连续数字/英文各算 1 字。
|
|
* 不计入空白、markdown 语法符号(# * - 等)与 ASCII 标点。
|
|
*/
|
|
export function countWords(text: string): number {
|
|
if (!text) return 0;
|
|
const cjk = (text.match(/[一-鿿]/g) ?? []).length;
|
|
const cjkPunct = (text.match(/[,。、;:?!“”‘’()《》【】「」『』〈〉—…·~]/g) ?? []).length;
|
|
const alnumRuns = (text.match(/[A-Za-z0-9]+/g) ?? []).length;
|
|
return cjk + cjkPunct + alnumRuns;
|
|
}
|
|
|
|
/**
|
|
* 正文字数:与后端 word_count 同口径——**不计文末「参考文献」列表**。
|
|
* 后端在字数收敛后才追加 `## 参考文献` 段,其 word_count 只统计正文;前端展示「实际 vs 目标」
|
|
* 也必须排除该段,否则会因文献列表虚高几十~几百字,让用户误以为严重超标。
|
|
*/
|
|
export function countArticleWords(markdown: string): number {
|
|
if (!markdown) return 0;
|
|
const idx = markdown.lastIndexOf('## 参考文献');
|
|
const body = idx >= 0 ? markdown.slice(0, idx) : markdown;
|
|
return countWords(body);
|
|
}
|