mdx/
config.rs

1use crate::error::Error;
2use crate::parser::ParseOptions;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fs;
6use std::path::Path;
7
8/// Configuration for Markrust
9#[derive(Debug, Clone, Serialize, Deserialize, Default)]
10pub struct Config {
11    /// Parser configuration
12    #[serde(default)]
13    pub parser: ParserConfig,
14
15    /// Renderer configuration
16    #[serde(default)]
17    pub renderer: RendererConfig,
18
19    /// Theme configuration
20    #[serde(default)]
21    pub theme: ThemeConfig,
22
23    /// Custom component directories
24    #[serde(default)]
25    pub components: Vec<String>,
26}
27
28/// Parser configuration
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ParserConfig {
31    /// Enable GitHub-flavored markdown
32    #[serde(default = "default_true")]
33    pub gfm: bool,
34
35    /// Enable smart punctuation
36    #[serde(default = "default_true")]
37    pub smart_punctuation: bool,
38
39    /// Parse YAML frontmatter
40    #[serde(default = "default_true")]
41    pub frontmatter: bool,
42
43    /// Enable custom component syntax
44    #[serde(default = "default_true")]
45    pub custom_components: bool,
46}
47
48/// Renderer configuration
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct RendererConfig {
51    /// Default document title
52    #[serde(default = "default_title")]
53    pub title: String,
54
55    /// Include default CSS
56    #[serde(default = "default_true")]
57    pub include_default_css: bool,
58
59    /// Minify HTML output
60    #[serde(default)]
61    pub minify: bool,
62
63    /// Generate table of contents
64    #[serde(default)]
65    pub toc: bool,
66
67    /// Apply syntax highlighting to code blocks
68    #[serde(default = "default_true")]
69    pub syntax_highlight: bool,
70
71    /// Add copy buttons to code blocks
72    #[serde(default = "default_true")]
73    pub code_copy_button: bool,
74
75    /// Theme for syntax highlighting
76    #[serde(default = "default_highlight_theme")]
77    pub highlight_theme: String,
78}
79
80/// Theme configuration
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ThemeConfig {
83    /// Theme name
84    #[serde(default = "default_theme")]
85    pub name: String,
86
87    /// Theme variables
88    #[serde(default)]
89    pub variables: HashMap<String, String>,
90}
91
92impl Default for ParserConfig {
93    fn default() -> Self {
94        Self {
95            gfm: true,
96            smart_punctuation: true,
97            frontmatter: true,
98            custom_components: true,
99        }
100    }
101}
102
103impl Default for RendererConfig {
104    fn default() -> Self {
105        Self {
106            title: default_title(),
107            include_default_css: true,
108            minify: false,
109            toc: false,
110            syntax_highlight: true,
111            code_copy_button: true,
112            highlight_theme: default_highlight_theme(),
113        }
114    }
115}
116
117impl Default for ThemeConfig {
118    fn default() -> Self {
119        Self {
120            name: default_theme(),
121            variables: HashMap::new(),
122        }
123    }
124}
125
126impl Config {
127    /// Load configuration from a TOML file
128    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
129        let content = fs::read_to_string(path)?;
130        let config: Config = toml::from_str(&content)?;
131        Ok(config)
132    }
133}
134
135// Conversion from Config to component options
136impl From<&Config> for ParseOptions {
137    fn from(config: &Config) -> Self {
138        ParseOptions {
139            gfm: config.parser.gfm,
140            smart_punctuation: config.parser.smart_punctuation,
141            frontmatter: config.parser.frontmatter,
142            custom_components: config.parser.custom_components,
143        }
144    }
145}
146
147fn default_true() -> bool {
148    true
149}
150
151fn default_title() -> String {
152    "Markrust Document".to_string()
153}
154
155fn default_theme() -> String {
156    "modern".to_string()
157}
158
159fn default_highlight_theme() -> String {
160    "InspiredGitHub".to_string()
161}