bibdb-0.4.2: src/Bibliography.hs
-----------------------------------------------------------------------------
-- |
-- Module : Bibliography
-- Description : Functions for renaming, sorting, and cleaning up bibliography
-- Maintainer : coskuacay@gmail.com
-- Stability : experimental
--
-- This module removes duplicates in a bibliography database, sorts
-- citations such that cross-referenced ones come after the referrers,
-- and renames citations according to the given rule table.
-----------------------------------------------------------------------------
module Bibliography (bibliography) where
import Control.Arrow ((&&&))
import Data.Maybe (mapMaybe)
import qualified Data.Map.Strict as Map
import qualified Data.Graph as Graph
import qualified Data.Tree as Tree
import Reference
bibliography :: [(RefIdent, RefIdent)] -> [BibTeX] -> [BibTeX]
bibliography renames database =
let databaseMap = Map.fromList $ map (bibIdent &&& id) database
renamed = map (\(s, t) -> renameBib t $ databaseMap Map.! s) renames
renamedMap = Map.fromList $ map (bibIdent &&& id) renamed
allMap = Map.union renamedMap databaseMap
all = Map.elems allMap
in topsort $ reachable (map snd renames) all
topsort :: [BibTeX] -> [BibTeX]
topsort bib = map ((\(bib, _, _) -> bib) . vertexMap) sorted
where
(g, vertexMap, _) = Graph.graphFromEdges $ map bibToNode bib
sorted = Graph.topSort g
reachable :: [RefIdent] -> [BibTeX] -> [BibTeX]
reachable roots bib = map ((\(bib, _, _) -> bib) . vertexMap) reachableVertecies
where
(g, vertexMap, key) = Graph.graphFromEdges $ map bibToNode bib
rootsVertex = mapMaybe key roots
reachableVertecies = concatMap Tree.flatten (Graph.dfs g rootsVertex)
bibToNode :: BibTeX -> (BibTeX, RefIdent, [RefIdent])
bibToNode bib = (bib, bibIdent bib, crossrefs bib)