extern crate string_cache;
extern crate html5ever;
use std::io::{self, Read};
use std::default::Default;
use std::string::String;
use std::collections::HashMap;
use std::borrow::Cow;
use string_cache::QualName;
use html5ever::{parse_to, one_input};
use html5ever::tokenizer::Attribute;
use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText};
struct Sink {
next_id: usize,
names: HashMap<usize, QualName>,
}
impl Sink {
fn get_id(&mut self) -> usize {
let id = self.next_id;
self.next_id += 1;
id
}
}
impl TreeSink for Sink {
type Handle = usize;
fn get_document(&mut self) -> usize {
0
}
fn same_node(&self, x: usize, y: usize) -> bool {
x == y
}
fn elem_name(&self, target: usize) -> QualName {
self.names.get(&target).expect("not an element").clone()
}
fn create_element(&mut self, name: QualName, _attrs: Vec<Attribute>) -> usize {
let id = self.get_id();
self.names.insert(id, name);
id
}
fn create_comment(&mut self, _text: String) -> usize {
self.get_id()
}
fn append_before_sibling(&mut self,
_sibling: usize,
_new_node: NodeOrText<usize>) -> Result<(), NodeOrText<usize>> {
Ok(())
}
fn parse_error(&mut self, _msg: Cow<'static, str>) { }
fn set_quirks_mode(&mut self, _mode: QuirksMode) { }
fn append(&mut self, _parent: usize, _child: NodeOrText<usize>) { }
fn append_doctype_to_document(&mut self, _name: String, _public_id: String, _system_id: String) { }
fn add_attrs_if_missing(&mut self, _target: usize, _attrs: Vec<Attribute>) { }
fn remove_from_parent(&mut self, _target: usize) { }
fn reparent_children(&mut self, _node: usize, _new_parent: usize) { }
fn mark_script_already_started(&mut self, _node: usize) { }
}
fn main() {
let sink = Sink {
next_id: 1,
names: HashMap::new(),
};
let mut input = String::new();
io::stdin().read_to_string(&mut input).unwrap();
parse_to(sink, one_input(input), Default::default());
}