nargo_document/plugin/
mod.rs1use nargo_types::NargoValue;
5use std::collections::HashMap;
6
7pub mod container;
8pub mod katex;
9pub mod mermaid;
10pub mod prism;
11pub mod shiki;
12
13pub use container::{ContainerConfig, ContainerOptions, ContainerPlugin};
14pub use katex::KaTeXPlugin;
15pub use mermaid::MermaidPlugin;
16pub use prism::PrismPlugin;
17pub use shiki::ShikiPlugin;
18
19#[derive(Debug, Clone)]
21pub struct PluginMeta {
22 pub name: String,
24 pub version: String,
26 pub description: String,
28}
29
30impl PluginMeta {
31 pub fn new(name: String, version: String, description: String) -> Self {
33 Self { name, version, description }
34 }
35}
36
37#[derive(Debug, Clone)]
40pub struct PluginContext {
41 pub content: String,
43 pub frontmatter: HashMap<String, NargoValue>,
45 pub path: String,
47}
48
49impl PluginContext {
50 pub fn new(content: String, frontmatter: HashMap<String, NargoValue>, path: String) -> Self {
52 Self { content, frontmatter, path }
53 }
54
55 pub fn from_content(content: String, path: String) -> Self {
57 Self { content, frontmatter: HashMap::new(), path }
58 }
59}
60
61pub trait DocumentPlugin: Send + Sync {
64 fn meta(&self) -> &PluginMeta;
66
67 fn setup(&mut self, config: Option<HashMap<String, NargoValue>>) {
70 let _ = config;
71 }
72
73 fn before_render(&self, context: PluginContext) -> PluginContext {
76 context
77 }
78
79 fn after_render(&self, context: PluginContext) -> PluginContext {
82 context
83 }
84}
85
86pub struct PluginRegistry {
89 plugins: Vec<Box<dyn DocumentPlugin>>,
91}
92
93impl PluginRegistry {
94 pub fn new() -> Self {
96 Self { plugins: Vec::new() }
97 }
98
99 pub fn register<P: DocumentPlugin + 'static>(&mut self, plugin: P) {
101 self.plugins.push(Box::new(plugin));
102 }
103
104 pub fn setup_all(&mut self, config: Option<HashMap<String, NargoValue>>) {
106 for plugin in &mut self.plugins {
107 plugin.setup(config.clone());
108 }
109 }
110
111 pub fn before_render_all(&self, context: PluginContext) -> PluginContext {
113 let mut current_context = context;
114 for plugin in &self.plugins {
115 current_context = plugin.before_render(current_context);
116 }
117 current_context
118 }
119
120 pub fn after_render_all(&self, context: PluginContext) -> PluginContext {
122 let mut current_context = context;
123 for plugin in &self.plugins {
124 current_context = plugin.after_render(current_context);
125 }
126 current_context
127 }
128
129 pub fn plugin_count(&self) -> usize {
131 self.plugins.len()
132 }
133
134 pub fn plugin_metas(&self) -> Vec<&PluginMeta> {
136 self.plugins.iter().map(|p| p.meta()).collect()
137 }
138}
139
140impl Default for PluginRegistry {
141 fn default() -> Self {
142 Self::new()
143 }
144}