Skip to content

Commit

Permalink
Don't consume/eat the the exlaimation mark at the end of a link (#85)
Browse files Browse the repository at this point in the history
* Don't consume/eat the the exlaimation mark at the end of a link

closes #81

* add changelog entry
  • Loading branch information
Simon-Laux authored Jan 9, 2025
1 parent 6103181 commit 6c259a4
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- fix: parse fediverse addresses as text, so they are not mistaken for email addresses ([issue #82](https://github.com/deltachat/message-parser/issues/82))
- fix: don't consume/eat the the exlaimation mark at the end of a link #85

## 0.11.0 - Bug fixes for Link Parsing

Expand Down
2 changes: 1 addition & 1 deletion src/parser/link_url/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl LinkDestination<'_> {
pub fn parse_labelled(input: &str) -> IResult<&str, LinkDestination, CustomError<&str>> {
let (mut remaining, mut link) = Self::parse(input)?;
if let Some(first) = remaining.chars().next() {
if matches!(first, ';' | '.' | ',' | ':') {
if matches!(first, ';' | '.' | ',' | ':' | '!') {
// ^ markdown labelled links can include one of these characters at the end
// and it's therefore part of the link
let point = link.target.len().saturating_add(1);
Expand Down
2 changes: 1 addition & 1 deletion src/parser/link_url/parse_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ fn parse_iri(input: &str) -> IResult<&str, LinkDestination, CustomError<&str>> {
.saturating_add(fragment.len());
// compute length of link which is ihier_len + scheme + query + fragment
if let Some(link) = input_.get(0..len) {
if link.ends_with([':', ';', '.', ',']) {
if link.ends_with([':', ';', '.', ',', '!']) {
len = len.saturating_sub(1);
if path.is_empty() && query.is_empty() && fragment.is_empty() {
host = input_.slice(scheme.len().saturating_add(3)..input_.len().saturating_sub(1));
Expand Down
97 changes: 97 additions & 0 deletions tests/based_on_issue/exclamation_mark_at_end_of_link_81.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use deltachat_message_parser::parser::Element::*;
use deltachat_message_parser::parser::{parse_desktop_set, parse_markdown_text, parse_only_text};

use crate::text_to_ast::https_link_no_puny;

/// don't eat/consume the ! at the end of a link
/// as disscussed in https://github.com/deltachat/message-parser/issues/81
#[test]
fn text_only() {
assert_eq!(
parse_only_text("This is an my site: https://delta.chat!"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat", "delta.chat",)
},
Text("!")
]
);
assert_eq!(
parse_only_text("This is an my site: https://delta.chat#!test"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat#!test", "delta.chat",)
}
]
);
}

#[test]
fn desktop_set() {
assert_eq!(
parse_desktop_set("This is an my site: https://delta.chat!"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat", "delta.chat",)
},
Text("!")
]
);
}

#[test]
fn desktop_set_negative() {
assert_eq!(
parse_desktop_set("This is an my site: https://delta.chat#!test"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat#!test", "delta.chat",)
}
]
);
}

#[test]
fn markdown() {
assert_eq!(
parse_markdown_text("This is an my site: https://delta.chat!"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat", "delta.chat",)
},
Text("!")
]
);
}
#[test]
fn markdown_negative() {
assert_eq!(
parse_markdown_text("This is an my site: https://delta.chat#!test"),
vec![
Text("This is an my site: "),
Link {
destination: https_link_no_puny("https://delta.chat#!test", "delta.chat",)
}
]
);
}

#[test]
fn still_take_whole_link_in_labled_links() {
assert_eq!(
parse_markdown_text("This is an my [site](https://delta.chat/!)"),
vec![
Text("This is an my "),
LabeledLink {
label: vec![Text("site")],
destination: https_link_no_puny("https://delta.chat/!", "delta.chat",)
}
]
);
}
1 change: 1 addition & 0 deletions tests/based_on_issue/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod exclamation_mark_at_end_of_link_81;
pub mod fediverse_handle_82;
10 changes: 5 additions & 5 deletions tests/text_to_ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use deltachat_message_parser::parser::Element::*;
use deltachat_message_parser::parser::LinkDestination;

fn gopher_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
pub(crate) fn gopher_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
LinkDestination {
target,
hostname: Some(hostname),
Expand All @@ -10,7 +10,7 @@ fn gopher_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestinatio
}
}

fn http_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
pub(crate) fn http_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
LinkDestination {
target,
hostname: Some(hostname),
Expand All @@ -19,7 +19,7 @@ fn http_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<
}
}

fn ftp_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
pub(crate) fn ftp_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
LinkDestination {
target,
hostname: Some(hostname),
Expand All @@ -28,7 +28,7 @@ fn ftp_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'
}
}

fn https_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
pub(crate) fn https_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination<'a> {
LinkDestination {
target,
hostname: Some(hostname),
Expand All @@ -37,7 +37,7 @@ fn https_link_no_puny<'a>(target: &'a str, hostname: &'a str) -> LinkDestination
}
}

fn mailto_link_no_puny(target: &str) -> LinkDestination<'_> {
pub(crate) fn mailto_link_no_puny(target: &str) -> LinkDestination<'_> {
LinkDestination {
target,
hostname: None,
Expand Down

0 comments on commit 6c259a4

Please sign in to comment.