Skip to content

Commit

Permalink
[#6] Add a switch for allowing comments
Browse files Browse the repository at this point in the history
Problem: We want the interpolator to support commentaries in
arbitrary lines.

Solution: Implement a switch to allow writing comments and
add some tests against the implementation.
  • Loading branch information
nalkuatov committed Jun 10, 2022
1 parent 3958e21 commit 476894a
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 2 deletions.
6 changes: 6 additions & 0 deletions core/src/Text/Interpolation/Nyan/Core/Internal/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ data IntData = IntData
data ParsedIntPiece
= PipString Text
-- ^ Mere text.
| PipComments Text
-- ^ Comments.
| PipNewline Text
-- ^ Some line feed.
-- This must be preferred over 'PipString'.
Expand Down Expand Up @@ -84,6 +86,7 @@ data PreviewLevel
-- | All switches options.
data SwitchesOptions = SwitchesOptions
{ spacesTrimming :: Bool
, commenting :: Bool
, indentationStripping :: Bool
, leadingNewlineStripping :: Bool
, trailingSpacesStripping :: Bool
Expand All @@ -100,6 +103,7 @@ data SwitchesOptions = SwitchesOptions
-- mandatory for specifying in the interpolator.
data DefaultSwitchesOptions = DefaultSwitchesOptions
{ defSpacesTrimming :: Maybe Bool
, defCommenting :: Maybe Bool
, defIndentationStripping :: Maybe Bool
, defLeadingNewlineStripping :: Maybe Bool
, defTrailingSpacesStripping :: Maybe Bool
Expand All @@ -117,6 +121,7 @@ data DefaultSwitchesOptions = DefaultSwitchesOptions
basicDefaultSwitchesOptions :: DefaultSwitchesOptions
basicDefaultSwitchesOptions = DefaultSwitchesOptions
{ defSpacesTrimming = Just False
, defCommenting = Just False
, defIndentationStripping = Just False
, defLeadingNewlineStripping = Just False
, defTrailingSpacesStripping = Just False
Expand All @@ -130,6 +135,7 @@ basicDefaultSwitchesOptions = DefaultSwitchesOptions
recommendedDefaultSwitchesOptions :: DefaultSwitchesOptions
recommendedDefaultSwitchesOptions = DefaultSwitchesOptions
{ defSpacesTrimming = Just False
, defCommenting = Just False
, defIndentationStripping = Just True
, defLeadingNewlineStripping = Just True
, defTrailingSpacesStripping = Just True
Expand Down
24 changes: 23 additions & 1 deletion core/src/Text/Interpolation/Nyan/Core/Internal/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Fmt (Builder, build, fmt)
import Text.Interpolation.Nyan.Core.Internal.Base
import Text.Megaparsec (Parsec, customFailure, eof, errorBundlePretty, label, lookAhead, parse,
single, takeWhile1P, takeWhileP)
import Text.Megaparsec.Char (string)
import Text.Megaparsec.Error (ShowErrorComponent (..))

newtype OptionChanged = OptionChanged Bool
Expand All @@ -25,6 +26,7 @@ newtype OptionChanged = OptionChanged Bool
-- | An accumulator for switch options during parsing.
data SwitchesOptionsBuilder = SwitchesOptionsBuilder
{ spacesTrimmingB :: (OptionChanged, Maybe Bool)
, commentingB :: (OptionChanged, Maybe Bool)
, indentationStrippingB :: (OptionChanged, Maybe Bool)
, leadingNewlineStrippingB :: (OptionChanged, Maybe Bool)
, trailingSpacesStrippingB :: (OptionChanged, Maybe Bool)
Expand All @@ -38,6 +40,7 @@ toSwitchesOptionsBuilder :: DefaultSwitchesOptions -> SwitchesOptionsBuilder
toSwitchesOptionsBuilder DefaultSwitchesOptions{..} =
SwitchesOptionsBuilder
{ spacesTrimmingB = (OptionChanged False, defSpacesTrimming)
, commentingB = (OptionChanged False, defCommenting)
, indentationStrippingB = (OptionChanged False, defIndentationStripping)
, leadingNewlineStrippingB = (OptionChanged False, defLeadingNewlineStripping)
, trailingSpacesStrippingB = (OptionChanged False, defTrailingSpacesStripping)
Expand All @@ -50,6 +53,7 @@ toSwitchesOptionsBuilder DefaultSwitchesOptions{..} =
finalizeSwitchesOptions :: MonadFail m => SwitchesOptionsBuilder -> m SwitchesOptions
finalizeSwitchesOptions SwitchesOptionsBuilder{..} = do
spacesTrimming <- fromOptional "spaces trimming" spacesTrimmingB
commenting <- fromOptional "allow commenting" commentingB
indentationStripping <- fromOptional "indentation stripping" indentationStrippingB
leadingNewlineStripping <- fromOptional "leading newline stripping" leadingNewlineStrippingB
trailingSpacesStripping <- fromOptional "trailing spaces stripping" trailingSpacesStrippingB
Expand All @@ -73,6 +77,12 @@ setIfNew desc new (OptionChanged ch, old)
| old == Just new = fail $ "Switch option `" <> desc <> "` is set redundantly"
| otherwise = return (OptionChanged True, Just new)

setCommenting :: SwitchesOptionsSetter m => Bool -> m ()
setCommenting enable = do
opts <- get
res <- setIfNew "allow comments" enable (commentingB opts)
put opts{ commentingB = res }

setSpacesTrimming :: SwitchesOptionsSetter m => Bool -> m ()
setSpacesTrimming enable = do
opts <- get
Expand Down Expand Up @@ -150,6 +160,11 @@ switchesSectionP defSOpts =
, single 'S' $> False
] >>= setSpacesTrimming

, asum
[ single 'c' $> True
, single 'C' $> False
] >>= setCommenting

, asum
[ single 'd' $> True
, single 'D' $> False
Expand Down Expand Up @@ -201,6 +216,7 @@ switchesHelpMessage sopts =
(error "")
(error "")
(error "")
(error "")
-- ↑ Note: If you edit this, you may also need to update
-- the help messages below.
in mconcat
Expand Down Expand Up @@ -257,8 +273,14 @@ switchesHelpMessage sopts =
intPieceP :: Ord e => Parsec e Text [ParsedIntPiece]
intPieceP = asum
[

-- consume comments
string "--" >>= \prefix -> do
content <- takeWhile1P Nothing (/= '\n')
pure $ one $ PipComments (prefix <> content)

-- consume normal text
one . PipString <$> takeWhile1P Nothing (notAnyOf [(== '\\'), (== '#'), isSpace])
, one . PipString <$> takeWhile1P Nothing (notAnyOf [(== '\\'), (== '#'), isSpace])

-- potentially interpolator case
, single '#' *> do
Expand Down
8 changes: 8 additions & 0 deletions core/src/Text/Interpolation/Nyan/Core/Internal/Processor.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Text.Interpolation.Nyan.Core.Internal.Base
processIntString :: SwitchesOptions -> ParsedInterpolatedString -> InterpolatedString
processIntString sopts istr = istr
& V.fromList
& do if commenting sopts then skipComments else id
& do if leadingNewlineStripping sopts then stripLeadingNewline else id
& do if trailingSpacesStripping sopts then stripTrailingLeadingWs else id
& do if indentationStripping sopts then stripCommonIndentation else id
Expand All @@ -30,6 +31,8 @@ processIntString sopts istr = istr
where
(&) = flip ($)

skipComments = V.filter \case PipComments{} -> False; _ -> True

stripLeadingNewline ps = case V.uncons ps of
Just (PipNewline _, ps') -> ps'
_ -> ps
Expand All @@ -45,6 +48,9 @@ processIntString sopts istr = istr
PipString s ->
let s' = trimText s
in if T.null s' then Nothing else Just (PipString s')
PipComments s ->
let s' = trimText s
in if T.null s' then Nothing else Just (PipString s')
p@PipInt{} -> Just p

trimLeftSpaces ps = case V.uncons ps of
Expand Down Expand Up @@ -104,6 +110,7 @@ processIntString sopts istr = istr
-- invisible spaces to break the newlines sequence.
p@PipLeadingWs{} : l -> p : skipNext l
p@PipString{} : l -> p : reduceNext l
p@PipComments{} : l -> p : reduceNext l
p@PipInt{} : l -> p : reduceNext l
[] -> []

Expand All @@ -113,6 +120,7 @@ processIntString sopts istr = istr
PipNewline nl -> IpString nl
PipLeadingWs n -> IpString . mconcat $ replicate (fromIntegral n) " "
PipEmptyLine -> IpString mempty
PipComments s -> IpString s
PipInt i -> IpInt i

glueStrings :: InterpolatedString -> InterpolatedString
Expand Down
1 change: 1 addition & 0 deletions core/tests/Test/Customization.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ _AllFieldsAreExported =
(error "")
(error "")
(error "")
(error "")
-- ↑ if you change this, also add a field to the record below
in basicDefaultSwitchesOptions
{ defIndentationStripping = Nothing
Expand Down
14 changes: 14 additions & 0 deletions core/tests/Test/Interpolator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,20 @@ test_DefaultInterpolator = testGroup "Default interpolator"

]

----------------------------------
, testGroup "Commenting"

[ testCase "Basic comments" do
[int|tc|Abc -- this is a comment|]
@?= "Abc "

, testCase "Comments in arbitrary lines" do
[int|tc| -- comments at the beginning
My text -- comments in the middle
-- comments at the end
|] @?= " \nMy text \n\n"
]

]

]
Expand Down
2 changes: 1 addition & 1 deletion core/tests/Test/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ test_TextParser = testGroup "Main text parser"

basicSwitchesOptions :: SwitchesOptions
basicSwitchesOptions =
SwitchesOptions False False False False AnyFromBuilder False False PreviewNone
SwitchesOptions False False False False False AnyFromBuilder False False PreviewNone

test_SwitchesParser :: TestTree
test_SwitchesParser = testGroup "Switches parser"
Expand Down

0 comments on commit 476894a

Please sign in to comment.