packages feed

mmsyn4 (empty) → 0.1.0.0

raw patch · 5 files changed

+231/−0 lines, 5 filesdep +basedep +directorydep +mmsyn2setup-changed

Dependencies added: base, directory, mmsyn2, mmsyn3, process, vector

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for mmsyn4++## 0.1.0.0 -- 2019-10-17++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2019 OleksandrZhabenko++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Main.hs view
@@ -0,0 +1,179 @@+module Main (main) where++import System.Info (os)+import System.Directory+import System.CPUTime (getCPUTime)+import System.Process (callCommand)+import CaseBi (getBFst')+import qualified Data.Vector as V+import EndOfExe (showE)+import Data.Maybe (isJust)++isSep :: Char -> Bool+isSep c = c == ':'++isWindows :: Bool+isWindows = take 5 os == "mingw" ++divideString :: (Char -> Bool) -> String -> [String]+divideString p xs | null xs = []+                  | otherwise = let (zs,ys) = break p xs in zs:divideString p (if null ys then ys else tail ys)+                 +isEscapeChar :: Char -> Bool+isEscapeChar xs = xs `elem` "\n\r"++dropEmptyLines :: [String] -> [String]+dropEmptyLines [] = []+dropEmptyLines (ys:yss) | let ts = dropWhile isSep ys in all isEscapeChar ts || null ts = dropEmptyLines yss +                        | otherwise = ys:dropEmptyLines yss++cells :: String -> [[String]]+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 = []++isTruncated :: String -> String -> Bool+isTruncated w w' = null w && not (null w')++toBoolList :: [String] -> [Bool]+toBoolList y = zipWith isTruncated y ([]:y)+   +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 ++ [[]]+            +lineN :: Int -> [[String]] -> [String]+lineN n xss = last $! take n xss++lineN' :: Int -> [[String]] -> [String]+lineN' n xss = last $! take (n-1) xss++createNthLine :: [[String]] -> Int -> [String]+createNthLine xss n | n < 1 || n > length xss = error "Undefined line!"+                    | n == 1 = head xss+                    | otherwise = createSecondLine (lineN' n xss) (lineN n xss)+                           +fillEmptyCells :: [[String]] -> [[String]]+fillEmptyCells xss = map (createNthLine xss) [1..length xss]++changeNthLine :: [String] -> String+changeNthLine xs = "\"" ++ concatMap (++"\"->\"") xs ++ endOfLineGv++dropLast :: String -> String+dropLast xs | isWindows = if drop (length xs - 5) xs == "->\"\r\n" +    then dropLast (take (length xs - 5) xs) +    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+                  +dropNull :: [String] -> [String]+dropNull = filter (not . null)++processCellsA :: String -> [[String]]+processCellsA = fillEmptyCells . cells++processCellsZ :: [[String]] -> String+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++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)+                   | otherwise = dropNull (lineN n x)+                                         +fillEmptyCells2 :: [[String]] -> [[String]]+fillEmptyCells2 x = map (createNthLine2 x) (reverse [1..length x])++beginsWithAtSign :: String -> Bool+beginsWithAtSign xs | length xs < 2 = False+                    | head xs == '@' = True +                    | head xs == '\"' && (head . tail $ 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)))++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]++-- | 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.+-- 2. Begin to enter the text in the cells.+-- 3. Do not use colons, instead when needed switch to the nearest cell to the right.+-- 4. To make a text visually highlighted (yellowish), start the cell with an ’@’ sign.+-- 5. Lines create different chains in the resulting graph. To produce an arrow to the text in the cell, enter it in the next cell in the row to the right.+-- 6. To make several arrows from the cell, switch to the next to the right cell, enter needed new texts there and in the located below cells.+-- 7. Usually, you can search the needed text with @Ctrl+F@ if needed.+-- 8. Empty lines in the table do not influence the resulting visualization. Above each line, except the first one, there must be at least one filled cell. It must be located above the text on the new line or even further to the right above. Otherwise, the program will produce no reasonably useful output.+-- 9. After entering all the text, save the sheet as an 1.csv file in the working directory. Otherwise, the program won’t work.+-- 10. Run the apprapriate executable mmsyn4 in the terminal 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.+-- 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 more visualizations. +-- 14. Afterwards, you have a list of svg files, x12.gv file as a last source file for Graphviz, and a list of csv files, and a saved spreadsheet file. Then you can use the produced visualizations for some other documents.+main :: IO ()+main = do +         xs <- readFile "1.csv"+         if length xs > 0 +           then do+                  putStrLn "Please, input the basic name of the visualization file!"+                  zs <- getLine +                  let ys = combineCells xs in writeFile "x12.gv" ys+                  ts <- getCPUTime+                  renameFile "1.csv" (show ts ++ "." ++ zs ++ ".csv")+                  x1 <- findExecutable $ showE "fdp"+                  x2 <- findExecutable $ showE "twopi"+                  x3 <- findExecutable $ showE "circo"+                  x4 <- findExecutable $ showE "neato"+                  x5 <- findExecutable $ showE "sfdp"+                  if all isJust [x1,x2,x3,x4,x5]+                    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' (showE "neato", V.fromList [('c', showE "circo"), ('f', showE "fdp"), ('n', showE "neato"), ('s', showE "sfdp"), ('t', showE "twopi")]) r+                       callCommand $ temp u ++ " -Tsvg x12.gv > " ++ show ts ++ zs ++ ".svg"+                     else error "Please, install the GraphViz so that its executables are in the directories mentioned in the variable PATH!"  +           else error "Epmty file 1.csv!"+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ mmsyn4.cabal view
@@ -0,0 +1,25 @@+-- Initial mmsyn4.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/++name:                mmsyn4+version:             0.1.0.0+synopsis:            The "glue" between electronic tables and GraphViz+-- description:+homepage:            http://hackage.haskell.org/package/mmsyn4+license:             MIT+license-file:        LICENSE+author:              OleksandrZhabenko+maintainer:          olexandr543@yahoo.com+-- copyright:+category:            Graphics+build-type:          Simple+extra-source-files:  ChangeLog.md+cabal-version:       >=1.10++executable mmsyn4+  main-is:             Main.hs+  -- other-modules:+  -- other-extensions:+  build-depends:       base >=4.11 && <4.13, directory >=1.3 && <1.4, process >=1.6 && <1.7, mmsyn2 >=0.1 && <0.2, vector >=0.12 && <0.13, mmsyn3 >=0.1 && <0.2+  -- hs-source-dirs:+  default-language:    Haskell2010