1
0
mirror of https://github.com/mfontanini/presenterm.git synced 2026-09-01 23:33:21 -06:00

feat: allow configuring mermaid cli tool

This commit is contained in:
Matias Fontanini 2026-03-24 05:23:43 -07:00
parent 952061abec
commit 1edb436b35
5 changed files with 37 additions and 14 deletions

View File

@ -544,6 +544,11 @@
"MermaidConfig": {
"type": "object",
"properties": {
"cli": {
"description": "The application to use to generate diagrams.",
"default": "mmdc",
"type": "string"
},
"config_path": {
"description": "A path to a mermaid JSON configuration file to be used by the `mmdc` tool.",
"type": [

View File

@ -343,6 +343,10 @@ pub(crate) fn default_typst_ppi() -> u32 {
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct MermaidConfig {
/// The application to use to generate diagrams.
#[serde(default = "default_mermaid_cli")]
pub cli: String,
/// The scaling parameter to be used in the mermaid CLI.
#[serde(default = "default_mermaid_scale")]
pub scale: u32,
@ -356,7 +360,12 @@ pub struct MermaidConfig {
impl Default for MermaidConfig {
fn default() -> Self {
Self { scale: default_mermaid_scale(), puppeteer_config_path: None, config_path: None }
Self {
cli: default_mermaid_cli(),
scale: default_mermaid_scale(),
puppeteer_config_path: None,
config_path: None,
}
}
}
@ -364,6 +373,10 @@ pub(crate) fn default_mermaid_scale() -> u32 {
2
}
pub(crate) fn default_mermaid_cli() -> String {
if cfg!(windows) { "mmdc.cmd" } else { "mmdc" }.to_string()
}
#[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]

View File

@ -253,6 +253,7 @@ impl CoreComponents {
);
let third_party_config = ThirdPartyConfigs {
typst_ppi: config.typst.ppi.to_string(),
mermaid_cli: config.mermaid.cli.clone(),
mermaid_scale: config.mermaid.scale.to_string(),
mermaid_puppeteer_file: config.mermaid.puppeteer_config_path.clone(),
mermaid_config_file: config.mermaid.config_path.clone(),

View File

@ -1,6 +1,6 @@
use crate::{
ImageRegistry,
config::{default_mermaid_scale, default_snippet_render_threads, default_typst_ppi},
config::{default_mermaid_cli, default_mermaid_scale, default_snippet_render_threads, default_typst_ppi},
markdown::{
elements::{Line, Percent, Text},
text_style::{Color, TextStyle},
@ -30,6 +30,7 @@ use std::{
pub struct ThirdPartyConfigs {
pub typst_ppi: String,
pub mermaid_cli: String,
pub mermaid_scale: String,
pub mermaid_puppeteer_file: Option<String>,
pub mermaid_config_file: Option<String>,
@ -67,6 +68,7 @@ impl ThirdPartyRender {
impl Default for ThirdPartyRender {
fn default() -> Self {
let config = ThirdPartyConfigs {
mermaid_cli: default_mermaid_cli(),
typst_ppi: default_typst_ppi().to_string(),
mermaid_scale: default_mermaid_scale().to_string(),
mermaid_puppeteer_file: None,
@ -222,7 +224,7 @@ impl Worker {
args.extend(&["-c", path]);
}
ThirdPartyTools::mermaid(&args).run()?;
ThirdPartyTools::mermaid(&self.shared.config.mermaid_cli, &args).run()?;
self.load_image(snippet, &output_path)
}

View File

@ -17,9 +17,8 @@ impl ThirdPartyTools {
Tool::new("typst", args)
}
pub(crate) fn mermaid(args: &[&str]) -> Tool {
let mmdc = if cfg!(windows) { "mmdc.cmd" } else { "mmdc" };
Tool::new(mmdc, args)
pub(crate) fn mermaid(binary: &str, args: &[&str]) -> Tool {
Tool::new(binary, args)
}
pub(crate) fn d2(args: &[&str]) -> Tool {
@ -32,16 +31,18 @@ impl ThirdPartyTools {
}
pub(crate) struct Tool {
command_name: &'static str,
command_name: String,
command: Command,
stdin: Option<Vec<u8>>,
max_error_lines: usize,
}
impl Tool {
fn new(command_name: &'static str, args: &[&str]) -> Self {
fn new(command_name: &str, args: &[&str]) -> Self {
let mut command = Command::new(command_name);
command.args(args).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::piped());
let command_name = command_name.to_string();
Self { command_name, command, stdin: None, max_error_lines: DEFAULT_MAX_ERROR_LINES }
}
@ -87,9 +88,10 @@ impl Tool {
stdin
.write_all(data)
.and_then(|_| stdin.flush())
.map_err(|error| Communication { command: self.command_name, error })?;
.map_err(|error| Communication { command: self.command_name.clone(), error })?;
}
let output = child.wait_with_output().map_err(|error| Communication { command: self.command_name, error })?;
let output =
child.wait_with_output().map_err(|error| Communication { command: self.command_name.clone(), error })?;
self.validate_output(&output)?;
Ok(output)
}
@ -107,14 +109,14 @@ impl Tool {
#[derive(Debug, thiserror::Error)]
pub enum ExecutionError {
#[error("spawning '{command}' failed: {error}")]
Spawn { command: &'static str, error: io::Error },
Spawn { command: String, error: io::Error },
#[error("spawning '{command}' failed (is '{command}' installed?)")]
SpawnNotFound { command: &'static str },
SpawnNotFound { command: String },
#[error("communicating with '{command}' failed: {error}")]
Communication { command: &'static str, error: io::Error },
Communication { command: String, error: io::Error },
#[error("'{command}' execution failed: \n{stderr}")]
Execution { command: &'static str, stderr: String },
Execution { command: String, stderr: String },
}