Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Add PlantUML support to enable migrations onto latest version of docfx #9566

Closed
cjlotz opened this issue Dec 28, 2023 · 6 comments · Fixed by #9574
Closed
Labels
markdown Authoring and presenting content using markdown

Comments

@cjlotz
Copy link
Contributor

cjlotz commented Dec 28, 2023

Is your feature request related to a problem? Please describe.
We have been using plantuml and the docfx plantuml plugin to create of our technical documentation. The latest versions of docfx does not support plantuml with support being limited to mermaid diagrams.

Describe the solution you'd like
To continue using the latest versions of docfx we need plantuml support. We are willing to write a plugin that supports the feature set, but we are unclear as to where to start, what extensibility points to use etc. Can somebody please provide us with the relevant hooks/mechanisms to implement/override to enable this? It seens like we need to create a Markdig diagrams extension? The old plugin is based on the DFM syntax which I believe is not supported going forward. Any pointers will be much appreciated.

@filzrev
Copy link
Contributor

filzrev commented Dec 29, 2023

It thought it can be implemented with following steps.

  1. Create custom CodeBlockRenderer class.
  2. Implement CodeBlockRenderer methods that process PlantUML's FencedCodeBlock.
    (other code block should be handled by base class)
  3. Implement Extension that inherit IMarkdownExtension that register CustomCodeBlockRenderer at higher priority that default CodeBlockRenderer.
  4. Register custom markdig extension by ConfigureMarkdig method.

Example code: filzrev@2e227b0

Note

Step.4 requires ConfigureMarkdig method call.
As far as I know.
There is no extension point available to register Custom Markdig extension that can be used from docfx plugin.
So you need to do one of the following

  1. Create custom docfx build.
  2. Create custom application that use Docfx.App package.
  3. Create PR to support PlantUML

@cjlotz
Copy link
Contributor Author

cjlotz commented Dec 30, 2023

@filzrev thanks so much for the info - giving it a go to see what I can come up with

@cjlotz
Copy link
Contributor Author

cjlotz commented Dec 30, 2023

@filzrev I've done a POC to see if I can get the rendering of Plantuml up and running. I used the extensibility points you pointed out, but based the implementation on the PlantUml.Net library that was also used in the old Docfx PlantUml plugin. As you mentioned, the issue comes in with the configuration aspects of the extensions. This area needs a bit of rework as there is currently no hook to fit this into the current toolset.

I had a look at the existing extensions to see which of these require configuration. The QuoteSectionNote seems to be the only current extension with some configuration aspects. The configuration for this is specified as part of the markdownEngineProperties element in the docfx.json file. So I tried to make this a more generic extension point for any extension configuration. Something like the following:

{
    "markdownEngineProperties":     
    {
 	"alerts":  {
          "TODO": "alert alert-secondary"
      	},          
        "plantUml": {       
          "remoteUrl" : "https://www.plantuml.com/plantuml/",
          "outputFormat" : "svg"	  
        }
    }
}

So any extension can add their configuration as a new key in the existing configuration. All we then need is a mechanism for the specific extension to get hold of their configuration. As all extensions can have access to the MarkdownContext, I added a new GetExtensionConfiguration callback on it, to allow any extension to pull its configuration from the markdownEngineProperties. Here is an example for the QuoteSectionNote extension:

public class QuoteSectionNoteExtension : IMarkdownExtension
{
    private readonly MarkdownContext _context;
    private readonly Dictionary<string, string> _notes = new(StringComparer.OrdinalIgnoreCase)
    {
        ["NOTE"] = "NOTE",
        ["TIP"] = "TIP",
        ["WARNING"] = "WARNING",
        ["IMPORTANT"] = "IMPORTANT",
        ["CAUTION"] = "CAUTION",
    };

    public QuoteSectionNoteExtension(MarkdownContext context)
    {
        _context = context;

        var config = _context.GetExtensionConfiguration("Alerts");
        if (config != null)
        {
            foreach (var (key, value) in config)
                _notes[key] = value;
        }
    }
....

I implemented something similar for the PlantUmlExtension and it seems to work nicely. The MarkdownServiceProperties obviously also need to be extended to cater for the additional extension configuration properties so that it can be provided by the docfx configuration. Going this route seems to provide the best mechanism where extension configuration can be plugged into the existing tool chain (docfx, docfx.app etc.).

Here's a link to my commit where I implemented all of this. Any feedback on this would be much appreciated. I wrote one or two tests to verify the changes to the existing and new implementations, but I'm struggling to get the whole tool chain running on my machine. If the approach I'm following is acceptable, I can look at creating a pull request for this with additional feedback included.

@yufeih
Copy link
Contributor

yufeih commented Jan 1, 2024

@cjlotz Thank you for putting this together, this commit looks absolute great! The approach looks good to me, my only question is how does PlantUML themes work with docfx templates that supports dark/light mode. Can we switch themes dynamically in the browser using CSS/JS, or are the themes baked into the resulting SVG? If latter, we may need to generate 2 SVGs to be able to switch between light/dark in the browser.

@cjlotz
Copy link
Contributor Author

cjlotz commented Jan 1, 2024

@yufeih Not an expert on PlantUML themes, but a theme is added directly into the code block that is transformed to a SVG. We use specific themes to render some specific type of architecture diagrams more elegantly,

From these discussions it does not seem possible to dynamically switch the theme. I was not aware that docfx currently supports the dynamic switching of images based on theme based on unresolved feature requests like this.

For us, the ability to render PlantUML regardless of the light/dark theme using the latest docfx is what we are looking for as a starting point. This will allow us to move our technical docs forward using docfx due to our considerable investment in PlantUml. Otherwise, we will have to migrate to other alternatives like JetBrains Writerside which is starting to look promising but still missing the dynamic features of docfx which we also use extensively as part of our tech doc pipelines. Not to mention the considerable effort from our side for such a migration.

My suggestion is to land the PlantUml support and create a subsequent feature request to look at light/dark mode support.

The code as it stands with the current commit is fully functional. I tested a local copy of this on all our technical docs and the diagrams rendered successfully. The tests also run through barring for some failures on the QuoteSectionNoteTest which seems to be related to some new line carriage return issue when I look at the diff in my commit for the file. Currently a bit stumped on how to fix this. Might be due to differences line feed in commit styles for Git on Mac/Windows?

What are your current thoughts on taking this forward?

@yufeih
Copy link
Contributor

yufeih commented Jan 2, 2024

@cjlotz Sounds like a good plan. Would you like to send a pull request?

@yufeih yufeih added the markdown Authoring and presenting content using markdown label Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
markdown Authoring and presenting content using markdown
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants