tweag / ormolu

A formatter for Haskell source code
https://ormolu-live.tweag.io
Other
956 stars 83 forks source link

List items in Haddocks are getting escaped #1018

Closed tchoutri closed 1 year ago

tchoutri commented 1 year ago

Describe the bug List items in Haddocks are getting escaped in the Haddocks of a source file.

What was * List item is now \* List item.

To Reproduce I cannot manage to make a self-contained reproducer, but I can consistently reproduce on a particular file:

  1. Download this file: https://github.com/tchoutri/pg-entity/blob/main/docs/src/Tutorial.hs
  2. Run ormolu Tutorial.hs
  3. Scroll up to the #### Language Extensions section
  4. Observe that the list items are now:
-- #### Language Extensions
--
-- \* `OverloadedLists` allow us to use the `[list]` syntax for datatypes other than List, like Vector.
-- \* `QuasiQuotes` enable us to write plain SQL and field names in a `[|quasi-quoter block|]`.
-- \* The Deriving extensions give us more powerful typeclass derivation.

Expected behavior List items should not be escaped, because this breaks rendering.

Environment

Additional context None

amesgen commented 1 year ago

Thanks for the report! This is expected behavior, but it is somewhat tricky: The GHC parser (in Haddock mode) detects your list items as section headings, but they can't actually occur there as regular Haddock (only in export lists or named chunks), so Ormolu escapes them as per #837.

You can fix this by adding at least one extra space before the *:

-- #### Language Extensions
--
--   * `OverloadedLists` allow us to use the `[list]` syntax for datatypes other than List, like Vector.
--   * `QuasiQuotes` enable us to write plain SQL and field names in a `[|quasi-quoter block|]`.
--   * The Deriving extensions give us more powerful typeclass derivation.

Ormolu should not modify this. Hope this helps!

More details ```haskell -- foo -- -- * bar -- * baz module A where ``` has AST ```haskell ( HsModule ( XModulePs ( EpAnn ( Anchor { :1:1 } ( UnchangedAnchor ) ) ( AnnsModule [ ( AddEpAnn AnnModule ( EpaSpan { :5:1-6 } ) ) , ( AddEpAnn AnnWhere ( EpaSpan { :5:10-14 } ) ) ] ( AnnList ( Nothing ) ( Nothing ) ( Nothing ) [] [] ) ) ( EpaCommentsBalanced [ ( L ( Anchor { :1:1-6 } ( UnchangedAnchor ) ) ( EpaComment ( EpaLineComment "-- foo" ) { :1:1 } ) ) , ( L ( Anchor { :2:1-2 } ( UnchangedAnchor ) ) ( EpaComment ( EpaLineComment "--" ) { :1:1-6 } ) ) , ( L ( Anchor { :3:1-8 } ( UnchangedAnchor ) ) ( EpaComment ( EpaDocComment ( MultiLineDocString ( HsDocStringGroup ( 1 ) ) ( :| ( L { :3:5-8 } ( HsDocStringChunk " bar" ) ) [] ) ) ) { :2:1-2 } ) ) , ( L ( Anchor { :4:1-8 } ( UnchangedAnchor ) ) ( EpaComment ( EpaDocComment ( MultiLineDocString ( HsDocStringGroup ( 1 ) ) ( :| ( L { :4:5-8 } ( HsDocStringChunk " baz" ) ) [] ) ) ) { :3:1-8 } ) ) ] [ ( L ( Anchor { :6:1 } ( UnchangedAnchor ) ) ( EpaComment ( EpaEofComment ) { :5:10-14 } ) ) ] ) ) ( VirtualBraces ( 1 ) ) ( Nothing ) ( Nothing ) ) ( Just ( L ( SrcSpanAnn ( EpAnnNotUsed ) { :5:8 } ) { ModuleName: A } ) ) ( Nothing ) [] [] ) ``` Note the `EpaDocComment`s for `bar` and `baz`, which are `HsDocStringGroup`s (the internal name for section headings).
tchoutri commented 1 year ago

Ah, that's a great explanation, thanks a bunch!