aboutsummaryrefslogblamecommitdiff
path: root/haddock-library/src/Documentation/Haddock/Parser/Util.hs
blob: ffa91b09e6e1a7ada63b1b1af327c0c11fb99bc4 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
                                  









                                                   
                                          



                      
       
 



                                      
                                        
                                                   
                                           
                                    
 

                                              
 
                                             
                                
                                                                    
 

                                                              
 


                                                                             


                                                                          





                                         
 


                                                                                           
       
                        






                                                       
                                            
              
                                                 
                             
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module      :  Documentation.Haddock.Parser.Util
-- Copyright   :  (c) Mateusz Kowalczyk 2013-2014,
--                    Simon Hengel      2013
-- License     :  BSD-like
--
-- Maintainer  :  haddock@projects.haskell.org
-- Stability   :  experimental
-- Portability :  portable
--
-- Various utility functions used by the parser.
module Documentation.Haddock.Parser.Util (
  takeUntil,
  removeEscapes,
  makeLabeled,
  takeHorizontalSpace,
  skipHorizontalSpace,
) where

import qualified Text.Parsec as Parsec

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

import           Control.Applicative
import           Control.Monad (mfilter)
import           Documentation.Haddock.Parser.Monad
import           Prelude hiding (takeWhile)

import           Data.Char (isSpace)

-- | Characters that count as horizontal space
horizontalSpace :: [Char]
horizontalSpace = " \t\f\v\r"

-- | Skip and ignore leading horizontal space
skipHorizontalSpace :: Parser ()
skipHorizontalSpace = Parsec.skipMany (Parsec.oneOf horizontalSpace)

-- | Take leading horizontal space
takeHorizontalSpace :: Parser Text 
takeHorizontalSpace = takeWhile (Parsec.oneOf horizontalSpace)

makeLabeled :: (String -> Maybe String -> a) -> Text -> a
makeLabeled f input = case T.break isSpace $ removeEscapes $ T.strip input of
  (uri, "")    -> f (T.unpack uri) Nothing
  (uri, label) -> f (T.unpack uri) (Just . T.unpack $ T.stripStart label)

-- | Remove escapes from given string.
--
-- Only do this if you do not process (read: parse) the input any further.
removeEscapes :: Text -> Text
removeEscapes = T.unfoldr go
  where
  go :: Text -> Maybe (Char, Text)
  go xs = case T.uncons xs of
            Just ('\\',ys) -> T.uncons ys
            unconsed -> unconsed

-- | Consume characters from the input up to and including the given pattern.
-- Return everything consumed except for the end pattern itself.
takeUntil :: Text -> Parser Text 
takeUntil end_ = T.dropEnd (T.length end_) <$> requireEnd (scan p (False, end)) >>= gotSome
  where
    end = T.unpack end_ 

    p :: (Bool, String) -> Char -> Maybe (Bool, String)
    p acc c = case acc of
      (True, _) -> Just (False, end)
      (_, []) -> Nothing
      (_, x:xs) | x == c -> Just (False, xs)
      _ -> Just (c == '\\', end)

    requireEnd = mfilter (T.isSuffixOf end_)

    gotSome xs
      | T.null xs = fail "didn't get any content"
      | otherwise = return xs