Skip to main content

yozora_tokenizer_html_block/
tokenizer.rs

1use yozora_core_tokenizer::*;
2
3use crate::types::HTML_BLOCK_TOKENIZER_NAME;
4use crate::{parse, r#match};
5
6#[derive(Debug, Clone)]
7pub struct HtmlBlockTokenizer {
8    meta: TokenizerMeta,
9}
10
11impl Default for HtmlBlockTokenizer {
12    fn default() -> Self {
13        Self::new(TokenizerOptions::default())
14    }
15}
16
17impl HtmlBlockTokenizer {
18    pub fn new(options: TokenizerOptions) -> Self {
19        Self {
20            meta: TokenizerMeta {
21                name: options
22                    .name
23                    .unwrap_or_else(|| HTML_BLOCK_TOKENIZER_NAME.to_string()),
24                kind: TokenizerKind::Block,
25                priority: options.priority.unwrap_or(TokenizerPriority::ATOMIC),
26            },
27        }
28    }
29}
30
31impl Tokenizer for HtmlBlockTokenizer {
32    fn r#type(&self) -> TokenizerType {
33        TokenizerType::Block
34    }
35
36    fn name(&self) -> &str {
37        &self.meta.name
38    }
39
40    fn priority(&self) -> i32 {
41        self.meta.priority
42    }
43}
44
45#[derive(Debug, Clone, Copy, Default)]
46pub struct HtmlBlockMatchHook;
47
48impl HtmlBlockMatchHook {
49    pub fn new() -> Self {
50        Self
51    }
52}
53
54impl MatchBlockHook for HtmlBlockMatchHook {
55    fn is_containing_block(&self) -> bool {
56        false
57    }
58
59    fn eat_opener(
60        &mut self,
61        line: &PhrasingContentLine,
62        _parent_token: &BlockToken,
63    ) -> Option<EatOpenerResult> {
64        r#match::eat_opener(line)
65    }
66
67    fn eat_and_interrupt_previous_sibling(
68        &mut self,
69        line: &PhrasingContentLine,
70        prev_sibling_token: &BlockToken,
71        _parent_token: &BlockToken,
72    ) -> Option<EatAndInterruptPreviousSiblingResult> {
73        r#match::eat_and_interrupt_previous_sibling(line, prev_sibling_token)
74    }
75
76    fn eat_continuation_text(
77        &mut self,
78        line: &PhrasingContentLine,
79        token: &mut BlockToken,
80        _parent_token: &BlockToken,
81    ) -> EatContinuationTextResult {
82        r#match::eat_continuation_text(line, token)
83    }
84}
85
86pub struct HtmlBlockParseHook<'a> {
87    api: &'a dyn ParseBlockPhaseApi,
88}
89
90impl<'a> HtmlBlockParseHook<'a> {
91    pub fn new(api: &'a dyn ParseBlockPhaseApi) -> Self {
92        Self { api }
93    }
94}
95
96impl ParseBlockHook for HtmlBlockParseHook<'_> {
97    fn parse<'a>(&'a self, tokens: &'a [BlockToken]) -> ParseBlockResult<ParseBlockHookResult<'a>> {
98        Ok(parse::parse_html_block_tokens(tokens, self.api).into())
99    }
100}
101
102impl BlockTokenizer for HtmlBlockTokenizer {
103    fn r#match<'a>(&'a self, _api: &'a dyn MatchBlockPhaseApi) -> Box<dyn MatchBlockHook + 'a> {
104        Box::new(HtmlBlockMatchHook::new())
105    }
106
107    fn parse<'a>(&'a self, api: &'a dyn ParseBlockPhaseApi) -> Box<dyn ParseBlockHook + 'a> {
108        Box::new(HtmlBlockParseHook::new(api))
109    }
110}