mathgenealogy 1.2.0 → 1.3.0
raw patch · 6 files changed
+326/−137 lines, 6 filesdep +binarydep +filepathdep ~directory
Dependencies added: binary, filepath
Dependency ranges changed: directory
Files
- CmdParams.hs +84/−0
- Entry.hs +78/−21
- Extract.hs +5/−5
- Graph.hs +3/−4
- Main.hs +124/−99
- mathgenealogy.cabal +32/−8
+ CmdParams.hs view
@@ -0,0 +1,84 @@+-----------------------------------------------------------------------------+-- |+-- Module : CmdParams+-- Copyright : (C) Peter Robinson 2010-2013+-- License : GPL-2+--+-- Maintainer : Peter Robinson <thaldyron@gmail.com>+-- Stability : experimental+-- Portability : portable +-- +-- Contains the command line parameter definitions.+--+-----------------------------------------------------------------------------+module CmdParams+where+import System.Console.CmdArgs++data OutputFile = FileSVG | FilePDF | FilePNG + deriving(Eq,Data,Typeable)++instance Show OutputFile where+ show FileSVG = ".svg"+ show FilePDF = ".pdf"+ show FilePNG = ".png"++outputFileToGraphviz :: OutputFile -> String+outputFileToGraphviz FileSVG = " -Tsvg "+outputFileToGraphviz FilePDF = " -Tpdf "+outputFileToGraphviz FilePNG = " -Tpng "+++instance Default OutputFile where+ def = FilePDF++-- | Command line arguments:+data MathGenealogy = MathGenealogy + { prefix :: String + , keepDotFile :: Bool+ , graphvizArgs :: String+-- , onlyDotFile :: Bool+ , verbose :: Bool+ , includeTheses :: Bool+ , startURL :: String+ , outputFile :: OutputFile+ , font :: String+ , fontHeading :: String+ , fontSize :: Double+ , fontSizeHeading :: Double+ , fontSizeFirst :: Double+ , fontSizeFirstHeading:: Double+ , nodeBackgroundColor :: String+ , edgeColor :: String+ , oldTextLabels :: Bool+ }+ deriving(Eq,Data,Typeable,Show)+++mathGenealogy :: MathGenealogy+mathGenealogy = MathGenealogy+ { startURL = def &= args &= typ "URL" + , prefix = "output" &= typ "PREFIX" + , keepDotFile = False + , graphvizArgs = " -Gcharset=utf8 " &= typ "<graphviz parameters>" -- &= opt " -Gcharset=utf8 "+-- , onlyDotFile = False &= help "Only create a GraphViz '.dot' file."+ , verbose = False &= help "Print data to terminal."+ , includeTheses= False &= help "Include PhD thesis in output"+ , outputFile = enum [ FileSVG &= help "create SVG file (default - best supported by GraphViz; use this if you run into issues.)"+ , FilePDF &= help "create PDF file"+ , FilePNG &= help "create PNG file"+ ]+ , font = "Helvetica" &= help "Fonts included with GraphViz (see http://www.graphviz.org/doc/fontfaq.txt): AvantGarde-Book AvantGarde-BookOblique AvantGarde-Demi AvantGarde-DemiOblique Bookman-Demi Bookman-DemiItalic Bookman-Light Bookman-LightItalic Courier Courier-Bold Courier-BoldOblique Courier-Oblique Helvetica Helvetica-Bold Helvetica-BoldOblique Helvetica-Narrow Helvetica-Narrow-Bold Helvetica-Narrow-BoldOblique Helvetica-Narrow-Oblique Helvetica-Oblique NewCenturySchlbk-Bold NewCenturySchlbk-BoldItalic NewCenturySchlbk-Italic NewCenturySchlbk-Roman Palatino-Bold Palatino-BoldItalic Palatino-Italic Palatino-Roman Symbol Times-Bold Times-BoldItalic Times-Italic Times-Roman ZapfChancery-MediumItalic ZapfDingbats "+ , fontSize = 12 &= help "Font size of the additional information of all entries except the first one."+ , fontHeading = "Helvetica" &= help "Font used for names"+ , fontSizeHeading = 16 &= help "Font size used for names"+ , fontSizeFirstHeading = 20 &= help "Font size of first entry."+ , fontSizeFirst = 16 &= help "Font size of first entry."+ , nodeBackgroundColor = "LightBlue1" &= help "Node background color. See http://hackage.haskell.org/packages/archive/graphviz/2999.15.0.1/doc/html/Data-GraphViz-Attributes-Colors-X11.html"+ , edgeColor = "Gray" &= help "Edge color. See http://hackage.haskell.org/packages/archive/graphviz/2999.15.0.1/doc/html/Data-GraphViz-Attributes-Colors-X11.html"+ , oldTextLabels = False &= help "Fall back to non-HTML text labels. Use this if you are having issues with the rendering of the HTML-like labels. Note that all font parameters except 'font', 'fontsize', and 'fontsizefirst' are ignored with this setting."+ } &= summary "Mathematics Genealogy Visualizer (C) 2010-2013 Peter Robinson thaldyron@gmail.com" + &= details[ "Run the program with a start-URL, for example:"+ ,"# mathgenealogy http://genealogy.math.ndsu.nodak.edu/id.php?id=18231"+ ,"Disclaimer: This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License (version 2) for full details."+ ]
Entry.hs view
@@ -15,16 +15,18 @@ import Data.List(intercalate) import Data.Text.Lazy(Text) import qualified Data.Text.Lazy as T+import qualified Data.GraphViz.Attributes.HTML as GA+import Data.Text.Lazy.Encoding +import Data.Binary+import Control.Monad(liftM) data Entry = Entry { entryName :: Text , entryGraduationInfo :: [GraduationInfo] , entryAdvisors :: [(Text,Text)] }- deriving(Ord,Eq)+ deriving(Eq,Ord) -urlAdvisors :: Entry -> [Text]-urlAdvisors = map (T.pack . (++) "http://genealogy.math.ndsu.nodak.edu/" . T.unpack . snd) . entryAdvisors data GraduationInfo = GraduationInfo { gradDegree :: Maybe Text@@ -32,22 +34,42 @@ , gradYear :: Maybe Text , gradThesis :: Maybe Text }- deriving(Ord,Eq)+ deriving(Eq,Ord) -entryToText :: Entry -> Text-entryToText e =- entryName e `T.append` (T.concat $ map graduationInfoToText (entryGraduationInfo e))- `T.append` (T.concat $ map fst (entryAdvisors e))+instance Binary Text where+ put = put . encodeUtf8+ get = liftM decodeUtf8 get +instance Binary Entry where+ put (Entry x1 x2 x3) = put x1 >> put x2 >> put x3+ get = do + x1 <- get+ x2 <- get+ x3 <- get+ return $ Entry x1 x2 x3+ +instance Binary GraduationInfo where+ put (GraduationInfo x1 x2 x3 x4) = put x1 >> put x2 >> put x3 >> put x4+ get = do + x1 <- get+ x2 <- get+ x3 <- get+ x4 <- get+ return $ GraduationInfo x1 x2 x3 x4++++urlAdvisors :: Entry -> [Text]+urlAdvisors = map (T.pack . (++) "http://genealogy.math.ndsu.nodak.edu/" . T.unpack . snd) . entryAdvisors++ instance Show Entry where show e = let ginfos = concatMap show (entryGraduationInfo e) in T.unpack (entryName e)- ++ if ginfos /= [] then "\n" ++ ginfos else ""- where - maybeShow (Just g) = "\\n" ++ show g- maybeShow Nothing = ""+ ++ if length ginfos > 2 then "\\n" ++ ginfos else "" + instance Show GraduationInfo where show g = let ls = map T.unpack $ catMaybes [gradDegree g, gradUniversity g, gradYear g] in@@ -56,19 +78,54 @@ maybeShow (Just gi) = T.unpack gi maybeShow Nothing = "" ++-- | Transform an `Entry` to plaintext. +entryToText :: Entry -> Text+entryToText e =+ let ginfos = T.intercalate (T.pack "\\n") $ map graduationInfoToText (entryGraduationInfo e) in+ entryName e `T.append` (if T.length ginfos > 2 then T.pack "\\n" `T.append` ginfos else T.pack "")++ graduationInfoToText :: GraduationInfo -> Text graduationInfoToText g = - let ls = catMaybes [gradDegree g, gradUniversity g, gradYear g] in- T.intercalate (T.pack ", ") ls `T.append` (T.pack "\\n") `T.append` (maybeText (gradThesis g))- where- maybeText (Just gi) = gi - maybeText Nothing = T.pack "" + let ls = catMaybes [gradDegree g, gradUniversity g, gradYear g] in+ T.intercalate (T.pack ", ") ls `T.append` (maybeText (gradThesis g))+ where+ maybeText (Just gi) = T.pack "\\n" `T.append` gi + maybeText Nothing = T.pack "" +-- | Transform an `Entry` to an HTML-like label.+entryToHtml :: GA.Attributes -- ^ table attributes+ -> GA.Attributes -- ^ font options for header+ -> GA.Attributes -- ^ font options for body text+ -> Entry+ -> GA.Label+entryToHtml tableAtts headingAtts fontAtts e = + let ginfos = intercalate [GA.Newline []] $ map graduationInfoToHtml (entryGraduationInfo e) in+ GA.Table $ GA.HTable Nothing tableAtts $+ (GA.Cells [GA.LabelCell [GA.Align GA.HCenter] $ + GA.Text [GA.Font headingAtts [GA.Str (entryName e)]]]) :+ [GA.Cells [GA.LabelCell [] $ GA.Text [GA.Font fontAtts ginfos]]+ | not $ null ginfos ]+++graduationInfoToHtml :: GraduationInfo -> [GA.TextItem]+graduationInfoToHtml g = + let ls = catMaybes [gradDegree g, gradUniversity g, gradYear g] + thesis = maybeText (gradThesis g) in+ case (null ls,isNothing $ gradThesis g) of + (True,True) -> []+ (True,False) -> [thesis] + (False,True) -> [GA.Str (T.intercalate (T.pack ", ") ls)]+ (False,False) -> GA.Str (T.intercalate (T.pack ", ") ls) : (GA.Newline [] : [thesis])+ + where+ maybeText (Just gi) = GA.Str gi+ maybeText Nothing = GA.Str $ T.pack ""++ removeThesis :: Entry -> Entry removeThesis e = - e{ entryGraduationInfo = map (\g -> g{ gradThesis = Nothing }) $ entryGraduationInfo e }--- e{ entryGraduationInfo = case entryGraduationInfo e of--- Nothing -> Nothing--- Just g -> Just g{gradThesis = Nothing}}+ e{ entryGraduationInfo = map (\g -> g{ gradThesis = Nothing }) $ entryGraduationInfo e }
Extract.hs view
@@ -15,12 +15,10 @@ where import Network.HTTP import Text.HTML.TagSoup-import Control.Monad-import Control.Exception import Data.Char(isSpace)-import Data.Maybe import Data.Text.Lazy(Text) import Data.Text.Lazy.Encoding +import Control.Exception import qualified Data.Text.Lazy as T import qualified Data.ByteString.Lazy.Char8 as B import Control.Applicative@@ -29,6 +27,7 @@ import Entry +openURL :: String -> IO Text openURL x = return . T.pack =<< getResponseBody =<< simpleHTTP (getRequest x) @@ -58,7 +57,7 @@ let suffixes = sections (~== "<span style=\"margin-right: 0.5em\">") tags in map (graduationInfo tags) suffixes where- graduationInfo tags suffix = + graduationInfo _ suffix = let getTag i = notEmptyMaybeTagText $ removeClutter $ suffix !! i degree = getTag 1 univ = getTag 3 @@ -71,6 +70,7 @@ | length s >= 6 = GraduationInfo degree univ year Nothing | length s >= 4 = GraduationInfo degree univ Nothing Nothing | length s >= 2 = GraduationInfo degree Nothing Nothing Nothing+ | otherwise = throw $ AssertionFailed "Error - Could not parse downloaded data!" advisors :: [Tag Text] -> [(Text,Text)] @@ -99,7 +99,7 @@ catMaybes' :: [(Maybe a,Maybe b)] -> [(a,b)] catMaybes' [] = [] catMaybes' ((Just a,Just l):xs) = (a,l) : catMaybes' xs- catMaybes' ((Just a,Nothing):xs)= catMaybes' xs+ catMaybes' ((Just _,Nothing):xs)= catMaybes' xs catMaybes' ((Nothing,_):xs) = catMaybes' xs maybeAdv adv@(Just t)
Graph.hs view
@@ -1,7 +1,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Graph--- Copyright : (C) Peter Robinson 2010-2012+-- Copyright : (C) Peter Robinson 2010-2013 -- License : GPL-2 -- -- Maintainer : Peter Robinson <thaldyron@gmail.com>@@ -9,19 +9,18 @@ -- Portability : portable -- ------------------------------------------------------------------------------module Graph+module Graph(entryGraph) where import qualified Data.Map as M import Data.Graph.Inductive import Data.Text.Lazy(Text)-import qualified Data.Text.Lazy as T import Entry -- | Maps scientist names to Entries type EntryMap = M.Map Text Entry mkEntryMap :: [Entry] -> EntryMap -> EntryMap-mkEntryMap es theMap = foldl (\theMap e -> M.insert (entryName e) e theMap) theMap es+mkEntryMap es theMap = foldl (\m e -> M.insert (entryName e) e m) theMap es entryGraph :: [Entry] -> Gr Entry ()
Main.hs view
@@ -15,155 +15,180 @@ import Control.Applicative import Control.Concurrent import Control.Exception+import Prelude hiding(catch)+import Data.Char(toUpper) import Data.GraphViz import Data.GraphViz.Attributes.Complete+import qualified Data.GraphViz.Attributes.HTML as GA import qualified Data.ByteString.Lazy.Char8 as B import qualified Data.List as L+import System.Console.CmdArgs hiding (args) import System.Cmd(system) import System.IO(hFlush,stdout) import System.Exit import System.Directory-import Data.Maybe import Data.Text.Lazy(Text)-import qualified Data.Text.Lazy.IO as TI import Data.Text.Lazy.Encoding import qualified Data.Text.Lazy as T-import System.Console.CmdArgs-import Prelude hiding(catch)+import qualified Data.Text.Lazy.IO as TI+import Safe(readDef)+import Data.Binary(encodeFile,decodeFile)+import System.FilePath(pathSeparator) +import CmdParams(mathGenealogy,MathGenealogy(..),outputFileToGraphviz) import Extract import Entry import Graph -data OutputFile = FilePDF | FilePNG | FileSVG- deriving(Eq,Data,Typeable)--instance Show OutputFile where- show FilePDF = ".pdf"- show FilePNG = ".png"- show FileSVG = ".svg"--outputFileToGraphviz :: OutputFile -> String-outputFileToGraphviz FilePDF = " -Tpdf "-outputFileToGraphviz FilePNG = " -Tpng "-outputFileToGraphviz FileSVG = " -Tsvg "---instance Default OutputFile where- def = FilePDF---- command line arguments:-data MathGenealogy = MathGenealogy - { filePrefix :: String - , keepDotFile :: Bool- , graphvizArgs :: String- , onlyDotFile :: Bool--- , verbose :: Bool- , includeTheses:: Bool- , startURL :: String- , outputFile :: OutputFile- }- deriving(Eq,Data,Typeable,Show)--mathGenealogy = MathGenealogy- { startURL = def &= args &= typ "URL" - , filePrefix = "output" &= typ "PREFIX" - , keepDotFile = False --- , graphvizArgs = " -Tpdf -Gcharset=utf8 " &= typ "<graphviz parameters>" &= opt " -Tpdf -Gcharset=utf8 "- , graphvizArgs = " -Gcharset=utf8 " &= typ "<graphviz parameters>" -- &= opt " -Gcharset=utf8 "- , onlyDotFile = False &= help "Only create the GraphViz '.dot' file"--- , verbose = False &= help "Print data to terminal."- , includeTheses= False &= help "Include PhD thesis in output"- , outputFile = enum [ FilePDF &= help "create PDF file (default)"- , FilePNG &= help "create PNG file"- , FileSVG &= help "create SVG file"- ]- } &= summary "Mathematics Genealogy Visualizer (C) 2010-2012 Peter Robinson thaldyron@gmail.com" - &= details[ "Run the program with a start-URL, for example:"- ,"# mathgenealogy http://genealogy.math.ndsu.nodak.edu/id.php?id=18231"- ,"This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License (version 2) for more details."- ]---- | GraphViz style attributes for edges and nodes.--- See: http://hackage.haskell.org/packages/archive/graphviz/2999.12.0.4/doc/html/Data-GraphViz-Attributes.html--- TODO: figure out if GraphViz supports CSS files or similar. -edgeAtt = const [ Dir Forward- , color LightBlue2- ] --nodeAtt (num,e) = - [ textLabel (T.pack (show e)) - , Shape BoxShape- , FontSize (if num == 1 then 18 else 14)- , styles [rounded,filled,bold]- , color LightYellow1- , FontName (T.pack "ZapfChancery-MediumItalic") -- "Helvetica")- ]--+main :: IO () main = do args <- cmdArgs mathGenealogy- let targs = args when (null $ startURL args) $ throw (AssertionFailed "Missing start-URL.\nTry 'mathgenealogy --help' for more information.") - gvExecutable <- (do m <- findExecutable "dot" - if m == Nothing - then throw $ AssertionFailed "Error - Couldn't find 'dot' program. Did you install graphviz?"- else return (fromJust m))+ gvExecutable <- findExecutable "dot" >>=+ maybe (throw $ AssertionFailed "Error - Couldn't find the 'dot' program. Did you install GraphViz?")+ return let traverseEntries :: [Text] -> IO [Entry] traverseEntries = traverseEntries' 1 [] [] where+ traverseEntries' :: Int -> [Entry] -> [Text] -> [Text] -> IO [Entry] traverseEntries' _ acc _ [] = return $ L.nub acc traverseEntries' c acc prevUrls (url:urls) = do e <- (if includeTheses args then id else removeThesis) `liftM` downloadEntry url threadDelay 1000000--- if verbose args --- then TI.putStrLn $ entryToText e--- else do - putStr $ show c ++ " "- hFlush stdout+ if verbose args then + TI.putStrLn $ entryToText e+ else do + putStr $ "..." ++ show c+ hFlush stdout let newUrls = urlAdvisors e traverseEntries' (c+1) (e:acc) (url:prevUrls) ((newUrls L.\\ prevUrls) ++ urls) - putStrLn "Downloading entries from http://genealogy.math.ndsu.nodak.edu..."- putStrLn "(this might take a few minutes)"- theGraph <- entryGraph <$> traverseEntries [T.pack $ startURL args]- putStrLn "done. :)"- let dotFileName = filePrefix args ++ ".dot" - putStr $ "Writing DOT-file " ++ dotFileName ++ "..."+ appDir <- getAppUserDataDirectory "mathgenealogy"+ doesDirectoryExist appDir >>= \exAppDir -> + unless exAppDir $ createDirectory appDir+ let entryFilename = tail $ L.dropWhile (/='=') $ startURL args+ mEntryFile <- findFile [appDir] entryFilename+ doDownload <- case mEntryFile of+ Nothing -> return True+ Just _ -> yesno False "Found locally stored data for this entry. Download new data and overwrite it?"++ let dotFileName = prefix args ++ ".dot" + theGraph <- if doDownload then do+ putStrLn "Fetching entries from http://genealogy.math.ndsu.nodak.edu..."+ putStrLn "(this might take a few minutes)"+ putStr "Downloading entry number"+ entries <- traverseEntries [T.pack $ startURL args]+ putStrLn ". Done. :)"+ encodeFile (appDir ++ [pathSeparator] ++ entryFilename) entries+ putStr $ "Building DOT-file '" ++ dotFileName ++ "' from downloaded data..."+ return $ entryGraph entries+ else do+ (entries::[Entry]) <- decodeFile (appDir ++ [pathSeparator] ++ entryFilename)+ putStr $ "Building DOT-file '" ++ dotFileName ++ "' from locally stored data..."+ return $ entryGraph entries++ + let edgeAtt = const [ Dir Forward+ , parseColor "Error - Could not parse edge color!" $ edgeColor args+ ] + let bgcolorX11 = parseColorX11 "Error - Could not parse node background color!" $ + nodeBackgroundColor args+ let nodeAtt (num,e) = + if not $ oldTextLabels args then+ [ styles [rounded,filled]+ , Shape PlainText+ , parseColor "Error - Could not parse node backgroundcolor!" $ + nodeBackgroundColor args+ , toLabel $ + let fshead = if num == 1 then fontSizeFirstHeading args + else fontSizeHeading args + fs = if num == 1 then fontSizeFirst args + else fontSize args in+ entryToHtml [ GA.BGColor $ X11Color bgcolorX11+ , GA.Border 0+ , GA.CellBorder 0+ ]+ [ GA.Face (T.pack $ fontHeading args)+ , GA.PointSize fshead+ ]+ [ GA.Face (T.pack $ font args)+ , GA.PointSize fs+ ] e + ]+ else+ [ styles [rounded,filled]+ , textLabel $ entryToText e+ , Shape BoxShape+ , FontSize (if num == 1 then fontSizeFirst args else fontSize args)+ , parseColor "Error - Could not parse node background color!" $ + nodeBackgroundColor args+ , FontName (T.pack $ font args) + ] let output = printDotGraph $ graphToDot nonClusteredParams{ fmtNode = nodeAtt , fmtEdge = edgeAtt } theGraph B.writeFile dotFileName (encodeUtf8 output) `catch` (\(e::IOException) -> do { print e ; throw e })- putStrLn "done. :)"+ putStrLn "success! :)" - unless (onlyDotFile args) $ do- putStr "Generating graphics file..."- let command = gvExecutable ++ " " ++ outputFileToGraphviz (outputFile args) ++ graphvizArgs args- ++ " " ++ dotFileName ++ " > " - ++ filePrefix args ++ show (outputFile args)- print command- result <- system command- when (isExitFailure result) $ do- print $ "Error running the graphviz (dot) program. I tried: " ++ command- throw $ AssertionFailed "Exiting."- putStrLn "done. :)"+ putStr $ "Generating graphics file " ++ prefix args ++ show (outputFile args) ++ "..."+ let command = gvExecutable ++ " " ++ outputFileToGraphviz (outputFile args) ++ graphvizArgs args+ ++ " " ++ dotFileName ++ " > " + ++ prefix args ++ show (outputFile args)+ when (verbose args) $+ print command+ result <- system command+ when (isExitFailure result) $ do+ print $ "Error running the graphviz (dot) program. I tried: " ++ command+ throw $ AssertionFailed "Exiting."+ putStrLn "done. :)" unless (keepDotFile args) $ removeFile dotFileName where isExitFailure (ExitFailure _) = True isExitFailure _ = False+ + parseColor :: String -> String -> Attribute+ parseColor errMsg colStr = + let colStr1 = headToUpper colStr in+ color (readDef (throw $ AssertionFailed errMsg) colStr1 :: X11Color) + parseColorX11 :: String -> String -> X11Color+ parseColorX11 errMsg colStr = + let colStr1 = headToUpper colStr in+ readDef (throw $ AssertionFailed errMsg) colStr1 :: X11Color++-- | Conver the first character of the string to upper-case.+headToUpper :: String -> String+headToUpper str = toUpper (head str) : tail str+ +-- | Download and parse an entry. downloadEntry :: Text -> IO Entry downloadEntry t = do res <- parseEntry <$> getTags t case res of- Nothing -> throw $ AssertionFailed "Error parsing fetched data. Did you provide a valid URL to an existing math-genealogy entry?"+ Nothing -> throw $ AssertionFailed "Error - Could not parse fetched data. Did you provide a valid URL to an existing math-genealogy entry?" Just r -> return r ++yesno :: Bool -- Set to 'True' iff "y" is the default value.+ -> String -- Prompt string.+ -> IO Bool -- 'True' if the user answered affirmatively.+yesno defval prompt = do+ putStr $ prompt ++ if defval then " (Y/n) " else " (y/N) "+ hFlush stdout+ str <- getLine+ if null str then+ return defval+ else case headToUpper str of+ "Y" -> return True+ "N" -> return False+ _ -> do+ putStrLn "Invalid input."+ yesno defval prompt
mathgenealogy.cabal view
@@ -1,11 +1,12 @@ Name: mathgenealogy -Version: 1.2.0+Version: 1.3.0 Synopsis: Discover your (academic) ancestors! -Description: A simple command line program for extracting data from the+Description: A command line program for extracting data from the Mathematics Genealogy Project (<http://genealogy.math.ndsu.nodak.edu/index.php>).+ Note that this database also contains many entries of computer scientists. . Lookup your entry at <http://genealogy.math.ndsu.nodak.edu/index.php> and then use that URL as a command line argument. @@ -15,15 +16,34 @@ > mathgenealogy http://genealogy.math.ndsu.nodak.edu/id.php?id=18231 . which produces the directed acyclic graph- <http://dl.dropbox.com/u/22490968/genealogy_of_gauss.png>. See + <http://dl.dropbox.com/u/22490968/genealogy_of_gauss.svg>. See . > mathgenealogy --help .- for more options. Requires GraphViz (in particular the /dot/ program) to run.+ for the complete list of options. Requires the /dot/ program, which is+ part of the GraphViz package (/version 2.28.0 or later!/) to run. .+ Feedback and bug reports are appreciated!+ .+ /Changes in 1.3.0:/+ .+ * Switched to HTML-like labels in GraphViz. This is required for the advanced+ font formatting options. ATTENTION: this needs a recent+ installation of GraphViz (Linux: 2.28.0; MacOS: 2.29) and will yield+ best results for SVG output files. If you have an older version of GraphViz+ or run into issues, try the '--oldtextlabels' option.+ .+ * Downloaded entries are stored locally. This avoids re-downloading the same+ data if you want to generate multiple graphs of the same entry with+ different formatting options.+ .+ * Added more options for fine-tuning the fonts and colors. (requested by users)+ .+ * Default output is now SVG, as this is the format best supported by GraphViz.+ . /Changes in 1.2.0:/ .- * Correct handling of entries with multiple PhDs (reported by Dima Pasechnik)+ * Fixed handling of entries that have multiple degrees. (reported by Dima Pasechnik) . /Changes in 1.1.1:/ .@@ -39,7 +59,7 @@ . /Changes in 0.0.2:/ .- * Fixed bug regarding trailing commas (reported by Alexander Koessler) + * Fixed handling of trailing commas (reported by Alexander Koessler) -- Homepage: http://darcs.monoid.at/mathgenealogy @@ -69,7 +89,7 @@ Executable mathgenealogy build-depends: base >= 4 && < 5 , text >= 0.11 && <0.13- , directory >= 1.1 && <1.3+ , directory >= 1.2 && <1.3 -- , haskell98 >= 1.1 && <2.1 , process >= 1.1 && < 1.2 , bytestring >= 0.9 && <1.0@@ -80,11 +100,15 @@ , tagsoup >= 0.12.6 && <0.13 , HTTP >= 4000.1.2 && <5000 , safe >= 0.3.3 && <0.5+ , binary >= 0.6.4 && <0.7+ , filepath >= 1.3.0 && <1.4 Main-Is: Main.hs Other-modules: Graph , Extract , Entry+ , CmdParams extensions: ScopedTypeVariables , DeriveDataTypeable--- ghc-options: -O+ , DoAndIfThenElse+ ghc-options: -Wall -- ld-options: -static -pthread