Files
mnote/rust/crates/mnote-editor-core/src/projection.rs
T

56 lines
1.7 KiB
Rust

use crate::model::{BlockType, DocumentBlock, DocumentModel};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutlineEntry {
pub block_id: String,
pub level: u8,
pub title: String,
pub depth: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VisibilitySnapshot {
pub visible_block_ids: Vec<String>,
pub outline: Vec<OutlineEntry>,
}
impl VisibilitySnapshot {
pub fn derive(document: &DocumentModel) -> Self {
let mut hidden_ancestor_ids: Vec<String> = Vec::new();
let mut visible_block_ids = Vec::new();
let mut outline = Vec::new();
for block in document.blocks() {
hidden_ancestor_ids.retain(|ancestor_id| is_ancestor_of(document, ancestor_id, block));
let visible = hidden_ancestor_ids.is_empty();
if visible {
visible_block_ids.push(block.id.clone());
}
if matches!(block.block_type, BlockType::Heading) {
let level = block.heading_level.unwrap_or(1);
if visible {
outline.push(OutlineEntry {
block_id: block.id.clone(),
level,
title: block.content.text.clone(),
depth: block.indent as usize,
});
}
if block.collapsed {
hidden_ancestor_ids.push(block.id.clone());
}
}
}
Self {
visible_block_ids,
outline,
}
}
}
fn is_ancestor_of(document: &DocumentModel, ancestor_id: &str, block: &DocumentBlock) -> bool {
document.is_descendant_of(&block.id, ancestor_id)
}