diff options
author | Tom Smeding <tom@tomsmeding.com> | 2024-01-07 20:56:59 +0100 |
---|---|---|
committer | Tom Smeding <tom@tomsmeding.com> | 2024-01-07 20:56:59 +0100 |
commit | 5e333dbaae9d800863bbb46ef830a69339da982d (patch) | |
tree | 0d878046c6f1846fb200d856b2b58b99f6fd5f39 /Main.hs | |
parent | 266c94ac8dcb11e1058b61b1b58e02fbbfe3fd2e (diff) |
Diffstat (limited to 'Main.hs')
-rw-r--r-- | Main.hs | 62 |
1 files changed, 43 insertions, 19 deletions
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ViewPatterns #-} module Main (main) where import Control.Monad (ap, void, forM) @@ -21,13 +22,13 @@ import System.IO (hPutStrLn, stderr, hFlush, stdout) import Control.Applicative (Alternative(..)) -data Link = BootLib ByteString -- ^ packagename-version +data Link = Package ByteString -- ^ packagename-version ByteString -- ^ path (including #anchor) | Broken ByteString -- ^ packagename-version deriving (Show) renderLink :: Link -> Builder -renderLink (BootLib pkg path) = +renderLink (Package pkg path) = mconcat [BSB.string8 "https://hackage.haskell.org/package/" ,BSB.byteString pkg ,BSB.string8 "/docs/" @@ -48,24 +49,47 @@ instance Alternative Parser where Parser f <|> Parser g = Parser $ \s -> f s <|> g s parseLink :: Parser Link -parseLink = do - let endOfLink c = isSpace c || c `elem` "\"'" - string "../" <|> return () - string "file:///" - search (void $ satisfy endOfLink) - (string ".ghcup") - string "/ghc/" - _ <- word (/= '/') -- "9.2.2" - string "/share/doc/ghc-" - _ <- word (/= '/') -- "9.2.2" - string "/html/libraries/" - pkg <- word (/= '/') - string "/" - path <- word (not . endOfLink) - if path == Char8.pack "src" - then return (Broken pkg) - else return (BootLib pkg path) +parseLink = parsePackageLink <|> parseBootlibLink where + endOfLink c = isSpace c || c `elem` "\"'" + + parseBootlibLink :: Parser Link + parseBootlibLink = do + string "${pkgroot}/" -- wtf haddock? + _ <- many (string "../") + string "share/doc/ghc-" + _ghcversion <- word (/= '/') + string "/html/libraries/" + pkg <- word (/= '/') + string "/" + path <- word (not . endOfLink) + if path == Char8.pack "src" + then return (Broken pkg) -- not sure if this happens in practice + else return (Package pkg path) + + parsePackageLink :: Parser Link + parsePackageLink = do + string "file://" + search (void $ satisfy endOfLink) + (string "/.cabal/") + string "store/ghc-" + _ghcversion <- word (/= '/') + string "/" + namewithhash <- word (/= '/') + let pkg = + case BS.spanEnd ((`elem` "0123456789abcdefABCDEF") . tochar) namewithhash of + (pre, hash) + | BS.length hash == 64 + , Just (pre', tochar -> '-') <- BS.unsnoc pre -> + pre' + | otherwise -> + namewithhash + string "/share/doc/html/" + path <- word (not . endOfLink) + if path == Char8.pack "src" + then return (Broken pkg) + else return (Package pkg path) + string :: String -> Parser () string w = let w' = Char8.pack w |