use nargo_types::NargoValue;
use std::collections::HashMap;
pub mod container;
pub mod katex;
pub mod mermaid;
pub mod prism;
pub mod shiki;
pub use container::{ContainerConfig, ContainerOptions, ContainerPlugin};
pub use katex::KaTeXPlugin;
pub use mermaid::MermaidPlugin;
pub use prism::PrismPlugin;
pub use shiki::ShikiPlugin;
#[derive(Debug, Clone)]
pub struct PluginMeta {
pub name: String,
pub version: String,
pub description: String,
}
impl PluginMeta {
pub fn new(name: String, version: String, description: String) -> Self {
Self { name, version, description }
}
}
#[derive(Debug, Clone)]
pub struct PluginContext {
pub content: String,
pub frontmatter: HashMap<String, NargoValue>,
pub path: String,
}
impl PluginContext {
pub fn new(content: String, frontmatter: HashMap<String, NargoValue>, path: String) -> Self {
Self { content, frontmatter, path }
}
pub fn from_content(content: String, path: String) -> Self {
Self { content, frontmatter: HashMap::new(), path }
}
}
pub trait DocumentPlugin: Send + Sync {
fn meta(&self) -> &PluginMeta;
fn setup(&mut self, config: Option<HashMap<String, NargoValue>>) {
let _ = config;
}
fn before_render(&self, context: PluginContext) -> PluginContext {
context
}
fn after_render(&self, context: PluginContext) -> PluginContext {
context
}
}
pub struct PluginRegistry {
plugins: Vec<Box<dyn DocumentPlugin>>,
}
impl PluginRegistry {
pub fn new() -> Self {
Self { plugins: Vec::new() }
}
pub fn register<P: DocumentPlugin + 'static>(&mut self, plugin: P) {
self.plugins.push(Box::new(plugin));
}
pub fn setup_all(&mut self, config: Option<HashMap<String, NargoValue>>) {
for plugin in &mut self.plugins {
plugin.setup(config.clone());
}
}
pub fn before_render_all(&self, context: PluginContext) -> PluginContext {
let mut current_context = context;
for plugin in &self.plugins {
current_context = plugin.before_render(current_context);
}
current_context
}
pub fn after_render_all(&self, context: PluginContext) -> PluginContext {
let mut current_context = context;
for plugin in &self.plugins {
current_context = plugin.after_render(current_context);
}
current_context
}
pub fn plugin_count(&self) -> usize {
self.plugins.len()
}
pub fn plugin_metas(&self) -> Vec<&PluginMeta> {
self.plugins.iter().map(|p| p.meta()).collect()
}
}
impl Default for PluginRegistry {
fn default() -> Self {
Self::new()
}
}