Skip to content

Commit

Permalink
use branch builder for bold node
Browse files Browse the repository at this point in the history
  • Loading branch information
Lurk committed Feb 9, 2025
1 parent 5f0c9e6 commit 50d8767
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 65 deletions.
6 changes: 6 additions & 0 deletions src/nodes/bold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ impl Bold {
Self { body }
}
}

impl From<Vec<BoldNodes>> for Bold {
fn from(value: Vec<BoldNodes>) -> Self {
Self::new(value)
}
}
6 changes: 6 additions & 0 deletions src/nodes/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,9 @@ impl Default for Paragraph {
Self::new(vec![])
}
}

impl From<Vec<ParagraphNodes>> for Paragraph {
fn from(value: Vec<ParagraphNodes>) -> Self {
Self::new(value)
}
}
32 changes: 7 additions & 25 deletions src/parser/bold.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,24 @@
use crate::{lexer::TokenKind, nodes::Bold};

use super::{italic, strikethrough, Parser};
use super::{italic, strikethrough, BranchBuilder, Parser};

pub(crate) fn bold(p: &mut Parser<'_>) -> Option<Bold> {
let mut b = Bold::new(vec![]);
let mut text_start: Option<usize> = None;
let mut b = BranchBuilder::new();
let start_pos = p.pos();
p.next_token();

while let Some((t, pos)) = p.peek() {
match t.kind {
TokenKind::Terminator => break,
TokenKind::Tilde if t.slice.len() == 2 => {
if let Some(s) = strikethrough(p) {
if let Some(start) = text_start.take() {
b.body.push(p.range_to_string(start..pos).into());
}
b.body.push(s.into());
}
}
TokenKind::Underscore if t.slice.len() == 1 => {
if let Some(i) = italic(p) {
if let Some(start) = text_start.take() {
b.body.push(p.range_to_string(start..pos).into());
}
b.body.push(i.into());
}
}
TokenKind::Tilde if t.slice.len() == 2 => b.push(strikethrough(p), p, pos),
TokenKind::Underscore if t.slice.len() == 1 => b.push(italic(p), p, pos),
TokenKind::Star if t.slice.len() == 2 => {
if let Some(start) = text_start.take() {
b.body.push(p.range_to_string(start..pos).into());
}

b.consume_text(p, pos);
p.next_token();
return Some(b);
return b.build();
}
_ => {
text_start.get_or_insert(pos);
b.start_text(pos);
p.next_token();
}
}
Expand Down
42 changes: 42 additions & 0 deletions src/parser/branch_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use super::Parser;

pub struct BranchBuilder<Leaves: From<String>> {
nodes: Vec<Leaves>,
text_start: Option<usize>,
}

impl<Leaves: From<String>> BranchBuilder<Leaves> {
pub fn new() -> Self {
Self {
nodes: vec![],
text_start: None,
}
}
pub fn push<N: Into<Leaves>>(&mut self, n: Option<N>, p: &Parser, pos: usize) {
if let Some(n) = n {
self.consume_text(p, pos);
self.nodes.push(n.into());
}
}

pub fn start_text(&mut self, pos: usize) {
self.text_start.get_or_insert(pos);
}

pub fn consume_text(&mut self, p: &Parser, end: usize) {
if let Some(start) = self.text_start.take() {
self.nodes.push(p.range_to_string(start..end).into());
}
}

pub fn clear_text_if_shorter_than(&mut self, pos: usize, size: usize) {
self.text_start.take_if(|start| pos - *start < size);
}

pub fn build<Branch: From<Vec<Leaves>>>(self) -> Option<Branch> {
if self.nodes.is_empty() {
return None;
}
Some(self.nodes.into())
}
}
2 changes: 2 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod anchor;
mod bold;
mod branch_builder;
mod code;
mod code_span;
mod collapsible;
Expand All @@ -23,6 +24,7 @@ use std::{

pub(crate) use anchor::anchor;
pub(crate) use bold::bold;
pub(crate) use branch_builder::BranchBuilder;
pub(crate) use code::code;
pub(crate) use code_span::code_span;
pub(crate) use collapsible::collapsible;
Expand Down
43 changes: 3 additions & 40 deletions src/parser/paragraph.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,16 @@
use crate::{
lexer::{Token, TokenKind},
nodes::{Paragraph, ParagraphNodes},
nodes::Paragraph,
};

use super::{anchor, bold, code_span, emphasis, italic, strikethrough, Parser};

#[derive(Default)]
struct ParagraphBuilder {
nodes: Vec<ParagraphNodes>,
text_start: Option<usize>,
}

impl ParagraphBuilder {
fn push<N: Into<ParagraphNodes>>(&mut self, n: Option<N>, p: &Parser, pos: usize) {
if let Some(n) = n {
self.consume_text(p, pos);
self.nodes.push(n.into());
}
}

fn start_text(&mut self, pos: usize) {
self.text_start.get_or_insert(pos);
}

#[inline]
fn consume_text(&mut self, p: &Parser, end: usize) {
if let Some(start) = self.text_start.take() {
self.nodes.push(p.range_to_string(start..end).into());
}
}

fn clear_text_if_shorter_than(&mut self, pos: usize, size: usize) {
self.text_start.take_if(|start| pos - *start < size);
}

fn build(self) -> Option<Paragraph> {
if self.nodes.is_empty() {
return None;
}
Some(Paragraph::new(self.nodes))
}
}
use super::{anchor, bold, code_span, emphasis, italic, strikethrough, BranchBuilder, Parser};

pub(crate) fn paragraph<Callback>(p: &mut Parser<'_>, new_line_check: Callback) -> Option<Paragraph>
where
Callback: Fn(&Token) -> bool,
{
let start = p.pos();
let mut bulder = ParagraphBuilder::default();
let mut bulder = BranchBuilder::new();
let mut end_modifier = 0;

while let Some((t, pos)) = p.peek() {
Expand Down

0 comments on commit 50d8767

Please sign in to comment.