diff --git a/src/syntax/link.rs b/src/syntax/link.rs
index a2aa4d9..447b5a1 100644
--- a/src/syntax/link.rs
+++ b/src/syntax/link.rs
@@ -22,7 +22,7 @@ pub fn link_node(input: Input) -> IResult {
let mut parser = map(
tuple((
l_bracket2_token,
- take_while(|c: char| c != '<' && c != '>' && c != '\n' && c != ']'),
+ take_while(|c: char| c != '<' && c != '>' && c != ']'),
opt(tuple((
r_bracket_token,
l_bracket_token,
@@ -110,3 +110,66 @@ fn parse() {
assert!(link_node(("[[#id][desc]", config).into()).is_err());
}
+
+/// Emacs org-mode accepts a single newline inside a bracket link — both inside
+/// the path and inside the description. These tests document the discrepancy
+/// against orgize and serve as the reproducer for the upstream issue/PR.
+#[test]
+fn parse_multiline_link() {
+ use crate::{ast::Link, tests::to_ast};
+
+ let to_link = to_ast::(link_node);
+
+ // Path-only link with a newline inside the path.
+ let link = to_link("[[really really long link\nthat just keeps going]]");
+ insta::assert_debug_snapshot!(
+ link.syntax,
+ @r###"
+ LINK@0..49
+ L_BRACKET2@0..2 "[["
+ LINK_PATH@2..47 "really really long li ..."
+ R_BRACKET2@47..49 "]]"
+ "###
+ );
+
+ // Link with separate description that contains a newline.
+ let link = to_link("[[https://example.com][some\ndescription]]");
+ insta::assert_debug_snapshot!(
+ link.syntax,
+ @r###"
+ LINK@0..41
+ L_BRACKET2@0..2 "[["
+ LINK_PATH@2..21 "https://example.com"
+ R_BRACKET@21..22 "]"
+ L_BRACKET@22..23 "["
+ TEXT@23..39 "some\ndescription"
+ R_BRACKET2@39..41 "]]"
+ "###
+ );
+}
+
+/// `Org::parse` should also pick up multi-line links inside paragraphs. This
+/// is the end-to-end case relevant to downstream formatters (e.g. org-fmt).
+#[test]
+fn parse_multiline_link_in_paragraph() {
+ use crate::{ast::Link, Org};
+ use rowan::ast::AstNode;
+
+ let org = Org::parse(
+ "Here is a [[really really long link\nthat just keeps going]] in prose.\n",
+ );
+
+ let links: Vec<_> = org
+ .document()
+ .syntax()
+ .descendants()
+ .filter_map(Link::cast)
+ .collect();
+
+ assert_eq!(
+ links.len(),
+ 1,
+ "expected one link, found {}",
+ links.len(),
+ );
+}