fix(notion-writer): fence-aware image/translate, NtnUploadError boundary, dead-code removal

FIX 1: _content_has_local_images and extract_local_images now skip lines inside
  ``` fences so a local-image ref inside a code block is not treated as real.
FIX 2: md_translate.translate() tracks fence state; callout/columns/mention
  transforms are suppressed for lines inside ``` ... ``` blocks (pass verbatim).
FIX 3: main() catches NtnUploadError and prints a clean error + e.stderr before
  sys.exit(1); body moved to _main_body(parser, args).
FIX 4: ntn_files.upload() raises NtnUploadError on empty stdout instead of
  IndexError, giving a clean message combined with FIX 3.
FIX 5: Removed unused write_to_page() (both page paths are inlined).
FIX 6: create_page_markdown() omits the 'markdown' key when value is falsy,
  avoiding empty-markdown sends on DB rows created without --file/--stdin.
FIX 7: CLAUDE.md documents --allow-deleting-content scope (markdown engine only).
TDD: Added test_fence_passthrough_no_transform (md_translate, suite now 8) and
  test_local_image_inside_fence_ignored (engine_routing, suite now 6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-27 10:33:09 +09:00
parent cf7e649284
commit 759bb20911
7 changed files with 90 additions and 22 deletions

View File

@@ -56,6 +56,28 @@ def test_mention_invalid_plain():
assert "mention-page" not in out
def test_fence_passthrough_no_transform():
"""Lines inside fenced code blocks must pass through verbatim — no callout,
columns, or mention transformation applied."""
raw_id = "abcdef0123456789abcdef0123456789"
src = (
"```\n"
"> [!NOTE]\n"
"::: columns\n"
f"@[Page]({raw_id})\n"
"```"
)
out = md_translate.translate(src)
# No transformation should have occurred
assert "<callout" not in out, "callout must not be emitted inside fence"
assert "<columns>" not in out, "columns must not be emitted inside fence"
assert "<mention-page" not in out, "mention must not be emitted inside fence"
# Original lines must be present verbatim
assert "> [!NOTE]" in out
assert "::: columns" in out
assert f"@[Page]({raw_id})" in out
def run_all():
tests = [
test_passthrough_basics,
@@ -65,6 +87,7 @@ def run_all():
test_toggle_children_indented,
test_mention_url,
test_mention_invalid_plain,
test_fence_passthrough_no_transform,
]
for t in tests:
print(f"\n{t.__name__}")