use {
crate::{
line::*,
spacing::Spacing,
},
minimad::{Alignment, CompositeStyle},
};
#[derive(Debug)]
pub struct CodeBlock {
pub start: usize,
pub height: usize, pub width: usize, }
impl CodeBlock {
pub fn justify(&self, lines: &mut Vec<FmtLine<'_>>) {
for idx in self.start..self.start + self.height {
if let FmtLine::Normal(ref mut fc) = lines[idx] {
fc.spacing = Some(Spacing {
width: self.width,
align: Alignment::Left,
});
}
}
}
}
fn code_line_length(line: &FmtLine<'_>) -> Option<usize> {
match line {
FmtLine::Normal(fc) => match fc.composite.style {
CompositeStyle::Code => Some(fc.visible_length),
_ => None,
},
_ => None,
}
}
pub fn find_blocks(lines: &[FmtLine<'_>]) -> Vec<CodeBlock> {
let mut blocks: Vec<CodeBlock> = Vec::new();
let mut current: Option<CodeBlock> = None;
for (idx, line) in lines.iter().enumerate() {
if let Some(ll) = code_line_length(&line) {
match current.as_mut() {
Some(b) => {
b.height += 1;
b.width = b.width.max(ll);
}
None => {
current = Some(CodeBlock {
start: idx,
height: 1,
width: ll,
});
}
}
} else if let Some(c) = current.take() {
blocks.push(c);
}
}
if let Some(c) = current.take() {
blocks.push(c);
}
blocks
}
pub fn justify_blocks(lines: &mut Vec<FmtLine<'_>>) {
let blocks = find_blocks(lines);
for b in blocks {
b.justify(lines);
}
}