forked from LiveRamp/extravagance
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReplacer.hs
86 lines (64 loc) · 2.53 KB
/
Replacer.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module Replacer where
import Control.Monad
import Data.Char
import Data.List
import Data.Maybe
import Debug.Trace
import Text.Regex.Applicative
import Util
data Section = Section {
hash :: String,
text :: String
} deriving (Show)
instance Eq Section where
(==) Section {hash = hash1} Section {hash = hash2} = hash1 == hash2
(<++>) :: Monoid m => RE a m -> RE a m -> RE a m
a <++> b = mappend <$> a <*> b
inSet :: String -> Char -> Bool
inSet = flip elem
symIn :: String -> RE Char Char
symIn s = psym (`elem` s)
symNotIn :: String -> RE Char Char
symNotIn s = psym (not . inSet s)
whiteSpace :: RE Char String
whiteSpace = some $ psym isSpace
isPunc :: Char -> Bool
isPunc = isPunctuation .&& (/= '_')
punctuation ::RE Char String
punctuation = some $ psym isPunc
notWSOrPunc :: RE Char Char
notWSOrPunc = psym ((not . isSpace) .&& (not . isPunc))
linecomment :: RE Char String
linecomment = "//" <++> few anySym <++> "\n"
multicomment :: RE Char String
multicomment = "/*" <++> few anySym <++> "*/"
ignoredForEquality :: RE Char String
ignoredForEquality = join <$> many (linecomment <|> multicomment <|> whiteSpace <|> punctuation)
sectionMatcher :: RE Char Section
sectionMatcher = do
ignored <- ignoredForEquality
value <- many notWSOrPunc
return Section {hash = value, text = ignored ++ value}
sectionize :: String -> Maybe [Section]
sectionize = match (some sectionMatcher)
concatSections :: [Section] -> String
concatSections [] = []
concatSections (Section{text} : tail) = text ++ concatSections tail
mergeSections' :: Integer -> Bool -> [Section] -> [Section] -> [Section]
mergeSections' depth forceKeep (replacement : rem) (head : tail)
| replacement == head = (if forceKeep then head else replacement) : mergeSections' 0 False rem tail
| depth < 100 = head : mergeSections' (depth + 1) True (replacement : rem) tail
| otherwise = head : tail
mergeSections' _ _ _ orig = orig
mergeSections = mergeSections' 0 False
replaceMatchingStrings' :: String -> String -> Maybe String
replaceMatchingStrings' replacer original = do
sec1 <- sectionize replacer
sec2 <- sectionize original
return $ concatSections (mergeSections sec1 sec2)
replaceMatchingStrings :: String -> String -> String
replaceMatchingStrings replacer original = fromMaybe original replaced where
replaced = replaceMatchingStrings' replacer original