Skip to content

Commit

Permalink
Add statiq mermaid pipeline (#1909)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpvreony authored Sep 24, 2024
1 parent 0c89e7a commit 5aaafd4
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 1 deletion.
111 changes: 111 additions & 0 deletions src/Whipstaff.Statiq/Mermaid/MermaidDiagramModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) 2022 DHGMS Solutions and Contributors. All rights reserved.
// This file is licensed to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Statiq.Common;
using Whipstaff.Mermaid.HttpServer;
using Whipstaff.Mermaid.Playwright;
using Whipstaff.Playwright;

namespace Whipstaff.Statiq.Mermaid
{
/// <summary>
/// Statiq module for producing mermaid diagrams.
/// </summary>
public sealed class MermaidDiagramModule : Module
{
private readonly System.IO.Abstractions.IFileSystem _fileSystem;

/// <summary>
/// Initializes a new instance of the <see cref="MermaidDiagramModule"/> class.
/// </summary>
/// <param name="fileSystem">File system abstraction.</param>
public MermaidDiagramModule(System.IO.Abstractions.IFileSystem fileSystem)
{
ArgumentNullException.ThrowIfNull(fileSystem);
_fileSystem = fileSystem;
}

/// <inheritdoc />
protected override async Task<IEnumerable<IDocument>> ExecuteInputAsync(IDocument input, IExecutionContext context)
{
ArgumentNullException.ThrowIfNull(input);
ArgumentNullException.ThrowIfNull(context);

context.LogInformation(input, "Starting Mermaid Diagram CLI Module");

var path = _fileSystem.Path;
var inputFilename = path.GetFullPath(input.Source.FullPath);

var rootPath = path.GetFullPath(context.FileSystem.RootPath.FullPath);

var destination = input.Destination.FullPath;

// this is taking the input folder, the output folder
var outputFilename = path.Combine(
rootPath,
"output",
destination);

// and reversing the path separator on the output
outputFilename = path.GetFullPath(outputFilename);

// finally replace the file extension
// could be a setting for now assume svg
// might be a better way of doing all the output steps
// within the Statiq Context would need to dig.
outputFilename = path.ChangeExtension(
outputFilename,
".svg");

var targetDir = path.GetDirectoryName(outputFilename);

if (targetDir == null)
{
throw new InvalidOperationException("failed to work out target directory");
}

var directory = _fileSystem.Directory;
if (!directory.Exists(targetDir))
{
_ = directory.CreateDirectory(targetDir);
}

var logMessageActions = new PlaywrightRendererLogMessageActions();
var loggerFactory = context.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<PlaywrightRenderer>();
var logMessageActionsWrapper = new PlaywrightRendererLogMessageActionsWrapper(logMessageActions, logger);
var mermaidHttpServer = MermaidHttpServerFactory.GetTestServer(loggerFactory);

var playwrightRenderer = new Whipstaff.Mermaid.Playwright.PlaywrightRenderer(
mermaidHttpServer,
logMessageActionsWrapper);

var markdown = await _fileSystem.File.ReadAllTextAsync(inputFilename);

var diagramResponse = await playwrightRenderer.GetDiagram(
markdown,
PlaywrightBrowserTypeAndChannel.ChromiumDefault())
.ConfigureAwait(false);

if (diagramResponse == null)
{
throw new InvalidOperationException("Failed to generate diagram");
}

await _fileSystem.File.WriteAllTextAsync(
outputFilename,
diagramResponse.Svg)
.ConfigureAwait(false);

// keeping the working the same as the previous cli version
// could return the response object in future.
return Array.Empty<IDocument>();
}
}
}
29 changes: 29 additions & 0 deletions src/Whipstaff.Statiq/Mermaid/MermaidDiagramPipeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2022 DHGMS Solutions and Contributors. All rights reserved.
// This file is licensed to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using Statiq.Common;
using Statiq.Core;

namespace Whipstaff.Statiq.Mermaid
{
/// <summary>
/// Statiq pipeline for processing mermaid diagram files.
/// </summary>
public sealed class MermaidDiagramPipeline : Pipeline
{
/// <summary>
/// Initializes a new instance of the <see cref="MermaidDiagramPipeline"/> class.
/// </summary>
public MermaidDiagramPipeline()
{
// we need to check for mermaidjs-cli
// we need to look for *.mmd files
var patterns = new[] { "./**/*.mmd" };
var readFiles = new ReadFiles(patterns);
InputModules = new ModuleList(readFiles);

ProcessModules = new ModuleList(new MermaidDiagramModule(new System.IO.Abstractions.FileSystem()));
}
}
}
24 changes: 24 additions & 0 deletions src/Whipstaff.Statiq/Whipstaff.Statiq.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<PackageDescription>Re-usable logic for working with WPF.</PackageDescription>
</PropertyGroup>

<Target Name="AdjustVersion" DependsOnTargets="GetBuildVersion" AfterTargets="GetBuildVersion">
<PropertyGroup>
<PackageVersion>$(PackageVersion)-beta</PackageVersion>
</PropertyGroup>
</Target>

<ItemGroup>
<ProjectReference Include="..\Whipstaff.Mermaid\Whipstaff.Mermaid.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.60" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="21.0.29" />
</ItemGroup>

</Project>
8 changes: 7 additions & 1 deletion src/Whipstaff.sln
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whipstaff.Mermaid", "Whipst
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whipstaff.Wpf.MaterialDesign", "Whipstaff.Wpf.MaterialDesign\Whipstaff.Wpf.MaterialDesign.csproj", "{F23F9BFF-DF01-43A3-85E8-DF87CDA02A58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Whipstaff.Wpf.AvalonEdit", "Whipstaff.Wpf.AvalonEdit\Whipstaff.Wpf.AvalonEdit.csproj", "{4E69353A-56B5-4EAE-8BE4-8975EFDB7C4D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whipstaff.Wpf.AvalonEdit", "Whipstaff.Wpf.AvalonEdit\Whipstaff.Wpf.AvalonEdit.csproj", "{4E69353A-56B5-4EAE-8BE4-8975EFDB7C4D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Whipstaff.Statiq", "Whipstaff.Statiq\Whipstaff.Statiq.csproj", "{AE602A3A-6E12-4881-8EF6-A078C11BDF0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -257,6 +259,10 @@ Global
{4E69353A-56B5-4EAE-8BE4-8975EFDB7C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E69353A-56B5-4EAE-8BE4-8975EFDB7C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E69353A-56B5-4EAE-8BE4-8975EFDB7C4D}.Release|Any CPU.Build.0 = Release|Any CPU
{AE602A3A-6E12-4881-8EF6-A078C11BDF0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE602A3A-6E12-4881-8EF6-A078C11BDF0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE602A3A-6E12-4881-8EF6-A078C11BDF0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE602A3A-6E12-4881-8EF6-A078C11BDF0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 5aaafd4

Please sign in to comment.