diff --git a/app/MindWork AI Studio/Tools/Pandoc.cs b/app/MindWork AI Studio/Tools/Pandoc.cs
index 0d290a4c..c54aa21e 100644
--- a/app/MindWork AI Studio/Tools/Pandoc.cs
+++ b/app/MindWork AI Studio/Tools/Pandoc.cs
@@ -23,6 +23,29 @@ public static partial class Pandoc
private static readonly Version MINIMUM_REQUIRED_VERSION = new (3, 7);
private static readonly Version FALLBACK_VERSION = new (3, 7, 0, 2);
+ ///
+ /// Prepares a ProcessStartInfo for running pandoc with the given parameters.
+ ///
+ ///
+ /// Any local installation of pandoc will be preferred over the system-wide installation.
+ ///
+ /// The global rust service to access file system and data dir.
+ /// The input file to convert.
+ /// The output file to write the converted content to.
+ /// The format of the input file (e.g., markdown, html, etc.).
+ /// The format of the output file (e.g., pdf, docx, etc.).
+ /// Additional arguments to pass to the pandoc command (optional).
+ /// The ProcessStartInfo object configured to run pandoc with the specified parameters.
+ public static async Task PreparePandocProcess(RustService rustService, string inputFile, string outputFile, string inputFormat, string outputFormat, string? additionalArgs = null) => new()
+ {
+ FileName = await PandocExecutablePath(rustService),
+ Arguments = $"{inputFile} -f {inputFormat} -t {outputFormat} {additionalArgs ?? string.Empty} -o {outputFile}",
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
///
/// Checks if pandoc is available on the system and can be started as a process or is present in AI Studio's data dir.
///
@@ -31,20 +54,11 @@ public static partial class Pandoc
/// True, if pandoc is available and the minimum required version is met, else false.
public static async Task CheckAvailabilityAsync(RustService rustService, bool showMessages = true)
{
- var installDir = await GetPandocDataFolder(rustService);
- if (HasPandoc(installDir))
- return true;
-
try
{
- var startInfo = new ProcessStartInfo
- {
- FileName = PandocExecutableName,
- Arguments = "--version",
- RedirectStandardOutput = true,
- UseShellExecute = false,
- CreateNoWindow = true
- };
+ var startInfo = await PreparePandocProcess(rustService, string.Empty, string.Empty, string.Empty, string.Empty);
+ startInfo.Arguments = "--version";
+
using var process = Process.Start(startInfo);
if (process == null)
{
@@ -102,27 +116,6 @@ public static partial class Pandoc
return false;
}
}
-
- private static bool HasPandoc(string pandocDirectory)
- {
- try
- {
- var subdirectories = Directory.GetDirectories(pandocDirectory);
- foreach (var subdirectory in subdirectories)
- {
- var pandocPath = Path.Combine(subdirectory, PandocExecutableName);
- if (File.Exists(pandocPath))
- return true;
- }
-
- return false;
- }
- catch (Exception ex)
- {
- LOG.LogInformation("Pandoc is not installed in the data directory and might have thrown and error: {0}", ex.Message);
- return false;
- }
- }
///
/// Automatically decompresses the latest pandoc archive into AiStudio's data directory
@@ -301,6 +294,45 @@ public static partial class Pandoc
/// Reads the os platform to determine the used executable name.
///
private static string PandocExecutableName => CPU_ARCHITECTURE is RID.WIN_ARM64 or RID.WIN_X64 ? "pandoc.exe" : "pandoc";
+
+ ///
+ /// Returns the path to the pandoc executable.
+ ///
+ ///
+ /// Any local installation of pandoc will be preferred over the system-wide installation.
+ /// When a local installation is found, its absolute path will be returned. In case no local
+ /// installation is found, the name of the pandoc executable will be returned.
+ ///
+ /// Global rust service to access file system and data dir.
+ /// Path to the pandoc executable.
+ private static async Task PandocExecutablePath(RustService rustService)
+ {
+ //
+ // First, we try to find the pandoc executable in the data directory.
+ // Any local installation should be preferred over the system-wide installation.
+ //
+ var localInstallationRootDirectory = await GetPandocDataFolder(rustService);
+ try
+ {
+ var executableName = PandocExecutableName;
+ var subdirectories = Directory.GetDirectories(localInstallationRootDirectory);
+ foreach (var subdirectory in subdirectories)
+ {
+ var pandocPath = Path.Combine(subdirectory, executableName);
+ if (File.Exists(pandocPath))
+ return pandocPath;
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+
+ //
+ // When no local installation was found, we assume that the pandoc executable is in the system PATH.
+ //
+ return PandocExecutableName;
+ }
private static async Task GetPandocDataFolder(RustService rustService) => Path.Join(await rustService.GetDataDirectory(), "pandoc");