packages feed

pandoc-filter-indent-0.2.2.0: src/Token.hs

{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE ViewPatterns          #-}
-- | Common token representation used.
module Token(MyTok(..), MyLoc(..), Tokenized, line, col, mark, unwrap, unTikzMark) where

import           Data.Text(Text)
import qualified Data.Text as T
import           Optics.TH

-- * Common tokens and locations
--   We keep them here, so we can translate output from tokenizers to common format.
-- | Location is just line and column (not a slice.)
data MyLoc = MyLoc { _line :: Int  -- ^ Line number starting from 1
                   , _col  :: Int  -- ^ Column number starting from 1
                   , _mark :: Bool -- ^ Is this a valid indent mark?
                   }
  deriving (Eq, Ord, Show)

makeLenses ''MyLoc

-- | Token just classifies to blank, operator, and the style class
data MyTok =
    TBlank
  | TOperator
  | TKeyword
  | TCons
  | TVar
  | TNum
  | TOther
  | TTikz  Text -- TikZmark in a comment
  deriving (Eq, Ord, Show)

-- | Records tokenized and converted to common token format.
type Tokenized = (MyTok -- ^ Token type
                 ,MyLoc -- ^ Starting location for the token
                 ,Text  -- ^ text value of the token
                 )

-- | Unpack a Haskell comment with a TikZ mark indicator.
unTikzMark    :: Text -> Maybe Text
unTikzMark txt =
  unwrap "{->" "-}" txt >>= \case
    ""    -> Nothing
    aMark -> Just aMark

-- | Given opening text, and closing text,
--   check that input is "braced" by these, and strip them.
--   Return `Nothing` if input text does not match.
unwrap :: Text -- ^ Opening text
       -> Text -- ^ Closing text
       -> Text -- ^ Input to match
       -> Maybe Text
unwrap starter trailer   txt  |
  starter `T.isPrefixOf` txt &&
  trailer `T.isPrefixOf` txt  =
      Just
    $ T.dropEnd (T.length trailer)
    $ T.drop    (T.length starter) txt
unwrap _       _         _    = Nothing