Deciding if bold can start.

This commit is contained in:
Tom Alexander 2022-12-11 02:07:12 -05:00
parent b6b88a7d78
commit bb09ed41a4
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 60 additions and 1 deletions

View File

@ -20,6 +20,12 @@ pub struct Node<T> {
parent: Option<Rc<Node<T>>>,
}
impl<T> Node<T> {
pub fn get_data(&self) -> &T {
&self.data
}
}
// TODO: This Debug is only needed because of the try_unwrap+expect
impl<T: Debug> List<T> {
pub fn new() -> Self {
@ -72,6 +78,12 @@ impl<T: Debug> List<T> {
(Some(me), Some(them)) => Rc::ptr_eq(me, them),
}
}
pub fn iter(&self) -> impl Iterator<Item = &Rc<Node<T>>> {
NodeIter {
position: &self.head,
}
}
}
pub struct NodeIter<'a, T> {

View File

@ -1,9 +1,12 @@
use std::rc::Rc;
use nom::bytes::complete::take;
use nom::combinator::not;
use nom::error::VerboseError;
use nom::IResult;
use super::list::List;
use super::list::Node;
use super::token::Token;
type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>;
@ -32,6 +35,10 @@ impl<'r, 's> ContextTree<'r, 's> {
(popped_element, ContextTree { tree: remaining })
}
pub fn iter(&self) -> impl Iterator<Item = &Rc<Node<ContextElement<'r, 's>>>> {
self.tree.iter()
}
pub fn check_fail_matcher<'b>(
&'r self,
i: &'b str,

View File

@ -22,6 +22,8 @@ use super::text::TextElement;
use super::token::Token;
use super::Context;
use nom::branch::alt;
use nom::bytes::complete::take;
use nom::combinator::cond;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::not;
@ -118,11 +120,49 @@ pub fn context_paragraph_end<'s, 'r>(
paragraph_end(input)
}
fn can_start_bold<'s, 'r>(context: Context<'r, 's>) -> bool {
let mut context_iterator = context.iter().enumerate();
loop {
if let Some((i, ctx)) = context_iterator.next() {
match ctx.get_data() {
ContextElement::FailMatcherNode(_) => {},
ContextElement::PreviousElementNode(previous_element_node) => {
// TODO okay if previous element is a space but not if its text
match &previous_element_node.element {
Token::TextElement(text_element) => {
match text_element {
TextElement::Span(_) => return false,
TextElement::Space(_) => return true,
TextElement::LineBreak(_) => return true,
TextElement::Symbol(_) => return false,
TextElement::Bold(_) => return false,
TextElement::Link(_) => return false,
};
},
};
},
ContextElement::StartOfParagraph => {
return true;
},
}
} else {
break;
}
}
false
}
pub fn context_bold_start<'s, 'r>(
context: Context<'r, 's>,
input: &'s str,
) -> Res<&'s str, &'s str> {
recognize(bold_start)(input)
if can_start_bold(context) {
recognize(bold_start)(input)
} else {
// TODO: Make this a custom error
not(take(0usize))(input)?;
unreachable!()
}
}
pub fn context_bold_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> {