1use {
2 crate::*,
3 minimad::Alignment,
4};
5
6#[derive(Debug)]
8pub struct CodeBlock {
9 pub start: usize,
10 pub height: usize, pub width: usize, }
13impl CodeBlock {
14 pub fn justify(&self, lines: &mut [FmtLine<'_>]) {
16 for line in lines.iter_mut().skip(self.start).take(self.height) {
17 if let FmtLine::Normal(ref mut fc) = line {
18 fc.spacing = Some(Spacing {
19 width: self.width,
20 align: Alignment::Left,
21 });
22 }
23 }
24 }
25}
26
27const fn code_line_length(line: &FmtLine<'_>) -> Option<usize> {
28 match line {
29 FmtLine::Normal(fc) => match fc.kind {
30 CompositeKind::Code => Some(fc.visible_length),
31 _ => None,
32 },
33 _ => None,
34 }
35}
36
37pub fn find_blocks(lines: &[FmtLine<'_>]) -> Vec<CodeBlock> {
43 let mut blocks: Vec<CodeBlock> = Vec::new();
44 let mut current: Option<CodeBlock> = None;
45 for (idx, line) in lines.iter().enumerate() {
46 if let Some(ll) = code_line_length(line) {
47 match current.as_mut() {
48 Some(b) => {
49 b.height += 1;
50 b.width = b.width.max(ll);
51 }
52 None => {
53 current = Some(CodeBlock {
54 start: idx,
55 height: 1,
56 width: ll,
57 });
58 }
59 }
60 } else if let Some(c) = current.take() {
61 blocks.push(c);
62 }
63 }
64 if let Some(c) = current.take() {
65 blocks.push(c);
66 }
67 blocks
68}
69
70pub fn justify_blocks(lines: &mut [FmtLine<'_>]) {
73 let blocks = find_blocks(lines);
74 for b in blocks {
75 b.justify(lines);
76 }
77}