diff options
| author | Chris Wells <chris@mathematicaster.org> | 2025-02-04 10:26:00 -0600 |
|---|---|---|
| committer | Chris Wells <chris@mathematicaster.org> | 2025-02-04 10:26:00 -0600 |
| commit | 7085075a90c03025e5d53a256d42e317805b879b (patch) | |
| tree | 69d2dfe53cf35258818482bec3b2ff52acfdb37d | |
| parent | ceb898747ad287e83fe18f81a955c186b7abac8e (diff) | |
| download | main-7085075a90c03025e5d53a256d42e317805b879b.tar main-7085075a90c03025e5d53a256d42e317805b879b.tar.gz main-7085075a90c03025e5d53a256d42e317805b879b.tar.bz2 main-7085075a90c03025e5d53a256d42e317805b879b.tar.lz main-7085075a90c03025e5d53a256d42e317805b879b.tar.xz main-7085075a90c03025e5d53a256d42e317805b879b.tar.zst main-7085075a90c03025e5d53a256d42e317805b879b.zip | |
Working on alias resolution
| -rw-r--r-- | data/people.yaml | 49 | ||||
| -rw-r--r-- | src/Data/Alias.hs | 107 | ||||
| -rw-r--r-- | src/Data/Name.hs | 30 | ||||
| -rw-r--r-- | src/Data/Person.hs | 45 | ||||
| -rw-r--r-- | src/Hakyll/Alias.hs | 42 | ||||
| -rw-r--r-- | www-main.cabal | 1 |
6 files changed, 228 insertions, 46 deletions
diff --git a/data/people.yaml b/data/people.yaml new file mode 100644 index 0000000..3273ab9 --- /dev/null +++ b/data/people.yaml @@ -0,0 +1,49 @@ +- name: Zach Brennan + aliases: + - Zachary Brennan + +- name: Joe Briggs + webpage: "https://josephguybriggs.wordpress.com/" + aliases: + - Joseph Briggs + - Joseph Guy Briggs + - Joseph G Briggs + - Joseph G. Briggs + +- name: Boris Bukh + webpage: "http://borisbukh.org/" + +- name: Steve Butler + webpage: "http://orion.math.iastate.edu/butler/" + +- name: Bryan Curtis + webpage: "https://sites.google.com/view/bryancurtis?pli=1" + +- name: Ziqin Feng + webpage: "https://www.auburn.edu/cosam/faculty/math_stats/fengz/index.htm" + +- name: Enrique Gomez-Leos + +- name: Leslie Hogben + webpage: "https://www.aimath.org/~hogben/" + +- name: Bernard Lidický + webpage: "http://lidicky.name/" + aliases: + - Bernard Lidicky + - "Bernard Lidick\\'y" + - "Bernard Lidick{\\'y}" + - "Lidick{\\' y}, Bernard" + +- name: Ryan Martin + webpage: "https://rymartin.name/" + aliases: + - Ryan R Martin + - Ryan R. Martin + +- name: Alex Parker + +- name: Coy Schwieder + +- name: Derrick Stolee + webpage: "https://stolee.dev/" diff --git a/src/Data/Alias.hs b/src/Data/Alias.hs new file mode 100644 index 0000000..1a00212 --- /dev/null +++ b/src/Data/Alias.hs @@ -0,0 +1,107 @@ +module Hakyll.Alias + ( Aliased (..) + , ToAliases (..) + , FromAlias (..) + -- * Containers + , AliasMap (..) + , buildAliasMap + -- * Errors + , NoAlias (..) + , missingAlias + ) where + +import Prolog +import Data.Aeson +import Data.Aeson.KeyMap qualified as KM +import Data.HashMap.Strict qualified as HM +import Data.HashSet qualified as HS + + +data WithAliases a x = WithAliases (HS.HashSet a) x + deriving (Foldable, Functor, Generic, Generic1, Ord, Show, Traversable) + +instance Hashable a => Applicative (WithAliases a) where + pure = WithAliases mempty + WithAliases a1 f <*> WithAliases a2 x = WithAliases (a1 <> a2) (f x) + +instance Comonad (WithAliases a) where + extract (WithAliases _ x) = x + duplicate = join (<$) + +-- instance (FromJSON a, FromJSON x, Hashable a) => FromJSON (WithAliases a x) where +-- parseJSON (Object v) = WithAliases +-- <$> v .:? "aliases" .!= mempty +-- <*> (parseJSON (Object v) <|> v .: "value") +-- parseJSON v = WithAliases mempty <$> parseJSON v + +-- instance (ToJSON a, ToJSON x) => ToJSON (WithAliases a x) where +-- toJSON (WithAliases a x) +-- | HS.null a = toJSON x +-- | otherwise = case toJSON x of +-- Object o -> Object $ KM.singleton "aliases" (toJSON a) <> o +-- v -> object +-- [ "aliases" .= a +-- , "value" .= v +-- ] + -- toEncoding (WithAliases a x) + -- | HS.null a = toEncoding x + -- | otherwise = case toEncoding + + +aliases :: WithAliases a x -> HS.HashSet a +aliases (WithAliases h _) = h + +instance (Binary a, Binary x) => Binary (WithAliases a x) + +instance (Hashable a) => ToAliases (WithAliases a x) where + toAliases (WithAliases h _) = h + +newtype Aliased a x = Aliased { unAliased :: Either a x } + deriving newtype (Bifoldable, Bifunctor, Bitraversable, Binary, Eq, Foldable, Functor, Generic, Generic1, Hashable, Ord, Traversable) + deriving stock (Show) + +class (Eq a, Hashable a) => ToAliases x a where + toAliases :: x -> HS.HashSet a + +instance Hashable a => ToAliases a a where + toAliases = HM.singleton + +instance (Eq a, Hashable a) => ToAliases (HashSet a) a where + toAliases = id + +instance ToAliases x a => ToAliases [x] a where + toAliases = foldMap toAliases + + +class FromAlias a x where + fromAlias :: MonadThrow m => a -> m x + +instance FromAlias a a where + fromAlias = pure + +instance (FromAlias a x, FromAlias b x) => FromAlias (Either a b) x where + fromAlias = either fromAlias fromAlias + +instance FromAlias a x => FromAlias (Aliased a x) x where + fromAlias = fromAlias . unAliased + + +newtype AliasMap a x = AliasMap (HM.HashMap a x) + deriving newtype (Binary, Foldable, Functor, Generic, Generic1, Semigroup, Monoid, Traversable) + deriving stock (Show) + +buildAliasMap :: (Foldable t, ToAliases x a) => t x -> AliasMap a x +buildAliasMap = fmap Aliasmap $ foldMap $ \x -> x <$ HS.toMap (toAliases x) + +lookupAlias :: (MonadThrow m, Hashable a, Show a) => a -> AliasMap a x -> m x +lookupAlias a (AliasMap h) = maybe (throwM $ NoAlias a) pure $ HM.lookup a h + + +newtype NoAlias a = NoAlias a + deriving (Eq, Show) + +instance Show a => Exception (NoAlias a) where + displayException (NoAlias a) = show a <> " is not an alias" + +missingAlias :: MonadThrow m => a -> m b +missingAlias = throwM . NoAlias diff --git a/src/Data/Name.hs b/src/Data/Name.hs index 9572709..b1f2739 100644 --- a/src/Data/Name.hs +++ b/src/Data/Name.hs @@ -10,6 +10,7 @@ module Data.Name ) where import Prolog +import Data.Aeson import Data.Char (isSpace) import Data.List qualified as L import Data.Text qualified as T @@ -19,7 +20,7 @@ data Name a = Name { lastName :: !a , firstName :: !a , middleName :: !(Maybe a) - } deriving (Eq, Functor, Foldable, Generic, Generic1, Ord, Show, Traversable) + } deriving (Eq, Functor, Foldable, Generic, Generic1, Hashable, Hashable1, Ord, Show, Traversable) type Name_ = Name StrictText @@ -29,6 +30,33 @@ instance Applicative Name where pure a = Name a a (pure a) Name l f m <*> Name l' f' m' = Name (l l') (f f') (m <*> m') +instance ToJSON a => ToJSON (Name a) where + toJSON (Name l f m) = object $ + [ "first" .= f + , "last" .= l + ] <> maybe [] (pure . ("middle" .=)) m + toEncoding (Name l f m) = pairs $ fold $ + [ "first" .= f + , "last" .= l + ] <> maybe [] (pure . ("middle" .=)) m + +instance StringConv s StrictText => ToJSONKey (Name s) where + toJSONKey = showNameLFM . toSL >$< toJSONKey + +instance StringConv StrictText s => FromJSONKey (Name s) where + fromJSONKey = FromJSONKeyTextParser $ fmap toSL . (readNameLFM <|> readNameFML) + + + +instance StringConv StrictText s => FromJSON (Name s) where + parseJSON (Object v) = fmap toSL $ Name + <$> v .: "first" + <*> v .: "last" + <*> v .:? "middle" .!= Nothing + parseJSON (String t) = toSL <$> readNameLFM t + parseJSON _ = empty + + readNameLFM :: Alternative m => StrictText -> m Name_ readNameLFM t = T.map (\c -> if c == '~' then ' ' else c) <<$>> diff --git a/src/Data/Person.hs b/src/Data/Person.hs index a649c07..e7c5f76 100644 --- a/src/Data/Person.hs +++ b/src/Data/Person.hs @@ -7,7 +7,10 @@ module Data.Person ) where import Prolog +import Data.Aeson +import Data.Alias import Data.Name +import Data.HashMap.Strict qualified as HM import Network.URI (URI) import Text.Blaze import Text.Blaze.Html @@ -17,15 +20,51 @@ import Text.Blaze.Html5.Attributes (href) data Person a = Person { name :: !(Name a) , webpage :: !(Maybe URI) - , aliases :: ![Name a] } deriving (Eq, Functor, Foldable, Generic, Ord, Show, Traversable) instance Binary a => Binary (Person a) personHtml :: (ToMarkup a) => Person a -> Html -personHtml (Person n w _) = +personHtml (Person n w) = let withLink = maybe id (\x -> a ! href (toValue x)) w in withLink $ renderNameFML $ toMarkup <$> n personFromName :: Name a -> Person a -personFromName n = Person n Nothing [n] +personFromName n = Person n Nothing + + + +instance (FromJSON (Name a), Hashable (Name a)) => FromJSON (WithAliases (Name a) (Person a)) where + parseJSON = withObject "Person" $ \v -> do + n <- v .: "name" + w <- v .:? "webpage" .!= Nothing + as <- v .:? "aliases" .!= mempty + pure $ WithAliases (HS.fromList $ n : as) (Person n w) + +instance (FromJSON (Name a), Hashable (Name a)) => FromJSON (AliasMap (Name a) (Person a)) where + parseJSON = fmap b . parseJSON + where + b :: [WithAliases (Name a) (Person a)] -> AliasMap (Name a) (Person a) + b = buildAliasMap + +-- instance (StringConv StrictText a, Hashable a) => FromJSON (AliasMap (Name a) (Person a)) where +-- parseJSON v = +-- -- m >>= traverse x >>= pure . AliasMap . mk +-- where +-- m :: Parser (HM.HashMap (Name StrictText) Value) +-- m = parseJSON v +-- x :: Value -> Parser (Maybe URI, [Name StrictText]) +-- x (Object o) = (,) +-- <$> o .:? "webpage" .!= Nothing +-- <*> o .:? "aliases" .!= mempty +-- x s@(String _) = (,) <$> (Just <$> parseJSON s) <*> pure mempty +-- x a@(Array _) = (,) <$> pure Nothing <*> parseJSON a +-- mk :: (StringConv StrictText t, Hashable t) => HM.HashMap (Name StrictText) (Maybe URI, [Name StrictText]) -> HM.HashMap (Name t) (Person t) +-- mk hm = +-- let personify :: (Name a, (Maybe URI, [Name a])) -> ([Name a], Person a) +-- personify (n, (w, ns)) = (n : ns, Person n w) +-- in foldMap ((\(ns,p) -> HM.fromList $ (, (toSL <$> p)) . fmap toSL <$> ns ) . personify) $ HM.toList hm + + + +-- -- instance ToJSON a => ToJSON (Person a) where diff --git a/src/Hakyll/Alias.hs b/src/Hakyll/Alias.hs deleted file mode 100644 index b127a05..0000000 --- a/src/Hakyll/Alias.hs +++ /dev/null @@ -1,42 +0,0 @@ -module Hakyll.Alias where - -import Prolog -import Data.HashSet qualified as HS - - -newtype Aliased a x = Aliased { unAliased :: Either a x } - deriving newtype (Binary, Eq, Foldable, Functor, Generic, Generic1, Hashable, Ord, Show, Traversable) - -class (Eq a, Hashable a) => ToAliases x a where - toAliases :: x -> HashSet a - -instance Hashable a => ToAliases a a where - toAliases = HM.singleton - -instance (Eq a, Hashable a) => ToAliases (HashSet a) a where - toAliases = id - -instance ToAliases x a => ToAliases [x] a where - toAliases = foldMap toAliases - - -class FromAlias a x where - fromAlias :: MonadThrow m => a -> m x - -instance FromAlias a a where - fromAlias = pure - -instance (FromAlias a x, FromAlias b x) => FromAlias (Either a b) x where - fromAlias = either fromAlias fromAlias - -instance FromAlias a x => FromAlias (Aliased a x) x where - fromAlias = fromAlias . unAliased - -newtype NoAlias a =NoAlias a - deriving (Eq, Show) - -instance Show a => Exception (NoAlias a) where - displayException (NoAlias a) = show a <> " is not an alias" - -missingAlias :: MonadThrow m => a -> m b -missingAlias = throwM . NoAlias diff --git a/www-main.cabal b/www-main.cabal index 688bdeb..0991eae 100644 --- a/www-main.cabal +++ b/www-main.cabal @@ -14,6 +14,7 @@ build-type: Simple library exposed-modules: + Data.Alias Data.Name Data.Person Hakyll.Core.Identifier.Pattorn |
