module Hakyll.Paper where import Prolog import Hakyll import Data.Paper import Data.Name import Data.Time.Format import Hakyll.Core.Compiler.Internal import Hakyll.Core.Provider (resourceList) import Hakyll.Util (transformContext_) import System.FilePath findIdentifiers :: Pattern -> Compiler [Identifier] findIdentifiers pat = filterMatches pat . resourceList . compilerProvider <$> compilerAsk authorCtxt :: StringConv a String => Context (Name a) authorCtxt = fold $ [ field "name" $ pure . renderNameFML . fmap toSL . getItemBody ] paperCtxt :: StringConv a String => Context (Paper a) paperCtxt = fold $ [ listFieldWith "authors" authorCtxt $ pure . authors . itemBody , field "abstract" $ liftMaybe . fmap toSL . abstract . itemBody , field "title" $ pure . toSL . title . getItemBody , status >$< statusCtxt , eprint >$< maybeContext eprintCtxt , field "extra" $ \i -> case extraLink $ getItemBody i of Just l -> pure $ show l Nothing -> do let k = key $ itemBody i ident = toFilePath $ itemIdentifier i findItentifiers (fromString $ ident <> "/index.**") >>= witherM (fmap (>>= parseRelativeReference) . getRoute) >>= \case (x:_) -> pure $ show x _ -> fail $ "No extra for " <> toSL k ] mkPaperContext :: StringConv a String => [Paper a] -> Context b mkPaperContext papers = listField "papers" paperCtxt $ do fp <- getResourceFilePath forM papers $ \p -> do let itm = Item (fromFilePath $ replaceFileName fp (toSL $ key p)) p eprnt <- findLocal itm pure $ (\x -> x { eprint = eprnt }) <$> itm statusCtxt :: StringConv a String => Context (Status a) statusCtxt = fold $ [ field "date" $ formatTime defaultTimeLocale "%b %Y" . date . getItemBody , field "journal" $ \i -> case getItemBody i of Published _ j _ -> pure $ toSL j Accepted _ j -> pure $ toSL j _ -> fail "No journal" , field "doi" $ \i -> case getItemBody i of Published _ _ d -> pure $ show (doiLink d) ] eprintCtxt :: StringConv a String => Context (Eprint a) eprintCtxt = fold $ [ field "eprint" $ \i -> case itemBody i of ArXivEprint a _ -> pure $ show $ arXivLink ArXivAbs a OtherEprint _ l -> pure $ show $ l , field "eprintName" $ \i -> case itemBody i of ArXivEprint {..} -> "arXiv" OtherEprint n _ -> show n , field "arXivClass" $ \i -> case itemBody i of ArXivEprint _ c -> pure $ toSL c _ -> fail "No arXiv" , functionField "arXivLink" $ \args i -> case itemBody i of ArXivEprint a _ -> case args of ["abs"] -> pure $ show $ arXivLink ArXivAbs a ["pdf"] -> pure $ show $ arXivLink ArXivPdf a ["src"] -> pure $ show $ arXivLink ArXivSrc a xs -> fail $ "Invalid argument to arXivLink: " <> show xs _ -> fail "No ArXiv" ] maybeContext :: Context a -> Context (Maybe a) maybeContext = transformContext_ $ maybe (fail "Got Nothing") pure findLocal :: (StringConv a String, StringConv String a) => Item (Paper a) -> Compiler (Maybe (Eprint a)) findLocal paper = case eprint $ itemBody paper of Just e -> pure $ Just e Nothing -> do let k = key $ itemBody paper ident = toFilePath $ itemIdentifier paper findIdentifiers (fromString (ident <> ".pdf") .||. fromString (ident <> "/" <> toSL k <> ".pdf")) >>= witherM (fmap (>>= parseRelativeReference) . getRoute) >>= pure . \case (x:_) -> Just $ OtherEprint (toSL "eprint") x _ -> Nothing