obsidian-export icon indicating copy to clipboard operation
obsidian-export copied to clipboard

Horizontal bar being incorrectly detected as YAML frontmatter

Open jericjan opened this issue 1 year ago • 3 comments

This example

---
title: test
Date: 2023-11-12T22:00:00+08:00
lastMod: 2024-12-05T09:25:13+08:00
---

this is something

---
and here's more something
---

gives the following error:

Error: Failed to export './test/a.md'

Caused by:
   0: Failed to decode YAML frontmatter in './test/a.md'
   1: could not find expected ':' at line 5 column 1, while scanning a simple key at line 4 column 1

However this works just fine?

---
title: test
Date: 2023-11-12T22:00:00+08:00
lastMod: 2024-12-05T09:25:13+08:00
---
this is something
---
and here's more something
---

It loads just fine in Obsidian of course. YAML frontmatter can only ever be at the top so there shouldn't be any checks in the body of the file. I should mention that this was an old file, so it had to have been something from a new update. I still have a commit from Dec 9, 2023, 5:31AM UTC where this exported properly and it had the exact same contents

EDIT: markdownguide.org does say to add blank lines before horizontal rules, so that might be partly my fault. I've found that using - - - also works in Obsidian and also gets interpreted properly by the exporter. So my guess is it has something to do with the Heading 2 logic where a text gets set as Heading 2 whenever there is a number of - character on the line after it.

EDIT 2: There's another strange behavior where

asd
aand here's more something
asdasda
sdasd
---

turns into

## asd
aand here's more something
asdasda
sdasd

jericjan avatar Dec 05 '24 02:12 jericjan

This happens because of https://github.com/zoni/obsidian-export/commit/3afab84d697d82df1d4dfcc1948dd72dcdbe4c56. I didn't quite realize pulldown-cmark's implementation of metadata blocks supports blocks within a document body, which is somewhat different from the typical frontmatter seen in Obsidian and SSGs like Hugo, Jekyll, Zola, etc.

Dumping the events generated by pulldown-cmark shows clearly what's happening here:

# From within a clone of https://github.com/pulldown-cmark/pulldown-cmark.git:

cargo run -- --events --enable-metadata-blocks in.md
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/pulldown-cmark --events --enable-metadata-blocks in.md`
0..86: Start(MetadataBlock(YamlStyle))
4..83: Text(Borrowed("title: test\nDate: 2023-11-12T22:00:00+08:00\nlastMod: 2024-12-05T09:25:13+08:00\n"))
0..86: End(MetadataBlock(YamlStyle))
88..106: Start(Paragraph)
88..105: Text(Borrowed("this is something"))
88..106: End(Paragraph)
107..140: Start(MetadataBlock(YamlStyle))
111..137: Text(Borrowed("and here's more something\n"))
107..140: End(MetadataBlock(YamlStyle))
EOF

This is clearly working as intended for their implementation of metadata blocks, though it clashes with the rules for thematic breaks specified by CommonMark, which states Thematic breaks do not need blank lines before or after.

I suppose reverting 3afab84d697d82df1d4dfcc1948dd72dcdbe4c56 is an option, but I never liked that dependency and the way it extracted the frontmatter block, so I'm loathe to go that route. I'm tempted towards keeping the current implementation/behavior, considering the following simple workarounds are available, and neither feels like a tall ask of users:

  1. Inserting a blank line after the separator
  2. Using alternate symbols for the separator, like - - - or ***

How problematic would it be for you if this stayed as-is?

That being said, we can programmatically detect when we hit a metadata block that's not at the start of the document, and I do feel it's worth triggering a better warning or error when that happens. That way we can give the user some suggestions on what to do, instead of getting a YAML decode error (or worse, some text going missing from the document when it actually decodes as valid YAML).

zoni avatar Dec 08 '24 12:12 zoni

Using alternate symbols for the separator, like - - - or ***

For now, I wrote a script that replaces all --- with - - - except for YAML frontmatter, and it appears to have worked. I also regularly use obsidian-linter. I've posted an issue there, so I could possibly get that to work on their end.

But also yeah, it needs a better warning. I was dumbfounded when it said I had a frontmatter error when that was not the case at all.

jericjan avatar Dec 09 '24 01:12 jericjan

How problematic would it be for you if this stayed as-is?

Hello, I'd like to vote for fixing this issue somehow and not just leaving it as-is. I came here today to report it but found it's already reported. IMO YAML should not be expected in the middle of the file. However I understand now that this might be a pulldown-cmark's issue, not obsidian-export's.

Theoretically, I could write a sed script or something like this to change all the files in the vault. But I know that I still will be writing the separator as --- just because it's much easier to write than - - -.

goncharovdk avatar Dec 12 '24 11:12 goncharovdk

+1 on fix at a minimum a non cryptic error would also be usful

Theoretically, I could write a sed script or something like this to change all the files in the vault. But I know that I still will be writing the separator as --- just because it's much easier to write than - - -.

you can set a text replacement e.g. ---- → - - -

clehene avatar Sep 17 '25 18:09 clehene