{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}

-- | Postprocessing for the results of printing.
module Ormolu.Processing.Postprocess
  ( postprocess,
  )
where

import Data.Text (Text)
import qualified Data.Text as T
import Ormolu.Processing.Common
import qualified Ormolu.Processing.Cpp as Cpp

-- | Postprocess output of the formatter.
postprocess ::
  -- | Desired indentation level
  Int ->
  -- | Input to process
  Text ->
  Text
postprocess :: Int -> Text -> Text
postprocess Int
indent =
  [Text] -> Text
T.unlines
    ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Text
indentLine
    ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Text
Cpp.unmaskLine
    ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
magicComment)
    ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.lines
  where
    magicComment :: Text -> Bool
magicComment (Text -> Text
T.stripStart -> Text
x) =
      Text
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
forall s. IsString s => s
startDisabling Bool -> Bool -> Bool
|| Text
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
forall s. IsString s => s
endDisabling
    indentLine :: Text -> Text
indentLine Text
x = Int -> Text -> Text
T.replicate Int
indent Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x