fix(vault): tolerate BOM and leading blank lines in frontmatter parsing
A note saved by Notepad/PowerShell carries a leading UTF-8 BOM (and sometimes leading blank lines) before the opening `---`. The old \A-anchored regex treated that as "no frontmatter", dumping the whole YAML block into the body -- which then hits the destructive no-valid-ULID path in index.py. parse() now strips a leading BOM and tolerates leading whitespace before the delimiter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0139vHnNpS2sLNELjrAHX5Cu
This commit is contained in:
1 parent
9f976c54ea
commit
6c5531da98
2 files changed
+19
-2
No files matched your search
+5
-2
@@ -19,7 +19,7 @@ from ruamel.yaml.comments import CommentedMap
|
||||
from mdmem.config import NOTE_TYPES
|
||||
from mdmem.ids import filename_for, new_id, nfc
|
||||
|
||||
_FM_RE = re.compile(r"\A---[ \t]*\r?\n(.*?)\r?\n---[ \t]*\r?\n?", re.DOTALL)
|
||||
_FM_RE = re.compile(r"\A\s*---[ \t]*\r?\n(.*?)\r?\n---[ \t]*\r?\n?", re.DOTALL)
|
||||
_WIKILINK_RE = re.compile(r"\[\[([^\[\]|#]+?)(?:#[^\[\]|]*)?(?:\|[^\[\]]*)?\]\]")
|
||||
_HEADING_RE = re.compile(r"^(#{1,6})\s+(.*?)\s*#*\s*$", re.MULTILINE)
|
||||
|
||||
@@ -62,7 +62,10 @@ def parse(text: str, *, strict: bool = False) -> tuple[CommentedMap, str]:
|
||||
strict=True re-raises broken YAML — used where a human just typed it. The
|
||||
scanner stays lenient so one bad file cannot stop the whole vault indexing.
|
||||
"""
|
||||
text = nfc(text.replace("\r\n", "\n"))
|
||||
text = text.replace("\r\n", "\n")
|
||||
if text.startswith(""): # BOM left by Notepad/PowerShell
|
||||
text = text[1:]
|
||||
text = nfc(text)
|
||||
m = _FM_RE.match(text)
|
||||
if not m:
|
||||
return CommentedMap(), text
|
||||
|
||||
@@ -82,6 +82,20 @@ def test_missing_frontmatter_is_tolerated():
|
||||
assert body.strip() == "just a body"
|
||||
|
||||
|
||||
def test_parse_tolerates_leading_utf8_bom():
|
||||
"""A note saved by Notepad/PowerShell carries a leading BOM (finding 2)."""
|
||||
fm, body = parse("" + SAMPLE)
|
||||
assert fm["title"].startswith("llama-swap")
|
||||
assert body.startswith("llama-swap routes models")
|
||||
assert "---" not in body
|
||||
|
||||
|
||||
def test_parse_tolerates_leading_blank_lines_before_delimiter():
|
||||
fm, body = parse("\n\n \n" + SAMPLE)
|
||||
assert fm["title"].startswith("llama-swap")
|
||||
assert body.startswith("llama-swap routes models")
|
||||
|
||||
|
||||
def test_wikilinks_with_alias_and_heading():
|
||||
n = Note.new(title="T", body="see [[target|alias]] and [[other#Head]]", type="note")
|
||||
assert n.wikilinks == ["target", "other"]
|
||||
|
||||
Reference in new issue
Block a user