From d03b4643c9c4f85c642182da7a56a613b6f819d4 Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Sun, 1 Sep 2024 04:24:41 -0600 Subject: Allow escaping characters This patch adds the '\' character as a new rune, Rune::Special. This is for escaping special characters. Also works in strings (", '). --- src/poem/elements/rune.rs | 4 ++++ src/poem/read.rs | 9 +++++++++ src/poem/read/parse.rs | 16 ++++++++++++++++ 3 files changed, 29 insertions(+) (limited to 'src') diff --git a/src/poem/elements/rune.rs b/src/poem/elements/rune.rs index 64e3326..79d53d0 100644 --- a/src/poem/elements/rune.rs +++ b/src/poem/elements/rune.rs @@ -19,6 +19,9 @@ pub enum Rune { /// The space character, to dilineate words (`' '`) Pause, + /// The backslash character, to escape special character (`\`) + Special, + /// The forward slash character, to dilineate paths (`/`) Path, @@ -81,6 +84,7 @@ impl fmt::Display for Rune { let rune = match self { Rune::None => "", Rune::Pause => " ", + Rune::Special => "\\", Rune::Path => "/", Rune::Remark => "#", Rune::String => "\"", diff --git a/src/poem/read.rs b/src/poem/read.rs index 8f3fd4a..7f3ae32 100644 --- a/src/poem/read.rs +++ b/src/poem/read.rs @@ -243,6 +243,7 @@ impl Readable for Poem { // Determine the meter based on the character let rune = match c { ' ' => Rune::Pause, + '\\' => Rune::Special, '/' => Rune::Path, '#' => Rune::Remark, '\'' | '"' => Rune::String, @@ -356,6 +357,14 @@ impl Readable for Poem { verse.add(&mut word, channel); } + Rune::Special => { + let c = chars.next(); + match c { + Some(c) => word.push(c), + None => continue, + } + } + Rune::Remark => { remark!(chars); } diff --git a/src/poem/read/parse.rs b/src/poem/read/parse.rs index fc1979f..0b6c5a3 100644 --- a/src/poem/read/parse.rs +++ b/src/poem/read/parse.rs @@ -74,6 +74,14 @@ macro_rules! string { $word.push('\x0e'); $i += 1; } + Some(c) if c == '\\' => { + let c = match $chars.next() { + Some(c) => c, + None => continue, + }; + $word.push(c); + $i += 1; + } Some(c) => { $word.push(c); $i += 1; @@ -108,6 +116,14 @@ macro_rules! poem { match $chars.next() { None => return Err(Mishap::PartialMishap($j, $i, $c)), Some(c) if c == token => break, + Some(c) if c == '\\' => { + let c = match $chars.next() { + Some(c) => c, + None => continue, + }; + $word.push(c); + $i += 1; + } Some(c) => { poetry.push(c); $i += 1; -- cgit v1.2.3