Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T07:08:48.245Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

mindmap.rs

136 lines · 4.6 KB · rust
1use anyhow::Result;
2use quick_xml::events::{BytesStart, Event};
3
4use super::{AccentStackEntry, NodeTracker};
5
6pub(super) struct MindmapAccents {
7    section_classes: Vec<String>,
8    section_g_stack: Vec<AccentStackEntry>,
9    nodes: NodeTracker,
10    current_text_section: Option<usize>,
11}
12
13impl MindmapAccents {
14    pub(super) fn new() -> Self {
15        Self {
16            section_classes: Vec::new(),
17            section_g_stack: Vec::new(),
18            nodes: NodeTracker::default(),
19            current_text_section: None,
20        }
21    }
22
23    pub(super) fn process_event<'a>(&mut self, event: Event<'a>) -> Result<Event<'a>> {
24        match &event {
25            Event::Start(e) if e.name().as_ref() == b"g" => {
26                if super::is_foreign_object_fallback_group(e)? {
27                    self.section_g_stack.push(AccentStackEntry::none());
28                    return Ok(event);
29                }
30
31                let section_idx = self.parse_section_class(e)?;
32                if let Some(idx) = section_idx {
33                    let tracks_node = if let Some((tx, ty)) = super::parse_translate(e) {
34                        self.nodes.start_node(tx, ty, 0.0, idx);
35                        true
36                    } else {
37                        false
38                    };
39                    self.section_g_stack
40                        .push(AccentStackEntry::accent(idx, tracks_node));
41                } else {
42                    self.section_g_stack.push(AccentStackEntry::none());
43                }
44                Ok(event)
45            }
46
47            Event::End(e) if e.name().as_ref() == b"g" => {
48                if let Some(entry) = self.section_g_stack.pop() {
49                    if entry.tracks_node() {
50                        self.nodes.maybe_finish_node();
51                    }
52                }
53                Ok(event)
54            }
55
56            Event::Start(e) | Event::Empty(e)
57                if matches!(
58                    e.name().as_ref(),
59                    b"path" | b"rect" | b"circle" | b"polygon" | b"ellipse"
60                ) =>
61            {
62                if e.name().as_ref() == b"path" {
63                    self.nodes.update_half_height(e);
64                }
65                Ok(event)
66            }
67
68            Event::Start(e) | Event::Empty(e)
69                if e.name().as_ref() == b"text" || e.name().as_ref() == b"tspan" =>
70            {
71                let section_idx = self.current_section_accent().or_else(|| {
72                    if e.name().as_ref() == b"text" {
73                        self.nodes.lookup_accent(e)
74                    } else {
75                        None
76                    }
77                });
78
79                if e.name().as_ref() == b"text" {
80                    self.current_text_section = section_idx;
81                }
82
83                let idx = section_idx.or(self.current_text_section);
84
85                if let Some(idx) = idx {
86                    if let Some(class_name) = self.section_class_name(idx) {
87                        return super::add_to_event(&event, e, class_name);
88                    }
89                }
90
91                Ok(event)
92            }
93
94            Event::End(e) if e.name().as_ref() == b"text" => {
95                self.current_text_section = None;
96                Ok(event)
97            }
98
99            _ => Ok(event),
100        }
101    }
102
103    fn parse_section_class(&mut self, e: &BytesStart<'_>) -> Result<Option<usize>> {
104        let class_attr = match e.try_get_attribute("class")? {
105            Some(attr) => attr,
106            None => return Ok(None),
107        };
108        let class = class_attr.unescape_value()?;
109        let is_root = class.split_whitespace().any(|t| t == "section-root");
110
111        for token in class.split_whitespace() {
112            if let Some(rest) = token.strip_prefix("section-") {
113                if rest == "-1" || rest.parse::<u32>().is_ok() {
114                    let class_name = if is_root {
115                        "section-root section--1".to_string()
116                    } else {
117                        format!("section-{rest}")
118                    };
119                    let idx = self.section_classes.len();
120                    self.section_classes.push(class_name);
121                    return Ok(Some(idx));
122                }
123            }
124        }
125        Ok(None)
126    }
127
128    fn current_section_accent(&self) -> Option<usize> {
129        super::current_stack_accent(&self.section_g_stack)
130    }
131
132    fn section_class_name(&self, idx: usize) -> Option<&str> {
133        self.section_classes.get(idx).map(|s| s.as_str())
134    }
135}
136
Served at tenant.openagents/omega Member data and write actions are omitted.