Fortran-FOSS-Programmers / ford

Automatically generates FORtran Documentation from comments within the code.
https://forddocs.readthedocs.io
GNU General Public License v3.0
407 stars 133 forks source link

Plantuml diagrams with intra-doc links #370

Open mbraakhekke opened 2 years ago

mbraakhekke commented 2 years ago

Using the markdown extension plantuml-markdown it's possible to include plantuml diagrams in the markdown pages. These then get incorporated into the HTML output. Plantuml also supports hyperlinks in the diagrams. I would like to use this feature to link to other parts in the documentation from the diagrams. By specifying SVG output, it's possible to have links in generated diagrams that get incorporated in html.

Suppose we have a markdown page with a plantuml diagram and intra-doc links:

Here's some explanation of [[my_function(function)]].
```plantuml format="svg_inline"
participant my_function [[my_function(function)]]
participant my_other_function
my_function --> my_other_function
```

The first link to my_function will get properly converted but the second link within the plantuml code will not. Plantuml also uses double brackets to signify hyperlinks, so the string [[my_function(function)]] will get converted to something like <a href="my_function(function)">my_function(function)</a> in the SVG (and HTML) code. FORD won't recognize this because the double brackets are removed. But even if we could somehow keep the double brackets in the SVG (i.e. <a href="[[my_function(function)]]">my_function(function)</a>), this still wouldn't work because FORD assumes a bare string enclosed in double brackets, adds the HTML link stuff (the <a></a> tags, etc.)

At first I thought that this should be solved on the plantuml side so I posted a question on the plantuml forum. However, after studying the code I realize this also needs some changes to side in order to intra-doc links that are already in the form of a HTML hyperlink. So it's probably best to handle this completely on the FORD side.

Unfortunately plantuml doesn't like four sets of brackets ([[[[my_function(function)]]]]), and will raise a syntax error. A possible solution would be to allow an alternative syntax, e.g. double pipes ||mylink|| and change FORD to handle links like <a href="||my_function(function)||">my_function(function)</a>. However, this will require FORD to distinguish between the different parts of the hyperlink: the URL, the title, and the hover text. But perhaps there's better solution.

Anyway, if we can decide on an approach, I'd be happy to implement it and submit a PR.

ZedThree commented 2 years ago

I'm not sure I completely understand what you'd like to achieve. Do you want FORD to not expand double-bracket links in triple-backtick blocks, but hold off and later expand them in img tags? It sounds like you possibly also want FORD to expand a link into just the address and not the whole <a> tag?

Is this possibly related to #309, not expanding double-bracket links in triple-backtick blocks at all?

Do you need plantuml to handle some of the link generation? It looks like that can handle optional labels and tooltips, which FORD currently can't do. Is that something you need? That could be a useful feature in FORD itself.

Ah, although I see a potential conflict there -- if we did all this in FORD, that would conflict with #309. We'd need to completely expand the link in FORD before plantuml took over, or to have a different syntax for just the URL. Is that right?

mbraakhekke commented 2 years ago

I do need FORD to expand intra-doc links. The main problem is that FORD first converts the md files to HTML and then expands the intra-doc links. But FORD is currently not able to deal with intra-doc links in hyperlink form in the SVGs embedded in the HTML.

I implemented a possible solution that allows you to specify intra-doc links in the plantuml code as [[||my_function(function)||]]. Plantuml doesn't touch the double pipes, so this gets converted to hyperlinks with URL (href) set to "||my_function(function)||". By adjusting FORD to recognize and process strings in the form href="||my_function(function)||", I was able to make it work.

I created a sample project with an md file with the following plantuml code:

participant main
participant MyModule [[||MyModule||]]

main -> MyModule : [[||my_function(function)|| my_function()]]
main <-- MyModule

main -> MyModule : [[||my_subroutine(subroutine)||]]
main <-- MyModule

This gets gets converted to the following sequence diagram:

image

MyModule, my_function, and my_subroutine link to the corresponding pages in the FORD documentation (obviously not in this image). I still have to test it for other diagram types.

I also made adjustments to process the text part of the hyperlink. This works, but it's problematic because the textboxes in the diagram are sized based on the length of intra-doc link string, e.g. ||my_subroutine(subroutine)||. If that gets replaced by my_subroutine, the textbox is too wide resulting in aesthetic problems (see my_subroutine in image above). So in this case it is necessary to explicitly specify the link text in the diagram code (as with my_function).

I include the sample project: ford_plantuml_sample.zip. The built documentation is included under doc/build/. The diagram is located on page "Module description". To build it yourself you need to get the plantuml binary and store it under doc/ (or somewhere on the path). On Windows it should work with the included .bat file. For Linux you'd need to follow the instructions given on the plantuml-markdown site.

I took a quick look at #309, but as far as I can see this issue is not related.