diff --git a/crates/nuwiki-core/src/syntax/vimwiki/lexer.rs b/crates/nuwiki-core/src/syntax/vimwiki/lexer.rs index 12ba237..2d4b1af 100644 --- a/crates/nuwiki-core/src/syntax/vimwiki/lexer.rs +++ b/crates/nuwiki-core/src/syntax/vimwiki/lexer.rs @@ -526,10 +526,9 @@ impl<'src> LexState<'src> { if level == 0 { return false; } - // Must be followed by at least one space. - if leading_ws + level >= bytes.len() || bytes[leading_ws + level] != b' ' { - return false; - } + // vimwiki accepts both spaced (`== H ==`) and spaceless (`==H==`) + // headings, so we don't require a space after the opening `=`s. The + // title is still trimmed of one optional space per side below. // Trailing `=`s of the same level. let trimmed_end = line.trim_end_matches([' ', '\t']); diff --git a/crates/nuwiki-core/tests/html_renderer.rs b/crates/nuwiki-core/tests/html_renderer.rs index 7ab0598..713728e 100644 --- a/crates/nuwiki-core/tests/html_renderer.rs +++ b/crates/nuwiki-core/tests/html_renderer.rs @@ -77,6 +77,27 @@ fn centered_heading_gets_centered_class() { assert!(out.contains("
==Heading==
`. + let out = render("==Plain==\n"); + assert!( + out.contains( + ""), "not a paragraph: {out2}"); +} + #[test] fn heading_keyword_renders_as_plain_text_not_badge() { // `== TODO ==` is a section title, not an inline keyword: it must render as diff --git a/crates/nuwiki-core/tests/lexer.rs b/crates/nuwiki-core/tests/lexer.rs index 53a3fcb..b3aab42 100644 --- a/crates/nuwiki-core/tests/lexer.rs +++ b/crates/nuwiki-core/tests/lexer.rs @@ -85,6 +85,32 @@ fn centered_heading_is_marked_centered() { assert!(matches!(lexed[2], HeadingClose)); } +#[test] +fn spaceless_heading_is_a_heading() { + // vimwiki accepts `==Heading==` with no spaces around the text. + let lexed = lex("==Plain==\n"); + assert_eq!( + lexed, + vec![ + HeadingOpen { + level: 2, + centered: false + }, + text("Plain"), + HeadingClose, + Newline, + ] + ); +} + +#[test] +fn marker_only_or_unbalanced_lines_are_not_headings() { + // No title between markers, and trailing `=` not at line end → plain text. + assert!(!matches!(lex("======\n")[0], HeadingOpen { .. })); + assert!(!matches!(lex("==> arrow\n")[0], HeadingOpen { .. })); + assert!(!matches!(lex("==a==b\n")[0], HeadingOpen { .. })); +} + #[test] fn heading_with_inline_bold() { let lexed = lex("== Hello *world* ==\n");