jotdown/src/inline.rs

214 lines
5.5 KiB
Rust
Raw Normal View History

2022-11-16 16:11:55 -05:00
use crate::Span;
use crate::tree;
2022-11-20 13:13:48 -05:00
use crate::CowStr;
2022-11-16 16:11:55 -05:00
use Atom::*;
use Container::*;
2022-11-20 13:13:48 -05:00
pub type Tree<'s> = tree::Tree<Container, Atom<'s>>;
2022-11-16 16:11:55 -05:00
2022-11-20 13:13:48 -05:00
/*
pub fn parse<'s, I: Iterator<Item = Span>>(src: &'s str, inlines: I) -> Vec<Event<'s>> {
2022-11-16 16:11:55 -05:00
Parser::new(src).parse(inlines)
}
2022-11-20 13:13:48 -05:00
*/
2022-11-16 16:11:55 -05:00
2022-11-20 13:13:48 -05:00
pub enum Inline<'s> {
Atom(Atom<'s>),
2022-11-16 16:11:55 -05:00
Container(Container),
}
#[derive(Debug, Clone, PartialEq, Eq)]
2022-11-20 13:13:48 -05:00
pub enum Atom<'s> {
2022-11-16 16:11:55 -05:00
Str,
Softbreak,
Hardbreak,
Escape,
2022-11-20 13:13:48 -05:00
Nbsp, // ??
OpenMarker, // ??
Ellipses, // ??
ImageMarker, // ??
EmDash, // ??
FootnoteReference { label: CowStr<'s> },
ExplicitLink { label: CowStr<'s> },
ReferenceLink { label: CowStr<'s> },
Emoji { name: CowStr<'s> },
RawFormat { format: CowStr<'s> },
2022-11-16 16:11:55 -05:00
}
2022-11-20 13:13:48 -05:00
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2022-11-16 16:11:55 -05:00
pub enum Container {
// attributes
Attributes,
Span,
// typesetting
Subscript,
Superscript,
Insert,
Delete,
Emph,
Strong,
Mark,
Verbatim,
// smart quoting
SingleQuoted,
DoubleQuoted,
// math
DisplayMath,
InlineMath,
// URLs
Email,
Url,
ImageText,
LinkText,
Reference,
Destination,
}
2022-11-20 13:13:48 -05:00
#[derive(Debug)]
pub enum Event<'s> {
Start(Container, OpenerState),
End(Container),
Atom(Atom<'s>),
}
#[derive(Debug)]
pub enum OpenerState {
Unclosed,
Closed,
Discarded,
}
#[derive(Debug)]
pub enum ContainerType {
Opener,
Closer,
Both,
}
2022-11-16 16:11:55 -05:00
2022-11-20 13:13:48 -05:00
pub struct Parser<'s, I: Iterator<Item = char>> {
chars: std::iter::Peekable<I>,
2022-11-16 16:11:55 -05:00
openers: Vec<(Container, usize)>,
2022-11-20 13:13:48 -05:00
events: Vec<Event<'s>>,
2022-11-16 16:11:55 -05:00
//tree: tree::Builder<Container, Atom>,
}
2022-11-20 13:13:48 -05:00
impl<'s, I: Iterator<Item = char>> Parser<'s, I> {
pub fn new(chars: I) -> Self {
2022-11-16 16:11:55 -05:00
Self {
2022-11-20 13:13:48 -05:00
chars: chars.peekable(),
2022-11-16 16:11:55 -05:00
openers: Vec::new(),
events: Vec::new(),
}
}
2022-11-20 13:13:48 -05:00
/*
fn step(&mut self) -> lex::Token {
let token = lex::Lexer::new(&self.src[self.pos..]).next_token();
self.pos += token.len;
std::mem::replace(&mut self.next_token, token)
}
fn eat(&mut self) -> lex::TokenKind {
loop {
let end = self.pos;
let token = self.step();
if !matches!(token.kind, lex::TokenKind::Whitespace) {
self.span = Span::new(end - token.len, end);
return token.kind;
}
}
}
fn peek(&mut self) -> &lex::TokenKind {
if matches!(self.next_token.kind, lex::TokenKind::Whitespace) {
let _whitespace = self.step();
}
&self.next_token.kind
}
*/
pub fn parse(mut self) -> Vec<(Event<'s>, u32)> {
let mut len = 0;
while let Some(c) = self.chars.peek() {
//let start = self.pos();
let cont = match c {
'*' => Some((Strong, ContainerType::Both)),
'_' => Some((Emph, ContainerType::Both)),
'^' => Some((Superscript, ContainerType::Both)),
'~' => Some((Subscript, ContainerType::Both)),
'\'' => Some((SingleQuoted, ContainerType::Both)),
'"' => Some((DoubleQuoted, ContainerType::Both)),
'`' => todo!(),
'{' => todo!(),
'$' => todo!(),
'<' => todo!(),
'[' => todo!(),
_ => None,
};
let ev = cont
.and_then(|(cont, ty)| {
self.openers
.iter()
.rposition(|(c, _)| *c == cont)
.map(|i| {
if let Event::Start(c, state) = &mut self.events[i] {
assert_eq!(*c, cont);
if matches!(ty, ContainerType::Closer | ContainerType::Both) {
*state = OpenerState::Closed;
Some(Event::End(cont))
} else if matches!(ty, ContainerType::Opener | ContainerType::Both)
{
*state = OpenerState::Discarded;
Some(Event::Start(cont, OpenerState::Unclosed))
} else {
None
}
} else {
unreachable!()
}
})
.unwrap_or_else(|| {
matches!(ty, ContainerType::Opener | ContainerType::Both).then(|| {
self.openers.push((cont, self.events.len()));
Event::Start(cont, OpenerState::Unclosed)
})
})
})
.unwrap_or(Event::Atom(Str));
self.events.push(ev);
}
//self.events
2022-11-16 16:11:55 -05:00
todo!()
}
}
2022-11-20 13:13:48 -05:00
/*
impl<'s> Iterator for Parser<'s> {
type Item = (Event<'s>, Span);
fn next(&mut self) -> Option<Self::Item> {
self.chars.next().map(|c| {
match c {
'*' => todo!(),
'_' => todo!(),
'^' => todo!(),
'~' => todo!(),
'\'' => todo!(),
'"' => todo!(),
'$' => todo!(),
'<' => todo!(),
'{' => todo!(),
'[' => todo!(),
_ =>
}
})
}
}
*/