diff options
author | gennyble <gen@nyble.dev> | 2024-12-18 00:27:34 -0600 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2024-12-18 00:27:34 -0600 |
commit | 5ea6a13ead2a5cab0f578c8af5f0e0be88c3a08c (patch) | |
tree | f8ab97a0abeb03142da4c7a8ed859d6a408cd16a /src | |
parent | f6b441fe53dd75af5933c4456d92070ccb7bd8af (diff) | |
download | cutie-main.tar.gz cutie-main.zip |
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--] | src/lib.rs | 29 | ||||
-rwxr-xr-x[-rw-r--r--] | src/query.rs | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/tag.rs | 53 |
3 files changed, 78 insertions, 4 deletions
diff --git a/src/lib.rs b/src/lib.rs index 8b5c47d..bc8b629 100644..100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,6 +87,31 @@ impl Html { None } + pub fn get_by_id(&self, id: &str) -> Option<&Tag> { + // depth first + fn find_node<'a>(tag: &'a Tag, id: &str) -> Option<&'a Tag> { + if tag.id().unwrap_or_default() == id { + return Some(tag); + } + + for child in tag.child_tags() { + if let Some(tag) = find_node(child, id) { + return Some(tag); + } + } + + None + } + + for child in self.child_tags() { + if let Some(tag) = find_node(child, id) { + return Some(tag); + } + } + + None + } + fn parse_node(raw: &str) -> Consumed { match Self::is_tag(raw) { Some(_) => { @@ -133,14 +158,11 @@ impl Html { }; } - println!("Looking for {}", root_tag.name); - loop { // Special case <script> and <style> if root_tag.name == "script" && tag.get_attribute("src").is_none() || root_tag.name == "style" { - println!("\tparse special"); let special = Self::special_parse(rest.unwrap(), root_tag.name); match special { @@ -166,7 +188,6 @@ impl Html { // Find the closing end of out root_tag if let Some((parsed, remaining)) = Self::is_tag(rest.unwrap()) { if parsed.closing && parsed.name == root_tag.name { - println!("\tclosed {}", parsed.name); break Consumed { node: Node::Tag(tag), remaining, diff --git a/src/query.rs b/src/query.rs index 26b02aa..26b02aa 100644..100755 --- a/src/query.rs +++ b/src/query.rs diff --git a/src/tag.rs b/src/tag.rs index 0a97061..43c4e0c 100644..100755 --- a/src/tag.rs +++ b/src/tag.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::{iter::Peekable, str::CharIndices}; use crate::Node; @@ -208,6 +209,8 @@ impl<'a> Iterator for TagIteratorMut<'a> { mod test { use crate::Tag; + use super::peek_skip_while; + #[test] fn tag_finds_boolen_attribute() { let tag = Tag { @@ -240,4 +243,54 @@ mod test { }; assert!(tag.get_attribute("contenteditable").is_some()); } + + // yes, this is a bad name. + #[test] + fn peek_skip_while_works() { + let str = "\t no whitespace"; + let mut chari = str.char_indices().peekable(); + + peek_skip_while(&mut chari, |c| c.is_whitespace()); + + let next_idx = chari.next().unwrap().0; + assert_eq!(&str[next_idx..], "no whitespace"); + } +} + +struct Attribute<'body> { + name: &'body str, + content: Option<&'body str>, + start: usize, + len: usize, +} + +fn find_attribute<'body>(body: &'body str, attribute: &str) -> Option<Attribute<'body>> { + let mut chari = body.char_indices().peekable(); + + 'big: loop { + // skip whitespace + peek_skip_while(&mut chari, |c| c.is_whitespace()); + + let key_start = chari.next().unwrap(); + // find end of key + peek_skip_while(&mut chari, |c| c.is_alphanumeric()); + + let key_after = chari.next().unwrap(); + } + + todo!() +} + +fn peek_skip_while<P>(iter: &mut Peekable<CharIndices>, mut predicate: P) +where + P: FnMut(&char) -> bool, +{ + loop { + match iter.peek() { + Some((_, c)) if predicate(c) => { + iter.next(); + } + _ => break, + } + } } |