mirror of
https://github.com/YGGverse/ggemtext.git
synced 2026-03-31 17:15:33 +00:00
remove regex dependency, rename constructor, implement Gemtext trait
This commit is contained in:
parent
9d27cdfb49
commit
7802869d0d
2 changed files with 70 additions and 20 deletions
|
|
@ -1,4 +1,8 @@
|
||||||
use glib::{Regex, RegexCompileFlags, RegexMatchFlags};
|
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) tag
|
||||||
|
/// * store as entire static chars array
|
||||||
|
pub const TAG_H1: &str = "#";
|
||||||
|
pub const TAG_H2: &str = "##";
|
||||||
|
pub const TAG_H3: &str = "###";
|
||||||
|
|
||||||
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) type holder
|
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) type holder
|
||||||
pub enum Level {
|
pub enum Level {
|
||||||
|
|
@ -9,32 +13,78 @@ pub enum Level {
|
||||||
|
|
||||||
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) entity holder
|
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) entity holder
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
pub value: String,
|
|
||||||
pub level: Level,
|
pub level: Level,
|
||||||
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Parse `Self` from line string
|
/// Parse `Self` from line string
|
||||||
pub fn from(line: &str) -> Option<Self> {
|
pub fn parse(line: &str) -> Option<Self> {
|
||||||
// Parse line
|
|
||||||
let regex = Regex::split_simple(
|
|
||||||
r"^(#{1,3})\s*(.+)$",
|
|
||||||
line,
|
|
||||||
RegexCompileFlags::DEFAULT,
|
|
||||||
RegexMatchFlags::DEFAULT,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Result
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
level: match regex.get(1)?.len() {
|
level: line.to_level()?,
|
||||||
1 => Level::H1,
|
value: line.as_value()?.to_string(),
|
||||||
2 => Level::H2,
|
|
||||||
3 => Level::H3,
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
value: regex.get(2)?.trim().to_string(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converters
|
||||||
|
|
||||||
|
/// Convert `Self` to [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line
|
||||||
|
pub fn to_source(&self) -> String {
|
||||||
|
self.value.to_source(&self.level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Gemtext {
|
||||||
|
/// Get [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) value from `Self`
|
||||||
|
fn as_value(&self) -> Option<&Self>;
|
||||||
|
/// Convert `Self` to `Level`
|
||||||
|
fn to_level(&self) -> Option<Level>;
|
||||||
|
/// Convert `Self` to [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line
|
||||||
|
fn to_source(&self, level: &Level) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gemtext for str {
|
||||||
|
fn as_value(&self) -> Option<&Self> {
|
||||||
|
if let Some(h3) = self.strip_prefix(TAG_H3) {
|
||||||
|
if h3.trim_start().starts_with(TAG_H1) {
|
||||||
|
return None; // H4+
|
||||||
|
}
|
||||||
|
return Some(h3.trim());
|
||||||
|
}
|
||||||
|
if let Some(h2) = self.strip_prefix(TAG_H2) {
|
||||||
|
return Some(h2.trim());
|
||||||
|
}
|
||||||
|
if let Some(h1) = self.strip_prefix(TAG_H1) {
|
||||||
|
return Some(h1.trim());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn to_level(&self) -> Option<Level> {
|
||||||
|
if let Some(h3) = self.strip_prefix(TAG_H3) {
|
||||||
|
if h3.trim_start().starts_with(TAG_H1) {
|
||||||
|
return None; // H4+
|
||||||
|
}
|
||||||
|
return Some(Level::H3);
|
||||||
|
}
|
||||||
|
if self.starts_with(TAG_H2) {
|
||||||
|
return Some(Level::H2);
|
||||||
|
}
|
||||||
|
if self.starts_with(TAG_H1) {
|
||||||
|
return Some(Level::H1);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn to_source(&self, level: &Level) -> String {
|
||||||
|
format!(
|
||||||
|
"{} {}",
|
||||||
|
match level {
|
||||||
|
Level::H1 => TAG_H1,
|
||||||
|
Level::H2 => TAG_H2,
|
||||||
|
Level::H3 => TAG_H3,
|
||||||
|
},
|
||||||
|
self.trim()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ fn gemtext() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
if let Some(result) = Header::from(line) {
|
if let Some(result) = Header::parse(line) {
|
||||||
headers.push(result);
|
headers.push(result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue