Initial
This commit is contained in:
commit
242584f470
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "maud"
|
||||
version = "0.1.0"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "maud"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
94
src/main.rs
Normal file
94
src/main.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
// Explicit tag
|
||||
// a#id."a b c" href="/" [disabled rowspan=2] {"foo"}
|
||||
|
||||
// Implicit tag
|
||||
// h1 a#id."a b c" href="/" {"foo"};
|
||||
|
||||
type Offset = usize;
|
||||
type Parse<'a> = (&'a str, &'a str, Offset);
|
||||
type MaybeParse<'a> = Option<Parse<'a>>;
|
||||
|
||||
fn parse_until(i: &str, condition: impl Fn(char) -> bool) -> Parse {
|
||||
i.chars()
|
||||
.position(condition)
|
||||
.map(|pos| (&i[..pos], &i[pos..], pos))
|
||||
.unwrap_or((&i, "", i.len()))
|
||||
}
|
||||
|
||||
fn parse_ws(i: &str) -> Parse { parse_until(i, |c| !c.is_whitespace()) }
|
||||
|
||||
fn parse_char(i: &str, matches: char) -> MaybeParse {
|
||||
if let Some(c) = i.chars().next() {
|
||||
if c == matches {
|
||||
return Some((&i[0..1], &i[1..], 1));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn not_empty(parse: Parse) -> MaybeParse {
|
||||
if !parse.0.is_empty() {
|
||||
Some(parse)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_string(i: &str) -> MaybeParse {
|
||||
let mut skip = false;
|
||||
let (_, i, o1) = parse_char(i, '"')?;
|
||||
let mut o2 = 0;
|
||||
for c in i.chars() {
|
||||
if skip {
|
||||
skip = false;
|
||||
} else if c == '\\' {
|
||||
skip = true;
|
||||
} else if c == '"' {
|
||||
let off = o1 + o2 - 1;
|
||||
return Some((&i[..off], &i[off..], off));
|
||||
}
|
||||
o2 += 1;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_name(i: &str) -> MaybeParse {
|
||||
let (name, i, o1) = not_empty(parse_until(i, |c| c.is_whitespace()))?;
|
||||
let (_, i, o2) = parse_ws(i);
|
||||
Some((name, i, o1 + o2))
|
||||
}
|
||||
|
||||
fn parse_id(i: &str) -> MaybeParse {
|
||||
let (_, i, o1) = parse_char(i, '#')?;
|
||||
let (_, i, o2) = parse_ws(i);
|
||||
let (id, i, o3) = parse_name(i)?;
|
||||
let (_, i, o4) = parse_ws(i);
|
||||
Some((id, i, o1 + o2 + o3 + o4))
|
||||
}
|
||||
|
||||
fn parse_classes(i: &str) -> MaybeParse {
|
||||
let (_, i, o1) = parse_char(i, '.')?;
|
||||
let (_, i, o2) = parse_ws(i);
|
||||
let (classes, i, o3) = parse_string(i)?;
|
||||
let (_, i, o4) = parse_ws(i);
|
||||
Some((classes, i, o1 + o2 + o3 + o4))
|
||||
}
|
||||
|
||||
fn parse_tag(i: &str) -> Option<()> {
|
||||
let (name, i, o1) = parse_name(i)?;
|
||||
let (id, i, o2) = parse_id(i).unwrap_or(("", i, 0));
|
||||
let (classes, i, o3) = parse_classes(i).unwrap_or(("", i, 0));
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn parse(i: &str) {
|
||||
let mut explicit_stack: Vec<&str> = vec![];
|
||||
let mut inline_stack: Vec<&str> = vec![];
|
||||
let mut out = String::new();
|
||||
let mut off = 0;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p = parse_classes(".\"a b c\"");
|
||||
println!("{:?}", p);
|
||||
}
|
Loading…
Reference in a new issue