From 4eae60a67542455d8cc1e7211e482e9f2ec25707 Mon Sep 17 00:00:00 2001 From: Roman Ponomarev Date: Sun, 24 Jul 2022 13:57:39 +0400 Subject: [PATCH] Make some refactoring and bump version to 1.1.1 --- Cargo.toml | 2 +- README.md | 2 +- pkg/README.md | 2 +- pkg/package.json | 2 +- pkg/text_to_sounds_bg.wasm | Bin 24488 -> 24485 bytes src/highlighter.rs | 48 ++---- src/lib.rs | 3 +- src/parser.rs | 9 +- src/scanner.rs | 155 +++++++++++++++--- src/utils.rs | 24 --- www/public/bootstrap.js | 2 +- ....wasm => f0c1c9e522f377d52b00.module.wasm} | Bin 24515 -> 24512 bytes 12 files changed, 150 insertions(+), 99 deletions(-) delete mode 100644 src/utils.rs rename www/public/{05bcb57c37ef323178f3.module.wasm => f0c1c9e522f377d52b00.module.wasm} (87%) diff --git a/Cargo.toml b/Cargo.toml index 3c69da3..430a9e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "text-to-sounds" -version = "1.1.0" +version = "1.1.1" edition = "2021" authors = ["maksugr "] description = "Text-to-sounds parsing tool." diff --git a/README.md b/README.md index f77fcd5..22b70af 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ In order to use this crate, you have to add it under `[dependencies]` to your `C ```toml [dependencies] -text-to-sounds = "1.1.0" +text-to-sounds = "1.1.1" ``` ## Javascript / WASM diff --git a/pkg/README.md b/pkg/README.md index f77fcd5..22b70af 100644 --- a/pkg/README.md +++ b/pkg/README.md @@ -59,7 +59,7 @@ In order to use this crate, you have to add it under `[dependencies]` to your `C ```toml [dependencies] -text-to-sounds = "1.1.0" +text-to-sounds = "1.1.1" ``` ## Javascript / WASM diff --git a/pkg/package.json b/pkg/package.json index eab3ce4..579a444 100644 --- a/pkg/package.json +++ b/pkg/package.json @@ -4,7 +4,7 @@ "maksugr " ], "description": "Text-to-sounds parsing tool.", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT OR Apache-2.0", "repository": { "type": "git", diff --git a/pkg/text_to_sounds_bg.wasm b/pkg/text_to_sounds_bg.wasm index d30caaf2225357507615f86fa2cd10151eea7748..f2bad5dda664f403914eccf1587d4ecb0a0ca2dc 100644 GIT binary patch delta 180 zcmZ3npK0b_5j5s_qqbLNP3Fv2<7 z5>w3M(->Lm6&N&_SU?1WBV(2llOt0}mSaQ10R{yokRXqzv?7ZFqXrWPP(qOz#9~ln sV0KVoR$^jtP+)Sb$pVUkbSp48vScYTD6jz8?!1iL+zO1F6$9G&0Xu0XUH||9 delta 183 zcmZ3wpK-;0#tlqNj8ir0b_5j5s_qqbLNP3Fv2<7 z5>w2RG8tLw6&N*`SU?1WBV(2llOt0}mSaQ10R{yo1x81nETFijv?7ZFg9Z}^P)?B< w#9~lnWOh(sR$^jtP+)Sb$pVUk3;=3i$x>ugU;(n-c^SF66&N bool { - PUNCTUATION_CHARS.iter().any(|cc| cc == c) -} - -fn is_first(scanner: &Scanner) -> bool { - let prev_char = scanner.peek_prev(); - - scanner.is_first() - || prev_char == &' ' - || prev_char == &NON_BREAKABLE_HTML_CHAR - || is_punctuation(prev_char) -} - -fn is_last(scanner: &Scanner) -> bool { - let next_char = scanner.peek_next(); - - scanner.is_last() - || next_char == &' ' - || next_char == &NON_BREAKABLE_HTML_CHAR - || is_punctuation(next_char) -} fn highlight_two_letters( first_letter: &char, @@ -60,7 +34,7 @@ pub fn highlight>(text: T) -> String { while !scanner.is_done() { match scanner.peek() { - letter @ ('c' | 'C') if !is_last(&scanner) && any_letter(vec!['h', 'H'], &scanner) => { + letter @ ('c' | 'C') if !scanner.is_last() && scanner.is_next_any(vec!['h', 'H']) => { let next_letter = scanner.peek_next(); highlight_two_letters(letter, next_letter, SoundKind::Ch, &mut result_text); @@ -69,11 +43,11 @@ pub fn highlight>(text: T) -> String { scanner.pop(); } letter @ ('p' | 'P' | 't' | 'T' | 'c' | 'C') - if is_first(&scanner) || is_last(&scanner) => + if scanner.is_first() || scanner.is_last() => { if (letter == &'t' || letter == &'T') - && !is_last(&scanner) - && any_letter(vec!['h', 'H'], &scanner) + && !scanner.is_last() + && scanner.is_next_any(vec!['h', 'H']) { let next_letter = scanner.peek_next(); @@ -93,7 +67,7 @@ pub fn highlight>(text: T) -> String { scanner.pop(); } - letter @ ('t' | 'T') if any_letter(vec!['h', 'H'], &scanner) => { + letter @ ('t' | 'T') if scanner.is_next_any(vec!['h', 'H']) => { let next_letter = scanner.peek_next(); highlight_two_letters(letter, next_letter, SoundKind::Th, &mut result_text); @@ -101,7 +75,7 @@ pub fn highlight>(text: T) -> String { scanner.pop(); scanner.pop(); } - letter @ ('w' | 'W') if is_first(&scanner) => { + letter @ ('w' | 'W') if scanner.is_first() => { result_text.push_str(&format!( "{}", SoundKind::W, @@ -110,7 +84,7 @@ pub fn highlight>(text: T) -> String { scanner.pop(); } - letter @ ('v' | 'V') if is_first(&scanner) => { + letter @ ('v' | 'V') if scanner.is_first() => { result_text.push_str(&format!( "{}", SoundKind::V, @@ -120,7 +94,7 @@ pub fn highlight>(text: T) -> String { scanner.pop(); } letter @ ('n' | 'N') - if !is_last(&scanner) && any_letter(vec!['g', 'G', 'k', 'K'], &scanner) => + if !scanner.is_last() && scanner.is_next_any(vec!['g', 'G', 'k', 'K']) => { let next_letter = scanner.peek_next(); @@ -129,7 +103,7 @@ pub fn highlight>(text: T) -> String { scanner.pop(); scanner.pop(); } - letter @ ('j' | 'J') if is_first(&scanner) => { + letter @ ('j' | 'J') if scanner.is_first() => { result_text.push_str(&format!( "{}", SoundKind::Dj, @@ -205,7 +179,7 @@ mod highlight { } #[test] - fn it_should_highlight_with_non_breakable_chars() { + fn it_should_highlight_with_non_breakable_char() { assert_eq!( highlight("Put\u{a0}W"), "Put\u{a0}W" @@ -214,7 +188,7 @@ mod highlight { } #[test] - fn it_should_highlight_with_punctuation_chars() { + fn it_should_highlight_with_punctuation_char() { assert_eq!( highlight("what!the such-exp:the going?Jhon much; Going."), "what!the such-exp:the going?Jhon much; Going." diff --git a/src/lib.rs b/src/lib.rs index cd82a11..76f9583 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ //! //! ```toml //! [dependencies] -//! text-to-sounds = "1.1.0" +//! text-to-sounds = "1.1.1" //! ``` //! //! ## Examples @@ -83,7 +83,6 @@ mod parser; mod scanner; mod serializer; mod sound; -mod utils; mod wasm; pub use crate::highlighter::highlight; diff --git a/src/parser.rs b/src/parser.rs index 4534648..93c7387 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,5 @@ use crate::scanner::Scanner; use crate::sound::{Sound, SoundKind}; -use crate::utils::any_letter; fn add_sound_from_two_letters( first_letter: &char, @@ -63,7 +62,7 @@ pub fn parse>(text: T) -> Vec { while !scanner.is_done() { match scanner.peek() { letter @ ('c' | 'C') - if !scanner.is_last() && any_letter(vec!['h', 'H'], &scanner) => + if !scanner.is_last() && scanner.is_next_any(vec!['h', 'H']) => { let next_letter = scanner.peek_next(); @@ -77,7 +76,7 @@ pub fn parse>(text: T) -> Vec { { if (letter == &'t' || letter == &'T') && !scanner.is_last() - && any_letter(vec!['h', 'H'], &scanner) + && scanner.is_next_any(vec!['h', 'H']) { let next_letter = scanner.peek_next(); @@ -92,7 +91,7 @@ pub fn parse>(text: T) -> Vec { sounds.push(Sound::new(SoundKind::Ptk, letter.to_string())); scanner.pop(); } - letter @ ('t' | 'T') if any_letter(vec!['h', 'H'], &scanner) => { + letter @ ('t' | 'T') if scanner.is_next_any(vec!['h', 'H']) => { let next_letter = scanner.peek_next(); add_sound_from_two_letters(letter, next_letter, SoundKind::Th, &mut sounds); @@ -109,7 +108,7 @@ pub fn parse>(text: T) -> Vec { scanner.pop(); } letter @ ('n' | 'N') - if !scanner.is_last() && any_letter(vec!['g', 'G', 'k', 'K'], &scanner) => + if !scanner.is_last() && scanner.is_next_any(vec!['g', 'G', 'k', 'K']) => { let next_letter = scanner.peek_next(); diff --git a/src/scanner.rs b/src/scanner.rs index 9d7c8c0..f24827e 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -6,9 +6,18 @@ pub struct Scanner { characters: Vec, } -/// Default letter if Scanner will found nothing +/// Space html character +const SPACE_HTML_CHAR: &char = &' '; + +/// Non-breakable space html character +const NON_BREAKABLE_SPACE_HTML_CHAR: &char = &'\u{a0}'; + +/// Default char if Scanner will found nothing /// Just an easy workaround for Option -const DEFAULT_LETTER: &char = &' '; +const DEFAULT_CHAR: &char = SPACE_HTML_CHAR; + +/// Array of the punctuation characters +const PUNCTUATION_CHARS: [char; 7] = ['.', ',', ';', '!', '?', ':', '-']; impl Scanner { /// Creates new Scanner @@ -20,32 +29,26 @@ impl Scanner { } /// Returns the current cursor. Useful for reporting errors. - #[allow(dead_code)] pub fn cursor(&self) -> usize { self.cursor } /// Returns the next character without advancing the cursor. pub fn peek(&self) -> &char { - self.characters.get(self.cursor).unwrap_or(DEFAULT_LETTER) + self.characters.get(self.cursor).unwrap_or(DEFAULT_CHAR) } /// Returns the next + 1 character without advancing the cursor. pub fn peek_next(&self) -> &char { - self.characters - .get(self.cursor + 1) - .unwrap_or(DEFAULT_LETTER) + self.characters.get(self.cursor + 1).unwrap_or(DEFAULT_CHAR) } /// Returns the prev character without advancing the cursor. pub fn peek_prev(&self) -> &char { - if self.is_first() { - return DEFAULT_LETTER; + match self.cursor() == 0 { + true => DEFAULT_CHAR, + false => self.characters.get(self.cursor - 1).unwrap_or(DEFAULT_CHAR), } - - self.characters - .get(self.cursor - 1) - .unwrap_or(DEFAULT_LETTER) } /// Returns true if further progress is not possible. @@ -55,12 +58,35 @@ impl Scanner { /// Returns true if the first char. pub fn is_first(&self) -> bool { - self.cursor == 0 + match self.cursor == 0 { + true => true, + false => { + let prev_char = self.peek_prev(); + + prev_char == SPACE_HTML_CHAR + || prev_char == NON_BREAKABLE_SPACE_HTML_CHAR + || Self::is_punctuation(prev_char) + } + } } /// Returns true if the last char. pub fn is_last(&self) -> bool { - self.cursor + 1 == self.characters.len() + match self.cursor + 1 == self.characters.len() { + true => true, + false => { + let next_char = self.peek_next(); + + next_char == SPACE_HTML_CHAR + || next_char == NON_BREAKABLE_SPACE_HTML_CHAR + || Self::is_punctuation(next_char) + } + } + } + + // Returns true if next char exists in `chars` param + pub fn is_next_any(&self, chars: Vec) -> bool { + chars.iter().any(|c| self.peek_next() == c) } /// Returns the next character and advances the cursor. @@ -71,9 +97,14 @@ impl Scanner { character } - None => DEFAULT_LETTER, + None => DEFAULT_CHAR, } } + + /// Returns true if the character is a punctuation character + fn is_punctuation(c: &char) -> bool { + PUNCTUATION_CHARS.iter().any(|cc| cc == c) + } } #[cfg(test)] @@ -148,7 +179,7 @@ mod peek { fn empty() { let scanner = Scanner::new(""); - assert_eq!(scanner.peek(), DEFAULT_LETTER) + assert_eq!(scanner.peek(), DEFAULT_CHAR) } #[test] @@ -169,7 +200,7 @@ mod peek_next { fn empty() { let scanner = Scanner::new(""); - assert_eq!(scanner.peek_next(), DEFAULT_LETTER) + assert_eq!(scanner.peek_next(), DEFAULT_CHAR) } #[test] @@ -190,7 +221,7 @@ mod peek_prev { fn empty() { let scanner = Scanner::new(""); - assert_eq!(scanner.peek_prev(), DEFAULT_LETTER) + assert_eq!(scanner.peek_prev(), DEFAULT_CHAR) } #[test] @@ -214,6 +245,24 @@ mod is_first { assert!(scanner.is_first()) } + #[test] + fn is_first_with_punctuation_char() { + let mut scanner = Scanner::new("!abc"); + + scanner.pop(); + + assert!(scanner.is_first()) + } + + #[test] + fn is_first_with_non_breakable_char() { + let mut scanner = Scanner::new("\u{a0}abc"); + + scanner.pop(); + + assert!(scanner.is_first()) + } + #[test] fn not_is_first() { let mut scanner = Scanner::new("abc"); @@ -229,21 +278,60 @@ mod is_last { use super::*; #[test] - fn not_is_last() { - let scanner = Scanner::new("abc"); + fn is_last() { + let mut scanner = Scanner::new("abc"); - assert!(!scanner.is_last()) + scanner.pop(); + scanner.pop(); + + assert!(scanner.is_last()) } #[test] - fn is_last() { - let mut scanner = Scanner::new("abc"); + fn is_last_with_punctuation_char() { + let mut scanner = Scanner::new("abc!"); scanner.pop(); scanner.pop(); assert!(scanner.is_last()) } + + #[test] + fn is_last_with_non_breakable_char() { + let mut scanner = Scanner::new("abc\u{a0}"); + + scanner.pop(); + scanner.pop(); + + assert!(scanner.is_last()) + } + + #[test] + fn not_is_last() { + let scanner = Scanner::new("abc"); + + assert!(!scanner.is_last()) + } +} + +#[cfg(test)] +mod is_next_any { + use super::*; + + #[test] + fn it_should_be_true() { + let scanner = Scanner::new("cheese"); + + assert!(scanner.is_next_any(vec!['h'])); + } + + #[test] + fn it_should_be_false() { + let scanner = Scanner::new("cheese"); + + assert!(!scanner.is_next_any(vec!['c'])); + } } #[cfg(test)] @@ -254,7 +342,7 @@ mod pop { fn empty() { let mut scanner = Scanner::new(""); - assert_eq!(scanner.pop(), DEFAULT_LETTER); + assert_eq!(scanner.pop(), DEFAULT_CHAR); assert_eq!(scanner.cursor(), 0) } @@ -274,7 +362,22 @@ mod pop { scanner.pop(); scanner.pop(); - assert_eq!(scanner.pop(), DEFAULT_LETTER); + assert_eq!(scanner.pop(), DEFAULT_CHAR); assert_eq!(scanner.cursor(), 3) } } + +#[cfg(test)] +mod is_punctuation { + use super::*; + + #[test] + fn is_punctuation() { + assert!(Scanner::is_punctuation(&'!')); + } + + #[test] + fn is_not_punctuation() { + assert!(!Scanner::is_punctuation(&'k')); + } +} diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index 051914f..0000000 --- a/src/utils.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::scanner::Scanner; - -pub fn any_letter(letters: Vec, scanner: &Scanner) -> bool { - letters.iter().any(|letter| scanner.peek_next() == letter) -} - -#[cfg(test)] -mod any_letter { - use super::{any_letter, Scanner}; - - #[test] - fn it_should_be_true() { - let scanner = Scanner::new("cheese"); - - assert!(any_letter(vec!['h'], &scanner)); - } - - #[test] - fn it_should_be_false() { - let scanner = Scanner::new("cheese"); - - assert!(!any_letter(vec!['c'], &scanner)); - } -} diff --git a/www/public/bootstrap.js b/www/public/bootstrap.js index cb7e109..139ead8 100644 --- a/www/public/bootstrap.js +++ b/www/public/bootstrap.js @@ -159,7 +159,7 @@ /******/ promises.push(installedWasmModuleData); /******/ else { /******/ var importObject = wasmImportObjects[wasmModuleId](); -/******/ var req = fetch(__webpack_require__.p + "" + {"../pkg/text_to_sounds_bg.wasm":"05bcb57c37ef323178f3"}[wasmModuleId] + ".module.wasm"); +/******/ var req = fetch(__webpack_require__.p + "" + {"../pkg/text_to_sounds_bg.wasm":"f0c1c9e522f377d52b00"}[wasmModuleId] + ".module.wasm"); /******/ var promise; /******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') { /******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) { diff --git a/www/public/05bcb57c37ef323178f3.module.wasm b/www/public/f0c1c9e522f377d52b00.module.wasm similarity index 87% rename from www/public/05bcb57c37ef323178f3.module.wasm rename to www/public/f0c1c9e522f377d52b00.module.wasm index 8fd7840dc88f16a3790e0e5b396ed11938ffde07..9d05356c655c9536882ac4875f35bf219bb4e692 100644 GIT binary patch delta 200 zcmX@SpYgzc#tl+Tj8isCGvx}hTVyFPJN{sp+%IeoXI~ZG!3!1763}wx<(SMUqOy6P z$a_Ww3M(->Lm6&N&_SU?1WBV(2llOt0}mSaQ10R{yokRXqz zv?7ZFqXrWPP(qOz#9~lnV0KVoR$^jtP+)Sb$pVUkbSp48vScYTD6jz8?!1iL+zO1F IEd#pv0g+5A_5c6? delta 203 zcmX@GpYia1#tl+TjMFzuGvx}h|6s^cV0N^a+%IeoXI~ZG!3!1763}wx<(SMUqOy6P z$a_Ww2RG8tLw6&N*`SU?1WBV(2llOt0}mSaQ10R{yo1x81n zETFijv?7ZFg9Z}^P)?B<#9~lnWOh(sR$^jtP+)Sb$pVUk3;=3i$x>ugU;(n-c^SF6 M6&N;~1$6NP06ozxs{jB1