satteri_plugin_api/
plugin.rs1use crate::context::PluginContext;
2use crate::typed_nodes::*;
3use satteri_arena::{Arena, Mdast};
4use satteri_ast::mdast::MdastNodeType;
5
6#[derive(Debug, Clone)]
8pub struct PluginMeta {
9 pub name: &'static str,
10 pub version: Option<&'static str>,
11 pub description: Option<&'static str>,
12}
13
14impl PluginMeta {
15 pub fn new(name: &'static str) -> Self {
16 Self {
17 name,
18 version: None,
19 description: None,
20 }
21 }
22}
23
24pub enum VisitResult {
26 NoChange,
28 Replace(crate::commands::NewNode),
30 Remove,
32}
33
34impl VisitResult {
35 pub fn no_change() -> Self {
36 Self::NoChange
37 }
38 pub fn replace(node: crate::commands::NewNode) -> Self {
39 Self::Replace(node)
40 }
41 pub fn remove() -> Self {
42 Self::Remove
43 }
44}
45
46pub trait Plugin: Send + Sync {
51 fn meta(&self) -> PluginMeta;
52
53 fn init(&mut self) {}
55
56 fn before(&mut self, _arena: &Arena<Mdast>, _ctx: &mut PluginContext) {}
58
59 fn after(&mut self, _arena: &Arena<Mdast>, _ctx: &mut PluginContext) {}
61
62 fn visit_heading(&mut self, _node: &Heading, _ctx: &mut PluginContext) -> VisitResult {
63 VisitResult::NoChange
64 }
65 fn visit_paragraph(&mut self, _node: &Paragraph, _ctx: &mut PluginContext) -> VisitResult {
66 VisitResult::NoChange
67 }
68 fn visit_text(&mut self, _node: &Text, _ctx: &mut PluginContext) -> VisitResult {
69 VisitResult::NoChange
70 }
71 fn visit_link(&mut self, _node: &Link, _ctx: &mut PluginContext) -> VisitResult {
72 VisitResult::NoChange
73 }
74 fn visit_image(&mut self, _node: &Image, _ctx: &mut PluginContext) -> VisitResult {
75 VisitResult::NoChange
76 }
77 fn visit_code(&mut self, _node: &Code, _ctx: &mut PluginContext) -> VisitResult {
78 VisitResult::NoChange
79 }
80 fn visit_list(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
81 VisitResult::NoChange
82 }
83 fn visit_list_item(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
84 VisitResult::NoChange
85 }
86 fn visit_blockquote(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
87 VisitResult::NoChange
88 }
89 fn visit_emphasis(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
90 VisitResult::NoChange
91 }
92 fn visit_strong(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
93 VisitResult::NoChange
94 }
95 fn visit_inline_code(&mut self, _node: &Text, _ctx: &mut PluginContext) -> VisitResult {
96 VisitResult::NoChange
97 }
98 fn visit_html(&mut self, _node: &Text, _ctx: &mut PluginContext) -> VisitResult {
99 VisitResult::NoChange
100 }
101 fn visit_table(&mut self, _node: &NodeView, _ctx: &mut PluginContext) -> VisitResult {
102 VisitResult::NoChange
103 }
104
105 fn transform_root(
107 &mut self,
108 _arena: &Arena<Mdast>,
109 _ctx: &mut PluginContext,
110 ) -> Option<Arena<Mdast>> {
111 None
112 }
113}
114
115pub struct NodeView<'a> {
117 pub(crate) node_id: u32,
118 pub(crate) arena: &'a Arena<Mdast>,
119}
120
121impl<'a> NodeView<'a> {
122 pub fn id(&self) -> u32 {
123 self.node_id
124 }
125 pub fn children(&self) -> &[u32] {
126 self.arena.get_children(self.node_id)
127 }
128 pub fn position(&self) -> NodePosition {
129 NodePosition::from_node(self.arena.get_node(self.node_id))
130 }
131 pub fn node_type(&self) -> MdastNodeType {
132 let raw = self.arena.get_node(self.node_id).node_type;
133 MdastNodeType::from_u8(raw).unwrap_or(MdastNodeType::Root)
134 }
135}