mmsyn4 0.1.2.0 → 0.1.3.0
raw patch · 4 files changed
+89/−56 lines, 4 files
Files
- ChangeLog.md +5/−0
- Main.hs +78/−52
- README +4/−2
- mmsyn4.cabal +2/−2
ChangeLog.md view
@@ -16,3 +16,8 @@ * First version revised C. Changed the output files scheme. Avoided a pipe redirection in the terminal. Some minor documentation and .cabal file improvements.++## 0.1.3.0 -- 2019-12-16++* First version revised D. Added the possibility to avoid using the at-sign in the resulting visualization file. Added the possibility to choose +different splines schemes according to the GraphViz documentation.
Main.hs view
@@ -43,23 +43,23 @@ cells x = map (divideString isSep) (dropEmptyLines (lines x)) changeCell :: String -> String -> String -> String-changeCell x y z | not . null $ y = y- | null y && (not . null $ z) = x- | otherwise = []+changeCell xs ys zs | not . null $ ys = ys+ | null ys && (not . null $ zs) = xs+ | otherwise = [] isTruncated :: String -> String -> Bool-isTruncated w w' = null w && not (null w')+isTruncated ws vs = null ws && not (null vs) toBoolList :: [String] -> [Bool]-toBoolList y = zipWith isTruncated y ([]:y)+toBoolList yss = zipWith isTruncated yss ([]:yss) countChanged :: [Bool] -> Int countChanged z = length (takeWhile not z) createSecondLine :: [String] -> [String] -> [String]-createSecondLine x y = take (countChanged (toBoolList y)) t- where t = zipWith3 changeCell x y u- u = tail y ++ [[]]+createSecondLine xss yss = take (countChanged (toBoolList yss)) tss+ where tss = zipWith3 changeCell xss yss uss+ uss = tail yss ++ [""] lineN :: Int -> [[String]] -> [String] lineN n xss = last $! take n xss@@ -69,7 +69,7 @@ createNthLine :: [[String]] -> Int -> [String] createNthLine xss n | n < 1 || n > length xss = error "Undefined line!"- | n == 1 = head xss+ | n == 1 = concat . take 1 $ xss | otherwise = createSecondLine (lineN' n xss) (lineN n xss) fillEmptyCells :: [[String]] -> [[String]]@@ -84,13 +84,11 @@ else xs ++ ";\r\n" | drop (length xs - 4) xs == "->\"\n" = dropLast (take (length xs - 4) xs) | otherwise = xs ++ ";\n"- + dropDouble :: String -> String-dropDouble xs | length xs > 1 = - if head xs == '\"' && head (tail xs) == '\"' - then dropDouble (tail xs)- else head xs:dropDouble (tail xs)- | otherwise = xs+dropDouble (x:y:xs) | x == '\"' && y == '\"' = dropDouble (y:xs)+ | otherwise = x:dropDouble (y:xs)+dropDouble xs = xs dropNull :: [String] -> [String] dropNull = filter (not . null)@@ -102,47 +100,47 @@ processCellsZ = concatMap (dropDouble . dropLast . changeNthLine) takeColumn :: Int -> [[String]] -> [String]-takeColumn n xss | if n < 1 then True else n > length (head xss) = error "Undefined column!"- | otherwise = map (head . drop (n-1)) xss- -findLastX :: Int -> Int -> [[String]] -> String-findLastX n m xss | if m < 2 then True else m > length xss = error "Undefined column!"- | otherwise = last . dropNull . take (m - 1) $ takeColumn n xss+takeColumn n xss | null xss = error "Empty list in takeColumn!"+ | if n < 1 then True else n > (length . head $ xss) = error "Undefined column!"+ | otherwise = map (concat . take 1 . drop (n-1)) xss +-- | m is a column number of the cell, which 'findParentCell' function returns, n is a line number of the cell, which calls 'findParentCell' function+findParentCell :: Int -> Int -> [[String]] -> String+findParentCell m n xss | if n < 2 then True else n > length xss = error "Undefined column!"+ | otherwise = last . dropNull . take (n - 1) $ takeColumn m xss+ createNthLine2 :: [[String]] -> Int -> [String] createNthLine2 x n | if n < 1 then True else n > length x = error "Undefined line!" | n == 1 = dropNull . head $ x- | null . head . lineN n $ x = findLastX (length . takeWhile null . lineN n $ x) n x:dropNull (lineN n x)+ | null . head . lineN n $ x = findParentCell (length . takeWhile null . lineN n $ x) n x:dropNull (lineN n x) | otherwise = dropNull (lineN n x) fillEmptyCells2 :: [[String]] -> [[String]]-fillEmptyCells2 x = map (createNthLine2 x) (reverse [1..length x])+fillEmptyCells2 xss = map (createNthLine2 xss) [length xss,length xss - 1..1] beginsWithAtSign :: String -> Bool-beginsWithAtSign xs | length xs < 2 = False- | head xs == '@' = True - | head xs == '\"' && (head . tail $ xs) == '@' = True+beginsWithAtSign xs | null xs = False+ | length xs < 2 = False+ | take 1 xs == "@" = True + | take 1 xs == "\"" && (drop 1 . take 2 $ xs) == "@" = True | otherwise = False findFilledWithColor :: [[String]] -> [String] findFilledWithColor = concatMap (filter beginsWithAtSign) -(+++) :: String -> String -> String -> String-(+++) x y z = x ++ y ++ z - endOfLineGv :: String endOfLineGv | isWindows = "\r\n" | otherwise = "\n" makeFilledWithColor :: [String] -> String-makeFilledWithColor xs = concat (zipWith3 (+++) (repeat "\"") xs (repeat ("\" [style=filled, fillcolor=\"#ffffba\"];" ++ endOfLineGv)))+makeFilledWithColor xss = concat (zipWith (++) xss (repeat (" [style=filled, fillcolor=\"#ffffba\"];" ++ endOfLineGv))) processCells :: String -> String processCells = processCellsZ . fillEmptyCells2 . processCellsA -combineCells :: String -> String-combineCells x = let (y,z) = (x,x) in concat ["strict digraph 1 {", endOfLineGv, "overlap=false", endOfLineGv, processCells z, - makeFilledWithColor . findFilledWithColor . fillEmptyCells2 . processCellsA $ y, endOfLineGv, "}", endOfLineGv]+combineCells :: String -> String -> String+combineCells x0 x = let ch = getBFst' ("true", V.fromList [("0", "false"), ("1", "true"), ("2", "ortho"), ("3", "polyline")]) x0 in let (y,z) = (x,x) in concat ["strict digraph 1 {", endOfLineGv, + "overlap=false", endOfLineGv, "splines=", ch, endOfLineGv, processCells z, makeFilledWithColor . findFilledWithColor . fillEmptyCells2 . processCellsA $ y, endOfLineGv, "}", endOfLineGv] {-| Usage 1. After installation the executable mmsyn4 is created. Afterwards, it is used to process files. So, open an office spreadsheet program, e. g. LibreOffice Calc.@@ -169,25 +167,53 @@ putStrLn "Please, input the basic name of the visualization file!" zs <- getLine ts <- getCPUTime- let ys = combineCells xs in writeFile (show ts ++ "." ++ zs ++ ".gv") ys- renameFile "1.csv" (show ts ++ "." ++ zs ++ ".csv")- let x1 = showE "fdp"- x2 = showE "twopi"- x3 = showE "circo"- x4 = showE "neato"- x5 = showE "sfdp"- if foldl1 (&&) (map isJust [x1,x2,x3,x4,x5])+ putStrLn "Please, specify the splines mode for GraphViz (see the documentation for GraphViz)"+ putStrLn "0 -- for \"splines=false\""+ putStrLn "1 -- for \"splines=true\""+ putStrLn "2 -- for \"splines=ortho\""+ putStrLn "3 -- for \"splines=polyline\""+ putStrLn "The default one is \"splines=true\""+ x2 <- getLine+ let x0 = take 1 x2+ putStrLn "Would you like to remove all \'@\' signs from the visualization file?"+ remAt <- getLine+ if take 1 remAt == "y" then do - putStrLn "Please, specify the GraphViz command: "- putStrLn "\'f\' -- for fdp"- putStrLn "\'t\' -- for twopi"- putStrLn "\'c\' -- for circo"- putStrLn "\'n\' -- for neato"- putStrLn "\'s\' -- for sfdp"- putStrLn "otherwise there will be used the default neato"- u <- getChar- let temp r = getBFst' (fromJust (showE "neato"), V.fromList (map (\(x, y) -> (x, fromJust y)) [('c', showE "circo"), ('f', showE "fdp"), ('n', showE "neato"), ('s', showE "sfdp"), ('t', showE "twopi")])) r- callCommand $ temp u ++ " -Tsvg " ++ show ts ++ "." ++ zs ++ ".gv -O "- else error "Please, install the GraphViz so that its executables are in the directories mentioned in the variable PATH!" + let ys = filter (/='@') . combineCells x0 $ xs in writeFile ("new." ++ show ts ++ "." ++ zs ++ ".gv") ys+ putStrLn "The visualization will be created without the at-sign."+ processFile 'n' ts zs+ removeFile $ show ts ++ "." ++ zs ++ ".csv"+ else do + let ys = combineCells x0 xs in writeFile (show ts ++ "." ++ zs ++ ".gv") ys+ putStrLn "The visualization will be created with the at-sign preserved."+ processFile 'a' ts zs else error "Epmty file 1.csv!" +processFile :: Char -> Integer -> String -> IO ()+processFile w ts zs = do+ renameFile "1.csv" (show ts ++ "." ++ zs ++ ".csv")+ let x1 = showE "fdp"+ x2 = showE "twopi"+ x3 = showE "circo"+ x4 = showE "neato"+ x5 = showE "sfdp"+ x6 = showE "dot"+ if all isJust [x1,x2,x3,x4,x5,x6]+ then do + putStrLn "Please, specify the GraphViz command: "+ putStrLn "\'d\' -- for dot"+ putStrLn "\'f\' -- for fdp"+ putStrLn "\'t\' -- for twopi"+ putStrLn "\'c\' -- for circo"+ putStrLn "\'n\' -- for neato"+ putStrLn "\'s\' -- for sfdp"+ putStrLn "otherwise there will be used the default sfdp"+ vs <- getLine+ let u = take 1 vs in if null u || u == "\n" || u == "\x0000" + then error "Please, specify the needed character" + else do + let temp = getBFst' (fromJust (showE "sfdp"), V.fromList (map (\(x, y) -> (x, fromJust y)) [("c", showE "circo"), ("d", showE "dot"), ("f", showE "fdp"), + ("n", showE "neato"), ("s", showE "sfdp"), ("t", showE "twopi")])) in callCommand $ temp u ++ (if w == 'n' then " -Tsvg new." else " -Tsvg ") ++ + show ts ++ "." ++ zs ++ ".gv -O "+ else error "Please, install the GraphViz so that its executables are in the directories mentioned in the variable PATH!"+
README view
@@ -32,8 +32,10 @@ or from the command line while being in the directory with the 1.csv file. Enter a word name of the .csv file to be saved. DO use alphanumeric symbols and dashes if- needed. Then specify the needed visualization scheme- by specifying the appropriate character in the terminal.+ needed. Then specify the needed splines and visualization + schemes by specifying the appropriate characters in the + terminal. For more information, see the GraphViz + documentation. 11. Your first visualization is then created. 12. Save the spreadsheet document as a spreadsheet file. 13. Repeat the steps from 2 to 12 as needed to produce
mmsyn4.cabal view
@@ -2,10 +2,10 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: mmsyn4-version: 0.1.2.0+version: 0.1.3.0 synopsis: The "glue" between electronic tables and GraphViz description: The program mmsyn4 converts a specially formated .csv file with a colon as a field separator obtained from the electronic table into a visualized by GraphViz graph.-homepage: http://hackage.haskell.org/package/mmsyn4+homepage: https://hackage.haskell.org/package/mmsyn4 license: MIT license-file: LICENSE author: OleksandrZhabenko