packages feed

dhall-docs 0.0.1 → 1.0.0

raw patch · 91 files changed

+1836/−711 lines, 91 filesdep +foldldep +lens-family-coredep +tasty-hunitdep ~basedep ~bytestringdep ~dhallPVP ok

version bump matches the API change (PVP)

Dependencies added: foldl, lens-family-core, tasty-hunit, turtle

Dependency ranges changed: base, bytestring, dhall, optparse-applicative, path, prettyprinter

API changes (from Hackage documentation)

+ Dhall.Docs: [characterSet] :: Options -> CharacterSet
+ Dhall.Docs.Core: BadPrefixesOnSingleLineComments :: CommentParseError
+ Dhall.Docs.Core: BadSingleLineCommentsAlignment :: CommentParseError
+ Dhall.Docs.Core: MissingNewlineOnBlockComment :: CommentParseError
+ Dhall.Docs.Core: SeveralSubseqDhallDocsComments :: CommentParseError
+ Dhall.Docs.Core: data CommentParseError
+ Dhall.Docs.Core: data DhallDocsText
+ Dhall.Docs.Core: parseComments :: String -> Text -> [DhallComment 'RawComment]
+ Dhall.Docs.Core: parseSingleDhallDocsComment :: String -> Text -> Maybe (Either [CommentParseError] DhallDocsText)
+ Dhall.Docs.Core: unDhallDocsText :: DhallDocsText -> Text
- Dhall.Docs: Options :: FilePath -> FilePath -> (Path Abs Dir -> Text) -> Options
+ Dhall.Docs: Options :: FilePath -> FilePath -> (Path Abs Dir -> Text) -> CharacterSet -> Options
- Dhall.Docs.Core: generateDocs :: Path Abs Dir -> Path Abs Dir -> Text -> IO ()
+ Dhall.Docs.Core: generateDocs :: Path Abs Dir -> Path Abs Dir -> Text -> CharacterSet -> IO ()
- Dhall.Docs.Core: generateDocsPure :: Text -> [(Path Rel File, Text)] -> GeneratedDocs [(Path Rel File, Text)]
+ Dhall.Docs.Core: generateDocsPure :: Text -> CharacterSet -> [(Path Rel File, ByteString)] -> GeneratedDocs [(Path Rel File, Text)]

Files

CHANGELOG.md view
@@ -1,3 +1,19 @@+1.0.0++* [Generate documentation from header comment](https://github.com/dhall-lang/dhall-haskell/pull/1929)+    * `dhall-docs` will now render a module header from a comment at+      the beginning of a Dhall file+    * The comment syntax is essentially markdown with the same whitespace+      and indentation rules as multi-line strings in Dhall+    * Both block comments and multiple single-line comments are supported+* [Jump to imports](https://github.com/dhall-lang/dhall-haskell/pull/1959)+    * The documentation will now generate links for relative and remote imports found within the+      rendered source code+* [Add support for non-`let` type annotations](https://github.com/dhall-lang/dhall-haskell/pull/1928)+    * `dhall-docs` can now also extract the type of a module from a type+      annotation on a bare expression (i.e. an expression that is not a+      `let` expression)+ 0.0.1 -* Project skeleton with command line options+* Initial beta release
dhall-docs.cabal view
@@ -1,5 +1,5 @@ Name: dhall-docs-Version: 0.0.1+Version: 1.0.0 Cabal-Version: >=1.10 Build-Type: Simple Tested-With: GHC == 8.6.1@@ -37,6 +37,9 @@     tasty/data/golden/a/b/*.html     tasty/data/golden/a/b/c/*.html     tasty/data/golden/deep/nested/folder/*.html+    tasty/data/comments/empty/*.txt+    tasty/data/comments/invalid/*.txt+    tasty/data/comments/valid/*.txt Data-Files:     *.css     *.js@@ -46,7 +49,7 @@  Source-Repository head     Type: git-    Location: https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-json+    Location: https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-docs   Flag ghci-data-files@@ -56,31 +59,35 @@ Library     Hs-Source-Dirs: src     Build-Depends:-        base                 >= 4.9.1.0  && < 5   ,-        bytestring                          < 0.11,-        containers                                ,-        directory            >= 1.3.0.0  && < 1.4 ,-        dhall                >= 1.32.0            ,-        file-embed           >= 0.0.10.0          ,-        filepath             >= 1.4      && < 1.5 ,-        lucid                >= 2.9.12   && < 2.10,-        mmark                >= 0.0.7.0  && < 0.8 ,-        megaparsec           >= 7        && < 8.1 ,-        path                 >= 0.7.0    && < 0.8 ,-        path-io              >= 1.6.0    && < 1.7 ,-        prettyprinter        >= 1.5.1    && < 1.7 ,-        tar                  >= 0.5.1.0  && < 0.6 ,-        text                 >= 0.11.1.0 && < 1.3 ,-        mtl                  >= 2.2.1    && < 2.3 ,-        optparse-applicative >= 0.14.0.0 && < 0.16+        base                 >= 4.11.0.0  && < 5   ,+        bytestring                           < 0.11,+        containers                                 ,+        directory            >= 1.3.0.0   && < 1.4 ,+        dhall                >= 1.34.0    && < 1.35,+        file-embed           >= 0.0.10.0           ,+        filepath             >= 1.4       && < 1.5 ,+        lens-family-core     >= 1.0.0     && < 2.2 ,+        lucid                >= 2.9.12    && < 2.10,+        mmark                >= 0.0.7.0   && < 0.8 ,+        megaparsec           >= 7         && < 8.1 ,+        path                 >= 0.7.0     && < 0.9 ,+        path-io              >= 1.6.0     && < 1.7 ,+        prettyprinter        >= 1.5.1     && < 1.8 ,+        tar                  >= 0.5.1.0   && < 0.6 ,+        text                 >= 0.11.1.0  && < 1.3 ,+        mtl                  >= 2.2.1     && < 2.3 ,+        optparse-applicative >= 0.14.0.0  && < 0.16     Exposed-Modules:         Dhall.Docs         Dhall.Docs.Core     Other-Modules:+        Dhall.Docs.CodeRenderer+        Dhall.Docs.Comment         Dhall.Docs.Embedded         Dhall.Docs.Html         Dhall.Docs.Markdown         Dhall.Docs.Store+        Dhall.Docs.Util         Paths_dhall_docs     GHC-Options: -Wall     Default-Language: Haskell2010@@ -119,15 +126,20 @@     Hs-Source-Dirs: tasty     Main-Is: Main.hs     Build-Depends:-        base                   ,-        containers             ,-        dhall-docs             ,-        HaXml        >= 1.25.5 ,-        path                   ,-        path-io                ,-        pretty       >= 1.1.1.1,-        tasty        <  1.4    ,-        tasty-silver <= 3.1.15 ,+        base                              ,+        bytestring                        ,+        containers                        ,+        dhall                             ,+        dhall-docs                        ,+        foldl        < 1.5                ,+        HaXml        >= 1.25.5            ,+        path                              ,+        path-io                           ,+        pretty       >= 1.1.1.1           ,+        tasty        <  1.4               ,+        tasty-silver <= 3.1.15            ,+        tasty-hunit  >= 0.10     && < 0.11,+        turtle       < 1.6                ,         text     GHC-Options: -Wall     Default-Language: Haskell2010
src/Dhall/Docs.hs view
@@ -17,9 +17,9 @@     ) where  import Control.Applicative ((<|>))-import Data.Monoid         ((<>)) import Data.Text           (Text) import Data.Version        (showVersion)+import Dhall.Pretty        (CharacterSet(..)) import Dhall.Docs.Core import Options.Applicative (Parser, ParserInfo) import Path                (Abs, Dir, Path)@@ -42,6 +42,7 @@         { packageDir :: FilePath         -- ^ Directory where your package resides         , docLink :: FilePath            -- ^ Link to the generated documentation         , resolvePackageName :: Path Abs Dir -> Text+        , characterSet :: CharacterSet         }     | Version @@ -63,8 +64,20 @@             )        <> Options.Applicative.value "./docs" )     <*> parsePackageNameResolver+    <*> parseAscii     ) <|> parseVersion   where+    switch name description =+        Options.Applicative.switch+            (   Options.Applicative.long name+            <>  Options.Applicative.help description+            )++    parseAscii = fmap f (switch "ascii" "Format rendered source code using only ASCII syntax")+      where+        f True  = ASCII+        f False = Unicode+     parseVersion =         Options.Applicative.flag'             Version@@ -117,7 +130,7 @@          resolvedDocLink <- Path.IO.resolveDir' docLink         let packageName = resolvePackageName resolvedPackageDir-        generateDocs resolvedPackageDir resolvedDocLink packageName+        generateDocs resolvedPackageDir resolvedDocLink packageName characterSet     Version ->         putStrLn (showVersion Meta.version) 
+ src/Dhall/Docs/CodeRenderer.hs view
@@ -0,0 +1,183 @@+{-# LANGUAGE NamedFieldPuns    #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}++{-| Contains the logic to render the source code inside a HTML. It also provides+    context-sensitive features such as jump-to-definition+-}+module Dhall.Docs.CodeRenderer+    ( renderCodeWithHyperLinks+    , renderCodeSnippet+    , ExprType(..)+    ) where++import Data.Text       (Text)+import Data.Void       (Void)+import Dhall.Core+    ( Expr (..)+    , File (..)+    , FilePrefix (..)+    , Import (..)+    , ImportHashed (..)+    , ImportType (..)+    , Scheme (..)+    , URL (..)+    )+import Dhall.Docs.Util+import Dhall.Src       (Src (..))+import Lucid++import qualified Data.Text+import qualified Data.Text.Prettyprint.Doc             as Pretty+import qualified Data.Text.Prettyprint.Doc.Render.Text as Pretty.Text+import qualified Dhall.Core                            as Core+import qualified Dhall.Parser+import qualified Dhall.Pretty+import qualified Lens.Family                           as Lens+import qualified Text.Megaparsec.Pos                   as SourcePos++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Dhall.Core (Directory (..))++-- | Given a Dhall expression return all imports with their location on the file.+--   Contents are already sorted by 'Src', which allows 'renderAsHtml' to traverse+--   the return of this function to inject anchors+getImports :: Expr Src Import -> [(Src, Import)]+getImports (Note src (Embed a)) = [(src, a)]+getImports expr = concatMap getImports $ Lens.toListOf Core.subExpressions expr++fileAsText :: File -> Text+fileAsText File{..} = foldr (\d acc -> acc <> "/" <> d) "" (Core.components directory)+    <> "/" <> file++{-| Given an 'Import', render the contents in an HTML element that will allow+    users to jump to another file or domain. The 'Text' argument is the contents+    inside the anchor tag++    Example:++    >>> :set -Wno-missing-fields+    >>> let file = File { directory = Directory [], file = ""}+    >>> let url = URL { scheme = HTTPS, authority = "google.com", query = Nothing, path = file}+    >>> let import_ = Import {importHashed = ImportHashed { importType = Remote url }}+    >>> renderImport import_ "link for google"+    <a href="https://google.com/" target="_blank">link for google</a>+-}+renderImport :: Import -> Text -> Html ()+renderImport (Import {importHashed = ImportHashed { importType }}) =+    case importType of+        Remote URL {..} -> a_ [href_ href, target_ "_blank"] . toHtml+          where+            scheme_ = case scheme of+                HTTP -> "http"+                HTTPS -> "https"++            path_ = fileAsText path++            query_ = case query of+                Nothing -> ""+                Just d -> "?" <> d++            -- we don't include the headers here since we treat links to open a file+            -- in another tab+            href = scheme_ <> "://" <> authority <> path_ <> query_++        Local Here file -> a_ [href_ href] . toHtml+          where+            href = "." <> fileAsText file <> ".html"++        Local Parent file -> a_ [href_ href] . toHtml+          where+            href = ".." <> fileAsText file <> ".html"++        _ -> toHtml++-- | Given a Text and the parsed `Expr Src Import` from it, this will render the+--   the source code on HTML with jump-to-definition on URL imports. Use this+--   to render the source code with the same structure (whitespaces, comments,+--   language elements) as the source file+renderCodeWithHyperLinks :: Text -> Expr Src Import -> Html ()+renderCodeWithHyperLinks contents expr = pre_ $ go (1, 1) (Data.Text.lines contents) imports+  where+    imports = getImports expr++    -- we keep the current line, column and consumed text as part of function argument+    go :: (Int, Int) -> [Text] -> [(Src, Import)] -> Html ()+    go _ textLines [] = mapM_ (\t -> toHtml t >> br_ []) textLines+    go (currLine, currCol) currentLines ((Src {..}, import_) : rest) = do+        let sourceLine = SourcePos.unPos . SourcePos.sourceLine+        let sourceColumn = SourcePos.unPos . SourcePos.sourceColumn++        let importStartLine = sourceLine srcStart+        let importEndLine = sourceLine srcEnd++        let importStartCol = sourceColumn srcStart+        let importEndCol = sourceColumn srcEnd++        let (prefixLines, restLines) = splitAt (importStartLine - currLine) currentLines+        let (importLines, suffixLines) = splitAt (importStartLine - importStartLine + 1) restLines++        -- calls to `head` and `last` here should never fail since `importLines`+        -- have at least one element+        let (firstImportLine, lastImportLine) = (head importLines, last importLines)+        let prefixCols = Data.Text.take (importStartCol - currCol) firstImportLine+        let suffixCols = Data.Text.drop (importEndCol - currCol) lastImportLine++        -- prefix lines and columns+        mapM_ (\t -> toHtml t >> br_ []) prefixLines+        toHtml prefixCols++        -- rendered import+        renderImport import_ srcText++        -- add a newline if last line of import consumes the remaining line on+        -- the original text+        if Data.Text.null suffixCols then br_ [] else return ()++        let suffix = if Data.Text.null suffixCols then suffixLines else suffixCols : suffixLines++        -- move the cursor to next line if no characterse are remaining on the+        -- suffix cols, otherwise keep the last line and next char right after+        -- the import. This is done to handle properly several imports on the+        -- same line+        let nextPosition = if Data.Text.null suffixCols then+                               (importEndLine + 1, 1)+                           else (importEndLine, importEndCol)++        go nextPosition suffix rest++-- | Internal utility to differentiate if a Dhall expr is a type annotation+--   or the whole file+data ExprType = TypeAnnotation | AssertionExample++-- | Renders an AST /fragment/ from the source file AST. Use this only for that+--   purpose. The difference between this and 'renderCodeWithHyperLinks' is because that+--   the extracted fragment's 'SourcePos's need to be re-generated to+--   render them in a better way; just adding whitespace at the beginning of the+--   first line won't render good results.+renderCodeSnippet :: Dhall.Pretty.CharacterSet -> ExprType -> Expr Void Import -> Html ()+renderCodeSnippet characterSet exprType expr = renderCodeWithHyperLinks formattedFile expr'+  where+    layout = case exprType of+        AssertionExample -> Dhall.Pretty.layout+        TypeAnnotation -> typeLayout++    formattedFile = Pretty.Text.renderStrict+        $ layout+        $ Dhall.Pretty.prettyCharacterSet characterSet (Core.denote expr)++    expr' = case Dhall.Parser.exprFromText "" formattedFile of+        Right e -> e+        Left _ -> fileAnIssue "A failure has occurred while parsing a formatted file"++    typeLayout :: Pretty.Doc ann -> Pretty.SimpleDocStream ann+    typeLayout = Pretty.removeTrailingWhitespace . Pretty.layoutSmart opts+      where+        -- this is done so the type of a dhall file fits in a single line+        -- its a safe value, since types in source codes are not that large+        opts :: Pretty.LayoutOptions+        opts = Pretty.defaultLayoutOptions+                { Pretty.layoutPageWidth =+                    Pretty.Unbounded+                }
+ src/Dhall/Docs/Comment.hs view
@@ -0,0 +1,248 @@+{-| Provides utilities to parse Dhall comments+-}++{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE KindSignatures    #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns      #-}++module Dhall.Docs.Comment+    ( parseComments+    , CommentParseError(..)+    , DhallDocsText+    , parseSingleDhallDocsComment+    , unDhallDocsText+    ) where++import Control.Applicative (many, some, (<|>))+import Data.Functor        (void)+import Data.List.NonEmpty  (NonEmpty (..), (<|))+import Data.Text           (Text)+import Dhall.Docs.Util+import Dhall.Parser        (Parser (..))+import Text.Megaparsec     (SourcePos, (<?>))++import qualified Data.Either+import qualified Data.Foldable+import qualified Data.List.NonEmpty      as NonEmpty+import qualified Data.Maybe              as Maybe+import qualified Data.Text+import qualified Dhall.Parser.Expression as Expression+import qualified Dhall.Parser.Token      as Token+import qualified Text.Megaparsec+import qualified Text.Megaparsec.Pos     as Megaparsec.Pos++-- | For explanation of this data-type see 'DhallComment'+data CommentType = DhallDocsComment | MarkedComment | RawComment++type ListOfSingleLineComments = NonEmpty (SourcePos, Text)++{-| Internal representation of Dhall comments. Text is always stripped from+    whitespace from both the start and begin of the string++    * If @a = 'DhallDocsComment'@ then comment is valid to extract its contents+    and be rendered on documentation+    * If @a = 'MarkedComment'@ then comment has the @|@ marker that+    @dhall-docs@ will be aware of, but this comment may not be a @dhall-docs@+    comment+    * If @a = `RawComment`@ then the comment is a raw comment+-}+data DhallComment (a :: CommentType)+    -- | A single block comment: starting from @{-@ and ending in @-}@+    = BlockComment Text+    {-| A group of subsequent single line comment, each one starting from @--@+        and ending in the last character to the end of the line. Each one keeps+        its 'SourcePos' to validate indentation.++        A property of 'SingleLineComments' is that the 'sourceLine's in the+        'NonEmpty (SourcePos, Text)' are in strictly-increasing order /and/+        the difference between the 'sourceLine' of any adyacent pair is @1@.++        Note that several @dhall-docs@ comments maybe inside a single 'SingleLineComments'+    -}+    | SingleLineComments ListOfSingleLineComments+    deriving Show++-- | Extracted text from a valid @dhall-docs@ comment+newtype DhallDocsText = DhallDocsText Text+    deriving Show++unDhallDocsText :: DhallDocsText -> Text+unDhallDocsText (DhallDocsText t) = t++-- | A mirror of "Dhall.Parser.Token".'Dhall.Parser.Token.lineComment' but+--   returning a 'DhallComment'+lineCommentParser :: Parser (NonEmpty (DhallComment 'RawComment))+lineCommentParser = do+    (l : ls) <- some singleLine+    pure $ NonEmpty.map SingleLineComments $ groupComments (l :| ls)+  where+    groupComments :: ListOfSingleLineComments -> NonEmpty ListOfSingleLineComments+    groupComments ls = case NonEmpty.nonEmpty remaining of+        Nothing -> g :| []+        Just l -> g <| groupComments l+      where+        lineNumber = Megaparsec.Pos.unPos . Megaparsec.Pos.sourceLine++        (g, remaining) = removeSubseq ls+        removeSubseq :: ListOfSingleLineComments -> (ListOfSingleLineComments, [(SourcePos, Text)])+        removeSubseq (x :| []) = (x :| [], [])+        removeSubseq (x@(xPos, _) :| ys@(y@(yPos, _) : rest))+            | lineNumber yPos - lineNumber xPos == 1+                = let (subSeq, r) = removeSubseq (y :| rest) in (x <| subSeq, r)+            | otherwise = (x :| [], ys)++    singleLine = do+      sourcePos <- Expression.getSourcePos+      commentLine <- Token.lineComment+      whitespace+      pure (sourcePos, commentLine)++-- | Consume whitespace lines or lines that only have whitespaces *before* a comment+whitespace :: Parser ()+whitespace = Text.Megaparsec.skipMany (Text.Megaparsec.choice+    [ void (Text.Megaparsec.takeWhile1P Nothing predicate)+    , void (Token.text "\r\n")+    ] <?> "whitespace")+  where+    predicate c = c == ' ' || c == '\t' || c == '\n'++blockCommentParser :: Parser (DhallComment 'RawComment)+blockCommentParser = do+    c <- Token.blockComment+    whitespace+    pure $ BlockComment c++-- | Parse all comments in a text fragment+parseComments :: String -> Text -> [DhallComment 'RawComment]+parseComments delta text = case result of+    Left err -> error ("An error has occurred while parsing comments:\n "+      <> Text.Megaparsec.errorBundlePretty err)+    Right comments -> comments+  where+    parser = do+        comments <- many $ do+            whitespace+            lineCommentParser <|> ((:| []) <$> blockCommentParser)+        Text.Megaparsec.eof+        pure $ concatMap NonEmpty.toList comments++    result = Text.Megaparsec.parse (unParser parser) delta text++data CommentParseError+    = MissingNewlineOnBlockComment+    | BadSingleLineCommentsAlignment+    | BadPrefixesOnSingleLineComments+    | SeveralSubseqDhallDocsComments+    deriving Show++-- | Checks if a 'RawComment' has the @dhall-docs@ marker+parseMarkedComment :: DhallComment 'RawComment -> Maybe (DhallComment 'MarkedComment)+parseMarkedComment (BlockComment comment)+    | "{-|" `Data.Text.isPrefixOf` comment = Just $ BlockComment comment+    | otherwise = Nothing++parseMarkedComment (SingleLineComments ls)+    | any (("--|" `Data.Text.isPrefixOf`) . snd) ls = Just (SingleLineComments ls)+    | otherwise = Nothing++-- | Knowing that there is a @dhall-docs@ marker inside the comment, this+--   checks if a 'MarkedComment' is a 'DhallDocsComment'. For 'SingleLineComments'+--   this also removes the prefix lines before the first marked comment+parseDhallDocsComment :: DhallComment 'MarkedComment -> Either CommentParseError (DhallComment 'DhallDocsComment)+parseDhallDocsComment (BlockComment comment) =+    if any (`Data.Text.isPrefixOf` comment) ["{-|\n", "{-|\r\n"] then Right $ BlockComment comment+    else Left MissingNewlineOnBlockComment++parseDhallDocsComment (SingleLineComments lineComments) =+    fmap SingleLineComments $ checkAlignment lineComments >>= checkAmountOfMarkers >>= checkPrefixes+  where+    sourceCol = Text.Megaparsec.unPos . Text.Megaparsec.sourceColumn++    checkAmountOfMarkers :: ListOfSingleLineComments -> Either CommentParseError ListOfSingleLineComments+    checkAmountOfMarkers ls =+        if numberOfMarkers > 1 then Left SeveralSubseqDhallDocsComments+        else case newLines of+            [] -> fileAnIssue "checkAmountOfMarkers failed with newLines = []"+            l : remainder -> Right $ l :| remainder+      where+        commentLines = NonEmpty.toList ls+        numberOfMarkers = length $ filter (Data.Text.isPrefixOf "--|" . snd) commentLines+        (_, newLines) = break (Data.Text.isPrefixOf "--|" . snd) commentLines++    checkAlignment :: ListOfSingleLineComments -> Either CommentParseError ListOfSingleLineComments+    checkAlignment ls@((first, _) :| rest)+        | all ((== sourceCol first) . sourceCol . fst) rest = Right ls+        | otherwise = Left BadSingleLineCommentsAlignment++    checkPrefixes :: ListOfSingleLineComments -> Either CommentParseError ListOfSingleLineComments+    checkPrefixes ls@((_, first) :| rest)+        | "--| " `Data.Text.isPrefixOf` first && all (p . snd) rest+            = Right ls+        | otherwise = Left BadPrefixesOnSingleLineComments+      where+        p t = Data.Text.isPrefixOf "--  " t || (Data.Text.compareLength t 2 == EQ && "--" == t)++parseDhallDocsText :: DhallComment 'DhallDocsComment -> DhallDocsText+parseDhallDocsText (BlockComment blockComment) =+    case Data.Text.stripSuffix "-}" joinedText of+        Nothing -> fileAnIssue ("Obtained 'Nothing' on extractText.stripSuffix with text: \"" <> joinedText <> "\"")+        Just e -> DhallDocsText e+  where+    joinedText = Data.Text.strip $ Data.Text.unlines reIndentedLines+    (_ : commentLines) = Data.Text.lines blockComment++    leadingSpaces = Data.Text.takeWhile isSpace+        where+        isSpace t = t == ' ' || t == '\t'++    nonEmptyCommentLines = filter (not . Data.Text.null) commentLines++    commonIndentation = Data.Text.length $+        case map leadingSpaces nonEmptyCommentLines of+            l : ls -> Data.Foldable.foldl' sharedPrefix l ls+            []     -> ""+        where+        sharedPrefix ab ac =+            case Data.Text.commonPrefixes ab ac of+                Just (a, _, _) -> a+                Nothing          -> ""++    reIndentedLines = map (Data.Text.drop commonIndentation) commentLines++parseDhallDocsText (SingleLineComments (fmap snd -> (first :| rest))) =+    DhallDocsText $ Data.Text.unlines $ firstLine : map cleanRest rest+  where+    debugLines = Data.Text.unlines (first : rest)+    firstLine = case Data.Text.stripPrefix "--| " first of+        Nothing -> fileAnIssue $+            "Error strippping \"--| \" prefix on parseDhallDocsText. " <>+            "All comment lines are here:\n" <> debugLines++        Just s -> s++    cleanRest l = case Data.Text.stripPrefix "--  " l <|> Data.Text.stripPrefix "--" l of+        Nothing -> fileAnIssue $+            "Error strippping \"--  \" prefix on parseDhallDocsText. " <>+            "All comment lines are here:\n" <> debugLines++        Just s -> s++-- | Returns 'Nothing' when 'DhallDocsComment' was parsed or no error was detected+parseSingleDhallDocsComment :: String -> Text -> Maybe (Either [CommentParseError] DhallDocsText)+parseSingleDhallDocsComment delta text = do+    let rawComments = parseComments delta text+    let markedComments = Maybe.mapMaybe parseMarkedComment rawComments+    let (errors_, dhallDocsComments) = Data.Either.partitionEithers $ map parseDhallDocsComment markedComments++    let errors =+                if length dhallDocsComments >= 2 then+                    SeveralSubseqDhallDocsComments : errors_+                else+                    errors_++    case (errors, dhallDocsComments) of+        ([] ,  []) -> Nothing+        (_:_,   _) -> Just $ Left errors+        (_  , [a]) -> Just $ Right $ parseDhallDocsText a+        (_  ,   _) -> fileAnIssue "Returned more than one comment at parseSingleDhallDocsComment"
src/Dhall/Docs/Core.hs view
@@ -4,7 +4,6 @@     To do so, just wrap your function in `IO` if you need to do I/O operations,     and make pure functions receive that IO result as an input -}-{-# LANGUAGE CPP                   #-} {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns        #-}@@ -12,14 +11,24 @@ {-# LANGUAGE RecordWildCards       #-} {-# LANGUAGE TemplateHaskell       #-} {-# LANGUAGE TupleSections         #-}+{-# LANGUAGE ViewPatterns          #-} -- {-# OPTIONS_GHC -Wno-unused-imports #-} -module Dhall.Docs.Core (generateDocs, generateDocsPure, GeneratedDocs(..)) where+module Dhall.Docs.Core+    ( -- * Core functionality+      generateDocs+    , generateDocsPure+    , GeneratedDocs(..) +      -- * Comment parsing+    , module Dhall.Docs.Comment+    ) where++import Control.Applicative        (Alternative (..)) import Control.Monad.Writer.Class (MonadWriter)+import Data.ByteString            (ByteString) import Data.Function              (on) import Data.Map.Strict            (Map)-import Data.Monoid                ((<>)) import Data.Text                  (Text) import Data.Void                  (Void) import Dhall.Core@@ -30,6 +39,7 @@     , Var (..)     , denote     )+import Dhall.Docs.Comment import Dhall.Docs.Embedded import Dhall.Docs.Html import Dhall.Docs.Markdown@@ -39,6 +49,7 @@     , ParseError (..)     , exprAndHeaderFromText     )+import Dhall.Pretty               (CharacterSet) import Dhall.Src                  (Src) import Path                       (Abs, Dir, File, Path, Rel, (</>)) import Text.Megaparsec            (ParseErrorBundle (..))@@ -47,13 +58,13 @@ import qualified Control.Monad import qualified Control.Monad.Writer.Class as Writer import qualified Data.ByteString-import qualified Data.Either import qualified Data.List import qualified Data.List.NonEmpty         as NonEmpty import qualified Data.Map.Strict            as Map import qualified Data.Maybe import qualified Data.Maybe                 as Maybe import qualified Data.Text+import qualified Data.Text.Encoding import qualified Data.Text.IO               as Text.IO import qualified Data.Text.Lazy             as Text.Lazy import qualified Dhall.Core@@ -92,29 +103,57 @@ data DocsGenWarning     = InvalidDhall (Text.Megaparsec.ParseErrorBundle Text Void)     | InvalidMarkdown MarkdownParseError+    | DhallDocsCommentError (Path Rel File) CommentParseError +warn :: String+warn = "\n\ESC[1;33mWarning\ESC[0m: "+ instance Show DocsGenWarning where     show (InvalidDhall err) =-        "\n\ESC[1;33mWarning\ESC[0m: Invalid Input\n\n" <>+        warn <> "Invalid Input\n\n" <>         Text.Megaparsec.errorBundlePretty err <>         "... documentation won't be generated for this file"      show (InvalidMarkdown MarkdownParseError{..}) =-        "\n\ESC[1;33mWarning\ESC[0m: Header comment is not markdown\n\n" <>+        warn <>"Header comment is not markdown\n\n" <>         Text.Megaparsec.errorBundlePretty unwrap <>         "The original non-markdown text will be pasted in the documentation" +    show (DhallDocsCommentError path err) =+        warn <> Path.fromRelFile path <> specificError+      where+        specificError = case err of+            MissingNewlineOnBlockComment -> ": After the `|` marker of a block comment " <>+                "there must be a newline (either \\n or \\r\\n)"++            SeveralSubseqDhallDocsComments -> ": Two dhall-docs comments in the same " <>+                "comment section are forbidden"++            BadSingleLineCommentsAlignment -> ": dhall-docs's single line comments " <>+                "must be aligned"++            BadPrefixesOnSingleLineComments -> ": dhall-docs's single line comments " <>+                "must have specific prefixes:" <>+                "* For the first line: \"--| \"\n" <>+                "* For the rest of the linse: \"--  \""++-- | Extracted text from from Dhall file's comments+newtype FileComments = FileComments+    { headerComment :: Maybe DhallDocsText -- ^ 'Nothing' if no comment or if invalid+    }+ -- | Represents a Dhall file that can be rendered as documentation. --   If you'd like to improve or add features to a .dhall documentation page, --   add that extra information here. data DhallFile = DhallFile     { path :: Path Rel File             -- ^ Path of the file-    , expr :: Expr Src Import           -- ^ File contents-    , header :: Header                  -- ^ Parsed `Header` of the file+    , contents :: Text                  -- ^ File contents+    , expr :: Expr Src Import           -- ^ Parsed AST from 'contents'     , mType :: Maybe (Expr Void Import) -- ^ Type of the parsed expression,                                         --   extracted from the source code     , examples :: [Expr Void Import]    -- ^ Examples extracted from assertions                                         --   in the file+    , fileComments :: FileComments     }  {-| Takes a list of files paths with their contents and returns the list of@@ -125,34 +164,43 @@      The result is sorted by `path` -}-getAllDhallFiles :: [(Path Rel File, Text)] -> GeneratedDocs [DhallFile]-getAllDhallFiles = emitErrors . map toDhallFile . filter hasDhallExtension+getAllDhallFiles :: [(Path Rel File, ByteString)] -> GeneratedDocs [DhallFile]+getAllDhallFiles = fmap Maybe.catMaybes . mapM toDhallFile . foldr validFiles [] . filter hasDhallExtension   where-    hasDhallExtension :: (Path Rel File, Text) -> Bool+    hasDhallExtension :: (Path Rel File, a) -> Bool     hasDhallExtension (absFile, _) = case Path.splitExtension absFile of         Nothing -> False         Just (_, ext) -> ext == ".dhall" -    toDhallFile :: (Path Rel File, Text) -> Either DocsGenWarning DhallFile+    validFiles :: (Path Rel File, ByteString) -> [(Path Rel File, Text)] -> [(Path Rel File, Text)]+    validFiles (relFile, content) xs = case Data.Text.Encoding.decodeUtf8' content of+        Left _ -> xs+        Right textContent -> (relFile, textContent) : xs++    toDhallFile :: (Path Rel File, Text) -> GeneratedDocs (Maybe DhallFile)     toDhallFile (relFile, contents) =         case exprAndHeaderFromText (Path.fromRelFile relFile) contents of-            Right (header, expr) ->-                let denoted = denote expr :: Expr Void Import in-                Right DhallFile-                    { path = relFile-                    , expr, header+            Right (Header header, expr) -> do+                let denoted = denote expr :: Expr Void Import++                headerContents <-+                    case parseSingleDhallDocsComment (Path.fromRelFile relFile) header of+                        Nothing -> return Nothing+                        Just (Left errs) -> do+                            Writer.tell $ map (DhallDocsCommentError relFile) errs+                            return Nothing+                        Just (Right c) -> return $ Just c++                return $ Just $ DhallFile+                    { expr, contents+                    , path = relFile                     , mType = extractTypeIfInSource denoted                     , examples = examplesFromAssertions denoted+                    , fileComments = FileComments headerContents                     }-            Left ParseError{..} ->-                Left $ InvalidDhall unwrap--    emitErrors :: [Either DocsGenWarning DhallFile] -> GeneratedDocs [DhallFile]-    emitErrors errorsOrDhallFiles = do-        let (errors, dhallFiles) = Data.Either.partitionEithers errorsOrDhallFiles-        Writer.tell errors-        let sortedDhallFiles = Data.List.sortBy (compare `on` path) dhallFiles-        return sortedDhallFiles+            Left ParseError{..} -> do+                Writer.tell [InvalidDhall unwrap]+                return Nothing      bindings :: Expr Void Import -> [Binding Void Import]     bindings expr = case expr of@@ -161,14 +209,21 @@             in NonEmpty.toList bs         _ -> [] -     extractTypeIfInSource :: Expr Void Import -> Maybe (Expr Void Import)-    extractTypeIfInSource expr = do-        V name index <- maybeNameInLet expr-        (Binding _ _ _ (Just (_, exprType)) _ _) <--            getLetBindingWithIndex index $ getLetBindingsWithName name-        return exprType+    extractTypeIfInSource expr =+            fromOrdinaryAnnotation expr+        <|> fromLetBindingAnnotation       where+        fromOrdinaryAnnotation (Let _ e)    = fromOrdinaryAnnotation e+        fromOrdinaryAnnotation (Annot _ _T) = pure _T+        fromOrdinaryAnnotation  _           = empty++        fromLetBindingAnnotation = do+            V name index <- maybeNameInLet expr+            (Binding _ _ _ (Just (_, exprType)) _ _) <-+                getLetBindingWithIndex index $ getLetBindingsWithName name+            return exprType+         -- | For an expression of the form @let x0 = y0 let x1 = y1 ... in e@         --   where @e@ is a variable, maybeNameInLet returns the variable name.         maybeNameInLet :: Expr Void Import -> Maybe Var@@ -177,7 +232,7 @@         maybeNameInLet _ = Nothing  -        {-| For an expression of the form @let x0 = y0 x1 = y1 ... in e@+        {-| For an expression of the form @let x0 = y0 let x1 = y1 ... in e@             and a variable name @v@, this returns every @xi@ that is equal to             v in the reverse order of the source code. @@ -214,6 +269,7 @@         fromAssertion (Assert e) =  Just e         fromAssertion _ = Nothing + {-| Given a relative path, returns as much @..\/@ misdirections as needed     to go to @.@ @@ -230,15 +286,16 @@         "." -> ""         _ -> "../" <> resolveRelativePath (Path.parent currentDir) -{-| Generates `Text` from the html representation of a `DhallFile`+{-| Generates `Text` from the HTML representation of a `DhallFile` -} makeHtml     :: Text                 -- ^ Package name+    -> CharacterSet         -- ^ Output encoding     -> DhallFile            -- ^ Parsed header     -> GeneratedDocs Text-makeHtml packageName DhallFile {..} = do+makeHtml packageName characterSet DhallFile {..} = do     let relativeResourcesPath = resolveRelativePath $ Path.parent path-    let strippedHeader = stripCommentSyntax header+    let strippedHeader = Maybe.maybe "" unDhallDocsText (headerComment fileComments)     headerAsHtml <-         case markdownToHtml path strippedHeader of             Left err -> do@@ -248,23 +305,13 @@      let htmlAsText = Text.Lazy.toStrict $ Lucid.renderText $ dhallFileToHtml             path+            contents             expr             examples             headerAsHtml-            DocParams { relativeResourcesPath, packageName }+            DocParams { relativeResourcesPath, packageName, characterSet }      return htmlAsText-  where-    stripCommentSyntax :: Header -> Text-    stripCommentSyntax (Header h)-        | Just s <- Data.Text.stripPrefix "--" strippedHeader-            = Data.Text.strip s-        | Just commentPrefixStripped <- Data.Text.stripPrefix "{-" strippedHeader-        , Just commentSuffixStripped <- Data.Text.stripSuffix "-}" commentPrefixStripped-            = Data.Text.strip commentSuffixStripped-        | otherwise = strippedHeader-      where-        strippedHeader = Data.Text.strip h  {-| Create an @index.html@ file on each available folder in the input. @@ -284,23 +331,22 @@     @a/b/c@ and no @index.html@ should be generated inside of `a/` or     `a/b/`, but yes on `a/b/c/` in the last one there is the @b.dhall@ file -}-createIndexes :: Text -> [DhallFile] -> [(Path Rel File, Text)]-createIndexes packageName files = map toIndex dirToDirsAndFilesMapAssocs+createIndexes :: Text -> CharacterSet -> [DhallFile] -> [(Path Rel File, Text)]+createIndexes packageName characterSet files = map toIndex dirToDirsAndFilesMapAssocs   where     -- Files grouped by their directory     dirToFilesMap :: Map (Path Rel Dir) [DhallFile]-    dirToFilesMap = Map.unionsWith (<>) $ map toMap files+    dirToFilesMap = Map.unionsWith (<>) $ map toMap $ Data.List.sortBy (compare `on` path) files       where         toMap :: DhallFile -> Map (Path Rel Dir) [DhallFile]-        toMap dhallFile =-            Map.singleton (Path.parent $ path dhallFile) [dhallFile]+        toMap dhallFile = Map.singleton (Path.parent $ path dhallFile) [dhallFile]      {-  This is used to compute the list of exported packages on each folder.         We try to compress the folders as much as we can. See `createIndexes`         documentation to get more information.     -}     dirToDirsMap :: Map (Path Rel Dir) [Path Rel Dir]-    dirToDirsMap = Map.map removeHereDir $ foldl go initialMap dirs+    dirToDirsMap = Map.map removeHereDir $ foldr go initialMap dirs       where         -- > removeHeredir [$(mkRelDir "a"), $(mkRelDir ".")]         --   [$(mkRelDir "a")]@@ -316,8 +362,8 @@         initialMap :: Map (Path Rel Dir) [Path Rel Dir]         initialMap = Map.fromList $ map (,[]) dirs -        go :: Map (Path Rel Dir) [Path Rel Dir] -> Path Rel Dir -> Map (Path Rel Dir) [Path Rel Dir]-        go dirMap d = Map.adjust ([d] <>) (key $ Path.parent d) dirMap+        go :: Path Rel Dir -> Map (Path Rel Dir) [Path Rel Dir] -> Map (Path Rel Dir) [Path Rel Dir]+        go d dirMap = Map.adjust ([d] <>) (key $ Path.parent d) dirMap           where             key :: Path Rel Dir -> Path Rel Dir             key dir = if dir `Map.member` dirMap then dir else key $ Path.parent dir@@ -338,7 +384,7 @@             indexDir             (map (\DhallFile{..} -> (stripPrefix $ addHtmlExt path, mType)) dhallFiles)             (map stripPrefix dirs)-            DocParams { relativeResourcesPath = resolveRelativePath indexDir, packageName }+            DocParams { relativeResourcesPath = resolveRelativePath indexDir, packageName, characterSet }          stripPrefix :: Path Rel a -> Path Rel a         stripPrefix relpath =@@ -355,7 +401,7 @@ -- https://docs.github.com/en/github/managing-your-work-on-github/about-automation-for-issues-and-pull-requests-with-query-parameters fileAnIssue :: Text -> a fileAnIssue titleName =-    error $ "\ESC[1;31mError\ESC[0mDocumentation generator bug\n\n" <>+    error $ "\ESC[1;31mError\ESC[0m Documentation generator bug\n\n" <>              "Explanation: This error message means that there is a bug in the " <>             "Dhall Documentation generator. You didn't did anything wrong, but " <>@@ -378,12 +424,13 @@     :: Path Abs Dir -- ^ Input directory     -> Path Abs Dir -- ^ Link to be created to the generated documentation     -> Text         -- ^ Package name, used in some HTML titles+    -> CharacterSet -- ^ Output encoding     -> IO ()-generateDocs inputDir outLink packageName = do+generateDocs inputDir outLink packageName characterSet = do     (_, absFiles) <- Path.IO.listDirRecur inputDir-    contents <- mapM (Text.IO.readFile . Path.fromAbsFile) absFiles+    contents <- mapM (Data.ByteString.readFile . Path.fromAbsFile) absFiles     strippedFiles <- mapM (Path.stripProperPrefix inputDir) absFiles-    let GeneratedDocs warnings docs = generateDocsPure packageName $ zip strippedFiles contents+    let GeneratedDocs warnings docs = generateDocsPure packageName characterSet $ zip strippedFiles contents     mapM_ print warnings     if null docs then         putStrLn $@@ -422,14 +469,14 @@ -} generateDocsPure     :: Text                    -- ^ Package name-    -> [(Path Rel File, Text)] -- ^ (Input file, contents)+    -> CharacterSet            -- ^ Output encoding+    -> [(Path Rel File, ByteString)] -- ^ (Input file, contents)     -> GeneratedDocs [(Path Rel File, Text)]-generateDocsPure packageName inputFiles = go+generateDocsPure packageName characterSet inputFiles = go   where     go :: GeneratedDocs [(Path Rel File, Text)]     go = do         dhallFiles <- getAllDhallFiles inputFiles-        htmls <- mapM (makeHtml packageName) dhallFiles-        let indexes = createIndexes packageName dhallFiles+        htmls <- mapM (makeHtml packageName characterSet) dhallFiles+        let indexes = createIndexes packageName characterSet dhallFiles         return (zip (map (addHtmlExt . path) dhallFiles) htmls <> indexes)-
src/Dhall/Docs/Embedded.hs view
@@ -29,7 +29,7 @@  getDataDir :: IO [(Path Rel File, ByteString)] #if defined(EMBED)-getDataDir = return $(embedDir "src/Dhall/data") >>= mapM f+getDataDir = mapM f $(embedDir "src/Dhall/data")   where     f :: (FilePath, ByteString) -> IO (Path Rel File, ByteString)     f (filePath, contents) = (,contents) <$> Path.parseRelFile filePath
src/Dhall/Docs/Html.hs view
@@ -17,95 +17,43 @@     , DocParams(..)     ) where -import Data.Monoid  ((<>))-import Data.Text    (Text)-import Data.Void    (Void)-import Dhall.Core   (Expr, Import)-import Dhall.Pretty (Ann (..))-import Dhall.Src    (Src)+import Data.Text               (Text)+import Data.Void               (Void)+import Dhall.Core              (Expr, Import)+import Dhall.Docs.CodeRenderer+import Dhall.Pretty            (CharacterSet)+import Dhall.Src               (Src) import Lucid-import Path         (Dir, File, Path, Rel)+import Path                    (Dir, File, Path, Rel)  import qualified Control.Monad import qualified Data.Foldable import qualified Data.Text-import qualified Data.Text.Prettyprint.Doc                           as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Util.SimpleDocTree as Pretty-import qualified Dhall.Pretty import qualified Path-import qualified System.FilePath                                     as FilePath+import qualified System.FilePath as FilePath  -- $setup -- >>> :set -XQuasiQuotes -- >>> import Path (reldir, relfile) --- | Internal utility to differentiate if a Dhall expr is a type annotation---   or the whole file-data ExprType = TypeAnnotation | FileContentsExpr---exprToHtml :: ExprType -> Expr a Import -> Html ()-exprToHtml exprType expr = pre_ $ renderTree prettyTree-  where-    layout = case exprType of-        FileContentsExpr -> Dhall.Pretty.layout-        TypeAnnotation -> typeLayout--    prettyTree = Pretty.treeForm-        $ layout-        $ Dhall.Pretty.prettyExpr expr--    textSpaces :: Int -> Text-    textSpaces n = Data.Text.replicate n (Data.Text.singleton ' ')--    renderTree :: Pretty.SimpleDocTree Ann -> Html ()-    renderTree sds = case sds of-        Pretty.STEmpty -> return ()-        Pretty.STChar c -> toHtml $ Data.Text.singleton c-        Pretty.STText _ t -> toHtml t-        Pretty.STLine i -> br_ [] >> toHtml (textSpaces i)-        Pretty.STAnn ann content -> encloseInTagFor ann (renderTree content)-        Pretty.STConcat contents -> foldMap renderTree contents--    encloseInTagFor :: Ann -> Html () -> Html ()-    encloseInTagFor ann = span_ [class_ classForAnn]-      where-        classForAnn = "dhall-" <> case ann of-            Keyword -> "keyword"-            Syntax -> "syntax"-            Label -> "label"-            Literal -> "literal"-            Builtin -> "builtin"-            Operator -> "operator"--    typeLayout :: Pretty.Doc ann -> Pretty.SimpleDocStream ann-    typeLayout = Pretty.removeTrailingWhitespace . Pretty.layoutSmart opts-      where-        -- this is done so the type of a dhall file fits in a single line-        -- its a safe value, since types in source codes are not that large-        opts :: Pretty.LayoutOptions-        opts = Pretty.defaultLayoutOptions-                { Pretty.layoutPageWidth =-                    Pretty.Unbounded-                }-- -- | Params for commonly supplied values on the generated documentation data DocParams = DocParams     { relativeResourcesPath :: FilePath -- ^ Relative resource path to the                                         --   front-end files     , packageName :: Text               -- ^ Name of the package+    , characterSet :: CharacterSet      -- ^ Render code as `ASCII` or `Unicode`     }  -- | Generates an @`Html` ()@ with all the information about a dhall file dhallFileToHtml     :: Path Rel File            -- ^ Source file name, used to extract the title-    -> Expr Src Import          -- ^ Contents of the file+    -> Text                     -- ^ Contents of the file+    -> Expr Src Import          -- ^ AST of the file     -> [Expr Void Import]       -- ^ Examples extracted from the assertions of the file     -> Html ()                  -- ^ Header document as HTML     -> DocParams                -- ^ Parameters for the documentation     -> Html ()-dhallFileToHtml filePath expr examples header params@DocParams{..} =+dhallFileToHtml filePath contents expr examples header params@DocParams{..} =     doctypehtml_ $ do         headContents htmlTitle params         body_ $ do@@ -118,9 +66,9 @@                 Control.Monad.unless (null examples) $ do                     h3_ "Examples"                     div_ [class_ "source-code code-examples"] $-                        mapM_ (exprToHtml FileContentsExpr) examples+                        mapM_ (renderCodeSnippet characterSet AssertionExample) examples                 h3_ "Source"-                div_ [class_ "source-code"] $ exprToHtml FileContentsExpr expr+                div_ [class_ "source-code"] $ renderCodeWithHyperLinks contents expr   where     breadcrumb = relPathToBreadcrumb filePath     htmlTitle = breadCrumbsToText breadcrumb@@ -157,7 +105,7 @@             a_ [href_ fileRef] $ toHtml itemText             Data.Foldable.forM_ maybeType $ \typeExpr -> do                 span_ [class_ "of-type-token"] ":"-                span_ [class_ "dhall-type source-code"] $ exprToHtml TypeAnnotation typeExpr+                span_ [class_ "dhall-type source-code"] $ renderCodeSnippet characterSet TypeAnnotation typeExpr       listDir :: Path Rel Dir -> Html ()@@ -275,7 +223,7 @@     head_ $ do         title_ $ toHtml title         stylesheet $ relativeResourcesPath <> "index.css"-        stylesheet "https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Lato&display=swap"+        stylesheet "https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Lato:ital,wght@0,400;0,700;1,400&display=swap"         script relativeResourcesPath         meta_ [charset_ "UTF-8"] 
+ src/Dhall/Docs/Util.hs view
@@ -0,0 +1,28 @@+{-| Common utilities for @dhall-docs@ -}+module Dhall.Docs.Util where++import Data.Text (Text)++import qualified Data.Text++-- | If you're wondering the GitHub query params for issue creation:+-- https://docs.github.com/en/github/managing-your-work-on-github/about-automation-for-issues-and-pull-requests-with-query-parameters+fileAnIssue :: Text -> a+fileAnIssue titleName =+    error $ "\ESC[1;31mError\ESC[0m Documentation generator bug\n\n" <>++            "Explanation: This error message means that there is a bug in the " <>+            "Dhall Documentation generator. You didn't did anything wrong, but " <>+            "if you would like to see this problem fixed then you should report " <>+            "the bug at:\n\n" <>++            "https://github.com/dhall-lang/dhall-haskell/issues/new?labels=dhall-docs,bug\n\n" <>++            "explaining your issue and add \"" <> Data.Text.unpack titleName <> "\" as error code " <>+            "so we can find the proper location in the source code where the error happened\n\n" <>++            "Please, also include your package in the issue. It can be in:\n\n" <>+            "* A compressed archive (zip, tar, etc)\n" <>+            "* A git repository, preferably with a commit reference"++
src/Dhall/data/index.css view
@@ -156,23 +156,8 @@     color: #333333; } -.source-code span.dhall-keyword {-    color: #0000FF;-    font-weight: bold;-}--.source-code span.dhall-syntax {-    color: #AF00DB;-}--.source-code span.dhall-literal {-    color: #098658;-    font-weight: bold;-}--.source-code span.dhall-builtin {-    color: #267F99;-    font-weight: bold;+.source-code a {+    font-family: 'Fira Code', monospace; }  .dhall-type {
tasty/Main.hs view
@@ -4,13 +4,19 @@  module Main (main) where +import Data.ByteString (ByteString) import Data.Map.Strict (Map) import Data.Text       (Text) import Dhall.Docs.Core+import Dhall.Pretty    (CharacterSet (..)) import Path            (Dir, File, Path, Rel, (</>))+import Prelude         hiding (FilePath) import Test.Tasty      (TestTree)+import Turtle          (FilePath, Pattern, Shell) +import qualified Control.Foldl                 as Foldl import qualified Control.Monad+import qualified Data.ByteString import qualified Data.Map.Strict               as Map import qualified Data.Text import qualified Data.Text.IO                  as Text.IO@@ -18,37 +24,44 @@ import qualified Path import qualified Path.IO import qualified Test.Tasty+import qualified Test.Tasty.HUnit              as Tasty.HUnit import qualified Test.Tasty.Silver             as Silver import qualified Test.Tasty.Silver.Interactive as Silver import qualified Text.PrettyPrint              as Pretty import qualified Text.XML.HaXml.Html.Parse     as HaXml import qualified Text.XML.HaXml.Pretty         as HaXml+import qualified Turtle  main :: IO () main = do     GHC.IO.Encoding.setLocaleEncoding GHC.IO.Encoding.utf8      input <- getPackageContents-    let GeneratedDocs _ docs = generateDocsPure "test-package" input+    let GeneratedDocs _ docs = generateDocsPure "test-package" Unicode input     let docsMap = Map.fromList docs-    Silver.defaultMain $ testTree docsMap+    commentTests <- getCommentTests+    let testTree = Test.Tasty.testGroup "dhall-docs"+                    [ docGenerationTests docsMap+                    , commentTests+                    ]+    Test.Tasty.defaultMain testTree -getDirContents :: Path Rel Dir -> IO [(Path Rel File, Text)]+getDirContents :: Path Rel Dir -> IO [(Path Rel File, ByteString)] getDirContents dataDir = do     files <- snd <$> Path.IO.listDirRecurRel dataDir     Control.Monad.forM files $ \file -> do-        contents <- Text.IO.readFile $ Path.fromRelFile $ dataDir </> file+        contents <- Data.ByteString.readFile $ Path.fromRelFile $ dataDir </> file         return (file, contents)  goldenDir :: Path Rel Dir goldenDir = $(Path.mkRelDir "./tasty/data/golden") -getPackageContents :: IO [(Path Rel File, Text)]+getPackageContents :: IO [(Path Rel File, ByteString)] getPackageContents = getDirContents $(Path.mkRelDir "./tasty/data/package") -testTree :: Map (Path Rel File) Text -> TestTree-testTree docsMap =-    Test.Tasty.testGroup "dhall-docs"+docGenerationTests :: Map (Path Rel File) Text -> TestTree+docGenerationTests docsMap =+    Test.Tasty.testGroup "doc-generation"         $ map makeTest $ Map.assocs docsMap   where     makeTest :: (Path Rel File, Text) -> TestTree@@ -63,3 +76,81 @@         prettyHtmlDoc = Pretty.render             $ HaXml.document             $ HaXml.htmlParse testName (Data.Text.unpack text)++getCommentTests :: IO TestTree+getCommentTests = do+    ignoreTests <- getIgnoreTests+    invalidCommentTests <- getInvalidCommentsTests+    validComentTests <- getValidCommentTests+    return $ Test.Tasty.testGroup "comments"+                [ ignoreTests+                , invalidCommentTests+                , validComentTests+                ]++getIgnoreTests :: IO TestTree+getIgnoreTests = do+    tests <- discover (Turtle.chars <* ".txt") makeText (Turtle.lstree testsPath)+    return $ Test.Tasty.testGroup "ignored comments" [ tests ]+  where+    testsPath = "./tasty/data/comments/empty/"+    makeText prefix = Tasty.HUnit.testCase (Data.Text.unpack prefix) $ do+        let inputFile  = Data.Text.unpack (prefix <> ".txt")++        inputText <- Text.IO.readFile inputFile++        case parseSingleDhallDocsComment inputFile inputText of+            Nothing -> return ()+            e -> fail ("Should not return a dhall-docs comment neither an error: " <> show e)+++getInvalidCommentsTests :: IO TestTree+getInvalidCommentsTests  = do+    tests <- discover (Turtle.chars <* ".txt") makeTest (Turtle.lstree testsPath)+    return $ Test.Tasty.testGroup "invalid comments" [ tests ]+  where+    testsPath = "./tasty/data/comments/invalid/"+    makeTest prefix = Tasty.HUnit.testCase (Data.Text.unpack prefix) $ do+        let inputFile  = Data.Text.unpack (prefix <> ".txt")++        inputText <- Text.IO.readFile inputFile++        case parseSingleDhallDocsComment inputFile inputText of+            Just (Left _) -> return ()+            e -> fail ("Should have returned an error: " <> show e)+++getValidCommentTests :: IO TestTree+getValidCommentTests = do+    tests <- discover (Turtle.chars <* "A.txt") makeTest (Turtle.lstree testPath)+    return $ Test.Tasty.testGroup "valid comments" [ tests ]+  where+    testPath = "./tasty/data/comments/valid/"+    makeTest prefix =+        Silver.goldenVsAction (drop 2 testName) goldenFilePath action converter+      where+        testName = Data.Text.unpack prefix+        goldenFilePath = testName <> "B.txt"+        action = do+            let inputFile = testName <> "A.txt"+            contents <- Text.IO.readFile inputFile+            case parseSingleDhallDocsComment inputFile contents of+                Just (Right t) -> return t+                e -> fail ("It shouldn't have returned an error or no-text: " <> show e)+        converter = unDhallDocsText+++discover :: Pattern Text -> (Text -> TestTree) -> Shell FilePath -> IO TestTree+discover pattern buildTest paths = do+    let shell = do+            path_ <- paths++            let pathText = Turtle.format Turtle.fp path_++            prefix : _ <- return (Turtle.match pattern pathText)++            return (buildTest prefix)++    tests <- Turtle.fold shell Foldl.list++    return (Test.Tasty.testGroup "discover" tests)
+ tasty/data/comments/empty/Empty.txt view
+ tasty/data/comments/empty/Mixed.txt view
@@ -0,0 +1,2 @@+{- foo -}+-- bar
+ tasty/data/comments/empty/SeveralLines.txt view
@@ -0,0 +1,2 @@+-- foo+-- bar
+ tasty/data/comments/empty/SingleBlock.txt view
@@ -0,0 +1,1 @@+{- foo -}
+ tasty/data/comments/empty/SingleLine.txt view
@@ -0,0 +1,1 @@+-- foo
+ tasty/data/comments/invalid/MissingNewLineBlock.txt view
@@ -0,0 +1,1 @@+{-| a new line needs to be here -}
+ tasty/data/comments/invalid/SingleLinesBadAligned.txt view
@@ -0,0 +1,3 @@+--| foo+  --  bar+ --  baz
+ tasty/data/comments/invalid/TwoValidBlocks.txt view
@@ -0,0 +1,4 @@+{-|+    foo -}+{-|+    foo -}
+ tasty/data/comments/invalid/TwoValidMixed.txt view
@@ -0,0 +1,4 @@+{-|+    foo -}+--| bla+--  qux
+ tasty/data/comments/invalid/TwoValidSingleLines.txt view
@@ -0,0 +1,5 @@+--| bla+--   qux++--| error here+--   foo
+ tasty/data/comments/valid/BlockA.txt view
@@ -0,0 +1,3 @@+{-|+    foo+    -}
+ tasty/data/comments/valid/BlockB.txt view
@@ -0,0 +1,1 @@+foo
+ tasty/data/comments/valid/BlockWithEmptyLinesIgnoredA.txt view
@@ -0,0 +1,5 @@+{-|+    foo++    bar+    -}
+ tasty/data/comments/valid/BlockWithEmptyLinesIgnoredB.txt view
@@ -0,0 +1,3 @@+foo++bar
+ tasty/data/comments/valid/BlockWithIndentationA.txt view
@@ -0,0 +1,4 @@+{-|+    foo+        bar+    -}
+ tasty/data/comments/valid/BlockWithIndentationB.txt view
@@ -0,0 +1,2 @@+foo+    bar
+ tasty/data/comments/valid/BlockWithOtherCommentsA.txt view
@@ -0,0 +1,5 @@+-- qux+{-|+    foo+    -}+{- bar -}
+ tasty/data/comments/valid/BlockWithOtherCommentsB.txt view
@@ -0,0 +1,1 @@+foo
+ tasty/data/comments/valid/BlockWithWhitespaceLinesA.txt view
@@ -0,0 +1,5 @@+{-|+    foo+  +    bar+    -}
+ tasty/data/comments/valid/BlockWithWhitespaceLinesB.txt view
@@ -0,0 +1,4 @@+foo++  bar+  
+ tasty/data/comments/valid/SingleLInesWithIndentationA.txt view
@@ -0,0 +1,3 @@+--| first line+--      indented with 4 spaces+--  third line
+ tasty/data/comments/valid/SingleLInesWithIndentationB.txt view
@@ -0,0 +1,3 @@+first line+    indented with 4 spaces+third line
+ tasty/data/comments/valid/SingleLineWithOtherCommentsA.txt view
@@ -0,0 +1,7 @@+-- bla++--| recovered+--  text+{-+    foo-}+{- bar -}
+ tasty/data/comments/valid/SingleLineWithOtherCommentsB.txt view
@@ -0,0 +1,2 @@+recovered+text
+ tasty/data/comments/valid/SingleLineWithPrefixWhitespaceA.txt view
@@ -0,0 +1,2 @@+  --| foo+  --  bar
+ tasty/data/comments/valid/SingleLineWithPrefixWhitespaceB.txt view
@@ -0,0 +1,2 @@+foo+bar
+ tasty/data/comments/valid/SingleLinesA.txt view
@@ -0,0 +1,3 @@+--| first line+--  second line+--  third line
+ tasty/data/comments/valid/SingleLinesB.txt view
@@ -0,0 +1,3 @@+first line+second line+third line
+ tasty/data/comments/valid/SingleLinesEmptyLineA.txt view
@@ -0,0 +1,3 @@+--| foo+--+--  bar
+ tasty/data/comments/valid/SingleLinesEmptyLineB.txt view
@@ -0,0 +1,3 @@+foo++bar
+ tasty/data/comments/valid/SingleLinesEmptyLineWithoutCommentA.txt view
@@ -0,0 +1,4 @@+--| foo+--  bar++--  baz
+ tasty/data/comments/valid/SingleLinesEmptyLineWithoutCommentB.txt view
@@ -0,0 +1,2 @@+foo+bar
+ tasty/data/comments/valid/SingleLinesIgnoreLInesBeforeMarkerA.txt view
@@ -0,0 +1,5 @@+--  ignored+-- ignored+--      ignored+--| foo+--  bar
+ tasty/data/comments/valid/SingleLinesIgnoreLInesBeforeMarkerB.txt view
@@ -0,0 +1,2 @@+foo+bar
+ tasty/data/golden/ImportAsType.dhall.html view
@@ -0,0 +1,50 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/ImportAsType.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >ImportAsType.dhall</span></h2+      ><a data-path="/ImportAsType.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+          >This example will show the link on the rendered source code <em+          >and</em> on the index+list</p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />This example will show the link on the rendered source code _and_ on the index<br+          />list<br+          />-}<br+          />{=} : <a href="./MarkdownExample.dhall.html"+          >./MarkdownExample.dhall</a+          ><br/></pre></div></div></body></html>
tasty/data/golden/IndexesExample.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/IndexesExample.dhall</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -33,45 +33,20 @@       ><br       /><div class="doc-contents"         ><p-        >Checking indexes</p>+          >This example shows that <code+          >dhall-docs</code> will find render the correct type on the+index respecting variable indices</p> </div       ><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >x</span-          ><br-          />    <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Bool</span-          ><br-          />    <span class="dhall-syntax"-          >=</span-          > <span class="dhall-builtin"-          >True</span-          ><br+          >{-|<br+          />This example shows that `dhall-docs` will find render the correct type on the<br+          />index respecting variable indices<br+          />-}<br           /><br-          /><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >x</span-          ><br-          />    <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Natural</span-          ><br-          />    <span class="dhall-syntax"-          >=</span-          > <span class="dhall-literal"-          >1</span-          ><br+          />let x : Bool = True<br+          />let x : Natural = 1<br           /><br-          /><span class="dhall-keyword"-          >in</span-          >  <span class="dhall-label"-          >x@1</span></pre></div></div></body></html>+          />in x@1<br/></pre></div></div></body></html>
+ tasty/data/golden/InvalidBlockComment.dhall.html view
@@ -0,0 +1,44 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/InvalidBlockComment.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >InvalidBlockComment.dhall</span></h2+      ><a data-path="/InvalidBlockComment.dhall"+          class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-| This example should throw a warning since after the `|` marker of the opening brace<br+          />    there *must* be a newline (either \n or \r\n) -}<br+          />{-|<br+          />    bar -}<br+          />{=}<br/></pre></div></div></body></html>
+ tasty/data/golden/InvalidConsecutiveComments.dhall.html view
@@ -0,0 +1,45 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/InvalidConsecutiveComments.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >InvalidConsecutiveComments.dhall</span></h2+      ><a data-path="/InvalidConsecutiveComments.dhall"+          class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />    This example should fail since two or more valid dhall-docs comment on the<br+          />    same section -}<br+          />{-|<br+          />    bar -}<br+          />{=}<br/></pre></div></div></body></html>
tasty/data/golden/InvalidMarkdown.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/InvalidMarkdown.dhall</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -32,51 +32,27 @@           >Copy path to clipboard</small></i></a       ><br       /><div class="doc-contents"-      >Represents an status in our messaging system `--- look, another line</div+      >This file contains a markdown error right here `+did you notice it?+</div       ><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >Pair</span-          > <span class="dhall-syntax"-          >=</span-          > ./Pair.dhall<br+          >--| This file contains a markdown error right here `<br+          />--  did you notice it?<br           /><br-          /><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >DeliveryStatus</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >Sent</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-label"-          >Pair</span-          > <span class="dhall-builtin"-          >Natural</span-          > <span class="dhall-builtin"-          >Text</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >InProgress</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >InQueue</span-          > <span class="dhall-syntax"-          >&gt;</span+          />let Pair = <a href="./Pair.dhall.html"+          >./Pair.dhall</a           ><br           /><br-          /><span class="dhall-keyword"-          >in</span-          >  <span class="dhall-label"-          >DeliveryStatus</span></pre></div></div></body></html>+          />let DeliveryStatus =<br+          />    &lt; Sent: Pair Natural Text {-| Message has been _sent_. It carries a ./Pair.dhall reference<br+          />                                    containing on the `first` field number of retries<br+          />                                    and on the `second` field the delivered text<br+          />                                -}<br+          />    | InProgress                -- | Message is on the way!<br+          />    | InQueue                   -- | Delivery for this message **hasn&#39;t** started<br+          />    &gt;<br+          /><br+          />in DeliveryStatus<br/></pre></div></div></body></html>
+ tasty/data/golden/JumpToHereImports.dhall.html view
@@ -0,0 +1,58 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/JumpToHereImports.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >JumpToHereImports.dhall</span></h2+      ><a data-path="/JumpToHereImports.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >let relatives =<br+          />    [ <a href="./IndexesExample.dhall.html"+          >./IndexesExample.dhall</a+          ><br+          />    , <a href="./MarkdownExample.dhall.html"+          >./MarkdownExample.dhall</a+          ><br+          />    , <a href="./NoDoc.dhall.html"+          >./NoDoc.dhall</a+          ><br+          />    ]<br+          /><br+          />let moreRelatives =<br+          />    [ <a href="./OrdinaryAnnotation.dhall.html"+          >./OrdinaryAnnotation.dhall</a+          > ,    <a href="./TwoAnnotations.dhall.html"+          >./TwoAnnotations.dhall</a+          > ]<br+          /><br+          />in relatives # moreRelatives<br/></pre></div></div></body></html>
+ tasty/data/golden/JumpToSelf.dhall.html view
@@ -0,0 +1,53 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/JumpToSelf.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >JumpToSelf.dhall</span></h2+      ><a data-path="/JumpToSelf.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+          >Althtough Dhall forbids cyclic imports, <code+          >dhall-docs</code> can handle them properly</p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />Althtough Dhall forbids cyclic imports, `dhall-docs` can handle them properly<br+          />-}<br+          />let selfs =<br+          />    [ <a href="./JumpToSelf.dhall.html"+          >./JumpToSelf.dhall</a+          ><br+          />    , <a href="../package/JumpToSelf.dhall.html"+          >../package/JumpToSelf.dhall</a+          > ]<br+          />in selfs<br/></pre></div></div></body></html>
+ tasty/data/golden/JumpToUrls.dhall.html view
@@ -0,0 +1,54 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/JumpToUrls.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >JumpToUrls.dhall</span></h2+      ><a data-path="/JumpToUrls.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+          >Example taken from <a href="https://docs.dhall-lang.org/tutorials/Language-Tour.html#prelude"+          >dhall documentation</a></p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />Example taken from [dhall documentation](https://docs.dhall-lang.org/tutorials/Language-Tour.html#prelude)<br+          />-}<br+          /><br+          /><br+          />let List/generate = <a href="https://prelude.dhall-lang.org/v15.0.0/List/generate"+                                   target="_blank"+          >https://prelude.dhall-lang.org/v15.0.0/List/generate</a+          ><br+          /><br+          />in List/generate 10 Text (\(n : Natural) -&gt; &quot;Result #${Natural/show n}&quot;)<br+          /><br/></pre></div></div></body></html>
tasty/data/golden/MarkdownExample.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/MarkdownExample.dhall</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -115,27 +115,46 @@       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-syntax"-          >{</span-          > <span class="dhall-label"-          >remitent</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Text</span-          ><span class="dhall-syntax"-          >,</span-          > <span class="dhall-label"-          >deliveryStatus</span-          > <span class="dhall-syntax"-          >:</span-          > ./DeliveryStatus.dhall<span class="dhall-syntax"-          >,</span-          > <span class="dhall-label"-          >body</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Text</span-          > <span class="dhall-syntax"-          >}</span></pre></div></div></body></html>+          >{-|<br+          /># Heading 1<br+          /><br+          />## Heading 2<br+          /><br+          />### Heading 3<br+          /><br+          />#### Heading 4<br+          /><br+          />##### Heading 5<br+          /><br+          />###### Heading 6<br+          /><br+          />Message data type for our _messaging-system_ config.<br+          /><br+          />    It is similar to the `kafka` message dto.<br+          />testing again another random text.<br+          /><br+          />**NOTE**: This is really important to know<br+          /><br+          />This allows you to:<br+          /><br+          />* Send messages<br+          />* Receive messages, knowing that:<br+          />    - nothing works (?)<br+          />    - weird huh<br+          /><br+          />As somebody said,<br+          /><br+          />&gt; The best way to code is to not code<br+          /><br+          />Here I show you some haskell code<br+          /><br+          />```haskell<br+          />main = putStrLn &quot;dhall rulez&quot;<br+          />```<br+          />-}<br+          />{ remitent: Text                         --| Remitent name<br+          />, deliveryStatus: <a href="./DeliveryStatus.dhall.html"+          >./DeliveryStatus.dhall</a+          > --| Status<br+          />, body: Text                             --| Message body<br+          />}<br/></pre></div></div></body></html>
+ tasty/data/golden/MultilineIndentationExample.dhall.html view
@@ -0,0 +1,71 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/MultilineIndentationExample.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >MultilineIndentationExample.dhall</span></h2+      ><a data-path="/MultilineIndentationExample.dhall"+          class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+        >Non indented text should remain as-is</p+        >+<pre+          ><code+          >indented code block+</code></pre+        >+<ul+          >+<li+            >+item 1+<ul+              >+<li+              >+item 2+</li>+</ul>+</li>+</ul>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />Non indented text should remain as-is<br+          /><br+          />    indented code block<br+          /><br+          />* item 1<br+          />    - item 2<br+          />-}<br+          />{=} : {}<br/></pre></div></div></body></html>
+ tasty/data/golden/NoDoc.dhall.html view
@@ -0,0 +1,39 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/NoDoc.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >NoDoc.dhall</span></h2+      ><a data-path="/NoDoc.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{=}<br/></pre></div></div></body></html>
+ tasty/data/golden/NonDhallDocsCommentAfterValid.dhall.html view
@@ -0,0 +1,51 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/NonDhallDocsCommentAfterValid.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >NonDhallDocsCommentAfterValid.dhall</span></h2+      ><a data-path="/NonDhallDocsCommentAfterValid.dhall"+          class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+          >This example shows that you can place non-dhall comments after a <em+          >valid</em>+dhall comment</p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />    This example shows that you can place non-dhall comments after a _valid_<br+          />    dhall comment -}<br+          />{-<br+          />    bar -}<br+          />-- qux<br+          />{=}<br/></pre></div></div></body></html>
+ tasty/data/golden/OrdinaryAnnotation.dhall.html view
@@ -0,0 +1,47 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/OrdinaryAnnotation.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >OrdinaryAnnotation.dhall</span></h2+      ><a data-path="/OrdinaryAnnotation.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+        >This file contains a Dhall expression with just a type annotation, which+should be selected as the expression&#39;s type</p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />This file contains a Dhall expression with just a type annotation, which<br+          />should be selected as the expression&#39;s type<br+          />-}<br+          />1 : Natural<br/></pre></div></div></body></html>
tasty/data/golden/Pair.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/Pair.dhall</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -40,95 +40,15 @@       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >Pair</span           ><br-          />    <span class="dhall-syntax"-          >:</span-          > <span class="dhall-syntax"-          >∀</span-          ><span class="dhall-syntax"-          >(</span-          ><span class="dhall-label"-          >A</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Type</span-          ><span class="dhall-syntax"-          >)</span-          > <span class="dhall-syntax"-          >→</span-          > <span class="dhall-syntax"-          >∀</span-          ><span class="dhall-syntax"-          >(</span-          ><span class="dhall-label"-          >B</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Type</span-          ><span class="dhall-syntax"-          >)</span-          > <span class="dhall-syntax"-          >→</span-          > <span class="dhall-builtin"-          >Type</span-          ><br-          />    <span class="dhall-syntax"-          >=</span-          > <span class="dhall-syntax"-          >λ</span-          ><span class="dhall-syntax"-          >(</span-          ><span class="dhall-label"-          >A</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Type</span-          ><span class="dhall-syntax"-          >)</span-          > <span class="dhall-syntax"-          >→</span-          > <span class="dhall-syntax"-          >λ</span-          ><span class="dhall-syntax"-          >(</span-          ><span class="dhall-label"-          >B</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Type</span-          ><span class="dhall-syntax"-          >)</span-          > <span class="dhall-syntax"-          >→</span-          > <span class="dhall-syntax"-          >{</span-          > <span class="dhall-label"-          >first</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-label"-          >A</span-          ><span class="dhall-syntax"-          >,</span-          > <span class="dhall-label"-          >second</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-label"-          >B</span-          > <span class="dhall-syntax"-          >}</span-          ><br+          />{-|<br+          />Just a *Pair* right here<br+          />-}<br           /><br-          /><span class="dhall-keyword"-          >in</span-          >  <span class="dhall-label"-          >Pair</span></pre></div></div></body></html>+          />let Pair<br+          />  : forall(A: Type) -- | Type of first position<br+          />  -&gt; forall(B: Type) -- | Type of second position<br+          />  -&gt; Type<br+          />  = λ(A: Type) -&gt; λ(B: Type) -&gt; {first: A, second: B}<br+          /><br+          />in Pair<br/></pre></div></div></body></html>
+ tasty/data/golden/TwoAnnotations.dhall.html view
@@ -0,0 +1,56 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/TwoAnnotations.dhall</title+    ><link href="index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >TwoAnnotations.dhall</span></h2+      ><a data-path="/TwoAnnotations.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+        ><p+          >This expression contains type annotations on both the <code+          >let</code+          > binding and on the+body of the <code+          >let</code> expression.  The documentation generator prefers to use the+latter annotation.</p>+</div+      ><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >{-|<br+          />This expression contains type annotations on both the `let` binding and on the<br+          />body of the `let` expression.  The documentation generator prefers to use the<br+          />latter annotation.<br+          />-}<br+          />let x = 1<br+          /><br+          />let y = Natural<br+          /><br+          />in  x : y<br/></pre></div></div></body></html>
+ tasty/data/golden/a/JumpToParent.dhall.html view
@@ -0,0 +1,49 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/a/JumpToParent.dhall</title+    ><link href="../index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="../index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="../dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="../index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html" class="title-crumb"+        >a</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >JumpToParent.dhall</span></h2+      ><a data-path="/a/JumpToParent.dhall" class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >let parents =<br+          />    [ <a href="../IndexesExample.dhall.html"+          >../IndexesExample.dhall</a+          ><br+          />    ]<br+          /><br+          />in parents<br/></pre></div></div></body></html>
tasty/data/golden/a/b.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/a/b.dhall</title     ><link href="../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -36,22 +36,12 @@           >Copy path to clipboard</small></i></a       ><br       /><div class="doc-contents"-        ><p-        >Hi there boys</p>-</div-      ><h3+      /><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >b</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-literal"-          >1</span-          > <span class="dhall-keyword"-          >in</span-          > <span class="dhall-label"-          >b</span></pre></div></div></body></html>+          >{-<br+          />Hi there boys<br+          />-}<br+          /><br+          />let b = 1 in b<br/></pre></div></div></body></html>
+ tasty/data/golden/a/b/JumpToGrandfather.dhall.html view
@@ -0,0 +1,54 @@+<!DOCTYPE HTML>+<html+  ><head+    ><title+    >/a/b/JumpToGrandfather.dhall</title+    ><link href="../../index.css" type="text/css" rel="stylesheet"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"+            type="text/css" rel="stylesheet"+    /><script src="../../index.js" type="text/javascript"+    /><meta charset="UTF-8"/></head+  ><body+    ><div class="nav-bar"+      ><img src="../../dhall-icon.svg" class="dhall-icon"+      /><p class="package-title"+      >test-package</p+      ><div class="nav-bar-content-divider"+      /><a id="switch-light-dark-mode" class="nav-option"+      >Switch Light/Dark Mode</a></div+    ><div class="main-container"+      ><h2 class="doc-title"+        ><span class="crumb-divider"+        >/</span+        ><a href="../../index.html"+        >test-package</a+        ><span class="crumb-divider"+        >/</span+        ><a href="../index.html" class="title-crumb"+        >a</a+        ><span class="crumb-divider"+        >/</span+        ><a href="index.html" class="title-crumb"+        >b</a+        ><span class="crumb-divider"+        >/</span+        ><span href="index.html" class="title-crumb"+        >JumpToGrandfather.dhall</span></h2+      ><a data-path="/a/b/JumpToGrandfather.dhall"+          class="copy-to-clipboard"+        ><i+          ><small+          >Copy path to clipboard</small></i></a+      ><br+      /><div class="doc-contents"+      /><h3+      >Source</h3+      ><div class="source-code"+        ><pre+          >let parents =<br+          />    [ <a href="../../IndexesExample.dhall.html"+          >../../IndexesExample.dhall</a+          ><br+          />    ]<br+          /><br+          />in parents<br/></pre></div></div></body></html>
tasty/data/golden/a/b/c.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/a/b/c.dhall</title     ><link href="../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -40,22 +40,12 @@           >Copy path to clipboard</small></i></a       ><br       /><div class="doc-contents"-        ><p-        >Hi there boys</p>-</div-      ><h3+      /><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >c</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-literal"-          >1</span-          > <span class="dhall-keyword"-          >in</span-          > <span class="dhall-label"-          >c</span></pre></div></div></body></html>+          >{-<br+          />Hi there boys<br+          />-}<br+          /><br+          />let c = 1 in c<br/></pre></div></div></body></html>
tasty/data/golden/a/b/c/a.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/a/b/c/a.dhall</title     ><link href="../../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -44,22 +44,12 @@           >Copy path to clipboard</small></i></a       ><br       /><div class="doc-contents"-        ><p-        >Hi there boys</p>-</div-      ><h3+      /><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >a</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-literal"-          >1</span-          > <span class="dhall-keyword"-          >in</span-          > <span class="dhall-label"-          >a</span></pre></div></div></body></html>+          >{-<br+          />Hi there boys<br+          />-}<br+          /><br+          />let a = 1 in a<br/></pre></div></div></body></html>
tasty/data/golden/a/b/c/index.html view
@@ -4,7 +4,7 @@     ><title     >/a/b/c</title     ><link href="../../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head
tasty/data/golden/a/b/index.html view
@@ -4,7 +4,7 @@     ><title     >/a/b</title     ><link href="../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -38,6 +38,9 @@       /><h3       >Exported files: </h3       ><ul+        ><li+          ><a href="JumpToGrandfather.dhall.html"+          >JumpToGrandfather.dhall</a></li         ><li           ><a href="c.dhall.html"           >c.dhall</a></li></ul
tasty/data/golden/a/index.html view
@@ -4,7 +4,7 @@     ><title     >/a</title     ><link href="../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -34,6 +34,9 @@       /><h3       >Exported files: </h3       ><ul+        ><li+          ><a href="JumpToParent.dhall.html"+          >JumpToParent.dhall</a></li         ><li           ><a href="b.dhall.html"           >b.dhall</a></li></ul
tasty/data/golden/deep/nested/folder/index.html view
@@ -4,7 +4,7 @@     ><title     >/deep/nested/folder</title     ><link href="../../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -49,17 +49,4 @@           >:</span           ><span class="dhall-type source-code"             ><pre-              ><span class="dhall-builtin"-              >Natural</span-              > <span class="dhall-syntax"-              >→</span-              > <span class="dhall-syntax"-              >&lt;</span-              > <span class="dhall-label"-              >even</span-              > <span class="dhall-syntax"-              >|</span-              > <span class="dhall-label"-              >odd</span-              > <span class="dhall-syntax"-              >&gt;</span></pre></span></li></ul></div></body></html>+              >Natural → &lt; even | odd &gt;<br/></pre></span></li></ul></div></body></html>
tasty/data/golden/deep/nested/folder/my-even.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/deep/nested/folder/my-even.dhall</title     ><link href="../../../index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="../../../index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -45,202 +45,26 @@           >Copy path to clipboard</small></i></a       ><br       /><div class="doc-contents"-        ><p-        >Check if a natural is even or not returning an union data-type</p>-</div-      ><h3+      /><h3       >Examples</h3       ><div class="source-code code-examples"         ><pre-          ><span class="dhall-label"-          >my-even</span-          > <span class="dhall-literal"-          >1</span-          > <span class="dhall-operator"-          >≡</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >odd</span></pre+          >my-even 1 ≡ &lt; even | odd &gt;.odd<br/></pre         ><pre-          ><span class="dhall-label"-          >my-even</span-          > <span class="dhall-literal"-          >2</span-          > <span class="dhall-operator"-          >≡</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >even</span></pre></div+          >my-even 2 ≡ &lt; even | odd &gt;.even<br/></pre></div       ><h3       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >my-even</span-          ><br-          />    <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Natural</span-          > <span class="dhall-syntax"-          >→</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><br-          />    <span class="dhall-syntax"-          >=</span-          > <span class="dhall-syntax"-          >λ</span-          ><span class="dhall-syntax"-          >(</span-          ><span class="dhall-label"-          >n</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-builtin"-          >Natural</span-          ><span class="dhall-syntax"-          >)</span-          > <span class="dhall-syntax"-          >→</span-          ><br-          />        <span class="dhall-keyword"-          >if</span-          > <span class="dhall-builtin"-          >Natural/even</span-          > <span class="dhall-label"-          >n</span-          > <span class="dhall-keyword"-          >then</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >even</span-          > <span class="dhall-keyword"-          >else</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >odd</span-          ><br-          /><br-          /><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >example0</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-keyword"-          >assert</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-label"-          >my-even</span-          > <span class="dhall-literal"-          >1</span-          > <span class="dhall-operator"-          >≡</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >odd</span-          ><br+          >{-<br+          />Check if a natural is even or not returning an union data-type<br+          />-}<br+          />let my-even<br+          />    : Natural → &lt; even | odd &gt;<br+          />    = λ(n : Natural) →<br+          />        if Natural/even n then &lt; even | odd&gt;.even else &lt; even | odd &gt;.odd<br           /><br-          /><span class="dhall-keyword"-          >let</span-          > <span class="dhall-label"-          >example0</span-          > <span class="dhall-syntax"-          >=</span-          > <span class="dhall-keyword"-          >assert</span-          > <span class="dhall-syntax"-          >:</span-          > <span class="dhall-label"-          >my-even</span-          > <span class="dhall-literal"-          >2</span-          > <span class="dhall-operator"-          >≡</span-          > <span class="dhall-syntax"-          >&lt;</span-          > <span class="dhall-label"-          >even</span-          > <span class="dhall-syntax"-          >|</span-          > <span class="dhall-label"-          >odd</span-          > <span class="dhall-syntax"-          >&gt;</span-          ><span class="dhall-syntax"-          >.</span-          ><span class="dhall-label"-          >even</span-          ><br+          />let example0 = assert : my-even 1 === &lt;even | odd&gt;.odd<br+          />let example0 = assert : my-even 2 === &lt;even | odd&gt;.even<br           /><br-          /><span class="dhall-keyword"-          >in</span-          >  <span class="dhall-label"-          >my-even</span></pre></div></div></body></html>+          />in my-even<br/></pre></div></div></body></html>
tasty/data/golden/index.html view
@@ -4,7 +4,7 @@     ><title     >/</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -34,66 +34,91 @@       >Exported files: </h3       ><ul         ><li+          ><a href="ImportAsType.dhall.html"+          >ImportAsType.dhall</a+          ><span class="of-type-token"+          >:</span+          ><span class="dhall-type source-code"+            ><pre+              ><a href="./MarkdownExample.dhall.html"+              >./MarkdownExample.dhall</a+              ><br/></pre></span></li+        ><li           ><a href="IndexesExample.dhall.html"           >IndexesExample.dhall</a           ><span class="of-type-token"           >:</span           ><span class="dhall-type source-code"             ><pre-              ><span class="dhall-builtin"-              >Bool</span></pre></span></li+              >Bool<br/></pre></span></li         ><li+          ><a href="InvalidBlockComment.dhall.html"+          >InvalidBlockComment.dhall</a></li+        ><li+          ><a href="InvalidConsecutiveComments.dhall.html"+          >InvalidConsecutiveComments.dhall</a></li+        ><li           ><a href="InvalidMarkdown.dhall.html"           >InvalidMarkdown.dhall</a></li         ><li+          ><a href="JumpToHereImports.dhall.html"+          >JumpToHereImports.dhall</a></li+        ><li+          ><a href="JumpToSelf.dhall.html"+          >JumpToSelf.dhall</a></li+        ><li+          ><a href="JumpToUrls.dhall.html"+          >JumpToUrls.dhall</a></li+        ><li           ><a href="MarkdownExample.dhall.html"           >MarkdownExample.dhall</a></li         ><li+          ><a href="MultilineIndentationExample.dhall.html"+          >MultilineIndentationExample.dhall</a+          ><span class="of-type-token"+          >:</span+          ><span class="dhall-type source-code"+            ><pre+              >{}<br/></pre></span></li+        ><li+          ><a href="NoDoc.dhall.html"+          >NoDoc.dhall</a></li+        ><li+          ><a href="NonDhallDocsCommentAfterValid.dhall.html"+          >NonDhallDocsCommentAfterValid.dhall</a></li+        ><li+          ><a href="OrdinaryAnnotation.dhall.html"+          >OrdinaryAnnotation.dhall</a+          ><span class="of-type-token"+          >:</span+          ><span class="dhall-type source-code"+            ><pre+              >Natural<br/></pre></span></li+        ><li           ><a href="Pair.dhall.html"           >Pair.dhall</a           ><span class="of-type-token"           >:</span           ><span class="dhall-type source-code"             ><pre-              ><span class="dhall-syntax"-              >∀</span-              ><span class="dhall-syntax"-              >(</span-              ><span class="dhall-label"-              >A</span-              > <span class="dhall-syntax"-              >:</span-              > <span class="dhall-builtin"-              >Type</span-              ><span class="dhall-syntax"-              >)</span-              > <span class="dhall-syntax"-              >→</span-              > <span class="dhall-syntax"-              >∀</span-              ><span class="dhall-syntax"-              >(</span-              ><span class="dhall-label"-              >B</span-              > <span class="dhall-syntax"-              >:</span-              > <span class="dhall-builtin"-              >Type</span-              ><span class="dhall-syntax"-              >)</span-              > <span class="dhall-syntax"-              >→</span-              > <span class="dhall-builtin"-              >Type</span></pre></span></li+              >∀(A : Type) → ∀(B : Type) → Type<br/></pre></span></li         ><li+          ><a href="TwoAnnotations.dhall.html"+          >TwoAnnotations.dhall</a+          ><span class="of-type-token"+          >:</span+          ><span class="dhall-type source-code"+            ><pre+              >y<br/></pre></span></li+        ><li           ><a href="package.dhall.html"           >package.dhall</a></li></ul       ><h3       >Exported packages: </h3       ><ul         ><li-          ><a href="deep/nested/folder/index.html"-          >deep/nested/folder/</a></li-        ><li           ><a href="a/index.html"-          >a/</a></li></ul></div></body></html>+          >a/</a></li+        ><li+          ><a href="deep/nested/folder/index.html"+          >deep/nested/folder/</a></li></ul></div></body></html>
tasty/data/golden/package.dhall.html view
@@ -4,7 +4,7 @@     ><title     >/package.dhall</title     ><link href="index.css" type="text/css" rel="stylesheet"-    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato&amp;display=swap"+    /><link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&amp;family=Lato:ital,wght@0,400;0,700;1,400&amp;display=swap"             type="text/css" rel="stylesheet"     /><script src="index.js" type="text/javascript"     /><meta charset="UTF-8"/></head@@ -39,26 +39,16 @@       >Source</h3       ><div class="source-code"         ><pre-          ><span class="dhall-syntax"-          >{</span-          > <span class="dhall-label"-          >Message</span-          > <span class="dhall-syntax"-          >=</span-          > ./Message.dhall<br-          /><span class="dhall-syntax"-          >,</span-          > <span class="dhall-label"-          >DeliveryStatus</span-          > <span class="dhall-syntax"-          >=</span-          > ./DeliveryStatus.dhall<br-          /><span class="dhall-syntax"-          >,</span-          > <span class="dhall-label"-          >Pair</span-          > <span class="dhall-syntax"-          >=</span-          > ./Pair.dhall<br-          /><span class="dhall-syntax"-          >}</span></pre></div></div></body></html>+          >{-|<br+          />This is your package entrypoint documentation<br+          />-}<br+          />{ Message = <a href="./Message.dhall.html"+          >./Message.dhall</a+          ><br+          />, DeliveryStatus = <a href="./DeliveryStatus.dhall.html"+          >./DeliveryStatus.dhall</a+          ><br+          />, Pair = <a href="./Pair.dhall.html"+          >./Pair.dhall</a+          ><br+          />}<br/></pre></div></div></body></html>
+ tasty/data/package/ImportAsType.dhall view
@@ -0,0 +1,5 @@+{-|+This example will show the link on the rendered source code _and_ on the index+list+-}+{=} : ./MarkdownExample.dhall
tasty/data/package/IndexesExample.dhall view
@@ -1,4 +1,7 @@-{- Checking indexes -}+{-|+This example shows that `dhall-docs` will find render the correct type on the+index respecting variable indices+-}  let x : Bool = True let x : Natural = 1
+ tasty/data/package/InvalidBlockComment.dhall view
@@ -0,0 +1,5 @@+{-| This example should throw a warning since after the `|` marker of the opening brace+    there *must* be a newline (either \n or \r\n) -}+{-|+    bar -}+{=}
+ tasty/data/package/InvalidConsecutiveComments.dhall view
@@ -0,0 +1,6 @@+{-|+    This example should fail since two or more valid dhall-docs comment on the+    same section -}+{-|+    bar -}+{=}
tasty/data/package/InvalidMarkdown.dhall view
@@ -1,5 +1,5 @@--- Represents an status in our messaging system `--- look, another line+--| This file contains a markdown error right here `+--  did you notice it?  let Pair = ./Pair.dhall 
+ tasty/data/package/InvalidUnicode.dhall view
@@ -0,0 +1,3 @@+{- This file contains invalid unicode, it shouldn't be present on the generated+   documentation -}+��
+ tasty/data/package/JumpToHereImports.dhall view
@@ -0,0 +1,10 @@+let relatives =+    [ ./IndexesExample.dhall+    , ./MarkdownExample.dhall+    , ./NoDoc.dhall+    ]++let moreRelatives =+    [ ./OrdinaryAnnotation.dhall ,    ./TwoAnnotations.dhall ]++in relatives # moreRelatives
+ tasty/data/package/JumpToSelf.dhall view
@@ -0,0 +1,7 @@+{-|+Althtough Dhall forbids cyclic imports, `dhall-docs` can handle them properly+-}+let selfs =+    [ ./JumpToSelf.dhall+    , ../package/JumpToSelf.dhall ]+in selfs
+ tasty/data/package/JumpToUrls.dhall view
@@ -0,0 +1,9 @@+{-|+Example taken from [dhall documentation](https://docs.dhall-lang.org/tutorials/Language-Tour.html#prelude)+-}+++let List/generate = https://prelude.dhall-lang.org/v15.0.0/List/generate++in List/generate 10 Text (\(n : Natural) -> "Result #${Natural/show n}")+
tasty/data/package/MarkdownExample.dhall view
@@ -1,4 +1,4 @@-{-+{-| # Heading 1  ## Heading 2
+ tasty/data/package/MultilineIndentationExample.dhall view
@@ -0,0 +1,9 @@+{-|+Non indented text should remain as-is++    indented code block++* item 1+    - item 2+-}+{=} : {}
+ tasty/data/package/NoDoc.dhall view
@@ -0,0 +1,1 @@+{=}
+ tasty/data/package/NonDhallDocsCommentAfterValid.dhall view
@@ -0,0 +1,7 @@+{-|+    This example shows that you can place non-dhall comments after a _valid_+    dhall comment -}+{-+    bar -}+-- qux+{=}
+ tasty/data/package/OrdinaryAnnotation.dhall view
@@ -0,0 +1,5 @@+{-|+This file contains a Dhall expression with just a type annotation, which+should be selected as the expression's type+-}+1 : Natural
tasty/data/package/Pair.dhall view
@@ -1,5 +1,6 @@ -{-  Just a *Pair* right here+{-|+Just a *Pair* right here -}  let Pair
+ tasty/data/package/TwoAnnotations.dhall view
@@ -0,0 +1,10 @@+{-|+This expression contains type annotations on both the `let` binding and on the+body of the `let` expression.  The documentation generator prefers to use the+latter annotation.+-}+let x = 1++let y = Natural++in  x : y
+ tasty/data/package/a/JumpToParent.dhall view
@@ -0,0 +1,5 @@+let parents =+    [ ../IndexesExample.dhall+    ]++in parents
+ tasty/data/package/a/b/JumpToGrandfather.dhall view
@@ -0,0 +1,5 @@+let parents =+    [ ../../IndexesExample.dhall+    ]++in parents
tasty/data/package/package.dhall view
@@ -1,4 +1,4 @@-{-+{-| This is your package entrypoint documentation -} { Message = ./Message.dhall