content: module Data.Graph.Inductive.Graphviz
         (Orient(..), graphviz, graphviz') where
  { import Data.Graph.Inductive.Graph;
     
    data Orient = Portrait
                | Landscape
                deriving (Eq, Show);
     
    o2s :: Orient -> String;
    o2s (Portrait) = "\trotate = \"0\"\n";
    o2s (Landscape) = "\trotate = \"90\"\n";
     
    graphviz ::
             (Graph g, Show a, Show b) =>
               g a b ->
                 String -> (Double, Double) -> (Int, Int) -> Orient -> String;
    i2d :: Int -> Double;
    i2d = fromInteger . toInteger;
    graphviz g t (w, h) p@(pw', ph') o
      = let { n = labNodes g;
              e = labEdges g;
              ns = concatMap sn n;
              es = concatMap se e;
              sz w' h'
                = if o == Portrait then show w' ++ "," ++ show h' else
                    show h' ++ "," ++ show w';
              ps = show w ++ "," ++ show h;
              (pw, ph) = if o == Portrait then p else (ph', pw');
              gs = sz (w * (i2d pw)) (h * (i2d ph))}
          in
          "digraph " ++ t ++ " {\n" ++ "\tmargin = \"0\"\n" ++ "\tpage = \""
            ++ ps
            ++ "\"\n"
            ++ "\tsize = \""
            ++ gs
            ++ "\"\n"
            ++ o2s o
            ++ "\tratio = \"fill\"\n"
            ++ ns
            ++ es
            ++ "}"
      where { sn (n, a)
                | sa == "" = ""
                | otherwise = '\t' : (show n ++ sa ++ "\n")
                where { sa = sl a};
              se (n1, n2, b)
                = '\t' : (show n1 ++ " -> " ++ show n2 ++ sl b ++ "\n")};
     
    graphviz' :: (Graph g, Show a, Show b) => g a b -> String;
    graphviz' g = graphviz g "fgl" (8.5, 11.0) (1, 1) Landscape;
     
    sq :: String -> String;
    sq ('"' : s)
      | last s == '"' = init s
      | otherwise = s;
    sq ('\'' : s)
      | last s == '\'' = init s
      | otherwise = s;
    sq s = s;
     
    sl :: (Show a) => a -> String;
    sl a
      = let { l = sq (show a)} in
          if (l /= "()") then (" [label = \"" ++ l ++ "\"]") else ""}
  