mirror of
https://github.com/panatgithub/AnkiHeadingSync.git
synced 2026-07-22 06:51:43 +00:00
feat: add cardAnswerCutoffMode with heading-block / double-blank-lines and unify marker/GI writeback normalization.
4.9 KiB
4.9 KiB
Card Answer Cutoff Decisions
Date: 2026-04-23
Decision 1: Add a new explicit settings enum
- Add
cardAnswerCutoffModetoPluginSettingsas:heading-blockdouble-blank-lines
- Default value is
heading-block. - Validation rejects anything else.
Reason:
- This matches the plan and keeps the new behavior fully explicit in persistence, tests, and fingerprint invalidation.
Decision 2: Use one shared boundary helper for all three parsing routes
- Introduce a shared helper under manual-sync parsing services.
- The helper will accept:
- source lines for the current region
- absolute start line
- fallback line for empty content
- cutoff mode
- marker matcher/parser callbacks
- The helper will return at least:
contentLinestrailingLinescontentEndLinemarkerLinemarkerIndent- marker parse result when valid
- marker presence state
Reason:
- The actual repository currently duplicates this logic three times. Consolidation is the smallest change that enforces plan-wide consistency.
Decision 3: Marker precedence scans the whole region, not only the last non-empty line
- The helper will search for the first valid marker candidate inside the region.
- A valid marker always wins over blank-line cutoff.
- Only valid markers lock the cutoff boundary.
- Invalid marker candidates do not lock the boundary.
- If no valid marker exists and mode is
double-blank-lines, the first run of 2 or more consecutive blank lines ends the content. - If neither applies, fallback remains the full heading block / child region / group block.
Reason:
- The plan requires old layout compatibility and new layout support where marker/GI is moved before remarks.
Decision 4: Preserve current hashing semantics except for intentional cutoff changes
- Normal QA/Cloze
rawBlockTextstaysheading + trimmed content lines. - Semantic QA
rawBlockTextstayssemantic-qa child identity + parent display title + child label + bodyMarkdown. - QA Group
rawBlockTextstays based on stem, parsed items, and normalized body lines. - The only intended hash shifts are those caused by the new cutoff rule excluding remarks/trailing content from the answer region.
Reason:
- This keeps state recovery behavior as stable as possible while still honoring the new contract.
Decision 5: Normalize marker/GI writeback with a shared blank-tail routine
- Card and group marker services will share a common normalization helper.
- The writeback contract is:
- trim blank lines immediately after the answer region
- remove existing marker line when replacing
- insert the new marker at
contentEndLine - remove any blank lines between marker and trailing content
- if trailing non-blank content exists, insert exactly two blank lines after the marker
- preserve trailing non-blank content exactly as scanned
- QA Group writeback will continue to strip legacy inner ID markers.
Reason:
- The current services already do most of this. Sharing the normalization step reduces divergence and makes the plan’s rule explicit.
Decision 6: Thread cutoff mode through indexing context only
- Add the setting to
CardIndexingContext. FileIndexerServicepasses it intoCardIndexingService.index()for both vault and single-file indexing.- No rendering-layer contract changes are needed.
Reason:
- The feature affects indexing and writeback placement, not render output formatting.
Decision 7: Put cutoff mode into the deck-rules fingerprint path
- Update
createDeckRulesFingerprint()to includecardAnswerCutoffMode. - Keep the existing fingerprint path rather than adding a parallel reindex fingerprint.
Reason:
- The repository already uses this fingerprint to force rereads on unchanged files. Reusing it is the smallest compatible integration.
Decision 8: Keep the settings UI shape consistent with the repository
- Add one dropdown setting labeled with the two cutoff modes.
- Add concise zh/en descriptions that mirror the user-facing semantics from the plan.
- Cover both locales in existing settings tab tests.
Reason:
- The existing settings page relies on dropdown/toggle controls and is already tested that way.
Decision 9: Test coverage will be expanded at the service level first
- Primary behavior tests go into:
CardIndexingService.test.tsSemanticQaListParser.test.tsCardMarkerService.test.tsGroupMarkerService.test.tsFileIndexerService.test.tsManualSyncService.test.tsPluginSettings.test.tsPluginSettingTab.test.ts
- Add QA Group parser/service tests only where the cutoff or writeback behavior actually changes.
Reason:
- These files already exercise the real runtime path and minimize new test scaffolding.
Confirmed Non-Goals
- No expansion of QA Group answer modeling beyond the existing “first second-level item” contract.
- No new sync pipeline or new persistence store shape.
- No unrelated deck, render, or note-field-mapping refactor.