Skip to main content

nargo_document/plugin/
mod.rs

1//! 插件模块
2//! 提供 nargo-document 文档编译器的插件系统
3
4use 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/// 插件元数据
20#[derive(Debug, Clone)]
21pub struct PluginMeta {
22    /// 插件名称
23    pub name: String,
24    /// 插件版本
25    pub version: String,
26    /// 插件描述
27    pub description: String,
28}
29
30impl PluginMeta {
31    /// 创建新的插件元数据
32    pub fn new(name: String, version: String, description: String) -> Self {
33        Self { name, version, description }
34    }
35}
36
37/// 插件上下文
38/// 提供给插件处理的文档信息
39#[derive(Debug, Clone)]
40pub struct PluginContext {
41    /// 文档内容
42    pub content: String,
43    /// 前置元数据
44    pub frontmatter: HashMap<String, NargoValue>,
45    /// 文档路径
46    pub path: String,
47}
48
49impl PluginContext {
50    /// 创建新的插件上下文
51    pub fn new(content: String, frontmatter: HashMap<String, NargoValue>, path: String) -> Self {
52        Self { content, frontmatter, path }
53    }
54
55    /// 从文档内容创建插件上下文
56    pub fn from_content(content: String, path: String) -> Self {
57        Self { content, frontmatter: HashMap::new(), path }
58    }
59}
60
61/// 文档插件 Trait
62/// 定义插件需要实现的钩子方法
63pub trait DocumentPlugin: Send + Sync {
64    /// 获取插件元数据
65    fn meta(&self) -> &PluginMeta;
66
67    /// 插件初始化钩子
68    /// 在编译开始前调用,用于插件的初始化
69    fn setup(&mut self, config: Option<HashMap<String, NargoValue>>) {
70        let _ = config;
71    }
72
73    /// 渲染前钩子
74    /// 在 Markdown 解析后、HTML 渲染前调用,用于修改文档内容
75    fn before_render(&self, context: PluginContext) -> PluginContext {
76        context
77    }
78
79    /// 渲染后钩子
80    /// 在 HTML 渲染后调用,用于修改渲染后的内容
81    fn after_render(&self, context: PluginContext) -> PluginContext {
82        context
83    }
84}
85
86/// 插件注册表
87/// 用于管理和注册文档插件
88pub struct PluginRegistry {
89    /// 已注册的插件列表
90    plugins: Vec<Box<dyn DocumentPlugin>>,
91}
92
93impl PluginRegistry {
94    /// 创建新的插件注册表
95    pub fn new() -> Self {
96        Self { plugins: Vec::new() }
97    }
98
99    /// 注册一个插件
100    pub fn register<P: DocumentPlugin + 'static>(&mut self, plugin: P) {
101        self.plugins.push(Box::new(plugin));
102    }
103
104    /// 初始化所有已注册的插件
105    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    /// 对所有已注册的插件调用渲染前钩子
112    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    /// 对所有已注册的插件调用渲染后钩子
121    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    /// 获取已注册插件的数量
130    pub fn plugin_count(&self) -> usize {
131        self.plugins.len()
132    }
133
134    /// 获取所有已注册插件的元数据
135    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}