diff options
Diffstat (limited to 'latexfmt.hs')
-rw-r--r-- | latexfmt.hs | 71 |
1 files changed, 47 insertions, 24 deletions
diff --git a/latexfmt.hs b/latexfmt.hs index dc26a80..6c070fc 100644 --- a/latexfmt.hs +++ b/latexfmt.hs @@ -1,20 +1,23 @@ -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} -import Control.Applicative -import Control.Monad.State -import Data.Attoparsec.Text hiding ( take ) -import Data.Char ( isAlpha - , isDigit - ) -import qualified Data.Text as T -import qualified Data.Text.IO as T -import Prelude hiding ( print - , takeWhile - ) +import Control.Applicative +import Control.Monad +import Control.Monad.State +import Data.Attoparsec.Text hiding (take) +import Data.Char + ( isAlpha, + isDigit, + ) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import Prelude hiding + ( print, + takeWhile, + ) data Tokens = Wrd {unwrd :: T.Text} | Cmd T.Text | BSq [Tokens] | BCr [Tokens] | NL | Cmt T.Text | Nobs | IMath T.Text | Math T.Text | Verbatim Bool T.Text - deriving Show + deriving (Show) isCtrl x = not $ isAlpha x || isDigit x @@ -29,13 +32,14 @@ toStr (Wrd w) = do else print w when (w == "(") suppress when (T.last w == '.') printnl -toStr (Cmd c) = if T.length c > 0 && isCtrl (T.head c) || T.length c == 1 - then print' $ "\\" `T.append` c - else do - printnl' - when (c == "end") unindent - print $ "\\" `T.append` c - when (c == "begin") indent +toStr (Cmd c) = + if T.length c > 0 && isCtrl (T.head c) || T.length c == 1 + then print' $ "\\" `T.append` c + else do + printnl' + when (c == "end") unindent + print $ "\\" `T.append` c + when (c == "begin") indent toStr (BSq ts) = do print' "[" suppress @@ -50,7 +54,7 @@ toStr (BCr ts) = do mapM_ toStr ts unindent print' "}" -toStr NL = printnl' >> printnl +toStr NL = printnl' >> printnl toStr (Cmt c) = do print "%" print' c @@ -69,30 +73,49 @@ toStr (IMath m) = do -- Tokeniser ws = inClass " \t\n" + pad = takeWhile ws + token = nl <|> pad *> (nobs <|> verbatim <|> verbatimStar <|> math <|> cmd <|> bsq <|> bcr <|> cmt <|> wrd) + nobs = string "~" *> pure Nobs + nl = string "\n" *> takeWhile (inClass " \t") *> string "\n" *> pure NL + cmd :: Parser Tokens cmd = Cmd <$> (string "\\" *> ((unwrd <$> wrd) <|> pure "")) + bsq = BSq <$> (string "[" *> many' token) <* pad <* string "]" + bcr = BCr <$> (string "{" *> many' token) <* pad <* string "}" + wrd = Wrd <$> takeWhile1 (notInClass " \t\n[]{}\\~") + cmt = Cmt <$> (takeWhile1 (== '%') *> takeWhile (/= '\n')) + math = oldmath <|> newmath <|> oldimath <|> newimath + oldmath = Math <$> (string "$$" *> takeWhile (/= '$')) <* string "$$" + newmath = Math . T.pack <$> (string "\\[" *> manyTill' anyChar (string "\\]")) + oldimath = IMath <$> (string "$" *> takeWhile (/= '$')) <* string "$" + newimath = IMath . T.pack <$> (string "\\(" *> manyTill' anyChar (string "\\)")) + verbatim = Verbatim False . T.pack <$> (string "\\begin{verbatim}" *> manyTill' anyChar (string "\\end{verbatim}")) + verbatimStar = Verbatim True . T.pack <$> (string "\\begin{verbatim*}" *> manyTill' anyChar (string "\\end{verbatim*}")) -- indented printer type Beginning = Bool + type Indent = Int + type SuppressSpace = Bool + data Printer = Printer Beginning SuppressSpace Indent T.Text - deriving Show + deriving (Show) print :: T.Text -> State Printer () print str = do @@ -101,7 +124,7 @@ print str = do then print' str else do let indent = T.pack . take (2 * i) $ repeat ' ' - str' = T.concat [s, if beg then indent else " ", str] + str' = T.concat [s, if beg then indent else " ", str] put $ Printer False False i str' -- force unindented @@ -109,7 +132,7 @@ print' :: T.Text -> State Printer () print' str = do (Printer beg _ i s) <- get let indent = T.pack . take (2 * i) $ repeat ' ' - str' = T.concat [s, if beg then indent else "", str] + str' = T.concat [s, if beg then indent else "", str] put $ Printer False False i str' printnl :: State Printer () |