FSharp.Formatting icon indicating copy to clipboard operation
FSharp.Formatting copied to clipboard

[WIP] Experiment with porting generation to signature like API

Open MangelMaxime opened this issue 1 year ago • 11 comments

Please do not merge as more work is needed before merging into main

This PR experiment with how we could use signature to document the API like proposed in https://github.com/fsprojects/FSharp.Formatting/issues/929.

🚨 I believe the CI is failing because I touch some templates files or because the HTML generation changed. It will be fixed once things are more stable.

Edit: Forgot to add a preview

https://github.com/user-attachments/assets/aaabc1c9-4d1a-4d5a-b34e-dd0357ec5974

Improve XLM Doc formatting

We use a port of TipFormatter.fs from FsAutoComplete.

I need to update it to the latest version, because I am using a fork from 3 years ago but it should not be too difficult.

Rendering of Signature

A new file GenerateSignature.fs has been created to isolate the logic used to render signatures. This is done using a custom TextNode DSL which is responsible for both rendering HTML but also computing the size in number of characters used by the signature elements.

This is important to be able to align the different signature elements:

CleanShot 2024-07-14 at 16 16 08

The main difficulty here came from FSharp.Formatting.HtmlModel because it renders the HTML with a lot of indentations. These indentations causes issues because some of them are interpreted as spaces by the browsers.

To work around this problem, I add a new this.ToMinifiedHtml() method.

I believe by default F# formatting should probably always minimise the generated HTML for optimising the size. If needed, for the tests it is possible to invoke an HTML beautifier like prettier which can be invoked via CLI.

Remarks regarding the current CSS

[!NOTE] The CSS I introduce is not optimised, I just added to for making things look ok for the experimentation

While working on this PR, I had a look at the CSS used and have several remarks:

  • I think it could be an improvement to use the BEM convention to harmonise the CSS naming convention in the repertoire.

  • It is recommended use rem and em instead of px for controlling the size in CSS.

    This is because rem and em are better for scaling and respect the user default font.

  • When designing a page layout, now days it is preferred to use margin-bottom instead of margin-top. This is because it follows the default flow of the page (top to bottom) and can be read as. After each paragraph, I add some spacing unless I am the last element of my scope for example.

  • The number of variables should be kept minimal if possible.

    For example, some of the variables are too contextual to be included by default IHMO, for example the having a spacing of 96px, 128px, 192px are probably never going to be used except for a specific components which will be able to define it's spacing for itself.

    This makes user decision easier because they have less options for the default styling.

  • Regarding the name of the CSS variables, I recently explored using the standard SI units instead of obscures names like main, second, important, etc. which don't works in all the contexts and for which the relation between them is not clear.

    /* Font sizes */
    --font-size-pico: 0.625rem;
    --font-size-micro: 0.75rem;
    --font-size-milli: 0.875rem;
    --font-size-base: 1rem;
    --font-size-kilo: 1.25rem;
    --font-size-mega: 1.5rem;
    --font-size-giga: 2rem;

    /* Spacing */
    --spacing-000: 0; /* 0px */
    --spacing-femto: 0.125rem; /* 2px */
    --spacing-pico: 0.25rem; /* 4px */
    --spacing-nano: 0.5rem; /* 8px */
    --spacing-micro: 0.75rem; /* 12px */
    --spacing-base: 1rem; /* 16px */
    --spacing-kilo: 1.5rem; /* 24px */
    --spacing-mega: 2rem; /* 32px */
    --spacing-giga: 3rem; /* 48px */

Prism.css needs to be customised to use the CSS variables used by F# formatting.

How was the colour for the syntax highlighting chosen? I am asking because I find some of the colour strange for a theme. We could perhaps looks at existing VSCode theme like Atom One or Vs and use their settings. This will make it easier for us to have good contrast for light and dark theme.

F# Formatting

I think it would be a good idea to revisit the Fantomas configuration especially regarding the list formatting.

I believe the current setting is fsharp_multiline_bracket_style = cramped which cause a lot of weird indentation (2 spaces instead of 4 spaces).

This makes the code harder to edit and copy/pasting difficult because the indentation is most often incorrect in the new place.

See how in the screenshot below almost none of the code is indented on the default 4 spaces indentation.

CleanShot 2024-07-14 at 16 37 02

Using fsharp_multiline_bracket_style = aligned make a huge improvements because everything is aligned on a 4 spaces "grid".

To go even further, we could also experiment with using a Feliz like syntax for HTML instead of the double list. But this will requires more work, and I don't know the opinion of everyone on using this syntax. For people, who don't know what I am talking about here is a "blog post" that I wrote which compares both approach.

Plus, I think using fsharp_multiline_bracket_style = aligned gives us a big improvements in term of quality of life for a minimal efforts thanks to the work done by Fantomas team.

Tests

I didn't add any tests, but I think it would be a good idea to add tests to prevents regression in the long run. At minimal, we should adds tests for covering the signature generation and to do so we can use Verify which supports snapshots this avoids having to manually maintains the expected strings which can be quite complexes.

Conclusion

In the end, I don't think the changes needed to use signature for generating the documentation are not too complex. It offers the opportunity to restructure the old code, to make it easier to read and maintain in the long run.

Please feel free to ask questions and provide feedbacks on the initial works done, and I will do my best to adapt it and convert all the generation to the new proposition.

MangelMaxime avatar Jul 13 '24 17:07 MangelMaxime