Reuse Word markers before inserting anchors
This commit is contained in:
parent
cb0beb1a12
commit
340fec3cab
@ -1980,11 +1980,12 @@ static void WordCompanionRuntimeFollowsMultipleImportedSceneAnchors()
|
|||||||
Assert(script.Contains("if (paragraph.sceneAnchorId)", StringComparison.Ordinal), "Runtime structure should start scenes from PD-SCENE anchors on ordinary paragraphs.");
|
Assert(script.Contains("if (paragraph.sceneAnchorId)", StringComparison.Ordinal), "Runtime structure should start scenes from PD-SCENE anchors on ordinary paragraphs.");
|
||||||
Assert(script.Contains("return chapter.scenes\r\n .filter((item) => item.startParagraphIndex <= paragraphIndex)", StringComparison.Ordinal)
|
Assert(script.Contains("return chapter.scenes\r\n .filter((item) => item.startParagraphIndex <= paragraphIndex)", StringComparison.Ordinal)
|
||||||
|| script.Contains("return chapter.scenes\n .filter((item) => item.startParagraphIndex <= paragraphIndex)", StringComparison.Ordinal), "Cursor resolution should select the latest preceding scene boundary.");
|
|| script.Contains("return chapter.scenes\n .filter((item) => item.startParagraphIndex <= paragraphIndex)", StringComparison.Ordinal), "Cursor resolution should select the latest preceding scene boundary.");
|
||||||
Assert(script.Contains("findExactAnchorControl(paragraph, tag)", StringComparison.Ordinal), "Marker insertion should reuse only the exact canonical SceneID tag.");
|
Assert(script.Contains("findExactAnchorControl(paragraph, tag)", StringComparison.Ordinal), "Marker insertion should prefer the exact canonical SceneID tag.");
|
||||||
|
Assert(script.Contains("const reusable = existing || findAnchorControl(paragraph, prefix)", StringComparison.Ordinal), "Marker insertion should reuse an existing same-prefix marker on the same paragraph before inserting another control.");
|
||||||
Assert(script.Contains("const rangeLocations = [\"Content\", \"Start\", \"Whole\"]", StringComparison.Ordinal), "Marker insertion should try heading content before progressively smaller Word ranges.");
|
Assert(script.Contains("const rangeLocations = [\"Content\", \"Start\", \"Whole\"]", StringComparison.Ordinal), "Marker insertion should try heading content before progressively smaller Word ranges.");
|
||||||
Assert(script.Contains("paragraph.getRange(rangeLocation).insertContentControl()", StringComparison.Ordinal), "Marker insertion should retry Word-supported paragraph range locations.");
|
Assert(script.Contains("paragraph.getRange(rangeLocation).insertContentControl()", StringComparison.Ordinal), "Marker insertion should retry Word-supported paragraph range locations.");
|
||||||
Assert(script.Contains("await ensureAnchorControl(context, paragraphs.items[index], title, tag, prefix)", StringComparison.Ordinal), "Bulk marker sync should await each marker insertion so Word range failures are isolated.");
|
Assert(script.Contains("await ensureAnchorControl(context, paragraphs.items[index], title, tag, prefix)", StringComparison.Ordinal), "Bulk marker sync should await each marker insertion so Word range failures are isolated.");
|
||||||
Assert(!script.Contains("const existing = findAnchorControl(paragraph, prefix);", StringComparison.Ordinal), "Marker insertion must not collapse distinct PD-SCENE tags by prefix.");
|
Assert(script.Contains("paragraphs.items[index].contentControls.load(\"items/tag,title\")", StringComparison.Ordinal), "Bulk marker sync should inspect existing paragraph markers before deciding to insert content controls.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WordCompanionExistingProjectBookLinkingRemainsAvailable()
|
static void WordCompanionExistingProjectBookLinkingRemainsAvailable()
|
||||||
|
|||||||
@ -2621,6 +2621,39 @@
|
|||||||
paragraphs.load("items/text,items/style,items/styleBuiltIn");
|
paragraphs.load("items/text,items/style,items/styleBuiltIn");
|
||||||
await context.sync();
|
await context.sync();
|
||||||
|
|
||||||
|
const markerParagraphIndexes = new Set();
|
||||||
|
if (chapterInstructions.length > 0 || sceneInstructions.length > 0) {
|
||||||
|
for (const instruction of [...chapterInstructions, ...sceneInstructions]) {
|
||||||
|
const index = Number.parseInt(instruction.wordParagraphIndex ?? instruction.WordParagraphIndex, 10);
|
||||||
|
if (Number.isInteger(index) && paragraphs.items[index]) {
|
||||||
|
markerParagraphIndexes.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const chapter of lastOnboardingScanPreview.chapters || []) {
|
||||||
|
const index = Number.parseInt(chapter.startPosition, 10);
|
||||||
|
if (Number.isInteger(index) && paragraphs.items[index]) {
|
||||||
|
markerParagraphIndexes.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const scene of lastOnboardingScanPreview.scenes || []) {
|
||||||
|
const index = Number.parseInt(scene.startPosition, 10);
|
||||||
|
if (Number.isInteger(index) && paragraphs.items[index]) {
|
||||||
|
markerParagraphIndexes.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const index of markerParagraphIndexes) {
|
||||||
|
paragraphs.items[index].contentControls.load("items/tag,title");
|
||||||
|
}
|
||||||
|
await context.sync();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Unable to inspect existing PlotDirector markers before marker sync.", error);
|
||||||
|
}
|
||||||
|
|
||||||
if (chapterInstructions.length > 0 || sceneInstructions.length > 0) {
|
if (chapterInstructions.length > 0 || sceneInstructions.length > 0) {
|
||||||
for (const instruction of chapterInstructions) {
|
for (const instruction of chapterInstructions) {
|
||||||
const index = Number.parseInt(instruction.wordParagraphIndex ?? instruction.WordParagraphIndex, 10);
|
const index = Number.parseInt(instruction.wordParagraphIndex ?? instruction.WordParagraphIndex, 10);
|
||||||
@ -4615,10 +4648,11 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existing) {
|
const reusable = existing || findAnchorControl(paragraph, prefix);
|
||||||
existing.title = title;
|
if (reusable) {
|
||||||
existing.tag = tag;
|
reusable.title = title;
|
||||||
existing.appearance = "Hidden";
|
reusable.tag = tag;
|
||||||
|
reusable.appearance = "Hidden";
|
||||||
await context.sync();
|
await context.sync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user