Skip to main content

yamd/nodes/
italic.rs

1use std::fmt::Display;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// # Italic
7///
8/// Any token except [Terminator](type@crate::lexer::TokenKind::Terminator) surrounded by
9/// [Underscore](type@crate::lexer::TokenKind::Underscore).
10///
11/// Example:
12///
13/// ```text
14/// _Italic can contain any token
15/// even EOL_
16/// ```
17///
18/// HTML equivalent:
19///
20/// ```html
21/// <i>Italic can contain any token
22/// even EOL</i>
23/// ```
24#[derive(Debug, PartialEq, Clone, Eq)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub struct Italic(pub String);
27
28impl Italic {
29    pub fn new<Body: Into<String>>(body: Body) -> Self {
30        Italic(body.into())
31    }
32}
33
34impl Display for Italic {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        write!(
37            f,
38            "_{}_",
39            self.0.replace("_", "\\_").replace("\n\n", "\\\n\n")
40        )
41    }
42}
43
44impl From<String> for Italic {
45    fn from(value: String) -> Self {
46        Italic(value)
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::nodes::Italic;
53
54    #[test]
55    fn italic() {
56        let italic: Italic = "Italic can contain any token even \n".to_string().into();
57        assert_eq!(italic.to_string(), "_Italic can contain any token even \n_");
58    }
59
60    #[test]
61    fn italic_with_underscore() {
62        let italic = Italic::new("Italic can contain any token even \ncan _be_ it");
63        assert_eq!(
64            italic.to_string(),
65            "_Italic can contain any token even \ncan \\_be\\_ it_"
66        );
67    }
68
69    #[test]
70    fn italic_with_terminator() {
71        let italic = Italic::new("Italic can contain any token even \n\n can be it");
72        assert_eq!(
73            italic.to_string(),
74            "_Italic can contain any token even \\\n\n can be it_"
75        );
76    }
77}