feat: 補齊工具一(最新章節狀態、作品用語、語言欄位、貼上章節、台詞引號檢查)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
8c25728206
commit
fb04b0fa23
+15
-4
@@ -5,7 +5,7 @@ import type { CharacterPack, Conflict, Extracted, WorkPack } from './extract'
|
||||
|
||||
export const EXTRACT_COMMAND = 'anima-extract'
|
||||
const PENDING_KEY = 'extract:pending'
|
||||
const USAGE = `用法:/jsc-anima:${EXTRACT_COMMAND} <章節檔案路徑>,之後用 /jsc-anima:${EXTRACT_COMMAND} confirm 逐步確認,cancel 取消。`
|
||||
const USAGE = `用法:/jsc-anima:${EXTRACT_COMMAND} <章節檔案路徑>(或 paste <章節名稱> 並於下一行起貼上內容),之後用 /jsc-anima:${EXTRACT_COMMAND} confirm 逐步確認,cancel 取消。`
|
||||
|
||||
type Plan = {
|
||||
files: { path: string; json: unknown }[]
|
||||
@@ -38,13 +38,17 @@ async function readJson<T>($: Engine, path: string): Promise<T | undefined> {
|
||||
|
||||
const slugKey = (c: Extracted['characters'][number]) => slugify(c.slug || c.nameEn || c.name) || c.name
|
||||
|
||||
async function stage($: Engine, path: string): Promise<string> {
|
||||
async function stageFile($: Engine, path: string): Promise<string> {
|
||||
const cwd = await $.session.cwd().catch(() => '')
|
||||
const full = path.startsWith('/') ? path : `${cwd}/${path}`
|
||||
if (!(await $.fs.exists(full).catch(() => false))) return `找不到檔案:${path}`
|
||||
const text = String(await $.fs.read(full))
|
||||
if (!text.trim()) return `檔案是空的:${path}`
|
||||
return stage($, (path.split('/').pop() ?? path).replace(/\.[^.]+$/, ''), text)
|
||||
}
|
||||
|
||||
async function stage($: Engine, chapter: string, text: string): Promise<string> {
|
||||
const cwd = await $.session.cwd().catch(() => '')
|
||||
const chunks = chunkText(text)
|
||||
const parts: Extracted[] = []
|
||||
for (const [i, chunk] of chunks.entries()) {
|
||||
@@ -55,7 +59,6 @@ async function stage($: Engine, path: string): Promise<string> {
|
||||
parts.push(parsed)
|
||||
}
|
||||
const extracted = mergeChunks(parts)
|
||||
const chapter = (path.split('/').pop() ?? path).replace(/\.[^.]+$/, '')
|
||||
const workSlug = slugify(extracted.work.slug || extracted.work.nameEn || extracted.work.name)
|
||||
if (!workSlug) return '無法產生作品代號,請在章節中提供作品的英文名。'
|
||||
const slugs: Record<string, string> = {}
|
||||
@@ -172,7 +175,15 @@ export async function runExtract($: Engine, args: string): Promise<string> {
|
||||
await $.store.delete(PENDING_KEY)
|
||||
return '已取消,沒有寫入任何檔案。'
|
||||
}
|
||||
if (head !== 'confirm') return stage($, args.trim())
|
||||
if (head === 'paste') {
|
||||
// 貼上:第一行 paste <章節名稱>,下一行起為章節內容。
|
||||
const [first = '', ...body] = args.trim().split('\n')
|
||||
const name = first.replace(/^paste\s*/, '').trim()
|
||||
const text = body.join('\n')
|
||||
if (!name || !text.trim()) return `貼上章節的用法:/jsc-anima:${EXTRACT_COMMAND} paste <章節名稱>,下一行起貼上章節內容。`
|
||||
return stage($, name, text)
|
||||
}
|
||||
if (head !== 'confirm') return stageFile($, args.trim())
|
||||
|
||||
const p = (await $.store.get(PENDING_KEY)) as Pending | undefined
|
||||
if (!p) return `沒有待確認的萃取,請先執行 /jsc-anima:${EXTRACT_COMMAND} <章節檔案路徑>。`
|
||||
|
||||
Reference in New Issue
Block a user