Skip to main content

dmc_transform/
config.rs

1//! Pipeline-level configuration. Compiled unconditionally so callers can
2//! describe the pipeline (themes, copy-linked-files paths, gfm switch, ...)
3//! whether or not the matching feature flags are enabled.
4//!
5//! When a config field describes a transformer whose feature is off,
6//! [`Pipeline::with_defaults_for`](crate::Pipeline::with_defaults_for)
7//! silently skips it -- the field is still allowed in the config so user
8//! settings round-trip cleanly across builds with different feature sets.
9
10use serde::{Deserialize, Serialize};
11use std::collections::BTreeMap;
12use std::path::PathBuf;
13
14/// Top-level config consumed by [`Pipeline::with_defaults_for`].
15/// All fields are optional; the empty config (`PipelineConfig::default()`)
16/// reproduces the historical `Pipeline::with_defaults()` behavior.
17#[derive(Debug, Clone, Default, Serialize, Deserialize)]
18#[serde(default)]
19pub struct PipelineConfig {
20  /// When `false`, append the `disable-gfm` transformer that strips GFM
21  /// extensions (tables, strikethrough, autolinks, task lists).
22  pub markdown_gfm: Option<bool>,
23  /// Pretty-code theme + multi-mode settings. `None` keeps the bundled
24  /// defaults (Catppuccin Latte/Mocha pair, dark primary).
25  pub pretty_code: Option<PrettyCodeOptions>,
26  /// LaTeX rendering engine. `None` -> [`MathEngine::Katex`].
27  pub math_engine: Option<MathEngine>,
28  /// When `Some`, append the `copy-linked-files` transformer with the
29  /// supplied paths.
30  pub copy_linked_files: Option<CopyLinkedFilesOptions>,
31  /// When `Some(false)`, do not push the `Emoji` transformer. `None`
32  /// or `Some(true)` keeps the default behaviour (transformer added
33  /// when the `emoji` feature is on). Used by the plugin gate to drop
34  /// the native transformer when the user prefers `remark-emoji`.
35  pub emoji: Option<bool>,
36  /// Same shape for the `AutolinkHeadings` transformer. Set to
37  /// `Some(false)` when the user prefers `rehype-slug` /
38  /// `rehype-autolink-headings`.
39  pub autolink_headings: Option<bool>,
40  /// Same shape for the `Math` transformer. Set to `Some(false)` when
41  /// the user prefers `remark-math` / `rehype-katex` / `rehype-mathjax`.
42  pub math: Option<bool>,
43  /// Same shape for the `PrettyCode` transformer. Set to `Some(false)`
44  /// when the user prefers `rehype-pretty-code` / `shiki`.
45  pub pretty_code_enabled: Option<bool>,
46}
47
48/// Which engine renders `$...$` / `$$...$$` math.
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
50#[serde(rename_all = "lowercase")]
51pub enum MathEngine {
52  /// Embedded KaTeX via `quick-js`. Output matches `rehype-katex` byte
53  /// for byte. Slow per-expression (1-5 ms each).
54  #[default]
55  Katex,
56  /// `pulldown-latex` -> MathML. Fast (microseconds). Browser MathML
57  /// rendering is functional but visually plainer than KaTeX HTML.
58  Mathml,
59}
60
61/// Pretty-code theme spec.
62///
63/// Deserialised untagged: pass a JSON string for single-theme, or an
64/// object `{ light: "...", dark: "...", ... }` for multi-mode output.
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(untagged)]
67pub enum PrettyCodeTheme {
68  /// Single bundled theme name. Emits per-token `style="color:#xxx"`.
69  Single(String),
70  /// Map of `mode -> bundled theme name`. Mode keys are arbitrary
71  /// (`light`, `dark`, `dim`, ...); they appear in the emitted CSS as
72  /// `--dmc-{mode}` / `--dmc-{mode}-bg` CSS custom properties.
73  Multi(BTreeMap<String, String>),
74}
75
76impl Default for PrettyCodeTheme {
77  fn default() -> Self {
78    Self::Multi(
79      [("light".to_string(), "Catppuccin Latte".to_string()), ("dark".to_string(), "Catppuccin Mocha".to_string())]
80        .into_iter()
81        .collect(),
82    )
83  }
84}
85
86/// Top-level pretty-code configuration. Stored on `CompileConfig` as
87/// `Option<PrettyCodeOptions>`; `None` means "use built-in defaults".
88#[derive(Debug, Clone, Default, Serialize, Deserialize)]
89#[serde(default)]
90pub struct PrettyCodeOptions {
91  /// Theme spec. String for single-theme, object for multi-mode.
92  pub theme: PrettyCodeTheme,
93  /// Mode key whose colors fill the unprefixed `color` /
94  /// `background-color` attrs. Only meaningful for [`PrettyCodeTheme::Multi`].
95  /// When unset, resolves to `"dark"` if present, else the first key.
96  pub default_mode: Option<String>,
97}
98
99/// Paths consumed by the `copy-linked-files` transformer.
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct CopyLinkedFilesOptions {
102  /// Directory the source `.mdx` lives in -- used to resolve relative
103  /// `src` / `href` attrs.
104  pub source_dir: PathBuf,
105  /// Output asset directory (where copies are written).
106  pub assets_dir: PathBuf,
107  /// Public URL prefix prepended to rewritten asset paths.
108  pub public_base: String,
109}